Jump to content

jdunham

Members
  • Posts

    625
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by jdunham

  1. QUOTE (Anders Björk @ Sep 29 2008, 03:55 AM)

    Right near the end of that article is the salient point

    QUOTE

    - The prompt and transparent handling of the banking sector problems in also important. The terms for recapitalisation should be such as to avoid moral hazard problems.

    What 'moral hazard' means is that if you reward the bad behavior of taking foolish risks, you encourage the same behavior in the future. We're teaching the bankers that as long as their casino bets are large enough to threaten the global economy, the politicians will be forced to bail them out, making it a no-lose situation. While I suspect this bailout is truly necessary, I haven't seen where we are preventing the moral hazard.

    A lot of Americans suspect that the only people weathly enough to recapitalize the banks are the former bank executives who get to keep their 'nut' (compensation in the hundreds of millions $US for falling asleep at the wheel) because they have bought and paid for the politicians who have no real interest in punishing the guilty.

    I realize there's not much point in replying unless I have something funny to add. I just don't have it in me today. :P

  2. QUOTE (raymyster @ Sep 26 2008, 12:13 PM)

    my problem is that i have three 1D arrays:

    Array number 1: a string array, lets say for example (sensor names) ===> data type: string

    Array number 1: a numeric array, lets say for expamle (sensor number) ===> data type: numeric

    Array number 3: a color box array, lets say for example (sensor color) ===> data type: color box

    i want to take these three arrays & put them in the database table lets say sensor_description this way:

    field 1: sen_name field 2: sen_num field 3: sen_color

    the problem is you can't combine an array of different data types :wacko:

    I recommend making a typedef cluster of one of each type. Then you should start to make individual VIs which can format this for a table, or for your database, or for display. Then you make your arrays into an array of these clusters, and you can just call your VIs in a loop. (If it needs to be fast, you can rethink whether the loop is inside or outside the subvi).

    In an object-oriented world, this typedef is your class object, and it represents your real-world sensor object, and then your set of VIs which work on this class is your set of methods. Even if you don't use lvclasses for this (I probably wouldn't bother), thinking about your code like this will probably make your design better.

  3. I think the real issue is that once you are an experienced user and you know what you want, the palettes mostly get in the way. The right answer is other tools like QuickDrop in LV8.6 (though i'm still stuck in LV8.5 for now). Presumably you want multi-selection so that you spend less time digging around in them. But if you need stuff on different palettes, and NI implements some kind of checkbox selection interface, I think it would be complex and annoying.

    I don't think that fixing the palettes themselves is as good as bypassing them. They are great for browsing around and exploring the feature set, but not that great for quick access to known items. Mostly I just drag and drop stuff from other similar VIs, especially controls for the front panel.

  4. QUOTE (mstoeger @ Sep 22 2008, 01:13 AM)

    The datatype "waveform" has advantages: dt, channel names and scales and other attributes are the easiest solution to keep this information when converting data to other NON-NI-data and/or file formats.

    When reading data once per second, I can start with applying filters, check limits and so on. After retrieving for example 300 reads I start with other calculations: fft, etc. And the last step is to store a piece of data with a "duration" of 300 sec into one file (or export it to another file format).

    At the moment I prepare an array for y-data of all channels for 300 sec, get waveform components, and after finishing read no. 300 I build an array of waveforms again.

    Sure, there are other possibilities: Get the date as 2D-array and not as waveform, take use of the function append waveforms, enlarge the daqmx buffer and read only all 300 sec., ...

    But I wonder, that there is not a proven, much simpler way. Because I think, this is a just usual task.

    Yes, You just need DAQmx Read.vi, and set the polymorphic selector to Analog -> Multiple Channels -> Mulitple Samples -> 1D Waveform

    and you will get an array of Waveform datatypes with one element for each of your channels. Before you execute that, get a DAQmx Read property node and set the "relative to" and "offset" properties to the desired value and you should be all set. You're right that this is simple and usual.

    Good luck

  5. QUOTE (Ben Zimmer @ Sep 21 2008, 12:55 PM)

    This is a bit of an advanced notion, but is a great solution to the question: how to acquire "essentially" forever. Once you wrap your mind around how to do this, I'd wager you use the circular buffer over and over in all of your projects. I know I do.

    If you're using DAQmx, it has a circular buffer built in. If you set the acquisition to "continuous" it will acquire forever (not sure what happens when you roll over an I64, but at 1Hz, you won't live to see it).

    There should be plenty of DAQmx examples you can use. If you need fancier access to specific points of the built-in circular buffer, you can have better control with DAQmx property nodes. Try out some of the examples and then post more questions if you hit a stumbling block.

    If you are using other hardware, especially non-NI products, then Ben is right; you may have to write your own circular buffer.

  6. I just posted this on the LV wish list. Since one doesn't ever get feedback from that (except maybe seeing your idea in a far-future version of LabVIEW), I wanted to get some reaction (support) here.

    QUOTE

    I usually use Bundle By Name rather than the plain Bundle for clusters, and certainly for all typedef clusters. The only time not to use it is when you need to do a multi-key sort, since that works really well, and the cluster data structure is just temporary. 99% of the time my clusters are typedefs, and using Bundle By Name always makes the code clearer and easier to debug by inspection.

    However there is a disadvantage in that if I add something to my cluster, then existing bundle by name nodes will just use the default value for the new item, and it's not always easy to find all the associated bundling nodes. This often leads to bugs.

    In contrast, I use enums a fair amount, and I disable the use of "Default" in the case structures, so when I add an item, my application breaks in a bunch of places, and so I am forced to go fix them all and in the process most of the potential bugs are eliminated right away.

    My suggestion is to add a right-click checkable property to the bundle by name node, requiring it to have all elements explicitly wired in. Then if I turned this on for a given node, the VI would break whenever I add an element (just like it does when I remove an element).

    It would also be helpful to have this on the unbundle by name node though I realize it's not very labview-like to be forced to wire a nodes outputs.

  7. QUOTE (Shaun Hayward @ Sep 19 2008, 10:34 AM)

    The reason we wanted to keep the servers for the different sites is that we do not have the speediest connections between sites, and therefore when you are in your home office, you would be able access the repositories at the full speed of the local network, regardless of whether your office is the HQ. Also, as far as concurrent users go, we a little over 20 engineers right now (and are trying to find more) so we would want something that is scalable for the future.

    I know that pallets are good way for reusable VIs, but in this instance we were more thinking about application / system frameworks - we have the same basic software package on several systems and just pick and choose the modules that are appropriate before customizing it to suit the individual customer.

    Have you ever had any reliability issues with svn? (especially with the all-eggs-in-one-basketrepository approach)?

    I think it would be a disaster to try to maintain separate SVN repositories at different locations if they shared data. With all the time that you will waste, it would be better to invest in more network bandwidth. Also remember you are not on the network all the time. You only really hit the network a few times per day, and SVN's deltas make network transfers very efficient.

    You might want to think about separate repositories for each customer in case there are issues with customer proprietary data, since it would be easy to archive a project and remove it from your server some time after the contract ends. But I would still run them all on the same server machine. However, Philippe is right that everything will probably be easier in a single repo.

    Don't be afraid of big numbers, they won't hurt you.

    Overall, I wouldn't worry abou the reliability/scalability issues. Your team is much smaller than many others which are successfully using SVN. Good luck.

  8. QUOTE (BrokenArrow @ Sep 18 2008, 01:02 PM)

    Because a LabVIEW class user only has access to the information you provide when you document the LabVIEW class, be sure to document the class and member VIs as completely as possible.

    Can someone please explain what that means?

    Well the idea is that if you have a good reusable object, you don't release the source code. Not always to keep it secret, but also to keep people from changing something that has already been debugged, and to keep them from breaking the encapsulation. So if you have a defined interface and a defined behavior and a hidden implementation, you need to document that better than you might document your 'normal' code, at least if you're anything like me.

    If you have the source code, this doesn't really apply to you. And since you failed to be able to reuse the object, you could probably call the design a failure.

  9. QUOTE (eaolson @ Sep 18 2008, 11:03 AM)

    • the project root directory gets an overall .lvproj file and the top-level VI, along with any INI file that will be loaded
    • subVIs - all subVIs under the top-level VI go here. If the number of files becomes large, it gets divided further by category.
    • typedefs - for typedefs used by the subVIs
    • controls - for custom GUI components
    • docs - non-LabVIEW documentation for the VI
    • HardwareDriver1, etc. - reusable components like hardware drivers are separate projects and are checked into their own directory using svn-externals
    • build - (unversioned) EXE builds and installers get generated into this directory. For some reason, LabVIEW seems to want to build into the parent of the project by default, which seems confusing to me.

    I don't believe it's good to keep typedefs separately. Even if you are not using OOP, it's better to group your files by topic rather than file type. If you are doing a report, do you keep your Word files in a separate folder from your Excel files? Even if the typedefs are used across your code, they should be "owned" by some functional group. GUI controls are sort of the same. Some may be a "window" into one of your modules, and should be grouped with the rest of that module/group for maximum reusability.

    The build folder should not be under your project. That way it is easy to check in all of your source code without having to ignore all the build output.

    The other thing I do is under my project, I have a folder called "source" and all code, including the lvproj, is under that. So under my project, I typically have

    • Source
    • Config
    • Data
    • Doc-internal
    • Doc-external
    • Build

    What's nice about this is that it's easy to check out different versions (Source, Source.version23, Source.latestrelease, source.trunk, etc.) of the source and run them against the same data and config files as needed.

    The reason for two documentation folders is that I think it's useful to separate stuff generated internally (it's a lot like source code and should always be under revision control), from stuff you get from customers and vendors, which is very useful, but you didn't get paid to generate, and is not part of your intellectual property.

  10. QUOTE (dannyt @ Sep 16 2008, 02:10 AM)

    This is using LabVIEW 8.2.1 and I noticed that when in a case statement the scan for string does not read the format string if it passed in from outside.

    Is this expected behaviour and the same in the newer version of LabVIEW ?

    Definitely expected behavior. LabVIEW sometimes reads a constant format value as a help. If you care about the data types, you shouldn't rely on that but should wire in a default value for each output.

  11. usually you would use a circular buffer. I think you should be able to find plenty of examples, either in LabVIEW examples or on the web. If you are using a National Instruments card, the circular buffer is usually done for you, but I would need more details on what you are reading to give you advice.

    It's somewhat unusual to get one sample per loop, and then perform an FFT, because usually interesting FFTs come from pretty fast data streams, and you are often getting many samples with every iteration.

  12. QUOTE (crelf @ Sep 12 2008, 12:37 PM)

    Yep - it's an age old problem - you can't measure the frequency of a signal that's period is larger than your timeout :) I wouldn't so much ignore the error, but filter it and output a number that represents the lowest frequency that your timeout allows.

    Crelf's implied point is that you should pick a timeout as short as you can, limited by the smallest frequency you care about measuring.

  13. QUOTE (Darren @ Sep 9 2008, 12:11 PM)

    I agree...it seems to me we should turn off this setting for subVIs in a built EXE. I made sure the App Builder team is aware of this thread. For now, you can use the attached VI Analyzer Test (saved in 8.6) to detect this situation in your VIs before you build an EXE. Place this LLB in [LabVIEW Data]\VI Analyzer Tests, then launch Tools > VI Analyzer > Analyze VIs and the SubVI Suspend When Called test will be one of the tests you can run. Note that in LabVIEW 8.6, you do not need to have the VI Analyzer Toolkit installed in order to run tests...the UI and Engine for the VI Analyzer are now part of core LabVIEW...the toolkit now consists of the toolkit's original test suite and the VI-based analysis API.

    Let me know if you have any questions,

    -D

    I guess it's possible that some misguided soul will design suspend-when-called into a built executable as a lame way of interacting with the user. I also heard (on LAVA) that debugging a built EXE works if you run a computer with the development system installed, though I haven't tried it. So it seems like there should be a possibility to get SWC to work in a built EXE, but you should have to jump through some hoops to make it happen rather than being on by default.

    Thanks for the heads up about the analyzer. I will definitely add that to our pre-build check as we migrate to 8.6.

    Jason

  14. I sent this in as a tech support issue, but I am posting it here for tips and/or comment:

    QUOTE

    We have a large application with multiple developers, and we ship the code with our product, which runs 24x7x365. If any VI or subVI instance is set to "Suspend When Called" (SWC) and the panel is not included in the build, then the built application will put up a "Null Window" dialog box, even if debugging is not enabled.

    We can actually search the VI hierarchy for VIs with SWC set, and check this before building (this is the kind of thing the App Builder should do for you!!!), but there is no way to check that a subvi instance does not have this setting enabled in the subvi's popup menu.

    It is very easy to leave this on by accident and forget about it, and have this setting end up in the build. If the VI is not used frequently, then it's possible that it won't show up during testing, but having an unplanned dialog box come up will cause major problems. It's basically a showstopper.

    Obviously if there is a way to find or disable this in my exe's I would like to know, but if I am correct that there is no way, I would like to try to get this prioritized for a future release.

    From an overall view, it is important that LabVIEW make it very difficult to have unexpected dialog boxes produced by a built executable.

  15. Error handling is great, and we use it just about everywhere, especially if there is any I/O or any chance for invalid arithmetic results. But if the routine does not have any need for error handling, then I think it is counterproductive to add it. If you were writing "Trim Whitespace.vi" for your own library, would you add error handling?

    Some of our code just converts between data structures, and those absolutely need to be in subvis so that the conversion is encapsulated. However there is usually no need for error handling. If there is bad data in the cluster, there will usually be an error thrown somewhere nearby, and it doesn't matter whether the conversion itself operates on an empty cluster.

  16. QUOTE (jlokanis @ Sep 2 2008, 04:11 PM)

    In my case, I launch many copies of the same VIT that call many reentrant VIs (all set to shared clones) that in turn create their own SEQs and pass them around to communicate between my producer and multiple consumers (7, in fact). So, if I was to preallocate, my memory usage would be through the roof (as it was before the shared close feature was added).

    Is there something special about using VI Templates? Nowadays you can just launch clones of a normal reentrant VI, without any copying, by passing option 8 into the Open VI Reference function. How are the queues 'passed around'? I think you said you used unnamed queues, but then it's not clear how that fits in with your cloning (not that we really need to know, but it may shed some light on your issue).

  17. QUOTE (jlokanis @ Sep 2 2008, 01:01 PM)

    NI has stated that you should not use the shared clones reentrant type if your VI has uninitialized shift registers (Functional Global). This is because the data space is shared between all instances of the VI so state cannot be maintained.

    My question is, what about consumers that have uninitialized shift registers? Since these VIs stay in memory and are running continuously, shouldn't they be immune to this problem? Can I have many instaces of this reentrant VI all running at once, without any data loss/corruption as long as they are all actively running (and waiting for their queue to feed them the next command?) I think this should work, but since I am seeing some strange behaviors, it would be good to get some second opinions.

    Thanks,

    -John

    Disclaimer: it's quite possible I don't know what I'm talking about. I'm just guessing based on experience and the minimal documentation provided.

    I think it's misleadingto say "the data space is shared". It may be more helpful to say "the data space may be recycled" between your instances. Running Labview VIs can't share a data space period, otherwise the data in the wires would get mixed up. If your vi is not reentrant, then there is just one data space, but calls to the VI will be blocking so that the data space is not shared. (I'm sure you know this)

    So if it's reentrant, then the safest thing to do is manufacture a new data space for each instance of the reentrant VI, since the instances can run in parallel. I think this is how LV used to work before this option was introduced. The drawback is that if you call the reentrant VI from 10,000 clones of the same VI, you would need 10,000 data spaces, and you might have a memory problem. If your system is such that only a couple of these are actually invoked in parallel, and you don't care about preserving state (USRs), then you would want LabVIEW to recycle the data spaces.

    However, if you start to invoke the VI,and all of the existing copies of the data space are in use, then LV will have to make a new data space right then and there, and that will introduce jitter. If timing is much more important than memory use, or if you are using LV tricks to remember state across calls, then you want to pre-allocate. I would imagine you would want this most of the time, so that the USRs that we're all addicted to will just work like always.

    But if your application design is such that preallocating clones is a huge waste of memory, it's nice to have this directive where the programmer can promise LabVIEW that the VI won't be relying on saved state, and in return LV will try to reuse any existing data spaces which have not yet been garbage collected. I'm guessing these checkboxes were was added because somebody designed some application and it was a huge memory hog, and it turned out that it was a side-effect of LV assuming that data spaces should never be recycled.

    EDIT: I was too slow!

  18. QUOTE (Ton @ Sep 1 2008, 11:59 AM)

    We really needed these, but I would extend them to say that they need to be available with property nodes or method VIs so that automated builds are possible.

    We couldn't wait and had to roll out a hacked version which directly edits the lvproj file. I feel like every second we spent on that was just wasted effort because it should have been added to the lvproj system right up front.

    Jason

  19. QUOTE (jlokanis @ Aug 29 2008, 01:56 PM)

    Thanks for the reply. That is definitely a way to cause a queue to be deallocated. In my case, however, I don't think that is possible. The structure of my code has a main vi that calls a sub VI to create the queue and then passes the queue ref to another sub VI that listens to the queue. When the listener quits, it passes its error cluster to the sub VI that destroys the queue. Since all of these VIs are part of the main VI, i don't see how it is possible that the queue reference would be automatically removed from memory. The VI that get the error is running as a sub VI of the same VI that called the VI that created the queue.

    I think the LV engine get 'confused' and screws this up. I can see many examples of this happening in various parts of my code where queues either become invalid while waiting or are invalid when passed to a subVI, even though a release was never called and their creator VI is still in memory and supposedly 'reserved for run' still...

    Perhaps there is some issue with all these VIs being reentrant? I only use the shared clones mode, but none of them have a uninitialized shift register...

    John:

    We also use plenty of queues and a smattering of reentrant VIs. We get error 1122 all the time, because we kill the queues on purpose to stop our processes, but it never happens unexpectedly.

    Are you using the "destroy" input for the Close Queue function? You should not need to destroy the queues, just close all the references you open. (there are good times to set destroy=True, but don't just set it because you feel like it).

    If not, then I would try to set a breakpoint immediately after the enqueue or dequeue function which is throwing that error and then poke around to see which of your parallel Vis is still running.

    Good luck.

  20. QUOTE (HChandler @ Aug 29 2008, 09:04 AM)

    If you have a reuse folder, I would just export it from svn, move it somewhere else on your HD, make a new SVN repo, and then try to load your old project. You may need to remove your reuse Vis from the project first, not sure. Be sure that the reuse VIs have been remove from the former hard drive location where they had been seen by your lvproj vis.

    Then I would load the project, and then make a new VI within the project, and drop as many of the reuse libs you can on that new VIs diagram. Then I would load your existing VIs and hopefully they will safely relink to the new location. The main thing is you have to make sure the old ones can't be found and that the new ones are in memory in your lvproj's application instance (loaded by some VI included in your project).

    Good luck

    QUOTE (HChandler @ Aug 29 2008, 09:04 AM)

    I can't help feeling that NI has over sold its "professional" development system. After spending 4 grand, the thought of spending an additional $1K... :thumbdown:

    Having formerly worked on integrated java/c++/etc projects using cvs and other free tools, the fact that this is such a huge and painful issue seems to be a huge oversight no NI's part.

    I guess that's what happens when everyone's drinking the same cool aid.

    Well it's true that "professional developers" have not been NI's bread and butter to date. Those free tools don't have some of the great out-of-the-box functionality with hardware that NI has, and NI has great tech support, which you pay for. A seat of LabVIEW costs a lot less than other kinds of software which make 'real' engineers productive, like ProE or Solidworks. I think that compared to the cost of labor for an engineer, the cost of the toolset (i.e LabVIEW and MS Office and a PC) to make that labor have value is relatively small; it's just a few percent of the total cost.

    But you're right about the kool-aid.

    Jason

  21. QUOTE (Aristos Queue @ Aug 28 2008, 03:51 PM)

    The problem with that is that you will be tempted to make changes in the "common directory" since those VIs will be loaded and editable. One solution would be to make the whole folder read-only, so LabVIEW would not be able to store your foolish edits. That is safe, but will probably get old in a hurry. :headbang:

    Any way you go, you will probably want a separate SVN repository for your reuse library.

    If you use "SVN externals" (more details in the svn docs), you can include the reuse library within each of your other projects. With the SVN external, local changes to the reuse library will be checked into the reuse repository along with your normal checkin. Once checked in, the improvements will be available to your other project(s) whenever you proceed to update them. Some SVN users think this is evil, but you will find it quite handy. :yes:

    Whenever you release your software, you can change the svn:external to point to a specific revision of the reuse library, so your release is protected from future evil changes in the library. Whenever you change the library, you risk breaking the other projects, but unless you are talking about released code, you should just keep fixing it and making the interfaces as clean and encapsulated as possible and the bugs will be minimized over time.

    To avoid the cross-linking, all you have to do is make sure that none of your reuse VIs access any of the project-specific VIs. Part of this is just good design, but in case you slip up, I would write a tool that inspects all loaded VIs and makes sure that no VIs in your reuse folder call any subvis outside that folder. It would be great if LabVIEW had better support for this, but you may be able to adapt Ton's Project Scanner (http://forums.lavag.org/Project-Scanner-t11635.html) to get this working, or else trick him into adding it as a feature. :thumbup:

    You will also want to check out the VI Package Manager http://www.jkisoft.com/vipm, which was designed to solve many of these problems. [others beat me to this before I could finish my post]

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.