Getting started#

Welcome to the getting started guide of JuPedSim, we want to guide you through the first steps for setting up a simulation.

First things first, to use JuPedSim install it via:

pip install jupedsim

Now, you are ready to set up your first simulation with JuPedSim.

To access this Jupyter Notebook on your local machine, you can download it here along with the accompanying data file here.

Let’s simulate an experiment#

This is a bottleneck experiment conducted at the University of Wuppertal in 2018. You can see the basic setup of the experiment in the picture below:


We aim to replicate the bottleneck scenario described in the experimental series linked to this study and detailed in the publication “Crowds in front of bottlenecks at entrances from the perspective of physics and social psychology”.

Our objective in this guide is to simulate this scenario using JuPedSim.

If you use JuPedSim in your work, please cite it using the following information from Zenodo:


Setting up the simulation geometry#

The first thing to consider when setting up a simulation is the area where the agents can move. In this scenario, we have a rectangular room with two obstacles that form a bottleneck, as displayed above. These obstacles are excluded areas from the simulation, which means that agents can not move inside these obstacles.

import shapely

geometry = shapely.Polygon(
    # complete area
        (3.5, -2),
        (3.5, 8),
        (-3.5, 8),
        (-3.5, -2),
        # left barrier
            (-0.7, -1.1),
            (-0.25, -1.1),
            (-0.25, -0.15),
            (-0.4, 0.0),
            (-2.8, 0.0),
            (-2.8, 6.7),
            (-3.05, 6.7),
            (-3.05, -0.3),
            (-0.7, -0.3),
            (-0.7, -1.0),
        # right barrier
            (0.25, -1.1),
            (0.7, -1.1),
            (0.7, -0.3),
            (3.05, -0.3),
            (3.05, 6.7),
            (2.8, 6.7),
            (2.8, 0.0),
            (0.4, 0.0),
            (0.25, -0.15),
            (0.25, -1.1),

This leads to the following setup:


In this geometric setup, we now need to define, where the agents can exit the simulation, e.g., where their target is located.

For this scenario, the exit is at the end of the bottleneck. If we would put it at the beginning of the bottleneck, the agents would disappear, hence, they wouldn’t be an obstacle for following agents.

An exit can be defined as:

exit_polygon = shapely.Polygon(
    [(-0.2, -1.9), (0.2, -1.9), (0.2, -1.7), (-0.2, -1.7)]

The complete setup would then look like, where the exit is shown in red:


Distribute the agents in the geometry#

The next step is to provide the initial positions of the agents in the simulation. JuPedSim provides different helper functions to automatically distribute the agents:

However, as we want to compare our simulation to the real-life experimental data, the agents in the simulation will start at the same positions as the pedestrians in the experiment. So we load the trajectory from the experiment and extract the locations at frame 0, which is the start of the experiment.

import pandas

experiment_data = pandas.read_csv(
    names=["id", "frame", "x", "y", "z"],
start_positions = experiment_data[experiment_data.frame == 0][["x", "y"]].values

Collision-free speed model#

At first, we want to run the simulation with the Collision-free speed model. In “Collision-free speed model for pedestrian dynamics” you can find the complete description of the model. To use it in JuPedSim we need to state, that we will use this model in the creation of the simulation object.

We also need to provide the previously defined geometry and the output file, where the resulting trajectories will be stored. Here, we will use the built-in SqliteTrajectoryWriter, which will write the results as a sqlite-database.

import pathlib

import jupedsim as jps

trajectory_file = "bottleneck_cfsm.sqlite"
simulation_cfsm = jps.Simulation(

After we defined the simulation we need to add a goal, which the agents should target. As we already defined the exit polygon above, we can add it to the simulation as a stage. After adding the exit to the simulation, we need to create a journey containing that exit. Journeys are used to manage more complex routing situation, an explanation of the underlying routing concept can be found here.

exit_id = simulation_cfsm.add_exit_stage(exit_polygon)
journey = jps.JourneyDescription([exit_id])
journey_id = simulation_cfsm.add_journey(journey)

Now we have the setup for the simulation. But there are no agents in simulation yet, so we need to add them.

Before adding a simulation we need to define the agent specific parameters. In this example, all the agents will get the same parameters. We will now re-use the above extracted start positions of the agents.

for position in start_positions:

After, we have added the agents. We’ve got everything needed to start a simulation. Here, we will iterate, as long as there are agents inside the simulation, e.g., some agents have not yet reached the exit.

while (
    simulation_cfsm.agent_count() > 0
    and simulation_cfsm.iteration_count() < 2000

Now, every agent has left the simulation. Let’s have a look at the result:

Hide code cell source
import pedpy
from jupedsim.internal.notebook_utils import animate, read_sqlite_file

trajectory_data, walkable_area = read_sqlite_file(trajectory_file)
speed = pedpy.compute_individual_speed(traj_data=trajectory_data, frame_step=5)
speed = speed.merge(, on=["id", "frame"], how="left")

animate(trajectory_data, walkable_area)