Jump to content

Mike Le

Members
  • Posts

    180
  • Joined

  • Last visited

  • Days Won

    6

Everything posted by Mike Le

  1. I'm running into a very strange Actor Framework problem. It's extremely hard to reproduce, so unfortunately I can't share the code (it's a large and proprietary project). I also don't think I can reduce it to a smaller example. I'm going to describe the behavior I'm seeing and hope that others here have (1) seen something similar or (2) have more debugging suggestions. I have a Controller Actor that launches four Nested Actors: the UI, a Hardware Interface, a Real-Time Plotter, and an Analysis Plotter. When the UI Actor panel closes, it sends a Stop message to the Caller (the Controller). The Controller sends a Stop message to all Nested Actors. Locked Behavior Scenarios Running and then closing the UI window results in locked libraries in the following scenarios. 1) Program is launched and streaming of data (from HW Interface to Controller to Real-Time Plotter) is started. The UI Window is closed. 2) Program is launched and UI Window is immediately closed (<2 seconds open). Description of "Locking" Behavior When the libraries are locked, the project window also exhibits strange behavior. I am able to "collapse" virtual folder and library contents. However, I cannot re-expand them. I am able to click and select files (highlighting them as selected). A right-click results in a complete freeze of the IDE, requiring a restart. Trying to simply "x" out of the Project Window causes all windows to close, but LabVIEW.exe keeps running until I do a task-kill. Additionally, if I try to Launch Debug Actor after the project window has locked, the execution gets held up in the Launch Actor primitive. Specifically, in the attempt to open the VI reference. It errors the first time and runs through the "VI Interface Type 4" property node into the "Open Reference" primitive. It never gets past the "Open Reference" primitive (not even to return an error). It just stays locked in execution, seemingly indefinitely. Last, SOMETIMES locking is not consistent. I can sometimes go through a complete run without any locking behavior the FIRST time. Running the code a SECOND time always yields the locked behavior in the above scenarios. Clean Shutdown Scenarios Running and then closing the UI window DOES NOT result in the locked behavior in the following scenarios. 1) Program is launched with only some of the 4 Nested Actors enabled, then the UI window is closed immediately. Example combinations: GUI + Analysis / GUI + Streaming + Analysis / GUI + Analysis + HW Interface / GUI only. 2) Launch Debug Actor is run. Debug Actor window comes up. THEN Program is launched with all 4 Nested Actors. This always closes cleanly in all tested scenarios: closing the GUI window immediately, streaming and then closing the GUI, etc. 3) I added a popup window to my Parent Actor overrides of Pre-Launch Init and Stop Core. They simply pop up a dialog that says "____ Actor starting up" or "______ Actor shutting down" respectively. With this modification, I can watch all Actors start up and shut down as expected. I can close the UI window immediately or start streaming, etc. Libraries never lock. 4) I disabled the dialogs and added a 100ms wait to "Pre-Launch Init." With this addition, everything closes cleanly under streaming and "close immediately" scenarios. Dropping the delay to 10ms causes the locking behavior to return. Next Steps I'm going to try disabling different parts of each Actor and see if there's any particularly problematic section. I may try adding a small delay between Launch Actor calls in the Controller, just to see what happens. Anyone seen anything like this? Any suggestions? When I restart, I get a weird error window that says "internal warning 0x occurred in setstate.cpp." This is the first time I've seen an error "0x" that doesn't have a followup identifying string. I attached one of the error logs if anyone wants to look at it.
  2. I've attached an example. The graph is set to "Scale Object with Pane." When executed, OpenG's "Fit VI window to Largest Decoration" method is called. Both the graph and the decoration shrink to a much smaller size. Closing the VI without saving and reopening it will restore the original sizes. If you uncheck "Scale Object with Pane" on the graph and execute, the window resizes to the decoration. Neither the Graph nor the decoration get erroneously resized. Our actual use case is more complicated, but basically involves a transparent decoration to set an initial size, but with the option for the user to resize. I stripped it down to just show the buggy behavior with as few parts as possible. Fit VI Window to Decoration Bug.vi
  3. In the past, I've refreshed Graph Indicators, but now I find a need to refresh the entire front panel. The issue is this: I have a "primary" front panel with several subpanels. The subpanels load modules on start-up and the modules arrange themselves around each other (automatic layout). The primary front panel does some initialization on itself when it starts. It zeroes its panel origin, hides scrollbars, etc. Depending on how it's called, it may perform other initialization steps. These initialization steps must finish before any modules are loaded into subpanels, or the subpanels may not arrange themselves in the correct layout. I have error wires going from the primary initialization and then to the VI that launches the modules. But it seems like, even though the error wires force the front panel's property/invoke nodes to execute first, that the layout of the main front panel doesn't finish updating before the modules load: they are consistently offset. Placing a 100ms wait between the two VIs solves the problem, but I hate artificial time delays. This is something that pure data flow should be able to handle. I've searched for a way to force a refresh/redraw of the front panel and come up empty. Any suggestions?
  4. Well, regardless I'll have to crop it down to the Graph control and the embedded subpanels. That's discouraging, I was planning on using user32.dll. We'll see how that goes.
  5. Jordan, what's the advantage of ShareX versus using LabVIEW's built-in Windows API? It seems much simpler just to drop a call to the Windows DLL for keyboard commands and use "printscreen" rather than build something in LabVIEW to talk to ShareX? Maybe I'm confused about what you're suggesting.
  6. That's frustrating but not terribly surprising. I may have to use the Windows API to call "print screen" and then crop it to the right area, which I'm worried could lead to little bugs or problems.
  7. I have a front panel with a few overlapping subpanels. The subpanels are transparent and sitting on top of a graph, with data plotted. One of them is my custom Legend control, which displays all the plotted signals. I'd like to take a screenshot of it and output to picture. I tried using the built-in "Get Image" invoke nodes. I found that even though the subpanels are transparent, when output as a picture, they return as opaque - thus obscuring parts of the graph. I need to take a picture of the panel exactly as it is, including the signals listed on the Legend, etc. but while preserving transparency. Does anyone know a good way to do this? Thanks.
  8. Reading Jack's post really drives home to me how much time slinging wires isn't about programming so much as doing battle with the compiler and the IDE. The list of otherwise useful LabVIEW features that are off-limits due to bizarre and mysterious corruption problems is absurdly large. I'm not quite at the point where I'm willing to take all of the preventative measures Jack recommends, but I also admit that I'm getting close. I think one more really bad corruption problem could tip me over the edge. As it is, these days I'm loading ALL my even tangentially-related LabVIEW code into memory any time I make a class or library ownership change, and that feels pretty extreme already. I long for an lvlib "lite" that allows me to associate a set of files together, pass them around to other people, and indicate hierarchically on the project window that they belong together... that DOESN'T try to load all the dependencies into memory, that doesn't check if the dependencies are IN TURN in libraries, and then try to load all the dependencies of THAT library into memory, etc...
  9. So last week I started working on a new UI. The layout of the UI is highly variable depending on what the user is doing. Certain controls are hidden or shown depending on what task is being performed, and may move around. I've moved each little UI module into its own subpanel actor. When events fire on the subpanel actor, each actor decides if it needs to pass a message up to the Controller for handling. The Controller decides what actors should be loaded into which subpanels, and also handles arranging the subpanels in different layouts. This isn't quite what most of us here might envision and doesn't really have to do with dynamic event registration. Also, the amount of effort involved is such that you wouldn't want to design an entire actor for such trivial interface elements. But it is a way to have user events trigger methods in a Controller, from a variety of sources that can be decided at run-time.
  10. We're working on parsing sets of data. As part of this process, I go from a TDMS file on-disk to an array of objects. Each object contains data from a single sub-test and provides access to several methods that help in analyzing and displaying the results. The size of this array could potentially be large, with perhaps a few thousand elements. We're concerned that this may cause memory management problems in LabVIEW. We'll be running tests to try it out, but we're curious if anyone else has done something similar, and what barriers or issues they may have run into. We're considering alternatives, such as performing read/writes directly from the TDMS file at all times. But regardless, we may have to plot large sets of data, which would require the data to be in memory anyway. Does LabVIEW have any problems automatically deallocating memory for large arrays, especially large arrays of objects? Some of my colleagues are concerned about this. My instinct is that it's no different than any other array. I think that once a class is loaded into memory, all the metadata about the class is locked in and can't be removed (the info about the private class and methods). But I don't think that particular caveat applies to specific instances of the class, which can be created or destroyed like instances of any other datatype (I think). I'll be looking through the Managing Large Data Sets in LabVIEW white paper. Any other references would be appreciated. Thanks.
  11. I agree with Steve. If it's not vital that you get 1kHz for ALL data, then you can try acquiring each measurement in a separate loop. So you would have two parallel loops, one for polling the stepper, and the other for polling the DAQ. If you find that the DAQ loop is able to keep up at 1kHz, then you could try creating a master loop that will continuously write DAQ data, as well as writing the "last polled" value from the stepper. I'm not sure what your end-goal is, however. If you have trouble getting the DAQ loop to poll at 1kHz, then you'll probably want to play around with the different DAQ read options - one of them should give you the performance you need.
  12. I have my own UI Parent Actor that has some useful functionality with methods I found myself needing quite often (some GUI initialization). From that actor, I have a couple basic dialog classes and a subpanel actor class. The subpanel actor has useful methods for inserting itself into a subpanel reference and handles a couple other small tasks (like determining how it looks inside the subpanel). I played around a little bit with dynamic event registration, but only for one specific case: stopping a UI event loop. My parent UI actor core registers a dynamic event, and I register the UI's event loop with that event. Then I have something in the UI parent Stop Core that sends the "stop" event out to the loop.
  13. Do you guys know if Inno Setup has an easy way to install prerequisites, like the LabVIEW Run-Time Engine? My fallback plan was to make a "base installer package" that will install the RTE through LabVIEW's builder profile. Then have another installer for my program. It's annoying, but it would only be a two-step process that first time. After that, I think people can just go directly to my latest installer for upgrades.
  14. Wow, that was incredibly trivial. Thanks Neil! Far easier to use than LabVIEW's app builder. I can see I'm going to have to tweak a few things to get it exactly how I want, but the fact that it builds a working installer on the first try (just using the GUI wizard you recommended) is huge. NI probably still has some weird behavior on their hands but now I don't have to waste any more time trying to debug it!
  15. Wow, interesting program! I downloaded it and am looking through the documentation/examples. I'll give it a try tonight! Any "gotchas" I should be aware of? It looks like I can modify some of the example files and run them from the same directory as my built application.
  16. Thanks for the tip, but I'm worried that a log won't be so helpful in this case. I think I've figured out what's wrong, but I don't know how to fix it. The installer erroneously thinks that "APT.exe" is a system folder and searches for a nonexistent folder, rather than trying to find files within the actual "APT.exe" executable. Not sure how to correct it! The exe profile correctly bundles the classes into the exe, and the installer profile should get its information from the exe profile. But where the exe profile correctly interprets my custom Destinations as being inside the exe, the installer profile thinks there's a file folder instead. I posted a bit about it here: http://lavag.org/topic/15883-get-lv-class-default-value-from-memory-not-from-disk/page-2#entry109482 No clue how to fix it, pretty irritated at LabVIEW's app builder right now.
  17. I'm running into a really weird issue with this workaround. I created many destinations like this and it seems to work as desired: the files get built into the exe. However, now the Installer fails to build correctly. The Installer seems to think that "MyApp.exe" is an actual system folder. It looks for my lvclasses in this nonexistent system folder and returns an error when it can't find them. Has anyone run into this before? Is there something wrong with the way I defined my destinations? EDIT: I know that the "Yen" symbol is showing up instead of backslash; that's some weird artifact of my virtual machine that I haven't sorted out. But rest assured the same issue manifests itself on normal desktops that display the backslash as normal.
  18. Here's the situation: I'm dynamically loading lots of classes in my application. These classes are sent to known destinations inside the exe, as specified in the exe build profile. The exe builds and runs flawlessly. But when I try to create an installer for the built exe, I get an error claiming that the files can't be found. It looks like this: That's no good! When I hit "Show details" on the error window, it returns the following: I'm new to using dynamic class loading in applications; is this a common issue? What's the solution/workaround? Thanks guys.
  19. I was nervous about LastPass operating over the internet. My paranoia seems to have been rewarded somewhat, as it's on the Mashable list as one of the "affected" sites. They're claiming that users do not need to change their master passwords. However, I suspect that any passwords they stored on your behalf were vulnerable to Heartbleed (even if the websites you stored were not vulnerable).
  20. I was actually quite pleased to discover that none of my financial institutions have bothered to update their security software the past few years, and as such, none were vulnerable to Heartbleed. I've been cursing these institutions for years because they use incredibly old security systems (seriously, you're only going to let me use an 8 character password?). But in this case, their glacially slow tech adoption rate was a blessing in disguise. This Mashable list has been helpful for me in determining which passwords I need to change. I'm extra paranoid, though, so I'll probably change all of them as I get around to logging into them. I'd also like to take this opportunity to extol the virtues of KeePass as a password manager.
  21. This is probably a stupid question, but how does LabVIEW know what to list in dependencies without actually loading the VI's contents into memory? In your example, "Uses Empty VI" is in memory, which calls Empty VI. Empty VI is in the same library as VI with Dependancy VI Call. Apparently "VI with Dependancy VI Call" is not loaded into memory, but the class it calls ("Cyclic Table") is? So, how does LabVIEW know that Cyclic Table is called without loading "VI with Dependancy VI Call"?
  22. So we're working on untangling dependencies in our projects. In the process, we've removed some member VIs from certain classes. These member VIs were organizationally related to their parent class but didn't actually use the class an input/output. They were sometimes called outside the class, which would load the entire class into memory in the IDE. This was undesirable behavior, so we moved them out. However, now I'm concerned that there are lots of "orphan" VIs floating in our repository that aren't organized in any way. I pitched the idea of throwing them into some lvlibs. For example, we have an application called APT. So if there are "orphan" VIs in APT, we could throw them into a library called "APT Common Code.lvlib" or something like that. My coworker Tom wanted to check some of the "common wisdom" we've heard that lvlibs do not load all their member VIs into memory when a single member is used. I created a dummy project and made a few Actor classes. The application just launches a window with a message saying "Application running." Then it shuts all the Actors down when that window is closed. I created "Dummy Library.lvlib." I put in two member VIs. One is just an empty VI with an error in and error out. I called this "Empty VI.vi". The other is called "APT Container.vi." On its block diagram I dropped one of the core APT VIs, which calls a lot of other VIs. "Dummy Library.lvlib" is not in the lvproj. I then dropped "Empty VI" onto one of the Actor Cores. "Dummy Library" of course shows up as a dependency. So does "APT_Main" and all of its dependencies, resulting in a massive list of dependencies. Project load time also increases from <10 seconds to about 1 minute. Based on this testing, I think I have a fundamental misunderstanding with how lvlib files work. I'd really appreciate any guidance on this topic. In particular: Do lvlib files load all their member VIs into memory? If not, then what am I doing wrong that is causing the member VIs to load into memory? Or what is my misunderstanding with the phrase "load into memory"? If yes, then is there an alternative way to organize these "orphan VIs" so they aren't simply floating in the workspace without any simple way to identify or group them? (while still avoiding loading all of them into memory when I only want a particular one) Thanks all.
  23. If I can find the time, I'll try to create a simple, repeatable example this week and post it. No promises, ha.
  24. I've been avoiding doing certain initialization steps in "Pre Launch Init," especially if they involve launching actors or references. So this has to take place in the Actor Core override, I think. If I can actually package all the initialization in Pre Launch Init, then that'd be welcome news, though. I'm guessing this is a trivial discussion to find if you know what you're looking for, but my searches turned up a bit fruitless. Is it this thread on Pre-Launch errors - or this thread on warnings? My Google fu is a bit weak, I fear.
  25. I was debugging an application today and tracked it down to an error being passed directly into Actor Core from an initialization method upstream. I had expected the error on occasion and have a case in my Handle Error override to display a front panel warning to the user. My oversight was thinking that Actor Core would call Handle Error if an error was passed directly into it. This isn't the case, of course: it skips running any of its code and passes the error straight through. Should an error passed into Actor Core call Handle Error? I assume this was considered and discarded for some reason. Anyone have any insight as to why? Thanks.
×
×
  • Create New...

Important Information

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