Jump to content

Stagg54

Members
  • Posts

    143
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by Stagg54

  1. I helped write the OO course, so take my comments with a grain of salt... of course I'm going to say it's worth it. :-)

    The course is 2 days. Day one focuses on design; Day two focuses on implementation. You work your way through designing a single application, working from a customer specification and identifying the classes that will be needed to do the project, and then you turn to implementing it, how that works in LabVIEW and the tools that are available to edit, debug and deploy the app. It's dense -- no question about that. I wish we could have made it three days so we could've added a little bit more breathing room and a few other topics, but at two days, a lot more customers can afford the time away from work, so it's more accessible.

    As for whether it helps with the CLA... the best prep for the CLA is still 5 years of actually architecting code. You do not need any OO knowledge to pass the CLA, though you are welcome to use OO in your architecture when you do the CLA if that's the architecture you think fits best.

    That must be fairly recent, because three or four years ago when I took the course it was based on Endevo's course and it was horrible. I sure the course you've designed is much better.

    Disclaimer: I have 5 years of LV experience. I don't have any certifications (except CLAD) because my company values experience over certificates.

    I work with several people who have many years of experience and still write crap code. You don't need a certificate to write good code, but having a certificate proves that you've written good code at least once.

    I would rather have someone with a small amount of experience writing good code, than a lot of experience writing bad code.

  2. I was able to upgrade to LV2011 SP1 and the problem went away. Not exactly what I was looking for, but it did work. I did not try the force recompile. At some point I may go back and do that just to see what happens.

    Thanks for all the advice and help. And thanks for NI for pointing me in the right direction.

  3. So I filed a service request on this and NI has been helpful but I haven't managed to resolve it yet, so I'll post what I know here and maybe someone will have an answer. It appears from talking to NI that this may have been resolved in 2011. Currently I am using 2010 SP1, 32bit on Windows 7. Upgrading to 2011 may not be option. I'm looking into that.

    Here is how I noticed the issue:

    I was trying to deploy and run some code on an RT target. When I deployed the code it asked me to save a particular lvclass file. I hadn't changed the class, so I'm not sure why it wanted to save it. I clicked ok to save and got into this endless loop where it kept asking me to save it. Clicking cancel got me out of the loop, but then I couldn't deploy the app.

    I thought maybe the class was corrupted so I tried to mass compile it and I got the following error: Fatal Internal Error at OMUDclasslinker.cpp line 4161.

    I tried running the same code not on RT but within the regular LabVIEW environment and it ran fine.

    I also noticed that: The save-all button is always enabled and everytime I click it and click on the show details button, it says that there have been changes to this particular class as well as its parent, even though I haven't changed anything. When I click save, this time I get no error, but afterwards the saveall button is still enabled. And the next time I click it the same thing happens.

    Anyone have any thoughts?

  4. No, you are not misusing libraries as far as I can tell and the "problem" you are seeing is one of the reasons I use them. In short, you have discovered an error in your design.

    That was what I was thinking. I guess I'll have to look a little closer at my design.

    to jgcode: It's not really causing problems so much as it seems odd to me that to load and work on a low-level component I have to load essentially the whole project. I think goes back to what Daklu said about dependencies. I think I need to readjust my paradigm to "let high level components depend on low level components, but not the oher way around."

  5. I'm just curious how many use libraries in your day to day development (I'm assuming a fair amount of you do). I'd like to know how and why you use them, especially if you are using multiple libraries in the same project.

    I'm running into this problem and I'm not sure its inherant in using libraries or if I'm just misusing them or not using them as intended. I have this project and every major component is in its own library. I have a config library. I have a notification library. I have a synchornization library. I have a file writing library. I have a TCP/IP communication library etc.

    However what I find is when I want work on one small component it ends up loading almost every library in the project.

    For example in my notification library, if I load any vi in that library it loads the whole notification library. There is a vi somewhere in the notification library that sends out a TCP/IP message. Because it uses a vi in the TCP/IP communication library to get a queue ref, now it loads the TCP/IP library. And also somewhere in the notification library it writes something to a file, so it loads the file library which happens so use a semaphore to control access to the file which loads the synchronization library, which somewhere has config file entry which determines the size of some queue which no requires loading the configuration library. And it goes on and on.

    So now to edit a single low-level vi I end up loading multiple libraries into LabVIEW.

    Anyone else run into this problem? How do you handle it? How do you determine what to put in libraries and what not to?

    This problem gets even worse, because I have 2 applications. One is an HMI app running on Windows and the other is an RT app. For communication I send objects over TCP/IP and have a command pattern that runs on the recieving end. When I do that however then I up loading half the HMI app into memory on the RT target, just because one of the messages references a library on the HMI. Now I have all this code loaded in RT that is intended for the HMI and will never run in the RT app.

    Did I explain my problem well enough?

    thoughts?

  6. I'm starting this new project where I have to send some objects over TCP/IP. I'm planning on flattening it to a string on one side and then unflattening it on the other. So far I haven't run into any problems, but I've only really tried it in the development environment with 2 vis on the same local machine. I'm basically using the command pattern to send commands over a TCP/IP link so I'm counting on the recieving end to recreate the correct child class, which it appears to be doing.

    The only potential issue I am aware of is making sure both sides have the same class definitions

    What other issues might I run into?

    I'm sending the objects from a Windows box running a exe built with LV2010 64bit and I'm sending it to a RT box running an exe built in LV2010RT 32bit. Can I make this work in that situation? Is the 64 vs 32 bit going to create any problems?

  7. disclaimer: first of all this is related to the NI challenge problem. Not asking anyone to give away any solutions or anything, I just want a better understanding of how LabVIEW manages arrays. And hopefully I'm not giving too much away by my questions.

    I have some questions about how LabVIEW handles arrays and memory management

    My understanding (please correct me if I am wrong):

    1. LabVIEW stores arrays in continuous blocks of memory, which it requests from Windows Memory manager in chunks. I believe LabVIEW just keeps a pointer to the first element. When you split the wire it makes another copy if necessary. The show buffer allocations should show you were this occurs.

    2. Using build array inside a FOR or while loop is not optimal because it can cause LabVIEW to have to go to Windows memory manager to request more memory (I believe under the hood it is somewhat smart about this and often requests more than is needed).

    3. When using the build array is much more efficient to add onto the end of an array because when adding to the beginning LabVIEW has to shift everything to make room for the new data at the beginning

    So my questions:

    1. deleting an element from the middle of an array - should require LabVIEW to move (shift) everything in the array after that point. Correct?

    2. deleting an element from the end of the array - should not require LabVIEW to do any kind of shifting or anything (in theory i should just change the size of the array). Correct?

    3. How does LabVIEW handle shifting? I assume that it it splits that array at the point where it is shifting (ie. what would become the new index 0)and then takes the first and second half and moves them to a temporary location and then appends the first half to the end of the second half. is that correct?

    Some of these questions may already have been answered somewhere. If so, if you could point me in the right direction that would be great.

    thanks,

    Sam

  8. in this case though I'm not entirely sure.

    The problem is the realtime output is continuous.

    So to make a simple semaphore work I would have to:

    Periodically stop the realtime task

    Release Resources

    Release the Semaphore

    Reacquire the Semaphore

    Reacquire the resources

    Resume output

    Playback from the file only occurs rarely. So I would constantly have the overhead of releasing the resources and then reacquiring them and 99% of the time it would just simply release and immediately reacquire. I'm not a DAQmx genius (in fact I know very little about it, just the basics) but I have to think that would chew up a lot of CPU time/resources. It kinds seems like polling versus being more event driven.

    It seems that even if I were to use a semaphore I would have to use some sort of notifer/event (or something similar) as well to stop the continuous output task so that I am not constantly stopping and starting it.

    Hence I was thinking that if I have to incorporate both a notifier and a semaphore that bundling them in a class might make sense.

    Am I still making it more complicated or is there an easier solution?

    oh and to add another wrench into the works

    there is talk of building the part of the program that does playback from files into its own seperate application, which opens a whole new can of worms.

  9. So here is my situation

    I inherited some code that has a bunch of parallel loops. Several of them share hardware. Specifically we have 1 channel of AO that goes to amplifier/speaker setup. Normally we use this channel to output realtime signals from our sensors. But there is a portion of the program that can "hijack" this AO channel and use it to output data from a file. The problem is not only interrupting the realtime output but also that the 2 tasks have different parameters/setup (for example sample rate, continuous vs. finite samples, etc.) So when this was developed they previously had 2 seperate programs and when they combined them they ran into all kinds of problems, so they invented this crazy scheme using all kinds of global variables to coordinate and do some handshaking. It's a mess. Its super-buggy and it needs rewritten. We also have a similar issue with an AO that is used for injecting test signals (we have 2 different types of test signals).

    I would like to implement an OOP solution. I'm still trying to wrap my mind around the problem, but I'm thinking about having some sort of arbiter class. It would decide who gets control of the resources. I'm thinking that to do it that way the arbiter would have to be by-ref. I was thinking of having some sort of "Output Data" method, where you pass it the data you want to ouput and tell it what type of output it is and it handles setting up the resources and coordination.

    Any thoughts? Am I on the right track? Would you use a different approach?

    Also, I'd kind of like to draw this up in UML. Anyone know of any good UML tutorials (as it pertains to OOP and classes)?

    thanks,

    Sam

  10. Hmmm, does it count the arguments from 0 or 1 ? If the former, then the problem would be the hWnd=0 which I think I would interpret as creating a client window on the desktop - perhaps it doesn't like doing that ?

    I'm afraid I rather suspect the intersection of the sets of SAP users and LabVIEW coders is probably a small number approximating unity

    SAP => Run for the hills!

  11. Your window manager could monitor key events, and regularly check the FP.Open status of all VIs in memory.

    The default state of the window manager would be to poll the positions of the open front panels (and only those), keep a log of their correct position and move the windows back if the position has changed but has now settled* (and they are still open). (Ideally there would be a window move event for this that you could set an event structure to respond to, but there is not...).

    If the user hits F2 the state is changed to an ignore mode until F2 is pressed again - in which case the monitoring state will automatically correct the positions back to their original values again...

    On start and every 1-5 seconds from then on the window manager will run through the list of VIs in memory and update the list of VIs it should monitor. I did a quick test now with 750 VIs in memory and checking their FP.OPen property only took about 40 ms on my machine so it should be doable (the CPU load was not bad either).

    It is not required that you know which window is currently active.

    * You could reset the position immediately when a change was detected but that would probably look extra messy so I would rather wait another cycle to ensure that the window has settled, before resetting it...

    That sounds like agreat idea! Thanks for the suggestion.

  12. I don't think LV keeps track of the active window--that's the OS's job. You might have to make windows api calls to get that information. There's a small visual basic example here that get the title of the window currently active. Perhaps you could parse the window name to get the vi name, and get the reference from that?

    That assumes that they are the same, which they are not.

    I could search through all VIs in memory, but that could be a bear (the app has 1000's of vis). Also then I how do I figure out which one is active? I could try the FP.Is Frontmost property but according to its help entry it ignores floating windows.

    Anyone have any other thoughts?

    On a side note: does anyone know what the Application.Active VI property is returning? I haven't been able to decipher it.

  13. Here is what I need to accomplish:

    The powers that be want all front panels in a particular application to have this feature they call "auto-snap". Basically all visible front panels should "snap" back into place if the user tries to moves them around (by clicking on the title bar and dragging them). The user should be able to hit the F2 key to unlock the window and move it where ever they want. Pressing F2 again should lock it again and snap it back into its original position.

    My original design was to create a "brat vi" (I got that term from Norm Kirchner - he calls it that because it manipulates its parent). Basically you dropped it into each vi that had a visible front panel. All you had to pass it was a notifier to tell it when to exit. It ran in parallel and automatically pulled out the callers ref and registered for the key down event and took care of everything. Very cool and it worked very well. Only downside is that you had to drop it into every vi with a frontpanel. A bit of a pain for anything you may want to reuse for another project.

    Now here is my problem. Now they want to pull in this reusable library that I have. I don't want to drop this brat vi into my reusable library. Most of the timeI don't want this feature and I don't want to pollute my library with something that is only going to be used for this one special case. Now this reusable library has one main entry point/UI vi. Now I can modify my brat vi to accept a reference and run it in parallel with the main UI of my reuse library. All works well until my reuse library calls up a subvi that shows its front panel.

    What I would like to do is launch a vi in parallel with everything that would automatically detect when a new vi is opened and becomes the active front panel and then to act upon that. That would be nice because then instead of dropping it into every UI vi, I can just drop it once and run it in parallel with my main vi.

    I guess my question is:

    How do I get a reference to the vi that is active (ie. that the user is currently interacting - ignoring subpanels for the moment -although my reuse library uses those heavily so maybe that will cause some problems as well.)

    I found the Application.Active VI property which I thought would do want I wanted. (Its a scripting node, but is supposedly works in the run-time which is what I need.) Unfortunately it does not appear to be returning what I am looking for. I'm nost sure what its returning. Even though Scripting is now supported (I'm using LV2009 by the way) there is not any documentation on what the term Active VI means. I does not appear to mean what I thought it did.

    Anyway, is what I'm trying to do possible? Does anyone see a better way to solve my problem? Did I do a good enough job explaining it?

    thanks,

  14. First, since you want to make this a generic messaging framework, I assume you're planning on adding it to your reuse library. Second, I know you mean "which bit of code should define the log text," but let's take a step back and read it a bit differently. Which developer--the library designer or the library user--should define what messages and text are logged? To me the answer is clearly the library user. (Maybe the user wants to log message data along with the message name... maybe the message contains a queue and the user wants to log the number of items on the queue... the possibilities are endless.) What part of the system is customized by the user on a per-application basis? If I'm understanding your system correctly, it's the messages. Therefore, the decision about what text to log should be left up to each message--option 1 from your list.

    What if I want the log file in xml format instead of text format? What if I need the log file stored on a server instead of the local computer? What if I just want the log messages to appear in a window instead of on disk? In other words, how can I, as the user, change the logger behavior without editing the distributed reuse code?

    4. Create an abstract MessageLogger class that can be injected into the Message Interface Object by the library user. If no MessageLogger is injected, no messages are logged and you don't suffer any performance penalties. You can supply a simple text file logger with the distribution. If users need different behavior, they can create their own MessageLogger child class that does exactly what they want it to do and inject it into the Message Interface Object.

    Those are some good thoughts.

    I really like #4, although I'm not entirely sure if that fits into my paradigm.

    If I was going to do something like that I would like some way to implement it "globally" within a specific application, rather than having each process specify which Logger to use. I already have a "Master Table" that records what process is registered for what messages. Perhaps I just define the logger there.

    Which developer--the library designer or the library user--should define what messages and text are logged?

    Obviously I am thinking the end-user (who in this case happens to be me as well). My end goal is to develop a framework where when I start a new project I can just grab a copy of this framework and I already have certain tools built in (ie. I already have a debugging window that lets me view who is registered for what message, and I can view all the message traffic.) I'm trying to include some kind of logging and basic error handling in that. Then I can take that basic library and I can start building my application from there. Obviously I should be able to customize the logger or error handler, etc. as needed, but I'm hoping that I can design something that will cover 90% of my uses cases.

    Right now I've got the messaging framework built up pretty well and I'm very happy with it. It's just a matter now of how to extend it.

    I'm kind of new to this whole object oriented thing. I'm just trying to make sure I get the design right.

    Also I was kind of thinking of the logger as more of a template.

    When you get a new copy of the framework, you get a copy of this logger and then you edit it to suit the needs of your specific application. In most cases it would already do 90% of what you need.

  15. Why not have the parent message class implement a dynamic method that logs some default information. Override methods can override/extend/extinguish as needed?

    I've done a few variants of this. Some parent method defines an interface, maybe it's supplied with a byte stream refnum, maybe it's as simple as providing a ToString() method that returns a log friendly form of the object. Regardless of the exact interface, the parent method ultimately logs some basics such as the timestamp, fully qualified class name, whatever is relevant. Some extending classes override this with other information entirely, other implementations call the parent then concatenate extra information, and others in turn override the method only to not do anything and therefore keep the messages entirely silent from a log perspective.

    This model of course depends on the message itself being able to define what needs to be logged and what doesn't, which is what I think you mean by your modules being unaware? That is the observer doesn't decide what gets logged, and the signalling process doesn't have direct control over the logs, except by virtue of what messages it sends.

    That was my initial though.

    I had some misgivings and things got a little hazy when I started thinking about who was responsible for what.

    But I think that idea might work after all.

  16. Ok, so here goes.

    Basically I have set up an observer pattern and I have a few questions about how I should handle a few things, most notably logging.

    Here's how my pattern basically works.

    I have a variety of independant processes running. Each one has it's own Message Interface Object. Through the Message Interface Object (really just a sophisticated queue based system with a "global" registry) it can send any messages that are descendants of "Message Parent". When any message is sent, the parent class captures the sending process and a time stamp and then sends it out to whoever is registered for it. I also have a hook so that any child class cna execute a specific piece of code right before the message is sent for error-checking or whatever. So any process can send any message and then it can also register to recieve specific messages. I also worked in an inheritance scheme, so if you register for a particular class you get all its children as well. One of the main design considerations though is that is a broadcast type system. That means when a process sends a message, it doesn't care if it gets a response or if anyone is listening. The only time it cares is when it is waiting to recieve a message. Even then it shouldn't care who sends it, it should just care about the message itself.

    So far I have the messaging scheme all worked out as far as sending and recieving messages. I'm trying to build a nice demo program to demonstrate it (I don't have an actual project to use this on at the moment).

    So I have nice debugging tool that is registered for the parent class, so it recieves every message that is sent out and it pulls out the timestamp and sending process etc. And I have a few dummy processes just sending data out.

    Now I'm trying to work on a logger. Something that would run in the background and just log important events. I'd like to make it as generic as possible, but I also want to have my other modules not care about the logger (ie. I don't like the idea of them determining what gets logged.) My question is what is the best way to log things? I guess my real question is whose responsibility should it be to determine what text gets logged?

    As I see it I have 3 options:

    1. Add a logtext field to the parent class and allow children to update it. Then when a child can update that when its private data is changed. In this case the responsibility would belong to each message child class.

    2. Add a loggable message class and have it contain a logtext field, which its children can update. This is nice because then I can just register my logger for the loggable message parent class and get all loggable messages.

    3. Have the logger itself determine what text to put in the file for each type of message. I think I am ok with this. My main concern is that the sending process be unaware of what is out there. THe recieving process kind of has to know what's out there or what to expect, or do I have this all wrong?

    Anybody have any thoughts?

  17. Edit: It seems like there is some hope by using the Search and Replace text feature that's built into LabVIEW. I think this will work for now.

    That sounds like it might be easier than scripting.

    In general I find scripting to be a pain to write. Once written it tends to be invaluable, although I find that most of the scripting I write tends to be very narrowly focused and address one specific use-case (maybe it's just me using poor programming practices and not being general enough.)

×
×
  • Create New...

Important Information

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