LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Multi Core synchronisation on traffic lights

Hi Everyone,

 

Before I start I've got to say I'm not looking for direct answers as this is coursework for my degree. What I am seeking is just some advice/point in the right direction as the last thing I want is to start developing down the wrong path and in the end run out of time, anyway...

 

I need to create a system that has 3 traffic junctions and 1 control centre. each have a core so will be ran on a quad-core system, the control centre will send out commands such as timings and an emergency stop so I'm thinking of using shared variables (as the spec states it needs to be modified easily to allow it to be moved to multiple machines). I have attached my current VI that I am working on but I am starting to get concerned that I have used the wrong techniques in order to have core synchronisation and a proper real-time system.

 

If you could have a quick look (all 3 junctions are the same so only the top timed loop needs to be seen) that would be great, really appreciate your help.

 

Thanks,

 

Matt

0 Kudos
Message 1 of 15
(3,414 Views)

I don't see any shared variables.

 

Your code is way too stacked for my taste: slow loops inside slow loops inside slow loops, ad infinitum.

Why do you need to reset 13 items per loop to defaults with each iteration of the outer loop?

 

For each site, I would recommend to use a single outer loop and a single case structure in a state machine architecture.  Now you only need to check the shared variables in exactly one place per site and then simply temporarily switch to a different state if an emergecy occurs. All lights terminals belong after the case structure

 

Assigning them to a core each makes no difference here because, there is no heavy math involved. All operations are done in nanoseconds, so there is no contention. Even if everything currently runs on a single CPU, splitting the code into four sites is not any more difficult later.

0 Kudos
Message 2 of 15
(3,404 Views)

Matt,

 

Thank you for indicating that this is coursework.  We are glad to help people learn LV, but it is amazing how many try to get their work done for them.

 

When using LV you probably do not need to worry too much about which core things run on.  LV's scheduler is generally quite good at allocating resources.

 

General comments on what you have done:

- I have no experience with timed loops because they are not available on my platform, but I think you are abusing them (except for forcing core assignment).  The code inside will always take longer to run than the timing.

- You are overusing and misusing property nodes and local variables.  There is only one common use of local variables in LV for which no other method is better and it does not exist in your code.  Use shift registers and wires.

- Set up the identical code as subVIs.  No need to write the same code over and over.  If you find a bug or need to change a feature, you only need to change one place when it is a subVI.

- You need to reconsider your timing method. If someone presses Emergency Stop just as the code enters state 0, it will be at least 4 seconds before it is detected.  Learn about Event structures.

- Learn about state machines. A traffic light controller is very suited to that architecture.  I suspect that you only need one loop for each Junction, not while loops nested inside a for loop nested inside a timed loop.

- Look at the style guides. Data should generally flow from left to right and wires should not run under or behind other nodes.

 

You have not shown any attempts at communication with the controller.   Again, I have no experience with shared variables because they are not available on my platform. For programs which run in one application instance (on one computer) queues and notifiers might be the best way to communicate. For a multi-computer network consider TCP/IP.  I think the shared variables use TCP or UDP internally.  Regardless of the communications "equipment" used, give careful thought to the types of messages to be sent, the speed of transmission, and error handling.

 

Also consider the program structures and data structures that you would need to expand this to a meaningful scale, perhaps a 10x20 grid with some junctions missing or not synchronized.

 

Your project is a topic that I have been considering.  I will not tell you now how I have thought about implementing some of these things, but I am interseted in your progress.  After you have moved along with your project, I will share some of my ideas.

 

Lynn

Message 3 of 15
(3,394 Views)

Thank you for your replies, really appreciated. I shall give the suggestions a go over the weekend and post back the progress I have made

0 Kudos
Message 4 of 15
(3,389 Views)

Hi Again,

 

An update!

 

I've tried to keep the nesting to a minimum but finding it hard due to what needs to be done, however, I have got rid of all the local variables. One thing I'm unsure of is how to get the sequence to poll if the emergency stop has been pressed when the Green is on its "wait" cycle. I've tried to use the event structure with the state machine, still working on only letting the Green and Red cycles be effected by the emergency stop

 

Thanks,

0 Kudos
Message 5 of 15
(3,359 Views)

Matt,

 

You are making progress.

 

Read up on the event structure in the LV help.  The idea is to have a structure which can respond immediately to user input.  To do that effectively the code inside an event case should never take more than a few tens of milliseconds to complete so that the system is ready to respond to the next event.

 

So Waits are rarely used inside an event case. Similarly while loops inside event cases are usually not a good idea.

 

Inside the North East and Start System case you have something like a state machine.  You did not include the CaseStructTrafficLight.vi so I cannot see what is does.

 

Typically when you want to use an event structure in single loop with a state machine the loop is outside the event structure, the state machine case structure is inside the timeout case (with the timeout set at perhaps 100 ms - less in some states), and the other event cases simply set values or commands for the state machine via shift registers.  The terminals for buttons or switches are usually inside the Value Changed event cases for those controls.  This is necessary for booleans with Latch mechanical action so they are read at the appropriate time. All states in the state machine must complete in a time less than the timeout setting. The timing is handled not by putting Wait functions inside the case structure but by Setting a Timing value in a shift register.  When North_South_Amber starts the Timing Value is set to the Current tick count plus GreenTimeDelayNorth. Then the state exits. If no new command is received the system returns to the SAME state.  On each iteration the Current tick count is compared to the TIming Value. When it is greater, then the specified time has elapsed and the system moves to the next state.

 

A program set up as I have described will respond very quickly to Emergency Stop and all other command inputs.  It can also be modified for changes in requirements quickly and easily.

 

You should have a Stop Program state. The program you have now can only be stopped by using the Abort button on the toolbar. That should only be used durign program development when a bug causes a program to run forever. Using a Stop Program state allows for orderly shutdown. Files can be closed. References can be closed. Data Acqusition boards can be restored to a default state. Communications to other computers can be closed.  Someone on the Forums has stated that using the Abort button to stop a program is like using a tree to stop a car. It works but can have undesired consequences.

 

Lynn

0 Kudos
Message 6 of 15
(3,353 Views)

Hi Lynn,

 

Thanks for your help.

 

I'm having slight trouble with the register version of timing each state. I've attached what I've got so far and I've commented where I'm currently working on.

 

Using the register method would the emergency stop be able to stop the lights when they are in a sequence I don't want to stop? for instance, if the lights are in a red, amber state I wouldn't want them to suddenly go to red but instead finish the sequence (Green, amber, red) if that makes sense?

 

I'm currently thinking I need to do the timing within the subVI and have "emergency" cases. Does this sound like the right path?

 

Really appreciate the help.

 

Matt

 

 

Download All
0 Kudos
Message 7 of 15
(3,318 Views)

You still have way too many layers of loops and other structures. A single outer while loop is all you need. Simplify!!!

 

(See attached quick modification draft, LV 2011. It is in no way complete, but show how do do basically flat code as suggested)

 

You delay loop experiment in the subVI needs a short wait, else it will do millions of iterations per second and basically complete instantly.

 

 

0 Kudos
Message 8 of 15
(3,311 Views)

Hi altenbach,

 

I'm thinking of removing the while loop and using the timed loop for the registers instead ( I need the timed loop to force this junction onto one CPU which is a requirement), would that be correct?

 

In terms of simplifying I find I need to use a case structure within the "emergency stop" so the lights change sequence safely unless there is a way to only allow the "emergency stop" to be deteceted when any light is green or red but not inbetween?

 

Oh I see the tick count now, wow I feel stupid :s I'll try and implement that now.

 

So it's ok to use the wait function in small quantities? especially if I don't want the program to inturrupt inbetween a certain sequence/set cases? 

 

Thanks for your help,

 

Matt

 

 

0 Kudos
Message 9 of 15
(3,306 Views)

flak714 wrote:

I'm thinking of removing the while loop and using the timed loop for the registers instead ( I need the timed loop to force this junction onto one CPU which is a requirement), would that be correct?


Yes, any loop will do. If you use a timed loop, you don't need the 100ms wait.

 


flak714 wrote:

In terms of simplifying I find I need to use a case structure within the "emergency stop" so the lights change sequence safely unless there is a way to only allow the "emergency stop" to be deteceted when any light is green or red but not inbetween?


WIthout the emergency stop, at least one light will always be yellow or green. If you want, you can add a new transition state where all lights are yellow before all lights turn red.


flak714 wrote:

So it's ok to use the wait function in small quantities? especially if I don't want the program to inturrupt inbetween a certain sequence/set cases? 



I don't understand what you mean here. What is interrupting what?

 What are small quantities?

0 Kudos
Message 10 of 15
(3,290 Views)