0

I am using simpy to model a traffic simulation where I want to model car following and disallow overtaking. As an example consider two cars: A is traveling at a fast speed and is approaching car B which is in front. car A cannot overtake car B and has to slow down.

My idea is to split the road into small chunks and have the chunks be resources. This way, when a car is using a road chunk other cars have to wait for the road chunk to be released before they can use it. If we order the chunks then overtaking cannot happen.

The downside is that the number of chunks can be big.

Before moving on with this approach, I want to ask if there is a better way to model this in simpy?

mrk
  • 3,061
  • 1
  • 29
  • 34

1 Answers1

0

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)
Michael
  • 1,671
  • 2
  • 4
  • 8