Skip to content

PedestrianDynamics/Motivation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

421 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Streamlit Ruff Mypy Tests

Motivation

An expectancy-value-payoff (EVP) motivation model for pedestrian dynamics, implemented on top of JuPedSim.

Setup

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Reproducing the paper results

The full pipeline runs in three stages. All commands are run from the repository root (simulation/).

Stage 1: Multi-seed simulation + per-seed analysis

python scripts/run_all_scenario_analyses.py

What it does (≈ 40 min):

  1. Reads scripts/run_coordination_scenarios.py which defines:
    • BASE_MODELS = ["P", "V", "SE", "PVE", "BASE_MODEL"]
    • NUMBER_AGENTS_VALUES = [40, 80]
    • SEEDS = [101, 102, ..., 110]
  2. For each (N, seed) combination, generates a per-seed config by copying the base JSON (e.g. files/base_PVE.json) and overwriting motivation_parameters.seed. The same seed is used across all models so that initial positions and value assignments are identical — this is the paired design.
  3. Runs simulation.py once per (model, seed), producing:
    • base_{MODEL}_seed{SEED}_{MODE}_{TIMESTAMP}.sqlite — trajectory
    • ..._motivation.csv — per-agent per-frame motivation values
  4. For each seed, calls the four analysis scripts with explicit --input MODEL=<file> overrides and a --tag suffix:
Analysis script What it computes Output
scripts/final_rank_analysis.py Distance-to-door rank at last frame + mean Voronoi area per agent final_rank_details_*_seed{N}.csv + scatter plots
scripts/coordination_number_analysis.py Delaunay neighbor count per agent per frame coordination_number_details_*_seed{N}.csv + histograms
scripts/motivation_heatmap_analysis.py Spatial mean-motivation grid heatmap PNGs
scripts/voronoi_density_analysis.py Voronoi density in measurement area over time voronoi_density_details_*_seed{N}.csv + time series

Outputs go to files/coordination_scenarios/agents_{N}_open_100/.

Stage 2: Aggregate across seeds

python scripts/aggregate_seeds.py

What it does (seconds):

  1. Walks files/coordination_scenarios/*/ and reads all seed-tagged detail CSVs from Stage 1.
  2. Computes per-seed summary scalars:
    • Rank–area: Spearman ρ, OLS slope, tail ratio
    • Voronoi density: mean, std, fraction of time above threshold
    • Coordination number: mean, std, mode
  3. Runs paired Wilcoxon signed-rank tests with Cliff's δ effect sizes comparing PVE vs BASE_MODEL.
  4. Produces band plots (median + IQR across 10 seeds).

Outputs go to files/coordination_scenarios/_aggregated/:

File Contents
seed_summary.csv One row per (seed, model, observable, scalar)
tests.csv Paired Wilcoxon p-values and Cliff's δ per comparison
rank_area_band_*.png Rank–area median + IQR bands
voronoi_density_band_*.png Density time-series bands
coordination_number_band_*.png Coordination number histogram bands

Stage 3: Experimental (CROMA) rank–area analysis

python scripts/experimental_rank_area.py

What it does (≈ 10 min):

  1. Reads the CROMA .txt trajectory files from ../trajectories_croma/.
  2. For each experimental run, computes crossing order at the door (first frame where y ≥ 20) as the experimental rank.
  3. Computes per-agent mean Voronoi area using PedPy with the CROMA corridor geometry.
  4. Writes per-scenario CSVs + summary scalars (Spearman ρ, slope, tail ratio) and comparison plots.

Outputs go to files/experimental_rank_area_results/.

Generating the EVP component figures

The expectancy, value, payoff, motivation, and parameter-mapping plots shown in the paper are produced headlessly by:

python scripts/plot_evp_schematics.py            # default: N=80, seed=101, base_PVE.json

This writes expectancy.pdf, value.pdf, payoff.pdf, motivation.pdf, and parameter_mappings.pdf directly into ../motivation-for-springer/figures/. Internally it instantiates an EVPStrategy from src/motivation_model.py and calls its plot() method plus motivation_mapping.plot_parameter_mappings().

Paper figures → generating scripts

Only the figures that are actually rendered in the paper are listed below. Three blocks (coordination-number bands, Voronoi density bands, N=40 final-rank scatter) are wrapped in \iffalse in the manuscript and are therefore not regenerated; the underlying analysis scripts still produce the data, but the PDFs are not copied into the paper.

Figure (paper) Output filename(s) Produced by
Fig 1 fig:evc_components (expectancy, value, payoff, motivation) expectancy.pdf, value.pdf, payoff.pdf, motivation.pdf scripts/plot_evp_schematics.py
Fig 2 fig:rank-area-bands rank_area_band_agents_{40,80}_open_100.png scripts/aggregate_seeds.py (Stage 2)
Fig 3 fig:motivation-heatmaps-scenarios agents_80_open_100/motivation_heatmap_results/motivation_heatmap_models_agents_80_open_100.png scripts/motivation_heatmap_analysis.py (Stage 1, per-seed; copy seed-101 output to the un-suffixed paper name)
Fig 4a fig:sim-trajectories-uniform (sim trajectories, single color) simulation_trajectories_5panel_uniform.png scripts/plot_simulation_trajectories.py
Fig 4b fig:sim-trajectories (sim trajectories, motivation-colored) simulation_trajectories_5panel_motivation.png scripts/plot_simulation_trajectories.py
Fig 5 fig:croma-trajectories (CROMA experimental trajectories, 1×4) croma_trajectories_4panel.png scripts/plot_experimental_trajectories.py
Fig 6 fig:croma-rank-area (CROMA rank-area nM/hM) croma_rank_area_{nM,hM}.png scripts/experimental_rank_area.py
Fig A.1 fig:parameter-mappings parameter_mappings.pdf scripts/plot_evp_schematics.py
Fig A.2 fig:final-rank-scenarios (N=80 only) agents_80_open_100/final_rank_results/final_rank_vs_area_{se,v,p,pve,base_model}_agents_80_open_100.pdf scripts/final_rank_analysis.py (Stage 1, per-seed; copy seed-101 outputs to the un-suffixed paper names)

The trajectory-panel and schematic scripts are standalone and read directly from existing simulation / CROMA outputs (no full pipeline rerun required):

# Schematics: expectancy/value/payoff/motivation/parameter_mappings (Fig 1, A.1)
python scripts/plot_evp_schematics.py

# CROMA 4-panel (Fig 5)
python scripts/plot_experimental_trajectories.py

# Simulation 5-panel × 2 variants (Fig 4a, 4b)
python scripts/plot_simulation_trajectories.py --seed 101

For Fig 3 and Fig A.2 the per-seed PDFs/PNGs in files/coordination_scenarios/agents_{N}_open_100/.../ carry a _seedNNN suffix; copy seed 101 to the un-suffixed paper name when syncing figures (the paper convention is to show a single representative seed):

cp files/coordination_scenarios/agents_80_open_100/motivation_heatmap_results/motivation_heatmap_models_agents_80_open_100_seed101.png \
   ../motivation-for-springer/figures/agents_80_open_100/motivation_heatmap_results/motivation_heatmap_models_agents_80_open_100.png
for m in se v p pve base_model; do
  cp files/coordination_scenarios/agents_80_open_100/final_rank_results/final_rank_vs_area_${m}_agents_80_open_100_seed101.pdf \
     ../motivation-for-springer/figures/agents_80_open_100/final_rank_results/final_rank_vs_area_${m}_agents_80_open_100.pdf
done

Configuration

All simulation parameters are in files/base_{MODEL}.json. Key settings:

Parameter Location in JSON Paper value
Motivation mode motivation_parameters.motivation_mode PVE / BASE_MODEL / P / V / SE
Auto-k logistic motivation_parameters.use_manual_logistic_k false
Seeds motivation_parameters.seed 101–110 (set by pipeline)
Number of agents simulation_parameters.number_agents 40 or 80
Door open time simulation_parameters.open_door_time 100 (> sim time → closed)
Simulation time simulation_parameters.simulation_time 90 s

Project structure

simulation/
├── simulation.py                  Main simulation runner (JuPedSim)
├── app.py                         Streamlit interactive UI
├── files/
│   ├── base.json                  Template configuration
│   ├── base_{MODEL}.json          Per-model configs (P, V, SE, PVE, BASE_MODEL)
│   ├── coordination_scenarios/    Simulation outputs + analysis results
│   └── experimental_rank_area_results/
├── scripts/
│   ├── run_coordination_scenarios.py   Config generation + seed definitions
│   ├── run_all_scenario_analyses.py    Full pipeline runner (Stage 1)
│   ├── aggregate_seeds.py              Cross-seed aggregation (Stage 2)
│   ├── experimental_rank_area.py       CROMA analysis (Stage 3)
│   ├── final_rank_analysis.py          Rank–area per-seed analysis
│   ├── coordination_number_analysis.py Coordination number per-seed analysis
│   ├── motivation_heatmap_analysis.py  Spatial motivation heatmaps
│   ├── voronoi_density_analysis.py     Voronoi density time series
│   ├── plot_experimental_trajectories.py  CROMA trajectories 1×4 panel (Fig 7)
│   └── plot_simulation_trajectories.py    Simulation 5-panel × 2 variants (Fig 6)
├── src/
│   ├── motivation_model.py        EVPStrategy: expectancy-value-payoff model
│   ├── motivation_mapping.py      Logistic motivation-to-parameter mapping
│   ├── coordination_number.py     Delaunay coordination numbers
│   ├── utilities.py               Voronoi area, rank, crossing-order utilities
│   └── ...
└── tests/

Interactive exploration

streamlit run app.py

Running a single simulation

python simulation.py --inifile files/base_PVE.json --output-dir output/

License

MIT