Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anticipation Velocity Model (AVM) #1432

Open
wants to merge 52 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
46c0bd8
Change version of jupedsim
chraibi Dec 30, 2024
09001fb
First version compiles
chraibi Dec 31, 2024
778523f
Running CollisionFreeSpeedModelV3.
chraibi Jan 1, 2025
6e65c65
update example
chraibi Jan 1, 2025
0e1838e
Rename model CollisionFreeSpeedModelV3 to AVM
chraibi Jan 3, 2025
f2344d9
remove unused imports
chraibi Jan 3, 2025
b7e4218
Implement direction of agents
chraibi Jan 6, 2025
9c6b365
Implement boundaryRepulsion
chraibi Jan 6, 2025
ec801e4
Update the direction according to eq 7
chraibi Jan 6, 2025
de57a2e
validate parameters of the model
chraibi Jan 6, 2025
42bb1db
Update functionality for walls behind walls
chraibi Jan 7, 2025
681b518
Add anticipation and reaction times to C-API
chraibi Jan 7, 2025
732f1a6
Fix bug in wall calculation
chraibi Jan 7, 2025
7dfffef
rename get reaction time
chraibi Jan 7, 2025
407bae0
Add two parameters and remove unused parameter from AVM API
chraibi Jan 7, 2025
f79dd6f
python bindings for AVM
chraibi Jan 7, 2025
efb7ca7
Add test can construct AVM
chraibi Jan 7, 2025
f83fbfa
Init new parameters in libjupedsim simulation
chraibi Jan 7, 2025
b7147a6
Add headon examples
chraibi Jan 7, 2025
c8df214
Wrong sign for wall influence
chraibi Jan 7, 2025
df7041f
Update velocity of agents
chraibi Jan 8, 2025
21bcc41
Fix bug: Apply Update velocity of agents
chraibi Jan 9, 2025
23305ae
Fix missmatch of neighbor and geometry parameters
chraibi Jan 9, 2025
f8a5ca1
Implement sliding walls
chraibi Jan 10, 2025
269b608
Refactor sliding walls
chraibi Jan 14, 2025
bdd9299
Add notebook to compare all models
chraibi Jan 14, 2025
e6cf0e0
Update models for anticipation velocity model
chraibi Jan 14, 2025
6f41508
Update notebook with time plots
chraibi Jan 14, 2025
9cc1865
Add documentation for AVM
chraibi Jan 14, 2025
f2d88a7
link notebook to documentation
chraibi Jan 14, 2025
920259f
Update model notebook
chraibi Jan 14, 2025
3ca16f1
Add requirement for notebook
chraibi Jan 14, 2025
6d37d3b
rename notebook and add it to index
chraibi Jan 14, 2025
8fbc35d
Add more explanatory context to the notebook
chraibi Jan 15, 2025
354da4b
Add tests for AVM and update AVM-parameters contraints
chraibi Jan 15, 2025
9092048
merge two cells in the notebook
chraibi Jan 15, 2025
bf8d459
Add test default parameters of AVM
chraibi Jan 15, 2025
0b9352f
update AVM default parameters
chraibi Jan 15, 2025
5e124cf
update clang format
chraibi Jan 15, 2025
264c09b
clang-format my code
chraibi Jan 15, 2025
42da8e2
clangformating
chraibi Jan 15, 2025
c615170
clang-formating a bunch
chraibi Jan 15, 2025
5710c4c
clang formatting
chraibi Jan 15, 2025
e339d71
sorting imports and ruffing
chraibi Jan 15, 2025
0045715
use clang-format 18
chraibi Jan 15, 2025
7db6421
clang format
chraibi Jan 15, 2025
35da307
Fixed python formatting
Ozaq Jan 15, 2025
9dfd0a4
Format cpp code to match newer clang-format version
Ozaq Jan 15, 2025
7320f23
Fix formatting
Ozaq Jan 15, 2025
d19228b
set version to 1.3.0
chraibi Jan 15, 2025
2444f89
update example 7
chraibi Jan 15, 2025
9fbb00d
reformatting and restructuring the comparison-models notebook
chraibi Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ add_subdirectory(python_bindings_jupedsim)
# Code formatting
################################################################################
if(UNIX AND WITH_FORMAT)
set(clang-format-version 15)
set(clang-format-version 18)
find_program(CLANG_FORMAT
NAMES
clang-format-${clang-format-version}
Expand Down
1 change: 1 addition & 0 deletions docs/source/notebooks/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Notebooks
.. toctree::
:maxdepth: 1

model-comparison
corner
double-bottleneck
journey
Expand Down
1 change: 1 addition & 0 deletions docs/source/notebooks/model-comparison.ipynb
42 changes: 42 additions & 0 deletions docs/source/pedestrian_models/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ models. Below is a list of all the models that are currently available. Please
refer to the links in the respective section for a detailed discussion of the
respective model.


**************************
Collision Free Speed Model
**************************
Expand Down Expand Up @@ -44,6 +45,47 @@ available on `PedestrianDynamics`_.

The original publication can be found at https://arxiv.org/abs/1512.05597

**************************
Anticipation Velocity Model
**************************

The anticipation velocity model (AVM) is a mathematical approach for pedestrian
dynamics that prevents collisions through anticipatory behavior. The model divides
anticipation into three components: situation perception, future prediction, and
strategy selection.
Building upon the collision-free speed model (CSM), AVM determines agent movement
through exponential repulsion from nearby agents. Unlike CSM, the influence
direction is orthogonal to the agent's desired direction.
Repulsion strength is affected by agents within the perception field -
specifically, those in the union of two half-planes where the agent moves or
intends to move. Agents adjust their speed based on anticipated distance to the
nearest neighbor in their headway, enabling navigation through congested areas
without overlap.
The model incorporates a reaction time factor to adjust the turning process rate
from the current to the new direction. Walls are treated as gliding surfaces:
when an agent is within critical distance of a wall and moving toward it, their
direction is projected parallel to the wall surface.
Movement calculation occurs in two steps: first, combining the desired direction
with neighbor influences, then adjusting for wall interactions when necessary.
Walls do not influence the speed of agents, only their direction.

The anticipation velocity model takes into account the length of the agent,
which determines the required space for movement, and the maximum achievable
speed of the agent. This simplified and computationally efficient model aims to
mirror real-world pedestrian behaviors while maintaining smooth movement
dynamics.

The parameters of the anticipation velocity model can be defined per-agent.

In :class:`~jupedsim.models.AnticipationVelocityModel` neighbor and wall
parameters are per-agent parameters that can be set individually via
:class:`~jupedsim.models.AnticipationVelocityModelAgentParameters` and can be
changed at any time.


The original publication can be found at https://doi.org/10.1016/j.trc.2021.103464


***********************************
Generalized Centrifugal Force Model
***********************************
Expand Down
72 changes: 72 additions & 0 deletions examples/example7_avm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#! /usr/bin/env python3

# Copyright © 2012-2024 Forschungszentrum Jülich GmbH
# SPDX-License-Identifier: LGPL-3.0-or-later

import pathlib
import sys

import jupedsim as jps
from shapely import Polygon


def main():
room1 = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)]) # Room 1 (10m x 10m)
room2 = Polygon([(15, 0), (25, 0), (25, 10), (15, 10)])
width = 0.8
num_agents = 10
corridor = Polygon(
[
(10, 5 - width / 2),
(15, 5 - width / 2),
(15, 5 + width / 2),
(10, 5 + width / 2),
]
)
geometry = room1.union(room2).union(corridor)
exit_polygon = Polygon([(24, 4.5), (25, 4.5), (25, 5.5), (24, 5.5)])
trajectory_file = "example_7.sqlite"
simulation = jps.Simulation(
model=jps.AnticipationVelocityModel(),
geometry=geometry,
trajectory_writer=jps.SqliteTrajectoryWriter(
output_file=pathlib.Path(trajectory_file)
),
)

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

start_positions = jps.distribute_by_number(
polygon=Polygon([(0, 0), (5, 0), (5, 10), (0, 10)]),
number_of_agents=num_agents,
distance_to_agents=0.5,
distance_to_polygon=0.2,
)

for position in start_positions:
simulation.add_agent(
jps.AnticipationVelocityModelAgentParameters(
journey_id=journey_id,
stage_id=exit_id,
position=position,
anticipation_time=0.5,
reaction_time=0.3,
)
)

while simulation.agent_count() > 0 and simulation.iteration_count() < 3000:
try:
simulation.iterate()
except KeyboardInterrupt:
print("CTRL-C Received! Shutting down")
sys.exit(1)
print(
f"Simulation completed after {simulation.iteration_count()} iterations ({simulation.elapsed_time()} s)"
)
print(f"{trajectory_file = }")


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions examples/example8_headon_AVM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#! /usr/bin/env python3

# Copyright © 2012-2024 Forschungszentrum Jülich GmbH
# SPDX-License-Identifier: LGPL-3.0-or-later

import pathlib

import jupedsim as jps
from shapely import Polygon


def main():
width = 2
length = 10
geometry = Polygon([(0, 0), (length, 0), (length, width), (0, width)])
exit_polygon = Polygon(
[(length - 0.5, 0), (length, 0), (length, width), (length - 0.5, width)]
)
trajectory_file = "headon_AVM.sqlite"
simulation = jps.Simulation(
model=jps.AnticipationVelocityModel(),
geometry=geometry,
trajectory_writer=jps.SqliteTrajectoryWriter(
output_file=pathlib.Path(trajectory_file)
),
)

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

start_positions = [(3, 0.5 * width), (0.5 * length, 0.5 * width)]
parameters = [
jps.AnticipationVelocityModelAgentParameters(
journey_id=journey_id,
stage_id=exit_id,
position=start_positions[0],
radius=0.2,
v0=1.2,
),
jps.AnticipationVelocityModelAgentParameters(
journey_id=journey_id,
stage_id=exit_id,
position=start_positions[1],
radius=0.2,
v0=0.2,
),
]
for position, param in zip(start_positions, parameters):
simulation.add_agent(parameters=param)

while simulation.agent_count() > 0 and simulation.iteration_count() < 1000:
simulation.iterate()

print(
f"Simulation completed after {simulation.iteration_count()} iterations ({simulation.elapsed_time()} s)"
)
print(f">> {trajectory_file = }")


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions examples/example8_headon_CSM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#! /usr/bin/env python3

# Copyright © 2012-2024 Forschungszentrum Jülich GmbH
# SPDX-License-Identifier: LGPL-3.0-or-later

import pathlib

import jupedsim as jps
from shapely import Polygon


def main():
width = 2
length = 10
geometry = Polygon([(0, 0), (length, 0), (length, width), (0, width)])
exit_polygon = Polygon(
[(length - 0.5, 0), (length, 0), (length, width), (length - 0.5, width)]
)
trajectory_file = "headon_CSM.sqlite"
simulation = jps.Simulation(
model=jps.CollisionFreeSpeedModel(),
geometry=geometry,
trajectory_writer=jps.SqliteTrajectoryWriter(
output_file=pathlib.Path(trajectory_file)
),
)

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

start_positions = [(3, 0.5 * width), (0.5 * length, 0.5 * width)]
parameters = [
jps.CollisionFreeSpeedModelAgentParameters(
journey_id=journey_id,
stage_id=exit_id,
position=start_positions[0],
radius=0.2,
v0=1.2,
),
jps.CollisionFreeSpeedModelAgentParameters(
journey_id=journey_id,
stage_id=exit_id,
position=start_positions[1],
radius=0.2,
v0=0.2,
),
]
for position, param in zip(start_positions, parameters):
simulation.add_agent(parameters=param)

while simulation.agent_count() > 0 and simulation.iteration_count() < 1000:
simulation.iterate()

print(
f"Simulation completed after {simulation.iteration_count()} iterations ({simulation.elapsed_time()} s)"
)
print(f">> {trajectory_file = }")


if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions libjupedsim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_library(jupedsim_obj OBJECT
src/build_info.cpp
src/collision_free_speed_model.cpp
src/collision_free_speed_model_v2.cpp
src/anticipation_velocity_model.cpp
src/error.cpp
src/generalized_centrifugal_force_model.cpp
src/geometry.cpp
Expand Down Expand Up @@ -112,6 +113,7 @@ install(
${header_dest}/build_info.h
${header_dest}/collision_free_speed_model.h
${header_dest}/collision_free_speed_model_v2.h
${header_dest}/anticipation_velocity_model.h
${header_dest}/error.h
${header_dest}/export.h
${header_dest}/generalized_centrifugal_force_model.h
Expand Down
11 changes: 11 additions & 0 deletions libjupedsim/include/jupedsim/agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
#pragma once

#include "anticipation_velocity_model.h"
#include "collision_free_speed_model.h"
#include "collision_free_speed_model_v2.h"
#include "error.h"
Expand Down Expand Up @@ -116,6 +117,16 @@ JPS_Agent_GetSocialForceModelState(JPS_Agent handle, JPS_ErrorMessage* errorMess
JUPEDSIM_API JPS_CollisionFreeSpeedModelV2State
JPS_Agent_GetCollisionFreeSpeedModelV2State(JPS_Agent handle, JPS_ErrorMessage* errorMessage);

/**
* Access Anticipation Velocity Model state.
* Precondition: Agent needs to use Anticipation Velocity Model
* @param handle of the agent to access.
* @param[out] errorMessage if not NULL: will be set to a JPS_ErrorMessage in case of an error.
* @return state or NULL on error
*/
JUPEDSIM_API JPS_AnticipationVelocityModelState
JPS_Agent_GetAnticipationVelocityModelState(JPS_Agent handle, JPS_ErrorMessage* errorMessage);

/**
* Opaque type of an iterator over agents
*/
Expand Down
Loading
Loading