Jump to content
Cat

Documenting State Machines

Recommended Posts

I'm ripping apart some code I wrote a couple years ago to "reuse" it for a new project. A main chunk of it is a state machine. When I'm in the midst of programming something, I generally have all the inputs and outputs to the different states more-or-less memorized, but in this case I was flipping in and out of states a lot trying to figure what was where. This led me to trying to come up with a good way to document state machines. I started with a typical SM:

post-9165-124966669949_thumb.png

Below is how I used to do it. As documentation goes, it's the best way, for programming, however, it's a pain to add/subtract inputs/outputs, negating one of the main reasons to use bundles/state machines. One of my states uses 13 inputs...

post-9165-124966682275_thumb.png

So I went to this:

post-9165-124966685676_thumb.png

What I don't like about it is that it loses the color-coding of the inputs/outputs. The colors really help make it easier to find things. And I have to be very anal-retentive about keeping it updated.

So I tried this:

post-9165-124966698951_thumb.png

It's easy to do, just go into the state vi, copy the unbundle and bundle, and paste them in the SM. The problem being, of course, that it breaks the code, and requires disabling the code. It's actually easier to read than it looks like from this pic, but it still is on the "foggy" side.

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

Share this post


Link to post
Share on other sites

I think it's a good idea to use the Disabled diagram since it won't include it at compile time.

You could also use PNG's since you'll remove block diagram when you make them EXE's. I don't know if we could use the new VI snippets in 2009 to do that? If we could get the PNG on our diagram without it being transformed to code... (just thinking out loud)

Share this post


Link to post
Share on other sites

So I tried this:

....

It's easy to do, just go into the state vi, copy the unbundle and bundle, and paste them in the SM. The problem being, of course, that it breaks the code, and requires disabling the code. It's actually easier to read than it looks like from this pic, but it still is on the "foggy" side.

With the Code Capture Tool you can capture a selection of the state VI, and copy this as an image to the clipboard. After pasting this on the SM you have a clear copy of the actual code.

You could even adjust the CCT to resize to half of the actual code size if you want that.

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

Well you could have saved a lot of time with the Code Capture Tool.

Good luck,

Ton

Share this post


Link to post
Share on other sites

I'm ripping apart some code I wrote a couple years ago to "reuse" it for a new project. A main chunk of it is a state machine. When I'm in the midst of programming something, I generally have all the inputs and outputs to the different states more-or-less memorized, but in this case I was flipping in and out of states a lot trying to figure what was where. This led me to trying to come up with a good way to document state machines. I started with a typical SM:

post-9165-124966669949_thumb.png

Below is how I used to do it. As documentation goes, it's the best way, for programming, however, it's a pain to add/subtract inputs/outputs, negating one of the main reasons to use bundles/state machines. One of my states uses 13 inputs...

post-9165-124966682275_thumb.png

So I went to this:

post-9165-124966685676_thumb.png

What I don't like about it is that it loses the color-coding of the inputs/outputs. The colors really help make it easier to find things. And I have to be very anal-retentive about keeping it updated.

So I tried this:

post-9165-124966698951_thumb.png

It's easy to do, just go into the state vi, copy the unbundle and bundle, and paste them in the SM. The problem being, of course, that it breaks the code, and requires disabling the code. It's actually easier to read than it looks like from this pic, but it still is on the "foggy" side.

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

Seems a bit arse about face to me. :blink:

Call me old fashioned, but..... I start with a word document (detailed design spec) and define flow/transition diagrams for each state machine then code from that with plenty of comments and references back to the original spec. If you want you can copy and paste the transition diagrams into the vi, but I don't bother since anyone modifying it should at least be able to read a spec. :D

Share this post


Link to post
Share on other sites

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

I have some suggestions.

  • One thing you may want to look at is Endevo's UML modeling tools. They have some interesting ways to document state machines, but this is more useful for modeling state transitions as opposed to state inputs.
  • Another thing you should consider is the design of your actual states. I may have just not looked hard enough, but it looks like you evolved into a pattern where you are passing your entire state machine data cluster in/out of each state VI. This is actually contributing significantly to the complexity of documenting your API. I would suggest that you consider changing your API to VIs within each state in some way such that you are no longer doing that.
  • You might consider moving to a different state machine template. I will make a shameless plug for our own JKI State Machine as its free and has received a lot of praise by the LabVIEW community (although it may not help you solve this particular aspect of documentation, you will find it has a lot of nice self documenting aspects related to state organization and it integrates with the Endevo UML tool as well).

Share this post


Link to post
Share on other sites

So I tried this:

post-9165-124966698951_thumb.png

It's easy to do, just go into the state vi, copy the unbundle and bundle, and paste them in the SM. The problem being, of course, that it breaks the code, and requires disabling the code. It's actually easier to read than it looks like from this pic, but it still is on the "foggy" side.

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

Copy the Bundle and Unbundle functions to MS Paint, and copy them again back to LabVIEW. They will be bitmaps and will not break your code. Just put a note next to them as a reminder, otherwise you'll freak out in two years when you can't figure out why you can't wire to them.

Share this post


Link to post
Share on other sites

Anyone have other ideas? Or has this one already been solved and I just wasted a half hour making pretty screen shots? smile.gif

It seems to me you are keeping all the data the states will work on in this shift register. This is in most cases not a very good idea as it ties the entire state machine implementation very strongly to the data of all states, even though most states will only work on some specific data on this. There is also a possible performance problem if your state data cluster gets more and more huge over time.

I have only a very limited state data cluster in my state machines and it is limited to containing data that is important for most of the states and directly important to the state machine itself. The rest of my application data is stored in various functional variables (uninitialized shift registers with different methods).

(And yes I know it is a lot like doing LVOOP without the formal framework of LVOOP and I should be looking into using LVOOP, but have not yet found the drive and time to do so.)

The various VIs do pull whatever data they need from those functional variables when they need it and where they need it and put the data back in there when needed. This keeps the state machine implementation very much decoupled of the application data itself and allows for much easier addition and modifications later on. The state machine itself will not document what data it uses but I feel this to be information that is not exactly part of the state machine design itself. It should be defined on a much higher level (anyone saying application design specification?)

The individual data should not really be important to the different states in most cases but what you want to know is what state transitions your state machine involves when, where and how.

Rolf Kalbermatter

  • Like 1

Share this post


Link to post
Share on other sites

It seems to me you are keeping all the data the states will work on in this shift register. This is in most cases not a very good idea as it ties the entire state machine implementation very strongly to the data of all states, even though most states will only work on some specific data on this. There is also a possible performance problem if your state data cluster gets more and more huge over time.

If a design is used for a SM with state information stored in cluster - but with the cluster being made up solely of (e.g. LVOOP) objects (so the cluster is only used as a container to pass the objects through the states to avoid multiple SR) - would that still be considered bad design?

Note: I ask out of an effort to seek information, not to debate any previous comments.

Edited by jgcode

Share this post


Link to post
Share on other sites

If a design is used for a SM with state information stored in cluster - but with the cluster being made up solely of (e.g. LVOOP) objects (so the cluster is only used as a container to pass the objects through the states to avoid multiple SR) - would that still be considered bad design?

Note: I ask out of an effort to seek information, not to debate any previous comments.

I personally wouldn't do that either. I would tend to actually put those object references into functional globals too. (But that would be isolating and encapsulating the object itself into a sort of higher class which I do tend to do in my current functional globals design, so that might be why I can't see the additional benefit of LVOOP getting involved in the picture.)

Rolf Kalbermatter

Share this post


Link to post
Share on other sites

I have only a very limited state data cluster in my state machines and it is limited to containing data that is important for most of the states and directly important to the state machine itself. The rest of my application data is stored in various functional variables (uninitialized shift registers with different methods).

Ditto. In fact, my implementations of state machines have only 1 piece of data passed from case to case; the next state to execute (a single enum). Anything else is either gleaned from functional globals or from files. No clusters whatsoever are used to transfer info from one state to another. If a particular state is reliant on previous state information, then it is highly probable that they can be serially linked the good old fashioned way.

Share this post


Link to post
Share on other sites

Ditto. In fact, my implementations of state machines have only 1 piece of data passed from case to case; the next state to execute (a single enum). Anything else is either gleaned from functional globals or from files. No clusters whatsoever are used to transfer info from one state to another. If a particular state is reliant on previous state information, then it is highly probable that they can be serially linked the good old fashioned way.

Well I do have some cluster sometimes but it contains only things that are specific to the entire state machine such as a flag to remember the previous state for some cases if I need to do special handling depending from where the current state was coming from. Of course this could be entirely avoided with a different state separation but sometimes it is easier to add such a special handling after the fact than to redesign several states more or less completely.

Rolf Kalbermatter

Share this post


Link to post
Share on other sites

Ditto. In fact, my implementations of state machines have only 1 piece of data passed from case to case; the next state to execute (a single enum). Anything else is either gleaned from functional globals or from files. No clusters whatsoever are used to transfer info from one state to another. If a particular state is reliant on previous state information, then it is highly probable that they can be serially linked the good old fashioned way.

This seems kind of extreme. It's also unnecessary. As long as the data relates to the state machine then it's valid to keep it in a local shift register. It also makes it clear to the observer, what design pattern you're using (don't tell me, you don't care about other people looking at your code right?). Using functional globals and file IO within the same VI to pass data feels like you're using the wrong tool for the job at hand. I don't see the benefits.

Let me make this clear. I'm specifically focusing on data that is only valid in the context of the current state machine

Share this post


Link to post
Share on other sites

This seems kind of extreme. It's also unnecessary. As long as the data relates to the state machine then it's valid to keep it in a local shift register.

Indeed. I have nothing against keeping data in shift registers.

It also makes it clear to the observer, what design pattern you're using (don't tell me, you don't care about other people looking at your code right?).

What's using clusters or not got to do with design patters?

I don't mind people looking at my code as long as they have read the spec first! That will tell them not only the design pattern, but how it works, why it works and above all which vi's do what. Please don't tell me you are of the impression that labview code is self explanatory with a few comments.

Using functional globals and file IO within the same VI to pass data feels like you're using the wrong tool for the job at hand. I don't see the benefits.

Let me make this clear. I'm specifically focusing on data that is only valid in the context of the current state machine

Indeed. The globals and file access is for shared data (product numbers, limits, images etc). The only information a state machine needs to know (generally, not entirely) is what state next to execute and, as I think I said, if data is dependent on previous states, then they can probably be serialised in a single state. I wouldn't (for example) have individual states for create image, acquire image and process image and pass the image around. Instead I would have a single state (take image?) that uses a functional global to retrieve a pre-initialised image (blank image), acquire the image, process it then put the image back in the functional global before moving on to another state. That way the state machine represents the functional operations (move motor in, open gripper, dispense part, close gripper, take image, move motor out) rather than the discrete steps required to achieve the function (get motor position, move motor, stop motor, check motor position, get gripper number, open gripper, check gripper is open etc, etc).

Share this post


Link to post
Share on other sites

First of all, thanks to Francois and Christian for answering my original question. Ton, your Code Capture Tool looks very useful. Omar, I will definitely take a look at the JKI State Machine.

Now, to the trashing of my coding style... smile.gif

That particular piece of code has very few states that automatically follow the one before. It can diverge in several spot and reconverge only at exit. Or it might follow step by step, depending on what the user has requested. Not to mention the fact that there are different error modes that need to be handled differently. Just serially linking the states is not feasible, and I believe a state machine is the best option here.

Rolf, I'm trying to wrap my brain around what I *think* you're saying -- you in essence try to decouple your data from your code, so it doesn't matter what form the data is in (I guess this is OOP-like). I can see how this might be a Good Thing, in theory, but I'm not quite sure how it would really save me development time in a practical sense. Yes, I am keeping all the data that pertains to this state machine in the shift register. Since the vast majority of it is not used anywhere else in the code, that seemed the logical place. Using functional globals and file I/O seems unnecessary when I can just string a wire from one state to another. I'm not sure how big is too big for a state machine cluster, but if I'm passing large arrays around, I do it by reference, not with actual data.

Shaun, unfortunately I am not developing in a vacuum. No one in my organization has the luxury of externally documenting code to the level you are able to. I tried it when I started working here eons ago, but the reality is that requirements for the projects I work on are an ever-moving target. It used to drive me crazy, until I finally gave up, drank the kool-aid, and just started trying to go with the flow. I code a basic structure, go back to the users, get their input, code a little more, add another function that someone just decided they can't live without, code that up, go back to the users, etc, repeat, until everyone is (relatively) happy. Then I take my project out on the test platform, and discover that in the heat of battle, it's really used completely differently than the users thought they'd be using it, or the data stream something else is supplying to me is full of errors I have to compensate for. I can't just say, "Sorry, that wasn't in the original specification and you're not getting it." One of the benefits of being here for so long is that I can generally anticipate changes/additions that might be requested, but my users are always surprising me.

I still do a top-level initial design, but the vast majority of the time the final product is very different, and any detailed design I would have done is obsolete. Oh, and then there's the harsh reality that nobody who's paying me wants to pay for detailed external code documentation. I’m not saying it’s right, but it is reality (mine, at least). So, it's very important to me to make sure I internally document the code as I go along. That is one place I can more-or-less keep up with the infinite changes. Hence my original question.

Shooey. It's a little too early in the morning for a my-job-can-be-a-real-pain rant. My head hurts. blink.gif

Cat

Share this post


Link to post
Share on other sites

My thinking on that:

When using a state machine, that particular VI should show everything that is related to the state machine bahaviour. Other code might be shown (inlined) if it is easy to catch (otherwise, a SubVI Icon might be better to document the code).

Here is my way of coding state machines:

* (Next)State has a distinct wire. The selection of the next state might come from a SubVI, but the actual selection is done in the state machine VI. For example a SubVi might have a boolean output 'Abort'.

* Error has a distinct wire. Most of the time I check each iteration of the while loop for an error and go to the error handling case.

* Data is 1 or 2 clusters. Most of the time I distiquish between 'Parameters' for Scalar Data and 'Data' for Array Data

* Other values that are constant inside this VI ('Recipe', 'Measurement Settings', References of various kind like File, Instruments) -> they don't need the shift register.

I'm for sure in one of those chaotic/'agile' environments where nobody pays you for doing any internal documentation of your code AND the requirements are changed any and every time you talk with customers. But I always document state machines if they go beyond a basic set of about 5 states (that's what I use for a simple dialog that saves settings when the user presses o.k. and else terminates without saving). For the documentaion I'm fine with simple 'Bubble-and-arrow' (Check the NI infomercials/'webcasts' on their state-something tools if you're infamiliar with it) using Powerpoint or OpenOffice Draw. If I'm in a good mind, I will copy-paste it on the BD. Seldom, I use the uml syntax where the 'decisions' have their own diamond representation. This is mainly done when I need to deal with external/non-LV software engineers.

They main issue about documenting it, whenever the wind of change comes whirling, I exactly see which transitions I need to alter.

Just to repeat, I'd put everything that makes the SM a SM in that top level SM.vi. All state tranisitions and the overall picture of which states might lead to which states.

Felix

Share this post


Link to post
Share on other sites

OK, the approach I use is a particular implementation of the State Pattern (OOP, when possible).

The example I will show is in RT and hence not OOP (but future implementations on RT will be OOP now that LVOOP works on that platform!). A particular state looks like this:

post-6989-13063_thumb.png

Notes:

I pass in the model as a single cluster (would be an object). The model should be separated (independent) from the controller so I think this is the way to go.

I create a UML statemachine diagram that shows the states and the transitions. The transitions appear in the code

It is easy to handle multiple state levels. (It's even easier--and more flexible--with OO since the states follow a simple inheritance hierarchy.)

The layer above looks like this:

post-6989-124992470478_thumb.png

Note that with an OO implementation I don't need the enumerations or the case structure since the states are themselves objects (and hence we can use dynamic dispatching).

Paul

Edited by Paul_at_Lowell

Share this post


Link to post
Share on other sites

Shaun, unfortunately I am not developing in a vacuum. No one in my organization has the luxury of externally documenting code to the level you are able to. I tried it when I started working here eons ago, but the reality is that requirements for the projects I work on are an ever-moving target. It used to drive me crazy, until I finally gave up, drank the kool-aid, and just started trying to go with the flow. I code a basic structure, go back to the users, get their input, code a little more, add another function that someone just decided they can't live without, code that up, go back to the users, etc, repeat, until everyone is (relatively) happy. Then I take my project out on the test platform, and discover that in the heat of battle, it's really used completely differently than the users thought they'd be using it, or the data stream something else is supplying to me is full of errors I have to compensate for. I can't just say, "Sorry, that wasn't in the original specification and you're not getting it." One of the benefits of being here for so long is that I can generally anticipate changes/additions that might be requested, but my users are always surprising me.

I still do a top-level initial design, but the vast majority of the time the final product is very different, and any detailed design I would have done is obsolete. Oh, and then there's the harsh reality that nobody who's paying me wants to pay for detailed external code documentation. I’m not saying it’s right, but it is reality (mine, at least). So, it's very important to me to make sure I internally document the code as I go along. That is one place I can more-or-less keep up with the infinite changes. Hence my original question.

There are techniques for handling agile specifications (google for iterative and incremental life-cycles). The only point I was trying to make was that software should be designed (which is actually your documentation) then coded, rather than coded then documented. It doesn't really matter whether your an old crusty like me and use word or a super "with it" and use a UML tool. You can usually get away with "growing" software if you are a team of one, but add another person or two, then it is imperative to document first. This is especially true if you have to interface to other disciplines. The other "human" aspect is that documenting is arguably the least stimulating task for a programmer so you are much less likely to do it at the end of a project than at the beginning.

A tried and tested method to "manage" your customers/users/consumers if they are always changing the goal posts is to get them to sign up for an initial spec (Statement Of work) and if they want to change it tell them to make the changes to the document and you will quote accordingly, or, if it isn't chargeable (e.g. internal customer), to tell them the impact on the delivery date. This causes them not only to go away and think about what they want and put it in writing, but also forces them to justify the changes (to the signatories) and filters out non-imperative demands. After all..... They want everything for nothing n'est pas? :P

Here is my way of coding state machines:

* (Next)State has a distinct wire. The selection of the next state might come from a SubVI, but the actual selection is done in the state machine VI. For example a SubVi might have a boolean output 'Abort'.

* Error has a distinct wire. Most of the time I check each iteration of the while loop for an error and go to the error handling case.

* Data is 1 or 2 clusters. Most of the time I distiquish between 'Parameters' for Scalar Data and 'Data' for Array Data

* Other values that are constant inside this VI ('Recipe', 'Measurement Settings', References of various kind like File, Instruments) -> they don't need the shift register.

<snip>

Just to repeat, I'd put everything that makes the SM a SM in that top level SM.vi. All state tranisitions and the overall picture of which states might lead to which states.

Can't fault that. Good balance and will lead to straight forward, easy to understand code. I also strongly agree with last bit (i.e no hiding state selections in sub vis).

Edited by ShaunR

Share this post


Link to post
Share on other sites

Just to throw my two cents in I generally don't believe in lots of documentation in the code itself. The main reason is that it is generally not maintained and therefore is rather useless. If you are in the code and you see that the code is different from the in source documentation which do you believe? A solid architecture, good use of modularization (and yes, all subVI's should have accurate documentation for the VI itself), meaningful data and subVI names as well as good style along with system level documentation tends to work best. I am not saying that you shouldn't use any documentation in the source code but it should be minimal. In the case of a state machine I do label all wires in and out of the state machine but they are labeled outside of the individual cases. As others have stated I try to minimize the number of wires flowing through a state machine and when appropriate I bundle the data into clusters. The unbundle and bundle by name inside the individual states will help to "document" what data is being used in the individual state (provided you use meaningful names on you cluster elements).

Lots of comments embedded inside the source code are just one more thing that need to be maintained.

Share this post


Link to post
Share on other sites

...The unbundle and bundle by name inside the individual states will help to "document" what data is being used in the individual state (provided you use meaningful names on you cluster elements)...

Indeed. There are few things you can do that are more useful in "self-documenting" code than having well-named data and data clusters along with well-named and well-defined states. If your data is/are named accurately the undbundle and bundle by name help make your code a lot more self-explanatory.

However, use with caution. One of the drawbacks to this approach is that in large applications some of your data names can get fairly long. If you have a cluster inside of a cluster inside of another cluster and you go after that data in one of your states your unbundle by name will be so long it takes up half your screen. ohmy.gif

Share this post


Link to post
Share on other sites

There are techniques for handling agile specifications (google for iterative and incremental life-cycles). The only point I was trying to make was that software should be designed (which is actually your documentation) then coded, rather than coded then documented. It doesn't really matter whether your an old crusty like me and use word or a super "with it" and use a UML tool. You can usually get away with "growing" software if you are a team of one, but add another person or two, then it is imperative to document first. This is especially true if you have to interface to other disciplines. The other "human" aspect is that documenting is arguably the least stimulating task for a programmer so you are much less likely to do it at the end of a project than at the beginning.

A tried and tested method to "manage" your customers/users/consumers if they are always changing the goal posts is to get them to sign up for an initial spec (Statement Of work) and if they want to change it tell them to make the changes to the document and you will quote accordingly, or, if it isn't chargeable (e.g. internal customer), to tell them the impact on the delivery date. This causes them not only to go away and think about what they want and put it in writing, but also forces them to justify the changes (to the signatories) and filters out non-imperative demands. After all..... They want everything for nothing n'est pas? tongue.gif

I just about went off on another rant about my job. Two mornings in a row would be too much.

Reader's Digest version: I do have the luxury, and the pain, of being a "team of one". Everyone else here is working in some variant of C. I interface to a lot of different systems, and those interfaces I insist on documenting. With external documentation. What I was trying to address in my original post is internal documentation for *me* when I have to go back 3 years later and remember what I was doing to reuse code. Unless I get hit by a bus on the way to work someday, the odds of anyone else ever looking at my code are pretty slim, so any code cleanup/documentation of my own software is entirely for my own benefit.

The culture here is to do everything on-the-fly. Mid-range projects ($250k+) and up have SOWs and appropriate top level design docs, but after those pass review, all bets are off. "Design meetings" consist of me and a user sitting down in front of a computer and them telling me something like, "I want a button that will export all this spectra data to Origin." Delivery dates are nebulous as testing is continually ongoing and code can often be delivered at any time. All my customers are internal, and while I can't say money is no object, if someone wants something badly enough someone can generally be found to fund it. The good side of all of this is there is a very strong sense of support for the concept of "do whatever it takes to get it done", but unfortunately it's often accompanied by "just don't bug me about the details until it's done and then I'll let you know if it needs to be changed". That's just the way things work around here.

The good news is that my (relatively new) team leader came to me the other day and suggested we start generating SOWs for even our little 2 week tasks! I got all wide-eyed and he thought I was going to protest, but I happily agreed. It's not detailed design documentation, but you have to start somewhere. smile.gif

Share this post


Link to post
Share on other sites

Just to throw my two cents in I generally don't believe in lots of documentation in the code itself. The main reason is that it is generally not maintained and therefore is rather useless. If you are in the code and you see that the code is different from the in source documentation which do you believe? A solid architecture, good use of modularization (and yes, all subVI's should have accurate documentation for the VI itself), meaningful data and subVI names as well as good style along with system level documentation tends to work best. I am not saying that you shouldn't use any documentation in the source code but it should be minimal. In the case of a state machine I do label all wires in and out of the state machine but they are labeled outside of the individual cases. As others have stated I try to minimize the number of wires flowing through a state machine and when appropriate I bundle the data into clusters. The unbundle and bundle by name inside the individual states will help to "document" what data is being used in the individual state (provided you use meaningful names on you cluster elements).

Lots of comments embedded inside the source code are just one more thing that need to be maintained.

If there is a discrepancy between code and docs, I'm going to believe the code. Assuming it worked at one point, the code doesn't lie. And the only thing worse than no documentation is incorrect documentation.

I agree the unbundle/bundle of a state is great internal documentation. That's my second pic in my original post. But the problem comes when you're an anal-retentive coder (like me) and insist on everything being neat and tidy. In this instance that means everything in a BD having to fit on one screen. All the wraps around the state machine take up lots of screen room (my development computer is 1024x768) so I tend to turn each state into a subvi to get more wiring space. So now that self-documentation is buried down another layer. When I'm first looking at the code again after a couple years, I have to click in and out of all the state subvis to figure out what gets read/written where. I'm doing that now with a piece of code, and looking at ways to make that process easier in the future is what started this whole thread. Either that, or I need to get therapy for my anal-retentiveness, and then this wouldn't be a problem anymore. smile.gif

Share this post


Link to post
Share on other sites

... I do have the luxury, and the pain, of being a "team of one".

I've been a "Team of One" for probably more than 10 of my 11+ years in LV. That's why we come here. smile.gif

Share this post


Link to post
Share on other sites

If there is a discrepancy between code and docs, I'm going to believe the code. Assuming it worked at one point, the code doesn't lie. And the only thing worse than no documentation is incorrect documentation.

I agree the unbundle/bundle of a state is great internal documentation. That's my second pic in my original post. But the problem comes when you're an anal-retentive coder (like me) and insist on everything being neat and tidy. In this instance that means everything in a BD having to fit on one screen. All the wraps around the state machine take up lots of screen room (my development computer is 1024x768) so I tend to turn each state into a subvi to get more wiring space. So now that self-documentation is buried down another layer. When I'm first looking at the code again after a couple years, I have to click in and out of all the state subvis to figure out what gets read/written where. I'm doing that now with a piece of code, and looking at ways to make that process easier in the future is what started this whole thread. Either that, or I need to get therapy for my anal-retentiveness, and then this wouldn't be a problem anymore. smile.gif

Since you are already putting the code into subVIs then take advantage of the documentation property and tip strips for VIs. By doing this you simply need to select the particular subVI and show its help. You save yourself from having to open the VI and you also get some consistency in your documentation by forcing the document property to be filled in for all of your VIs.

As far as which to believe, the code or the comment, you are right that the code is what is actually being done but you can't say with any certainty that it is what is right. The comment could be correct and it was simply coded wrong. That is one of teh main reasons I don't like using embedded comments in code.

Share this post


Link to post
Share on other sites

I'm for sure in one of those chaotic/'agile' environments where nobody pays you for doing any internal documentation of your code AND the requirements are changed any and every time you talk with customers.

I'm in that boat too.

I get the impression that those of us who use LabVIEW for data acquisition and processing operate in very different world than those doing ATE. In ATE, I would imagine that the system requirements are pretty clear from the outset. You know your process, and you know the manner in which you want it automated.

For data processing applications, the development process may be much more iterative, as you may not know what has to happen in step 3 of the processing until you can see the results of step 2. Likewise, the user may not know what his UI requirements are until he sees some initial results. This is especially true when using LabVIEW to develop new processing algorithms.

Share this post


Link to post
Share on other sites

Since you are already putting the code into subVIs then take advantage of the documentation property and tip strips for VIs.

That's a good idea.

I had a project a few years back where I had to create tip strips for 1024 indicators. After that I never wanted to see a tip strip again. smile.gif

I should probably give them another chance.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

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