May 31
/
Benjamin Schumann
How to get pedestrians and road-traffic to like each other in AnyLogic
You might be part of the 99% (or whatever the studies say) that think they are great car drivers. Well, I am not. In fact, my driving is appalling and so is my skillset as a pedestrian. I can tell because I change my behaviour drastically whenever I am around with my young daughter. Trying to teach her how cars and pedestrians should interact is pretty much what we will look at today in AnyLogic. How can we get drivers and pedestrians to be nice to each other in our little virtual crossroads we created last week?
DEFAULT SITUATION
Let’s have a look what happens if we add some simple pedestrians to the road traffic library model. I want some school children to leave their school and either cross the main road or walk to the bus stop for pick-up, see below:
Conceptually, this is modelled using the pedestrian library process blocks. “PedMoveTo” blocks tell them to walk to the traffic light first. Upon arrival, 50% try to go straight ahead across the road. The remaining pedestrian agents head south to go to the western bus stop.
Now, you might be hoping that pedestrians look out for car agents while trying to cross the road. Unfortunately, this is not the case. While AnyLogic generally aims for a “everything works with everything else” philosophy, this is one example where it doesn’t hold. Pedestrians will walk across the road (of which they have no perception, actually) without “seeing” cars approaching.
At the same time, cars do not “see” pedestrians so they happily drive on even if a flock of pedestrians blocks their way. And if you just closed your eyes to avoid seeing horrible pedestrian scenes, there is no need: cars simply pass through pedestrians like ghosts would. They are not even crashing into each other.
Currently, car and pedestrian agents do live in separate “worlds”, so to speak. Each is aware of their own world and there is little overlap. While this might be sensible from a modelling perspective, it is clearly a drawback for a large portion of traffic models that look at the interaction of cars and pedestrians.
There are two workarounds for you: simple and complex.
The simple fix
Last time, we already added a traffic light system to our cross roads. Now the pedestrian library has some blocks that we can employ to mimic pedestrians adhering to traffic. We will make them wait at the traffic light until their parallel traffic gets green lights. This way, they can cross the road without crashing orthogonal traffic.
The first step is to add a “PedWait” object one pedestrians reach the crossroads. Adjust it such that pedestrians only leave it “on free() function call” as below:
Now go back to the traffic light object from last week which regulates the crossroads traffic light. Just like many similar objects, it allows you to make it execute code at specific points in time. In the “on phase change” field, we can “free” all waiting pedestrians when the correct phase begins. Below, pedestrians should start crossing the road when “phase 0” starts. This happens to be the phase they walk in parallel with:
However, you will need to adjust traffic light phases to achieve a realistic result. In the example below, the phase is not long enough and orthogonal traffic starts driving again while pedestrians are still crossing.
However, even with a good sync, this solution is only viable for simple crossroads. As soon as you have cars turning into pedestrian flow, this won’t work. We need to find a way to get pedestrians and cars to really “see” each other.
The complex approach
Let’s keep the traffic light making pedestrians move, this is what happens in reality as well. However, we want cars to stop for any pedestrian in front of them, for example when they turn into them. To do that, let’s harness the power of agent-based modelling.
We need to turn all our cars and pedestrians into explicit agents (create new agent types for them). Then, each car can follow its unique state chart while following it’s normal driving tasks. First, however, let’s give each car a 2D view area as below:
We need to turn all our cars and pedestrians into explicit agents (create new agent types for them). Then, each car can follow its unique state chart while following it’s normal driving tasks. First, however, let’s give each car a 2D view area as below:
Make sure that your car agent scale is the same as the scale on the model Main. For the actual view area, you can use a Polyline or a Polygonal Node object. Now for the state chart: Conceptually, we want each car to regularly check if it finds any pedestrians in its view area. If so, it should stop, let the pedestrian pass and then continue. The state chart below does this feat:
Every 0.1 seconds, the transition “checkForPed” loops across every pedestrian in the model and checks if it currently sits inside the car’s view area:
for (Pedestrian thisPed : get_Main().pedestrian) {
// for each pedestrian in model
double pedX = thisPed.getX() - getX();
double pedY = thisPed.getY() - getY();
if (fieldOfView.contains(pedX, pedY)) {
pedInDanger = true;
break;
}
}
Notice how we need to to transform XY coordinates to align pedestrians and cars. As soon as the car “sees” a pedestrian, it goes into state “stopForPed”, waits for 10 seconds and then resumes its normal driving. This is what it looks like:
As you can see, cars do stop as soon as they observe pedestrians. However, it is generally too late. This is where you would need to start creating much more intelligent heuristics beyond my simplistic “stop if someone is in the view area”. This is possible but beyond the scope of this little exploration. What are your ideas to improve the situation?
Verdict
So cars and pedestrians do not know each other too well. We have seen how to overcome this. However, to approach realistic interactions, you’d need much more advanced screening heuristics. Pedestrians should start “watching” their surroundings for cars as well. Cars should do emergency stops, look around corners upon turning and dynamically adjust their view areas.
So the current situation leaves us with two very capable libraries that are best used for their intended areas: pedestrian movements and car traffic, where both do not come into contact with the other too much. It would be interesting to see if AnyLogic plans to change this in the future.
Outlook
I will leave the car-pedestrian interaction as is for the moment. Next week, we will add some real data into our model and start thinking about the correct metrics. Since cars and pedestrians cannot crash, we need to manually model this as well. Stay tuned.
PS: you can find the model files on GitHub.