LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

state machine with event structures that share a control

Solved!
Go to solution

@jgvarner57 wrote:

Responding to Wiebe:

No, it doesn't.

 

I realized after I made that comment that you were correct. Most chat threads would show who the reply was in response to, but this one doesn't. I see how people add the comment they are replying to manually (or maybe I am just not doing this right).


Hit the quote button, that looks like:

,,

 

 

Message 41 of 48
(1,525 Views)

@jgvarner57 wrote:

Responding to Wiebe:

No, it doesn't.

 

I realized after I made that comment that you were correct. Most chat threads would show who the reply was in response to, but this one doesn't. I see how people add the comment they are replying to manually (or maybe I am just not doing this right).


In all their infinite wisdom, Khoros decided to turn the obvious Quote button into a not-at-all obvious tool on the toolbar:

billko_0-1636743923925.png

 

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 42 of 48
(1,518 Views)

@altenbach wrote:

@jgvarner57 wrote:

, but the automatic handling of "latched when released" was not very elegant, and quite unpredictable, when it came to the states of the controls.


The reason is that latch action button reset to the default state when they are read by the code, meaning they need to be inside their respective events (even if not wired to anything) . If you have them outside the toplevel loop as you currently do, they will only get read once at the start of the program and will never reset again.

 

While I understand that your attached code is just a simplified mockup of the real thing, I see the following problem.

 

  • Property nodes are synchronous, forcing a thread switch and are thus expensive.
  • Having overlapping controls and constantly playing hide&seek with controls on top of each other is a nightmare during editing. All you need is one button where you change the boolean text. (Scalability is the key! Imagine if you have 10 states in the next project. How are you ever going to edit them??? Herding cats!)

 

Here's a quick draft that shows some alternatives. Maybe you can adapt some of the ideas to your code. It would be easy to expand for much more advanced functionality, e.g. trigger a queue handled elsewhere in a parallel loop, etc.

 

  • One while loop with one single event structure containing one single event case! (Flat code, nothing hidden in other cases, etc.)
  • Clear list of actions that can be expanded by adding more elements to the cluster.
  • All buttons are latch action
  • Three booleans instead of four.
  • One property node instead of 28(!). Good unless you get paid by the number of property nodes. 😄

 

altenbach_0-1636738589003.png

 

 


This absolutely blows my mind. This works perfectly yet I am scratching my head as to why. This is the epitome of coding efficiency and elegance. I will pour through this to better understand how this works and I will most definitely take this approach in my designs.

Message 43 of 48
(1,496 Views)

Note that there is some redundancy, because the "state & string" and "next state & button text" are each 100% correlated. If this is always the case (it typically is not in general), the code can be further simplified, e.g. as follows:

 

altenbach_0-1636977602213.png

 

 

If you format an enum, you get the string back, of course.

 

Message 44 of 48
(1,453 Views)

@altenbach wrote:

@jgvarner57 wrote:

, but the automatic handling of "latched when released" was not very elegant, and quite unpredictable, when it came to the states of the controls.


The reason is that latch action button reset to the default state when they are read by the code, meaning they need to be inside their respective events (even if not wired to anything) . If you have them outside the toplevel loop as you currently do, they will only get read once at the start of the program and will never reset again.

 

While I understand that your attached code is just a simplified mockup of the real thing, I see the following problem.

 

  • Property nodes are synchronous, forcing a thread switch and are thus expensive.
  • Having overlapping controls and constantly playing hide&seek with controls on top of each other is a nightmare during editing. All you need is one button where you change the boolean text. (Scalability is the key! Imagine if you have 10 states in the next project. How are you ever going to edit them??? Herding cats!)

 

This statement caught my eye (Property nodes are synchronous, forcing a thread switch and are thus expensive.)

 

I use property nodes almost exclusively to control the timing of read and write functions of controls, as local variables just hanging there can be accessed at any time in a frame and are thus unpredictable. What do you mean when you say property nodes are "expensive" (I assume you mean they chew up a lot of processor utilization)? Should I not be using them as much as I do, and why?

0 Kudos
Message 45 of 48
(1,394 Views)

@jgvarner57 wrote:

This statement caught my eye (Property nodes are synchronous, forcing a thread switch and are thus expensive.)


A significant number of property nodes can only run in the UI thread. There is only 1 UI thread for the whole OS, thus lots of processes may be competing for it. Thus you may have to wait for execution. In addition, running everything in the UI thread limits/stops parallelization.

Message 46 of 48
(1,391 Views)

@jgvarner57 wrote:
I use property nodes almost exclusively to control the timing of read and write functions of controls, as local variables just hanging there can be accessed at any time in a frame and are thus unpredictable. What do you mean when you say property nodes are "expensive" (I assume you mean they chew up a lot of processor utilization)? Should I not be using them as much as I do, and why?

The data for processing should be in the wire, not in front panel elements. Controls are for reading user input and indicators are to display something important to the operator. The inexperienced user will use these terminals (sometime even hidden on the FP) as poor mans "variables" he might remember from text based code. The UI is for the user, not for data. In LabVIEW, "the wire is the variable" (simplified).

 

A clean program design has very little use for local variables. It is always possible to wire to the terminal directly you just need to be creative and don't hide them deep inside stacks of structures. (my examples above don't have any!). Keep and update important values in shift registers and read and write the terminal on the toplevel diagram loop.

 

Local variables are more efficient, because internally they just update or read the transfer buffer (duplication of memory, expensive for large data structures!) while the front panel element has yet another data copy that will be updated at leisure whenever the UI thread executes.

 

Imagine a fast loop containing a terminal that is updated at each iteration:

 

Both writing to the terminal or to a local variable of the terminal will just update the transfer buffer (very efficient!) and the UI thread will occasionally update the indicators (You eye cannot see a million of updates per second because the screen refresh rate is much slower and the UI thread does not need to execute faster than that). If you use the same code and update the value via a value property node, each write will need to switch to the UI thread, update the value, and switch back to a normal thread for the next iteration. This is orders of magnitude more expensive! (On a side note, you can switch the terminal to "right-click...advanced...synchronous display". and then writing to the terminal will stall dataflow until the front panel has been updated, giving you a similar performance hit as with the value property, so don't do that!!). Of course it would be more reasonable to not even place the terminal inside the loop in this demo.

 

(There are plenty of old discussion here that deal with the same question, so feel free to do a search)

 

Message 47 of 48
(1,385 Views)

@mcduff wrote:

@jgvarner57 wrote:

This statement caught my eye (Property nodes are synchronous, forcing a thread switch and are thus expensive.)


A significant number of property nodes can only run in the UI thread. There is only 1 UI thread for the whole OS, thus lots of processes may be competing for it. Thus you may have to wait for execution. In addition, running everything in the UI thread limits/stops parallelization.


It's a bit more than running in the UI thread. That in itself would be fast(er) than it is.

 

The Value property and other properties that changes appearance, are synchronized with the refresh rate of the screen.

 

This doesn't mean each update waits for a refresh rate, but updating the screen blocks updating the control.

 

Locals and terminals work differently. Each local has a copy of the data (this could be expensive). At update time, the latest updated value is used. This means all updating can happen in parallel, synchronized with refresh rates. At the expense of a data copy for each instance.

 

If you want to update lots of properties (incl. value by property), you can turn defer panel updates on, do your updates, and then turn it off. At the risk of running into weird bugs, like cursors not being updated, even after defer panel updates is turned off again.

 

 

 

Message 48 of 48
(1,354 Views)