Jump to content

Increment enumeration constant in a state machine


Recommended Posts

Since enumeration variables have a number and a string associated with them, I figured I would be able to add an integer to an enumeration constant to be able to advance states in a state machine. But when I do that, the selector label in my case structure switches from displaying the string associated with the enumeration constant to the number instead..... Is there any way to force it to display the string?

Attached is a VI that illustrates my problem.

Link to comment

QUOTE(young grasshopper @ Sep 12 2007, 03:28 PM)

Since enumeration variables have a number and a string associated with them, I figured I would be able to add an integer to an enumeration constant to be able to advance states in a state machine. But when I do that, the selector label in my case structure switches from displaying the string associated with the enumeration constant to the number instead..... Is there any way to force it to display the string?

Attached is a VI that illustrates my problem.

Nice solutions have been proposed but I just want to say that using enums as numbers is a bad practice. Enums should be used as labels and your programming should not depend on their numeric values. In few months when you'll look at your diagram and ask "when does the state machine make a transition to the state 'do_this'?" and you won't find any state enum on the diagram set to 'do_this'.

Link to comment

QUOTE(jpdrolet @ Sep 12 2007, 01:17 PM)

Nice solutions have been proposed but I just want to say that using enums as numbers is a bad practice. Enums should be used as labels and your programming should not depend on their numeric values. In few months when you'll look at your diagram and ask "when does the state machine make a transition to the state 'do_this'?" and you won't find any state enum on the diagram set to 'do_this'.

That is a really good point. I really need to look past just answering the question more often...

Link to comment

QUOTE(young grasshopper @ Sep 12 2007, 03:28 PM)

Since enumeration variables have a number and a string associated with them, I figured I would be able to add an integer to an enumeration constant to be able to advance states in a state machine. But when I do that, the selector label in my case structure switches from displaying the string associated with the enumeration constant to the number instead..... Is there any way to force it to display the string?

Attached is a VI that illustrates my problem.

Your example VI has a case output tunnel which outputs a plain I32 from all its cases except one, which outputs the wire coming in. So, the tunnel is typed as a plain I32, which then is summed with another I32. So the enum wiretype never propagates past the left side shift register.

What I didn't see in the other answers so far is that all your tunnel assignments should be from constants of the same enumeration. If you do this, you'll preserve the enum type in the shift register terminals. Additionally, you need to understand that arithmetic operations like add and subtract can't really be properly performed on enums, so the editor coerces the enum to its numeric value to perform the math.

There is one exception to this (OK, two, technically): the increment and decrement primitives on the numeric palette. For enums, these behave as you'd expect. (Sorry, I think dsaunders post is incorrect in this regard.) Also, the enum value will "wrap" between its first and last values. These are the only "numeric" operations allowed on enums. I think they're really what you intended to do from your original posting. If you stick to these guidelines, you should never need to perform any re-casting to get your wire type "back".

And the advice you already got about typedef'ing an enum is very important. It allows you to add values to the enum later and ensure that they type-propagate to all those constants (if you dropped them as typedef instances). Create the typedef before you begin coding, and use it, otherwise you'll spend hours chasing coercion dots and running down out-of-date enum constants.

Best of luck!

Dave

Link to comment

QUOTE(dsaunders @ Sep 12 2007, 11:52 PM)

Well, well... :unsure: I'm not doing too hot here. You are right. I didn't even notice the lack of coercion dot. Thanks for correcting this, and pointing out some new behavior for enums that I didn't know about. I do agree with jpdrolet, though, that it would be better documented in the code to put the correct enum constant down, rather than incrementing or decrementing.

I knew something was bothering me about this. It works since, as Dave pointed out, it is really just casting an enum to the same enum. But I had tried to typecast a numeric to an enum before and it doesn't work. There is no error, and it compiles. But for some reason the enum output always goes to the default value (the first element).

This is a classical problem.. It happens when you try to cast a number to an enum where their representations are not the same.

E.g. trying to cast the output of 'Search 1D array' function (i32) to an enum (default u16) will always give you some unpredictable results (well, they are predictable I guess, but you'll have to do some bit-twiddling then..) unless you first convert the i32 to a u16.

Link to comment

QUOTE(dsaunders @ Sep 12 2007, 05:52 PM)

I think that the increment/decrement operations are appropriate when designing enum-driven state machines and the intended behavior is 'go to the next defined state'. While I'm completely in agreement with jpdrolet that one should never infer a numeric value from an enum, I think that it is valid to consider them as an ordered set of values. An advantage to using increment here is that changing the enumeration to include a new value between two existing values can often be done without revisitng the code, if the intention is still to step through the states.QUOTE(dsaunders @ Sep 12 2007, 05:52 PM)

I knew something was bothering me about this. It works since, as Dave pointed out, it is really just casting an enum to the same enum. But I had tried to typecast a numeric to an enum before and it doesn't work. There is no error, and it compiles. But for some reason the enum output always goes to the default value (the first element).

Possibly what you're being bitten by is the length of the numeric vs. the length of the enum. The square-peg-round-hole cast node preserves bit pattern, not numeric value, so if there's a size mismatch (say, an I32 number cast to a U16 enum), you'll get perhaps only the high-order two bytes of the numeric (depending on endianness). This is why casting to/from enums is so perilous. Try casting a U16 number to a U16 enum and see if you get the various values you'd expect.

Best regards,

Dave

And Jeffrey beat me to it...

Just for completeness' sake, the bullet casts DO preserve numeric value where possible. Only the SPRH cast behaves as described above.

Link to comment

QUOTE(dsaunders @ Sep 12 2007, 02:52 PM)

It works since, as Dave pointed out, it is really just casting an enum to the same enum. But I had tried to typecast a numeric to an enum before and it doesn't work. There is no error, and it compiles. But for some reason the enum output always goes to the default value (the first element).

I appreciate the lessons here. This was the first time I had tried to increment an enum, so I was bound to get bit :oops:

As mentioned above, I never thought to increment/decrement enums since I consider them to be (very powerful) numbered labels. The reason I rely so heavily on typdef enums in my programs is because I can be assured that all of my typedefs are changed when I add/remove a label...and all case structures would retain their intended behavior...which may very well (and probably would) break an incrementing/decrementing enum design.

I typically use arrays for ordered state management stuff. ;)

Link to comment

Join the conversation

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

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.