Join us today!

Notifications
Clear all

Traffic Simulation

3 Posts
2 Users
2 Reactions
518 Views
twinControls
Posts: 115
Admin
Topic starter
(@twincontrols)
Member
Joined: 2 years ago

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. 

 

Reply
2 Replies
Posts: 17
(@joris)
Eminent Member
Joined: 2 years ago

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

 

Reply
Posts: 17
(@joris)
Eminent Member
Joined: 2 years ago

The structure of the code

Structure

 

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 😀 

Reply
Share: