Have you thought about modeling this as a agent base model
I model each car as a agent that can see and react to the car that is in front of it. The behavior is not perfect in that crashes can happen. I also have one timer that broadcast to each car when it should update its state
"""
Simple agent base model of cars following each other
Each car adjust their speed to pervent crashing into
the preceeding car, or getting too far behind
Programmer: Michael R. Gibbs
"""
import simpy
import random
class Car():
"""
Models a cars movements and position
Each car reacts to the car in front of it
"""
car_cnt = 0
def __init__(self, env, start_pos, start_speed, lead_car=None):
"""
init starting state
"""
Car.car_cnt += 1
self.car_id = Car.car_cnt
self.env = env
self.pos = start_pos
self.speed = start_speed
self.lead_car = lead_car
def move(self):
"""
updates the car state
position and speed
"""
if self.lead_car is None:
# no lead car, must be the first car
# make random adjustment to speed
self.speed += random.triangular(-5,5,0)
dist = 0
else:
# addjust to lead car to be maintain a distance of 50
dist = self.lead_car.pos - self.pos
speed_diff = self.lead_car.speed - self.speed
x_from_goal_dist = dist - 50
if self.lead_car.pos <= self.pos: # tool close CRASHED!!!
print(f'{env.now} car {self.car_id} crashed')
self.speed = self.lead_car.speed - 5
if x_from_goal_dist <= -40: # getting way too close
self.speed -= 10
elif x_from_goal_dist >= 50: # getting way too far behind
self.speed += 5
elif x_from_goal_dist < 0: # creeping up, slow down
self.speed -= random.triangular(0,5,0)
else:
self.speed += random.triangular(0,5,0)
dist -= self.speed
self.pos += self.speed
print(f'{self.env.now} car {self.car_id} is {dist} from prev car at pos {self.pos} at speed {self.speed}')
def run_cars(env, car_list):
"""
Moves all the cars every time unit
"""
while True:
yield env.timeout(1)
for car in car_list:
car.move()
env = simpy.Environment()
car_list = []
car = Car(env,100,20)
car_list.append(car)
car = Car(env,50,25,car)
car_list.append(car)
car = Car(env,0,26,car)
car_list.append(car)
env.process(run_cars(env,car_list))
env.run(200)