cycleguy Posted February 7, 2011 Report Share Posted February 7, 2011 When using a simple state machine, what do you think the best way to share data between states is? I have been using shift registers, but have also used local variables. I would like to know if there is a 'Best Practices Hierarchy" for sharing data between cases. Quote Link to comment
Black Pearl Posted February 7, 2011 Report Share Posted February 7, 2011 Shift registers in most cases. If only very few states access the data, AEs/FGVs. Felix Quote Link to comment
Grampa_of_Oliva_n_Eden Posted February 7, 2011 Report Share Posted February 7, 2011 Shift registers in most cases. If only very few states access the data, AEs/FGVs. Felix Similar to what I teach my people. If the SR's are well designed clusters (only related data is grouped) then you can quickly spot which SR to move into the AE's by clicking through the states looking for a SR that only gets touched in a handful of places. Ben Quote Link to comment
jgcode Posted February 7, 2011 Report Share Posted February 7, 2011 I normally use a single SR (cluster) per module (SM) and if by design or if data gets complex (I.e. it should be encapsulated) I usually use classes within the cluster (to manage the data easily). Modules can call other modules, like the posts above. Quote Link to comment
ShaunR Posted February 7, 2011 Report Share Posted February 7, 2011 I usually use shift registers. Normally 2. One for the control/status etc. And one for data. Local variables get very messy very quickly. Quote Link to comment
crelf Posted February 8, 2011 Report Share Posted February 8, 2011 Another option is a current value table (also known as a currnet value repository) using variant attributes (discussed a little here). We have an internal reuse library that wraps the get/set methods (think polymorphic) and includes other functions like write-to/read-from file, search for tags using wildcards, probes, etc. There's also a CVT example from NI here - it's strictly-typed, but it might give you some ideas. 1 Quote Link to comment
Cat Posted February 8, 2011 Report Share Posted February 8, 2011 I usually use shift registers. Normally 2. One for the control/status etc. And one for data. Local variables get very messy very quickly. Is it okay if I disagree with you? Dragging shift register wires from one side of a diagram to the other, having to hop over other code that may be in an event case (for example), now THAT gets messy. For pure mess-reduction, local variables are the best way to go. But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted February 8, 2011 Report Share Posted February 8, 2011 Is it okay if I disagree with you? ... For pure mess-reduction, local variables are the best way to go. But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all. Sure, as long as I don't have to support the code. Does your definition of "Pure mess-reduction" completely ignore performance and ease of support? If so I agree whole-heartedly. :P Ben Quote Link to comment
jgcode Posted February 8, 2011 Report Share Posted February 8, 2011 Local variable should not be used to 'store' data. This is really bad practice. And if you really want to be anal they should only really be used to update a Control's display. If you use a template and lay it out, you should never have an issue with space. Like Shaun I sometimes use a couple of SR registers (for example, a private dynamic event refnum so I don't have to type it and keep updating it) but I always leave enough space so that I don't have to move code. Also since 8.6 you can set the tunnels to wire through automatically, which is a really cool feature. Quote Link to comment
ShaunR Posted February 9, 2011 Report Share Posted February 9, 2011 Is it okay if I disagree with you? Dragging shift register wires from one side of a diagram to the other, having to hop over other code that may be in an event case (for example), now THAT gets messy. For pure mess-reduction, local variables are the best way to go. But obviously it's not all just about mess-reduction, which is why local variables are generally used sparingly if at all. Linked tunnels mean you don't have to keep wiring them through. But even without them, I would never have more than 10 cases (yes. I'm looking at you JGCode...lol) so it wouldn't be a big deal. I also don't generally hop over code. I wire through sub-vis as I like to only have only sub-vis in each case frame rather than raw code - much cleaner and gives you the opportunity to make them subroutines. Locals (and globals for that matter) I try to avoid since you cannot sequence them with error wires. If it doesn't matter about UI updating affecting performance, I prefer to use a property node (because of the error terminal). But that's nothing to do with state-machines But then, I'm me. And that's a bad thing 1 Quote Link to comment
Cat Posted February 9, 2011 Report Share Posted February 9, 2011 Sure, as long as I don't have to support the code. Does your definition of "Pure mess-reduction" completely ignore performance and ease of support? If so I agree whole-heartedly. :P Ben I was wearing my Devil's Advocate hat when I wrote that. Shaun was talking about messiness, and I had just done some wiring on an event case that would have looked a lot neater if I would have used a couple local variables. But I know that's a no-no. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted February 9, 2011 Report Share Posted February 9, 2011 Linked tunnels mean you don't have to keep wiring them through. But even without them, I would never have more than 10 cases (yes. I'm looking at you JGCode...lol) so it wouldn't be a big deal. I also don't generally hop over code. I wire through sub-vis as I like to only have only sub-vis in each case frame rather than raw code - much cleaner and gives you the opportunity to make them subroutines. Locals (and globals for that matter) I try to avoid since you cannot sequence them with error wires. If it doesn't matter about UI updating affecting performance, I prefer to use a property node (because of the error terminal). But that's nothing to do with state-machines But then, I'm me. And that's a bad thing I agree with most of what you posted and tend toward keeping the number of cases low (in state machines) but the number is not the critical factor but rather the State Transition Diagram (STD) that is realized by the code. I suspect someone out there knows the theory behind it but the point at which STD get confusing is when it can no longer be drawn in a single plane, i.e. the transition lines have to cross over others. That is what I concider my "stop and re-write" point durring the design process. But before I let the diagrams get to that point I will start creating sub-STDs with a cohesive function and replacing the calling STD's code with the new "state". These are generally characterized by "single line in... single line out" structure in my STDs. But that is off-topic now so I should stop. Cat, Yup. That is what the double smiley-back at you was all about. Ben Quote Link to comment
ShaunR Posted February 9, 2011 Report Share Posted February 9, 2011 I agree with most of what you posted and tend toward keeping the number of cases low (in state machines) but the number is not the critical factor but rather the State Transition Diagram (STD) that is realized by the code. I suspect someone out there knows the theory behind it but the point at which STD get confusing is when it can no longer be drawn in a single plane, i.e. the transition lines have to cross over others. That is what I concider my "stop and re-write" point durring the design process. But before I let the diagrams get to that point I will start creating sub-STDs with a cohesive function and replacing the calling STD's code with the new "state". These are generally characterized by "single line in... single line out" structure in my STDs. But that is off-topic now so I should stop. Ben Not really off topic. The OP did ask about state-machines and what other people use. I'm with you on the sexually transmitted disease STD. I was generally referring to those that save a file using 20 case frames instead of just having "save" (because a certain tool makes it easy to do ). I've never found a need for more than 10 in control systems (well, I think there was a 12 once, but I eventually got it to less than 10). Simply because I do as you. The state-machine goes across the diagram and INTO the diagram (I think that's what you are saying). OK some state transitions aren't "kosha" (to get back the next level it might rattle through a few basically bypassing and doing a doing a NOP). But thats data-flow for ya. I actually find Labview pretty good for realising multi-planar machines where I equate each plane as a level in the VI hierarchy - Seems intuitive to me. Sure a few implementation problems. But much easier to debug a single branch in isolation than a fat, wide one with 100 states. Quote Link to comment
jgcode Posted February 9, 2011 Report Share Posted February 9, 2011 @ ShaunR - I have no idea what you are talking about. Have you never responded to more than 10 events on FP and had to wire data through each case? Quote Link to comment
Black Pearl Posted February 9, 2011 Report Share Posted February 9, 2011 Have you never responded to more than 10 events on FP and had to wire data through each case? Tunnel Wireing wizard is doing this for me. Oh, hey, wait, it's a scripting tool from the ancient times. Felix Quote Link to comment
ShaunR Posted February 10, 2011 Report Share Posted February 10, 2011 Have you never responded to more than 10 events on FP and had to wire data through each case? An event structure isn't a state machine Oops I forgot. You ab use it as one by firing off ValSig (Been known to do that myself on occasions....lol). But Linked tunnels work on it too 1 Quote Link to comment
Daklu Posted February 10, 2011 Report Share Posted February 10, 2011 An event structure isn't a state machine QFT. Maintaining data between loop iterations and carrying it through the case structure doesn't make the loop a state machine. It just makes it a loop with data you want to persist between iterations. It *has* state, but it's not necessarily a state machine. The OP mentioned a "simple state machine," which I interpret as the enum-into-a-case-structure kind. For that the shift register is the best way to go. Quote Link to comment
jgcode Posted February 10, 2011 Report Share Posted February 10, 2011 An event structure isn't a state machine Really? Then what do you call something that looks like this? Queued State Machine, Queued Message Handler, QSM with event structure, etc... I know what NI call it and what others have called if for years so I am happy to stick to that (even though if taken literal it may not be correct, but I am no software engineer and can't be bothered arguing semantics here) Anyways, I was just pointing out how handy the Linked Tunnels feature of LabVIEW is - I think its great. Oops I forgot. You ab use it as one by firing off ValSig (Been known to do that myself on occasions....lol). But Linked tunnels work on it too Hey, that was one time, and... Quote Link to comment
ShaunR Posted February 10, 2011 Report Share Posted February 10, 2011 Really? Then what do you call something that looks like this? Well. If "idle" has a plethora others (which I strongly suspect -how many?). I'd call it a mess But from the list I'd go for SM with event structure in the same sense that I'd go for a SM with an emergency stop, SM with foot switch and, indeed, any input stimulus to the actual state-machine. Hey, that was one time, and... I know. 'twas a bit below the belt. Especially because there is a very good example of it in the SQLite examples. Quote Link to comment
jgcode Posted February 10, 2011 Report Share Posted February 10, 2011 'twas a bit below the belt. Nothing compared to your Priscilla comment. Shazza Quote Link to comment
Grampa_of_Oliva_n_Eden Posted February 10, 2011 Report Share Posted February 10, 2011 QFT. Maintaining data between loop iterations and carrying it through the case structure doesn't make the loop a state machine. It just makes it a loop with data you want to persist between iterations. It *has* state, but it's not necessarily a state machine. The OP mentioned a "simple state machine," which I interpret as the enum-into-a-case-structure kind. For that the shift register is the best way to go. In theory yes, but in practice we should keep in mind the nautre of LV and not "drink the kool-aid" and expect LV to do our thinking for us. Performance! There are code construct that will absolutely freak out LV's inplaceness algoithm in which case it exercises the default rule "if not sure copy the buffer". Complex clusters seem to encounter these issues more often than the simple data structures and as LV evolves, where the in-placeness freaks, can change from version to version. So putt large data structures in a cluster in a SR and passing it in and out of sub-VI's can bite us. Two branches off that idea: "The key the key and nothing but the key so help me Codd." LVOOP LVOOP first. It seems that Aristos and his team but some excellent thought into the LVOOP data strutures. Mainitaining a class instance in a SR and invoking methods on the wire really "feel" like they are pointers. Confesion time! I screwed up in one of my apps and cast (using type cast) a LVOOP class as an array of the class by mistake. I was baffled by LV crashing and passed it to NI as a bug in the TDMS functions. After Aristos traced down MY ERROR, I fixed the code and all ws fine but what really clicked on the light bulb for me was that improperly cast wire ran through a mile of code with out causing a sinlge issue and it was only when it came time to actually acces the data inside the class wire (down in the TDMS functions) did the actual data make a difference. This bug experience should me just how little the LVOOP stuff is touched. Now back to Codd. I have never officially studied Normalization rules, but I have learned some from my wife. I have tried to keep some of those idea in mind when I design my clusters thinking about the clusters as if they were tables. Applying normaliztion rules help me sperate data that has nothing to do with each other while grouping those that do. (part of this can overlap with OOP ideas I suspect). now returning to a point I made early in this thread, if a data structure is only used in a small fraction of the states, move that data to an AE so that it is not being carried around with other data that it has nothing to do with. So yes, SR are the standard approach and seem perfect for LVOOP, but if you have a performance challenge staring you in the face, special attention should be given to who where and when they are touched. Just trying to firm up my ideas, Ben 1 Quote Link to comment
Daklu Posted February 10, 2011 Report Share Posted February 10, 2011 Really? Then what do you call something that looks like this? I'm curious, in your opinion what is it that makes a QSM a QSM, and what changes would take that construct out of the definition of QSM? I'm working on a presentation for our local user group. "QSM" seems to mean something different to everyone and I'm trying to figure out what the essence of a QSM is. Quote Link to comment
Daklu Posted February 13, 2011 Report Share Posted February 13, 2011 Performance! So yes, SR are the standard approach and seem perfect for LVOOP, but if you have a performance challenge staring you in the face, special attention should be given to who where and when they are touched. Excellent points Ben. I freely admit optimizing for performance is not something I have much experience with. In fact, I tend to follow the rule, "first make it work, then make it fast," even though that isn't always the fastest way to the solution. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted February 14, 2011 Report Share Posted February 14, 2011 Excellent points Ben. I freely admit optimizing for performance is not something I have much experience with. In fact, I tend to follow the rule, "first make it work, then make it fast," even though that isn't always the fastest way to the solution. Many of my apps require high speed as req #1. My slaes team seem to be able to find those projects that "almost work" but perfomance is lacking. There are at least three dedicated developers in my office that are working projects that started out as "fix the preformance" to start out projects. years ago (whwn I was just a wee-G-babe) the big boss lamented durring a meeting "why do so many of our apps suffer from performance?". So now we design for speed and we seldom here about perfomance thses days. The actual work process flow differe little from not keeping an eye on performance. VI development starts out with simple questions; 1) How large are the data sets for this VI going to to be? 2) How often is this going to have to run? If the datasets are small and the code runs infrequently, just code away. If the code could affect performance, approach it delicately. Take care, Ben Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.