Jump to content

K-node

Members
  • Posts

    90
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by K-node

  1. I love to add to my personal collection of books, but at $100US list, this is a bit pricey for my own library (I like buying the cheaper used ones). I might get my employer to purchase, but I am interested to know if anyone has looked at it. Here is the publiisers link: http://www.crcpress.com/product/isbn/9781439839812 It was published Dec 12, 2011. I am not familiar with the authors or contributors and the table of contents does not have me chomping at the bit, but I might be too focused: Excel ActiveX Automation Using LabVIEW, Steffan Benamou Interacting with Windows Applications, Bill VanArsdale A General Architecture for Image Processing, Craig Moore Radio Frequency Identification Read/Write in Sports Science, Ian Fairweather Pachube: Sensing the World through the Internet, Anne Brumfield Power System Applications in LabVIEW, Nesimi Ertugrul Recursive Computation of Discrete Wavelet Transform, Nasser Kehtarnavaz, Vanishree Gopalakrishna, and Philipos Loizou Solar Energy, Pedro Ponce, Brian MacCleery, Hiram Ponce, and Arturo Molina -Kurt
  2. Here are some of my "Feelings on Icons for Terminals"... , I could not resist! Have a great weekend! EDIT: Damn my employer, they lock down almost all internet capabilities. png's did not upload. I will try from home later.
  3. Alex (and others interested), I have ported the AFv3.0.6 to LV2010. I am testing it now, but I am willing to share the code. Please PM me with your email address so I can keep track of the users and send updates. Kurt
  4. AlexA, If you want a single or reduced set of wires, you could make a cluster of the classes you have identified or even Class with the set of classes you identified as private data. I find the latter a bit overkill as you will need lots of accessor (Read/Write) vi's. So I would vote for making a cluster of classes. Kurt
  5. Check mike5's posts at the end of this thread. I am not sure it will work for you as it is a specific implementation. http://lavag.org/topic/12874-really-get-the-class-name-at-run-time/ -Kurt
  6. I got access to Adobe Standard and removed the offending thumbnails buttons. For those that are experiencing the same issue, PM me for a PDF sans thumbnails. See you at NIWeek!
  7. I would like to print the PDF of the conference program but on many of the pages, the links that get you to the previous page and next page show a thumbnail image as if my mouse was hovering over that. Does anyone know how to turn that off for printing? I have Adobe Reader 9.4.1. Thanks, Kurt
  8. I am no expert on this, but wanted to point out AQ's response to where Event Queues run. In short, it is not necessarily in the UI Thread.
  9. I am not disagreeing with this point, but I always struggle on how to exchange queue information. How does object A tell object B to send me a message when criteria X has been achieved when A and B have been created independently. This is a classic Publish-Subscribe scenario. While I do not use the name parameter in my queue creation for this purpose, I do have a look-up table that is effectively the same thing. So, what is the best way to share queue references in a network of queues? Or perhaps you don't really share queues. Object A simply tells some message clearing house component that is it interested in knowing about 'criteria X' and Object B tells the same message clearing house component that it can generate a message on 'criteria X'. So, potentially, neither Object A or B now about each other, only the message clearing house component.
  10. I have no idea, but Justin might respond to a PM if he is not watching this thread. I copied this link from the OP: PM Justin here for info. As we are still a bit away from the date, he might take a check. I expect he needs to commit $s to the restaurant. Good luck. Hope to see you there!
  11. Look at the first post by crelf; this thread is now two pages so you may have to go back one. Kurt
  12. OK, I am in. This is my first NIWeek. I am ready to say been there, done that, got the t-shirt and will do it again! Most of the time I lurk and learn from you folks, occasionally chiming in on the OO stuff - perhaps too rambling on some posts according to Daklu . Anyway, this is going to be a long month until Austin. See ya' there!
  13. Actually it carries nothing. At moment state data is in the ChannelProcess shift registers or derived classes. There may be reasons to keep it for the future. Suppose you would like every channel to have a name or a keep track of how many messages it correctly handled. I would add those as private data to the Channel class. Remember Channel_A and Channel_B both derive from Channel class. These children will have access to that data. In my opinion, it should keep track of its own queue, but that is debatable. Currently it is held by MessageQ and I can get it by creating a Channel_A_Message queue and I did not want to change your system. ALSO, and mos importantly, it is the common Channel class that is giving you the DynamicDispatch - what you refer to as the automatic channel selection. It does not eliminate the 'automatic' channel selection. The channel selection you see is the design time resolution of a DynamicDispatch. Solely for the convenience of some lame programmers did you put these methods where they did not really belong. Think about the intent of the class and the methods it should publish. What is the intent of the MessageQ class? Despite its name, it really only keeps track of a list messages. What is a Channel class? It operates on a queue, but it does not hold the entire list of queues. What is a Message class? It holds data and actions that manipulate channels. They are distinct and do not have any hierarchical relationship to each other. You could do that. Actually, I can see MessageQ class being enhanced. I could send it a Channel_A_Message and it could return the queue for all Channel_A_Message derivations. This would isolate that loop that determines this and is implemented in multiple places. I do not see what you say. Drag a B derived message down and attach it the Channel_A.SendMessage. It seems to change to Channel_B.SendMessage for me. Am I missing something? Again you are not seeing anything but the compiler resolving the call, not selecting what channel. You may think it is really the same thing, but it is the SendMessage implementation that actually selects the channel at runtime. I can change Channel_A.SendMessage implementation. I do think I lost any functionality, I simply moved it to a new base class called Channel. All I did was move the commands that did nothing in MessageQ class to the Channel class. I created the queues using the Channel_X_Message classes not the Channel_X classes. This seemed more appropriate to me. I missed the ReleaseQ method. The queue used to test against the list should be created using the Message_A class. Yes, you could move these things around. My goal was not to make so many changes that it would be confusing. Frankly, I would not search for a queue by trying to cast all of them into the one I desire, but I did not want to go down that path. Personally I would rather use some sort of look up table. Since each Channel_X class will have a queue, you could use the class name. The Create and Release methods do not belong in the message class. I would not find it natural to as a message for a queue. I would consider the Create and Release to be in the MessageQ class since it is the one keeping track of those anyway, but you would have to use some other scheme to identify the queue. Yes, I see by creating the queue from the Channel_X class you do not have to make any changes. I don't have an alternative for that but I am not a fan of your message type specific queues anyway, but that is just me. I am still not sure you lost much that can't possibly be resolved in other ways. For the most part I moved methods to other base classes. What would be needed is an alternate approach to the identification of message queues based on message or class type. Realize that you do have more than one entitiy, right? And the instantiation of a derived class as a new entity brings along with it all of its parents footprint. I would find it confusing as a developer to see methods available to me in the message class that really do nothing. So when I implement the Channel_A_Count.ExecuteMessage method and I connect the Write Count to the message wire the Channel_A count did not change. There is nothing stopping the developer from doing that. I am not a fan of passing around a DVR. Actually you do not need to pass around the DVR but once. Once I have the DVR (as a true DVR not dereferenced) I have access to that memory and all of its updates that anyone does. That is the cool thing about DVRs. Publishing the list of queues does get to be a problem and I do not have a great solution yet. More experienced folks than I should answer the best ways to use DynamicDispatch. Your approach has its merits for your requirements. Not all systems have 7 unique channels. Some systems have hundreds of channels but not all of a unique type. Look at texting and cell phones. Cell phones are pretty much the same and they can send and receive a string. I would hate to create a unique Channel_X class for every phone - that's a lot of classes that are identical. I'd rather instantiate the same class for every phone. You are right. The message in my case determines where to be sent. But that seems normal to me. I like modeling behavior around the physical. Sorry, I did not remember that episode. -kugr
  14. Taking that to the extreme in a large system, you will have every possible method needed in every possible class with a Dynamic Dispatch vi originating from the base object. And all objects inheriting the memory footprint of the data (not the actual data of any instance) from all of its parent. So, what would I get if Channel_A_Count.ExecuteMethod 'called' its 'Read Channels' method. But Channel_A_Count does not have that property you say. It does from inheritance. So what stops the developer from selecting potentially wrong methods that might cause runtime errors? Nothing in this scheme. What is easier to fix - compile time or runtime errors - I would vote compile time. So a properly constructed hierarchy reduces these potential runtime errors. You got me there, but perhaps they should not be programming The actually do not need to know what channel to select, only that they need to select from the base channel class as it has the abstract methods that would have been in your MessageQ. There was a thread in this forum sometime ago about right clicking on a terminal or wire and selecting from a valid list of methods for that terminal/wire type. That would help a developer. I think somebody implemented some add-in - sciware or black pearl perhaps, maybe a jki person. True, but my point is that those methods it uses do not belong in MessageQ since it has no use for them. They belong in the abstract Channel class including the process loop. Yes, but it access the data via the MessageQ object passed into it, not from any internal representation of the MessageQ. In your implementation, the Channel does have the memory footprint (yes, a small DVR), but it is uninitialized. You are retrieving the data via a property call which has nothing to do with the base object of the channel. Funny you should ask. I did break up your example to see if what I was thinking would work. I am not sure you would call it simplified, but it encapsulates behavior in appropriate ways and perhaps it is better said as more understandable. For the most part it does work though I have some issues with the Stop not being a derived message. Not quite sure of that yet but I will, as they say, leave it to the reader. I did not clean up the folders and there is an abstract class called SuperClass that does nothing but it helped me dissect your initial hierarchy. Being new to LVOOP and asking questions on a forum such as this is a good thing. I am still learning and LVOOP is still forces me to think differently than traditional OOP. Have fun with it. -kugr p.s. Daklu, too much? MessageQ_krg.zip
  15. I am OK with it as it seems that what your are doing is some default behavior for the execute method. Realize that 'Call Parent Method' from a child message will get you true for the Stop terminal. I still don't see the advantage of your single hierarchy. The MessageQ class in your implementation really only needs the Read and Write property for the list of queues and the ReleaseMessageQ. The channel or message classes do not to derive from MessageQ. The abstract Channel Class has a CreateQ, GetMessage and ReleaseChannel methods. Children of Channel would have additional property methods, etc. I would also put the ChannelProcess method as a part of the Channel class. The abstract Message class has the Send and Execute methods. To support your message routing scheme you would have abstract Channel_A_Message and Channel_B_Message. From there you would derive additional messages for specific actions. Clearly, as you have demonstrated, you can make a single hierarchy but a derived class should be some 'enhancement' on its parent. Your Channel class, derived from MessageQ, does not require anything MessageQ provides and does not add to anything MessageQ could do. MessageQ is really only a list keeper. It can do more, but it would not necessarily be channel or message specific. Similarly, your message classes do not use anything that its base classes provide with the exception of identifying the queue based on the parent Channel class. To me that is not sufficient (and can be done differently as stated above), and the extra baggage the channel adds to the derived message class with its member data and method vtable for no gain within the message class is, well, a red flag. In the end, if it works for you, that is fine. But if I had to maintain the code, it would irritate me. -kugr
  16. I am generally pretty quiet, then I do a random core dump.
  17. Assuming you mean the message carries around uninitialized data, it probably is not that bad from a performance perspective. Still I have a problem with the hierarchy but I am no expert. Feel free to ask questions. I have pm'd AQ on the NI site and he has been very helpful. You can ask here too. I am using a derivation of this framework, but it is virtually unchanged from a fundamental aspect. Most of my changes were from deriving off of the classes. The biggest confusion is the creation of Actors. They are launched as opposed to having VIs with loops on the top level VI. And they have to exchange queue references - it is very clever, but takes a while to understand fully. Daklu's has a framework that looks great (there was an earlier thread about this) and actually can evolve into this if he ever desired to do that. His is simpler to understand from the contruction of 'actors' perspective. It uses strings, I think, to differentiate messages. The other 'challenge' with launching Actors is debugging. Good golly it can get confusing. I have started naming my queues solely to see who sent the message to who not to use in searching for a queue by name. I do need to keep track of queues, but I do that on my own. I hope not. It does make for a huge project and some maintenance issues when I find out I need to change something fundamental. For instance, I decided to wrap the LV queue object in a class - much like Daklu's message class. Ouch - every message had to be changed along with a number of other items including AQ's original framework. My biggest issue is the dependency between messages and actors. I have not been as careful as I should have in making sure about this. The dependencies make it hard to separate actors into independent projects - one actor sends a message and the message operates on another actor. So now sending actor's project will require the receiving actor's project. It is a hard thing to split. Overall, it has worked well for me. My Actors are set up to be observed so they keep track of who is 'watching'. They don't care who the observers are and will send an Update message to all of its observers. The observer does have to 'register' with the observed and this is done via a message. Actors that need to command other actors do so through a Proxy (a wrapper that handles sending the message for a specific command). This is not part of the AQ's original framework. The proxy adds a bit of complexity to the developer of an actor, but makes it easier for a user of an actor. Sine the actual message is hidden inside the proxy, a message really becomes calling a method. To set up a proxy, you do need to get the queue for a specific Actor so you've got some DB type stuff to handle there (some 'global' object needs to be able to resolve this request). I am not happy with my implementation of that, but it works. -kugr
  18. As daklu will attest, I rarely get involved in these discussions. Yes, dak, this is almost a monthly thing now! Anyway, my two cents... Have you checked out AQ's Actor framework? It does not perform auto-routing based on message type (I suppose there is some way it could be done) and it does not have the single hierarchy you might desire. But, each message has a Do (Execute) method. One of the terminals is the Actor (equivalent to your Channel class). Actor properties can be made public, so I can implement the all code in Message.Do. So now your message when passed around carries a potential boat load of uninitialized data that is got from deriving from the parent class. OK, fine, you can make it a DVR but now you have added a complexity to the problem and put yourself further from the dataflow paradigm. Why is the single hierarchy a requirement? There are really three distinct entities - messages, queues, and (for lack of a better word) actors. You can add a fourth, if you wish, as a message controller which your MessageQ class really seems to be. I am uncomfortable with making a a message a subclass of an actor which is a subclass of a message controller which is how I see your hierarchy. -kugr
  19. Thanks Mr Mike, Jon and JG. There is no way I can reproduce what I did. I moved a lot of files around and rearranged classes in a variety of new and existing libraries. Today I did put the Property capability back into the class that had the problem and used the Property Node in the VI was the last to execute before LabVIEW tanked. Not surprisingly, LV handled it this time. -kugr
  20. So, as my development normally goes, I end up refactoring the file and library structures in preparation for a cleaner release. Frequently (um, always), I break something and sometimes LabVIEW breaks something. Yesterday, I spent too many hours on a problem that caused LabVIEW to terminate unexpectedly and without warning or go into a hung state where task manager came to the rescue. In the end, the 'block' that caused my problem was setting two properties on a class using the Class Property Node capability in LV2010. I am using SP1. It seems that executing that function 'confused' LV. This approach was working until I made organizational changes to file locations and project libraries. I am pretty sure that this was the only place I used a Write property node where the class was inside a library (just an lvlib not packed). It could be that all I had to do was to remove the property node and add it again, but I was so frustrated by this problem that I got rid of class properties completely. When I finally realized where it died, I kind of remember reading about a problem like this on LAVA. I recall AQ indicating he was disappointed in how testing of this release missed this error. I cannot find that post though. Does anyone remember this? AQ, am I putting words in your post?
  21. implementing AQ's Actor Framework

  22. Awesome, thanks Felix! Here is the link: http://forums.ni.com...010/m-p/1143364 (Sorry no light saber included but many thanks to Darren!) -kugr
  23. Somewhere, on some website, maybe even this forum, there was listed a collection of native LV functions that operated even when the ErrorCluster indicated an error. This was not a bad thing as I think one of the VIs was perhaps the Close reference. Did anyone else remember reading that and where it was? I am remembering a collection of about 7 or so VIs were listed.
  24. Recently in this thread http://lavag.org/top...nentizing-code/ Daklu discussed his approach to error handling. This is toward the end of page 1. Those familiar with the standard templates for creating VIs for Static and Dynamic Dispatch and Data Member Access are already too aware of the big green box you are presented with in the block diagram wit the ominous command: "Wire the error cluster across even in the "No Error" case so that warnings get propagated." But is wrapping all of your code inside this block necessary? Daklu provided some thoughts that I thought deserved a thread of their own. Taken directly from one of Daklu's posts: First, I've ditched the rule of wrapping all sub-vi code in an error case structure. (Blasphemy! Burn me at the stake!) About 9 months ago AQ and I had a discussion about this. He termed it, "hyper-reactionary error handling" and talked about the impact it has on the cpu's resources. He said, Quote Since the common case is "no error", all that extraneous error checking *has* to hurt performance... I mean, in many VIs, several registers must be permanently allocated to the error cluster because it is constantly in your "most recently used" cache. These days I almost never wrap an entire code block in an error case. Many of my sub vis don't have an error case at all. The questions I ask myself when deciding about an error case are: 1. Do I need the sub vi outputs to be different if there is an error on the input terminal? If so, then I'll use a switch prim or case structure somewhere on the block diagram, though it may not wrap the entire code block. 2. Will the sub vi exit significantly faster by skipping the code on the block diagram when an error is on the input terminal? Yes? Then I'll wrap at least that section of code in an error case. The code I'm looking at here are things like For Loops containing primitive operations that don't have error terminals. String operations, array operations, cpu intesive math, etc. If a sub vi or prim has an error input terminal I don't worry about it's processing time. It will respond to the error input terminal appropriately and I assume (for simplicity) that its execution time = 0 if there is an error in. In the diagram above I'm doing a lot of data compilation to gather the information necessary to create a GutStep object. However, the only primitive operations on this bd are Search Array and Index Array. Is the time saved in those rare instances where there is an error in worth the cost of error checking the other 99.9% of the time when there isn't? Nope, not in my opinion. In fact, this entire block diagram and all the sub vis execute exactly the same code regardless of the error in condition. (I know the sub vis ignore the error in terminal because of the green triangle in the lower left corner.) But low level performance isn't the main reason I've ditched it. I found it adds a lot of complexity and causes more problems than it solves, like the issue you've run into. You've wrapped your accessor method code in an error case because that's what we're "supposed" to do. Why does the accessor method care about the error in terminal? Is unbundling a cluster so expensive that it should be skipped? Nope. Is it the accessor method's responsibility to say, "I saw an error so I'm not returning a real queue refnum because some of you downstream vis might not handle it correctly?" Nope. Each sub vi is responsible for it's own actions when there is an error on its input terminal. In pratical terms that means my accessor methods never have an error case. They set/get what's been requested, each and every time. My object "creator" methods almost never have an error case, also passing the error wire through. Most of my "processing" method don't have an error case either. In the diagram I have 3 different "Lookup" methods. Each of those encapsulates some processing based on the inputs and returns an appropriate output. None of them change their behavior based on the error in terminal's state. However, each of the three Lookup methods are capable of raising an error on their own (I know this because the lower right corner doesn't have a colored triangle,) which would ulitmately result in an invalid GutStep object being sent out. Is it the factory method's responsibility to try and prevent downstream code from accidentally using an invalid GutStep object? Nope. It's the factory method's responsibility to create GutStep object to the best of it's ability. If an error occurs in this method or upstream of this method that might cause the data used to create the GutStep object to be something other than expected, this method lets the calling vi know via the error wire. It's the responsiblity of the calling code to check the error wire and respond according to it's own specific requirements. That's a little bit more about my general approach to error handling. It's more geared around responsibilities--who should be making the decision? (Responsibility-based thinking permeates all my dev work.) I've found that, in general, much of the time I don't really care if there's an error on the wire or not. Many of the primitive functions and structures already know how to handle errors. What do I gain by blindly adding more layers on top of it? Complexity in the form of more possible execution paths, each of which needs to be tested or inspected to verify it is working correctly. Thanks, but I'll pass. ============================================================= END OF EXCERPT============================================================= All, I can say is 'Damn I wish I had thought about this' and then thought about the importance of this information buried in a thread about Componentizing code. So, with his permission I decided to generate this thread. Your comments are always appreciated. -kugr
  25. Ha Ha! Yup, I am pretty much a voyeur on this this site. I do enjoy your contributions though. I am not full time on LabVIEW programming but I do want to get a common framework that I can use on systems here. AQ's ActorFramework fit that bill for me with some enhancements on the derived Actor classes. For instance, my Actors have a name and know their receive queue - sometimes an actor will send itself a message. Actors also retain the queues of Observers. It seems the intent of the ActorFramework (especially for stability) was that an Actor that created another Actor was the only one that could communicate with that new Actor. AQ can correct me here but that was my take. There was nothing inherent in the framework that restricted this, it was just my understanding. I did not like that restriction and I generally allow a full network of messaging, though I do have the concept of retaining what Actors another created. The biggest change to AQ's framework was to make the Message:Do.vi re-entrant. Within an actor, the queue will keep processing to one message at a time. I was OK to have all actors processing messages in parallel though this does make debugging crazy at times. And I just added queue names to make my debugging a bit easier - now I can see the name of the actor who sent the message. Oh, yes, all of my messages allow the sender to add it's reply queue. Generally the Do.vi only gets the creator's queue, but sometimes I want to reply directly back. This is an added property in my derived message. I have added an ActorFacade class that can be derived to hide the nuances of all of the messages. A message is essentially wrapped in a method of an ActorFacade. The ActorFacade is not an actor though and cannot receive messages. It is usually contained within an Observer. The ActorFacade actually becomes very useful in updating UI controls via CtlRefnums. So it is a bit more than just a Facade with respect to a design pattern, but I am not sure what to call it. I also have ManagerActor (creates new actors via a message), a UIActor (an easy way to put a user interface on an actor), and a PollingActor (for those times when I need to watch for something to change that does not generate events). From there the derivations continue to my specific requirements. I deal with moving fluids so there are generally valves, pressures and temperatures to deal with. They boil down to analog and digital IO. Not sure this was very helpful but it is what I am up to. I will set the thread up shortly for Error Handling. -kugr
×
×
  • Create New...

Important Information

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