JKI Discussion Forums
  • (2 Pages) +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

jki state machine producer consumer loop

#1
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi

Has anyone adapted the jki state machine into the producer-consumer loop design with queues and event structures? Could you share examples?

thanks
0 kudos

#2
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Oct 25 2009, 10:58 AM, said:

Hi

Has anyone adapted the jki state machine into the producer-consumer loop design with queues and event structures? Could you share examples?

thanks


Hi!

Yes, we do this at JKI, in a variety of ways. You can put a Read Queue function in the timeout frame or you can use Dynamic User Events. This opens up a pretty big discussion -- to get things rolling I'll post an example that uses Dynamic Registration of User Events.

Attached File  Producer_Consumer_JKI_State_Machine__LV82_.vi (70.09K)
Number of downloads: 271 (LabVIEW 8.2)

Front Panel
Attached Image: monthly_10_2009/post-2-1256618397.png

Block Diagram
Attached Image: 0.png

Key things you should note:
  • The "Events: Register" and "Events: Unregister" frames are called by "Macro: Init" and "Macro: Exit" to handle the dynamic registration.
  • The event registration reference routed above the Event Structure is important. There are some LabVIEW type-propagation bugs caused when you wire out of the right-side Dynamic Event Terminal to the Case Structure tunnel.
  • The event data type(s) will propagate all the way to the Event Structure.
  • You can resize the Register for Events function in the "Events: Register" frame for adding other user events.
  • You can have multiple consumers (you can have multiple JKI State Machine's register for the same user event) -- this makes it a true publish-subscribe architecture.
  • Note that user events get queued and there is no way to preview or flush the queue (since NI did not intend for them to be used for pub-sub architectures, even though it's so natural...). This can cause big performance problems if your producers generate too many events (especially of large data) and your consumer loop does not iterate fast enough (calling the event structure to process the events).
  • You can wire clusters and arrays into the Register for Events function, in order to group events by name (with a cluster of user events) or have a single frame handle events from multiple sources (with an array of user events).
  • Watch out for the bug where Event Structure frames can incorrectly remap to other dynamic events
I'll post more noteable stuff, if I recall it. Also, if anyone else has comments, ideas, or knows of other things to watch out for, please feel free to join in on the discussion.

Cheers,
0 kudos

#3
User is offline   Jim C 

  • Group: Members
  • Posts: 23
  • Joined: 01-November 08
  • Gender:Male
  • Location:North Carolina, USA, Earth
  • Interests:LabVIEW
Arrrrrrrrrgh. It was bound to happen eventually. I'm surprised it took this long.

Do you have this for 8.6?
0 kudos

#4
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View PostJim C, on Oct 27 2009, 03:36 AM, said:

Arrrrrrrrrgh. It was bound to happen eventually. I'm surprised it took this long.

Do you have this for 8.6?


Sure -- I've updated the example VI (re-saved in LabVIEW 8.2).
0 kudos

#5
User is offline   Jim C 

  • Group: Members
  • Posts: 23
  • Joined: 01-November 08
  • Gender:Male
  • Location:North Carolina, USA, Earth
  • Interests:LabVIEW

View PostJim Kring, on Oct 27 2009, 11:36 AM, said:

Sure -- I've updated the example VI (re-saved in LabVIEW 8.2).

Thanks, Jim.

I'm thinking that User Events are the way I should handle things that I dynamically launch and let run in the background. I had used Queues & Notifiers for this but that requires me to poll for the event. I've written the program for one ATE this way. Is this an appropriate use of User Events?

You said in your first post that this "opens up a pretty big discussion". It should be very interesting; I hope it takes off.

Jim

This post has been edited by Jim C: 28 October 2009 - 09:54 AM

0 kudos

#6
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi!

Thanks for sharing the example for the JKI state machine applied to the producer consumer loop, it was very useful.

However, I am not sure what is the best way to share data between the producer-consumer loop. I can send the Message from the producer to the consumer, but, for example, if I need to send together with the Message another data, for example, a Boolean (to be processed in the consumer loop), what is the best way to do it? Should I use a variant (cluster of string-message and Boolean-data) as the user event data type in the producer loop, or there is a better way?


thanks

Helcio
0 kudos

#7
User is offline   Cindy 

  • Group: Members
  • Posts: 1
  • Joined: 28-October 09
Hi,

I have a question about initialization. What if you need to initialize something for the producer loop to run and it would make sense to do the initialization in the state machine loop? Is there a good way to do that and then signal the producer loop to start?

Cindy
0 kudos

#8
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Oct 28 2009, 10:05 AM, said:

However, I am not sure what is the best way to share data between the producer-consumer loop. I can send the Message from the producer to the consumer, but, for example, if I need to send together with the Message another data, for example, a Boolean (to be processed in the consumer loop), what is the best way to do it? Should I use a variant (cluster of string-message and Boolean-data) as the user event data type in the producer loop, or there is a better way?


Hi Helcio,

First, I would create separate user events for every event type. If you need to pass generic data with specific events, consider using LVOOP objects as the generic data, with child classes for decoding specific data. You can group your user events in a cluster, before passing them into the Register for Events. I'll try to post an example of this, soon.

Second, I like to make my event data a cluster and pass all relevant data in the cluster. Examples of this extra data are timestamp, additional data, etc. I tend not to pass "generic" string/variant data that has to be decoded programmatically. Again, I typically user LVOOP objects when I have to pass generic data.

-Jim
0 kudos

#9
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View PostCindy, on Oct 28 2009, 11:46 AM, said:

I have a question about initialization. What if you need to initialize something for the producer loop to run and it would make sense to do the initialization in the state machine loop? Is there a good way to do that and then signal the producer loop to start?


Hi Cindy,

You might consider using a Rendezvous -- have the Producer wait on a Rendezvous (of size 2) that the consumer (state machine) will wait on (therefore causing producer and the consumer to stop waiting).

I'll try to post an example of how to do this, soon (since, I've got to go to a meeting, right now).

-Jim
0 kudos

#10
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi Jim,

I tried to do what you have said for the producer consumer loop with events and data for the JKI state machine. I created a cluster with user all user events I needed and worked from there. I am sending the project file attached for labview version 2009 (could not be saved in Labview version 8.2 because it generates an error). I hope that this is what you had in mind.

However, I have no clue how I could use LVOOP to avoid having to convert variant, therefore you will see conversions all over the code:
Attached Image: monthly_10_2009/post-2790-1256858174.jpg
Attached Image: block_diagram.jpg



regards

Helcio

View PostJim Kring, on Oct 28 2009, 11:59 AM, said:

Hi Helcio,

First, I would create separate user events for every event type. If you need to pass generic data with specific events, consider using LVOOP objects as the generic data, with child classes for decoding specific data. You can group your user events in a cluster, before passing them into the Register for Events. I'll try to post an example of this, soon.

Second, I like to make my event data a cluster and pass all relevant data in the cluster. Examples of this extra data are timestamp, additional data, etc. I tend not to pass "generic" string/variant data that has to be decoded programmatically. Again, I typically user LVOOP objects when I have to pass generic data.

-Jim

Attached File(s)


This post has been edited by hburd: 29 October 2009 - 11:28 PM

0 kudos

#11
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Oct 29 2009, 04:00 PM, said:

I tried to do what you have said for the producer consumer loop with events and data for the JKI state machine. I created a cluster with user all user events I needed and worked from there. I am sending the project file attached for labview version 2009 (could not be saved in Labview version 8.2 because it generates an error). I hope that this is what you had in mind.


Helcio,

You did pretty good :wacko:

Here is a new version with some changes:

Attached File  jki_producer_consumer_loop_with_events_and_data_lv_2009.zip (89.66K)
Number of downloads: 243
You'll notice several things:

Every different event now has a type definition
Will definitely save you a LOT of time, if the event data ever changes.

The cluster of user events is now a type definition
Could save you a LOT of time, when the number of events ever changes.

I renamed "jki create and register events.vi" to "jki create events.vi"
"Creating" and "Registering" events should be separated, because we might have multiple consumer loops that register (subscribe) to the events.

Attached Image: 1.png

I renamed the event cluster output of "jki create events.vi" to "My User Events"Since this is the name that shows up in the event structure, we want it to be readable ("user events out" doesn't really apply well).

Attached Image: 0.png

Don't use variant data + string message for events with well-defined data type
Using variants takes too much work. Since you have multiple events, make each events data type different.

Attached Image: 2.png

There are still a few more improvements that I would probably make, that move it into a more object-/component-oriented" design. I'll make another follow-up post, soon, with some of these improvements.

Regarding LVOOP...

View Posthburd, on Oct 29 2009, 04:00 PM, said:

However, I have no clue how I could use LVOOP to avoid having to convert variant, therefore you will see conversions all over the code:

Sorry about that. LVOOP is a pretty advanced topic. In case you're interested, what I meant was: you can create a parent class called "Event.lvclass" and then create child classes for specific event types. Each child class can implement a dynamic method called "Handle Event.vi". Inside the event structure, when the event happens, you can call "Event.lvclass:Handle Event.vi". This will then dynamically dispatch to the child implementation, based on the type of the event object.
0 kudos

#12
User is offline   Callahan 

  • Group: Members
  • Posts: 8
  • Joined: 14-December 09
  • Gender:Male
  • Location:LYON, FRANCE
  • Interests:LabVIEW environnement<br />LabVIEW community<br />bug seaking<br />nice and simple code
Hum...just a question : Why the "Destroy User Event" function is not used in the upside example ?
Errare humanum est
0 kudos

#13
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View PostCallahan, on Dec 16 2009, 11:30 AM, said:

Hum...just a question : Why the "Destroy User Event" function is not used in the upside example ?


If "Destroy User Event" isn't being called, then thanks a bug -- good catch! ;)
0 kudos

#14
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi again,

The jki state machine producer consumer loop is working nicely using it in the way described by you. I was wondering what would be the best way to use the jki state machine producer consumer loop to intercommunicate with other jki state machines Producer consumer loops (JKI SM PC loop) in the same project, but not in the same vi.

For example, suppose I have 1 JKI SM PC loop that continuously acquire data from the serial port. What would be the best way to transfer the data from this jki sm pc loop to another jki sm pc loop in another vi which will plot the serial data acquired? Or alternatively, in the example given above (Attached File  jki_producer_consumer_loop_with_events_and_data_lv_2009.zip (89.66K)
Number of downloads: 243), what if another vi sends a command for this jki state machine PC loop execute the command for displaying a certain message on the screen?

Would the answer be to use notifiers? I mean, if I put a "wait on notification" in the timeout event structure of the jki sm pc loop that will execute the commands and a "send notofication" in the jki state machine PC loop that sends the commands?

thanks

Helcio

This post has been edited by hburd: 13 February 2010 - 04:14 AM

0 kudos

#15
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Feb 12 2010, 05:25 PM, said:

The jki state machine producer consumer loop is working nicely using it in the way described by you. I was wondering what would be the best way to use the jki state machine producer consumer loop to intercommunicate with other jki state machines Producer consumer loops (JKI SM PC loop) in the same project, but not in the same vi.


Hi Helcio,

The way that we tend to do this at JKI is to use GOOP-style objects/components. A component has a process that is a JKI state machine. Each component has a method called "Get Public Events" that outputs a cluster of its public events. Components can then easily register for the events of other components inside their own JKI State Machine process loops.

We also usually have a "Get Private Events" method that can be used by the component for sending messages/commands into its own process. This gets very tricky in a hurry, especially when you need to get data back from the process after it is finished handling the message/command. This can be achieved in a variety of ways.

Does that sort of answer your question?

Thanks,
0 kudos

#16
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi Jim,

Thanks for the information. I guess I really have to start learning GOOP, it will be very useful.

thanks again!


Helcio

View PostJim Kring, on Feb 15 2010, 10:33 PM, said:

Hi Helcio,

The way that we tend to do this at JKI is to use GOOP-style objects/components. A component has a process that is a JKI state machine. Each component has a method called "Get Public Events" that outputs a cluster of its public events. Components can then easily register for the events of other components inside their own JKI State Machine process loops.

We also usually have a "Get Private Events" method that can be used by the component for sending messages/commands into its own process. This gets very tricky in a hurry, especially when you need to get data back from the process after it is finished handling the message/command. This can be achieved in a variety of ways.

Does that sort of answer your question?

Thanks,

0 kudos

#17
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Feb 16 2010, 07:22 AM, said:

Hi Jim,

Thanks for the information. I guess I really have to start learning GOOP, it will be very useful.

thanks again!
Helcio


Hi Helcio,

You're very welcome. Yes, I think you're probably at a point where you would benefit from learning about OOP. A great place to start, even if I do say so myself, is the appendix on OOP techniques in LabVIEW for Everyone. I talk about the history of by reference OOP implementations in LabVIEW and talk a little bit about the principles of OOP.

Cheers!
0 kudos

#18
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi Jim,

I read the GOOP chapter indicated by you in the book. Also I am trying to learn more OOP, but still I continue without a clue in how to implement the JKI producer loop to share data with other JKI producer consumer loops. Could you post an example of that when you have time?

Also, there will be a presentation section in the NIWEEK 2010 dedicated to the comparison between the JKI state machine and the other types of state machine. Could you post the presentation on this website for those, like me, who won't attend the NIWEEK?

Thanks

Helcio



View PostJim Kring, on Feb 16 2010, 10:17 AM, said:

Hi Helcio,

You're very welcome. Yes, I think you're probably at a point where you would benefit from learning about OOP. A great place to start, even if I do say so myself, is the appendix on OOP techniques in LabVIEW for Everyone. I talk about the history of by reference OOP implementations in LabVIEW and talk a little bit about the principles of OOP.

Cheers!

0 kudos

#19
User is offline   Jim Kring 

  • Group: JKI Team
  • Posts: 1,204
  • Joined: 15-March 06

View Posthburd, on Jun 24 2010, 08:27 AM, said:

Hi Jim,

I read the GOOP chapter indicated by you in the book. Also I am trying to learn more OOP, but still I continue without a clue in how to implement the JKI producer loop to share data with other JKI producer consumer loops. Could you post an example of that when you have time?

Also, there will be a presentation section in the NIWEEK 2010 dedicated to the comparison between the JKI state machine and the other types of state machine. Could you post the presentation on this website for those, like me, who won't attend the NIWEEK?

Thanks

Helcio


Hi Helcio,

Please post/send us a reminder after NIWeek and we'll post links to the NIWeek presentations. This should include a lot of good stuff, including info about sharing data between JKI State Machine loops.

Stay tuned!

Thanks,

-Jim
0 kudos

#20
User is offline   hburd 

  • Group: Members
  • Posts: 15
  • Joined: 25-October 09
  • Gender:Male
  • Location:usa
Hi Jim!

The Ni week should be over tomorrow, so could you, please, post the link for the ni week presentations? Please could you also post the VIs in the presentation JKI STATE MACHINE VERSUS NI STATE MACHINE so that everybody can be able to download and follow the presentation?

thanks very much

Helcio
0 kudos

Share this topic:


  • (2 Pages) +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic