Join us today!
Traffic Simulation
Create a traffic simulation PLC program that follows object oriented programming guidelines.
- When a car gets close to the traffic light, if the light is red, it will stop.
- If the light is yellow, it will slow down and continue as long as the the red light is not on. After passing the traffic light, it will continue at regular speed.
- If the light is green, it will continue at regular speed.
- Check your distance with other cars to avoid collision.
The sample application can be seen below. We have used 3 cars for this simulation. Since the application has followed the object oriented programming style, it is quite easy to add additional cars into this simulation.
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
Hi everyone,
Here is my traffic simulation video. But I'm not really proud of my piece of code.
I don't have a strong OOP pratice . I tried it, it runs but I think it's can be improved.
For example if the second car has a higher speed than the first one, it moves forward, go back, go forward. :S
I can post my code now if you want or I can wait other solution.
I'm oppen to advices and remarks
The structure of the code
My car interface I_Car
METHOD Drive : I_Car VAR_INPUT i_xEn : BOOL; i_iTarget : INT; i_iLightStat : INT; END_VAR METHOD GetPos : INT VAR_INPUT END_VAR METHOD GetSpeed : INT VAR_INPUT END_VAR METHOD Run : I_Car VAR_INPUT i_iTarget : INT; END_VAR METHOD SetSpeed VAR_INPUT i_iSpeed : INT; END_VAR METHOD SlowDown : I_Car VAR_INPUT i_iTarget : INT; END_VAR METHOD Stop : I_Car VAR_INPUT END_VAR
My traffic light interface I_TrafficLight
METHOD GetPos : INT VAR_INPUT END_VAR METHOD GetStatus : int VAR_INPUT END_VAR METHOD SetDelay VAR_INPUT i_timDelay : TIME; END_VAR METHOD SetPos VAR_INPUT i_iPos : INT; END_VAR
The FB_Drive than implement a Car interface, it will manage each car
FUNCTION_BLOCK FB_Driver IMPLEMENTS I_Car VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR iPos : INT; iSpeed : INT; xStatus : BOOL; END_VAR
Methods
It could be modified by a property
METHOD GetPos : INT GetPos := iPos;
The same thing here
METHOD GetSpeed : INT GetSpeed := iSpeed;
METHOD Run : I_Car VAR_INPUT i_iTarget : INT; END_VAR iPos := iPos + iSpeed; xStatus := TRUE; Run := THIS^;
METHOD SetSpeed VAR_INPUT i_iSpeed : INT; END_VAR iSpeed := i_iSpeed;
METHOD SlowDown : I_Car VAR_INPUT i_iTarget : INT; END_VAR IF iPos + 2 <= i_iTarget THEN iPos := iPos + 2; ELSE iPos := i_iTarget; END_IF xStatus := TRUE; SlowDown := THIS^;
METHOD Stop : I_Car xStatus := FALSE; Stop := THIS^;
FB_TrafficLight
FUNCTION_BLOCK FB_TrafficLight IMPLEMENTS I_TrafficLight VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR iPos : INT; iStatus : INT; myTon : TON; END_VAR myTon(IN := NOT myTon.Q); IF myTon.Q THEN iStatus := iStatus - 1; ELSE ; END_IF IF iStatus < 0 THEN iStatus := 2; ELSE; END_IF
METHOD GetPos : INT GetPos := iPos;
METHOD GetStatus : INT GetStatus := iStatus;
METHOD SetDelay VAR_INPUT i_timDelay : TIME; END_VAR myTon.PT := i_timDelay;
METHOD SetPos VAR_INPUT i_iPos : INT; END_VAR iPos := i_iPos;
In the MAIN program. I think that the first 8 lines could be defined by a specific function bloc.
PROGRAM PLC_PRG VAR aMyDriver : ARRAY[0..1] OF FB_Driver; tonSample : Standard.TON; xFrwd : BOOL; aitfLight : ARRAY[0..1] OF FB_TrafficLight; iIdxLight : INT; iIdxCar : INT; iLimPos : INT; iCarSize : INT := 54; xRun : bool; END_VAR aitfLight[0].SetPos(100); aitfLight[0].SetDelay(T#5.3S); aitfLight[1].SetPos(250); aitfLight[1].SetDelay(T#5S); aitfLight[0](); aitfLight[1](); aMyDriver[0].SetSpeed(4); aMyDriver[1].SetSpeed(4); tonSample(in := NOT tonSample.Q, pt := T#1.8S); FOR iIdxCar := 0 TO 1 BY 1 DO iIdxLight := GetLightIdx(i_iPos := aMyDriver[iIdxCar].GetPos(), iq_aiLight := aitfLight); IF iIdxCar <> 0 THEN iLimPos := aMyDriver[iIdxCar - 1].GetPos() - iCarSize; ELSE iLimPos := aitfLight[iIdxLight].GetPos(); END_IF aMyDriver[iIdxCar].Drive(i_xEn := tonSample.Q AND xRun, i_iTarget := iLimPos , i_iLightStat := aitfLight[iIdxLight].GetStatus()); END_FOR
Thanks for your constructive comments to improve the code 😀
-
Array Comparison
2 years ago
-
Measuring the scan cycle of PLC
2 years ago
-
Momentary Push Button and LED - Programming Challenge
2 years ago
-
Adjustable Flowing LEDs - PLC Programming Challenge
2 years ago
-
Custom Flash Timer
2 years ago
- 17 Forums
- 267 Topics
- 942 Posts
- 4 Online
- 722 Members