Skip to main content

rustsim_crowd/
lib.rs

1//! Microscopic crowd locomotion models for rustsim.
2//!
3//! This crate implements the five microscopic pedestrian models catalogued at
4//! <https://pedestriandynamics.org/models/> in pure 2-D continuous space
5//! plus a **layered 2.5-D** extension in the [`threed`] module for
6//! multi-storey environments (stations, airports, stadiums, malls).
7//!
8//! It is called `rustsim-crowd` rather than `rustsim-pedestrian` because
9//! the same physics apply equally to cyclists, evacuees, queue-formers,
10//! and generic self-propelled agents.
11//!
12//! | Module | Model | Class | Primary references |
13//! |---|---|---|---|
14//! | [`social_force`] | Social Force | Force-based, 2nd order | Helbing & Molnár 1995; Helbing, Farkas & Vicsek 2000 |
15//! | [`collision_free_speed`] | Collision-Free Speed | Velocity-based, 1st order | Tordeux, Chraibi & Seyfried 2016 |
16//! | [`generalized_centrifugal_force`] | Generalized Centrifugal Force | Force-based, 2nd order | Chraibi, Seyfried & Schadschneider 2010 |
17//! | [`optimal_steps`] | Optimal Steps | Discrete-step utility | Seitz & Köster 2012 |
18//! | [`anticipation_velocity`] | Anticipation Velocity | Velocity-based, 1st order | Xu, Chraibi & Seyfried 2021 |
19//! | [`threed`] | Layered 2.5-D Social Force | Per-floor 2-D physics + vertical connectors | Industry standard (JuPedSim, MassMotion, Legion) |
20//!
21//! # API shape
22//!
23//! Every 2-D model shares the same three-type contract defined by the
24//! [`PedestrianModel`] trait:
25//!
26//! - [`Pedestrian`] — the shared per-agent state (position, velocity, radius,
27//!   desired speed, destination).
28//! - [`WallSegment`] — a 2-D line segment describing a static obstacle.
29//! - `Params` — a model-specific parameter bundle living inside each module.
30//!
31//! Each model exposes:
32//!
33//! - a `Params` struct with stable literature/engineering defaults.
34//! - explicit [`calibration`] helpers for deployments that must enforce a
35//!   published speed-density envelope such as Weidmann (1993).
36//! - a unit struct implementing [`PedestrianModel`] so callers can swap
37//!   models behind a trait object or generic bound.
38//! - a free `step(peds, walls, params, dt)` function (deprecated since
39//!   `0.0.3`; O(n²) reference path retained for parity tests). Production
40//!   callers use `step_scratch` (zero-alloc) or `step_with_grid`
41//!   (broadphase) instead.
42//!
43//! ```
44//! use rustsim_crowd::prelude::*;
45//!
46//! let mut peds = vec![Pedestrian::new(
47//!     [0.0, 0.0],
48//!     [0.0, 0.0],
49//!     0.25,
50//!     1.34,
51//!     [10.0, 0.0],
52//! )];
53//! let walls: Vec<WallSegment> = Vec::new();
54//! let params = social_force::Params::default();
55//! // Production hot path: zero-alloc, broadphase-accelerated.
56//! let mut scratch = Scratch::new(recommended_cell_size(
57//!     social_force::neighbor_cutoff(&params),
58//! ));
59//! social_force::step_scratch(&mut peds, &walls, &params, 0.05, &mut scratch);
60//! ```
61//!
62//! # Design constraints
63//!
64//! - Pure `f64`, SoA-friendly internals, no interior mutability.
65//! - `step_scratch(peds, walls, params, dt, &mut scratch)` is the
66//!   **zero-alloc hot path**: allocate one [`broadphase::Scratch`] per
67//!   simulation and reuse it tick-after-tick. `step_with_grid` takes a
68//!   caller-owned [`NeighborGrid`] and allocates one `Vec<[f64; 2]>`
69//!   per tick; `step` is the O(n²) reference path with no broadphase.
70//! - Determinism: every `step_*` variant is a deterministic function
71//!   of its inputs.
72
73#![deny(missing_docs)]
74
75pub mod anticipation_velocity;
76pub mod broadphase;
77pub mod calibration;
78pub mod collision_free_speed;
79pub mod common;
80#[cfg(feature = "cuda")]
81pub mod cuda;
82pub mod error;
83pub mod generalized_centrifugal_force;
84pub mod integration;
85pub mod optimal_steps;
86#[cfg(feature = "simd")]
87pub mod simd;
88pub mod social_force;
89pub mod threed;
90
91pub use broadphase::{recommended_cell_size, NeighborGrid, Scratch};
92pub use calibration::{
93    apply_weidmann_speed_cap, apply_weidmann_speed_target, density_for_area, mean_speed,
94    CalibrationPoint, CalibrationReport, WeidmannCurve,
95};
96pub use common::{Pedestrian, PedestrianModel, WallSegment};
97pub use error::CrowdError;
98pub use integration::{
99    pack_columns_from, step_columns_f64, step_scratch_store, step_scratch_store_observed,
100    unpack_columns_into, AnticipationVelocityModel, CollisionFreeSpeedModel, CrowdAgent,
101    CrowdObserver, CrowdStep, GeneralizedCentrifugalForceModel, OptimalStepsModel,
102    SocialForceModel,
103};
104#[cfg(feature = "rayon")]
105pub use integration::{step_scratch_store_observed_par, step_scratch_store_par, CrowdStepPar};
106pub use threed::{LayeredObserver, LayeredScratch, Pedestrian3D, WallPolygon3D};
107
108/// Convenience re-exports for the common consumer path.
109pub mod prelude {
110    pub use crate::broadphase::{recommended_cell_size, NeighborGrid, Scratch};
111    pub use crate::calibration::{
112        apply_weidmann_speed_cap, apply_weidmann_speed_target, density_for_area, mean_speed,
113        CalibrationPoint, CalibrationReport, WeidmannCurve,
114    };
115    pub use crate::common::{Pedestrian, PedestrianModel, WallSegment};
116    pub use crate::error::CrowdError;
117    pub use crate::integration::{
118        pack_columns_from, step_columns_f64, step_scratch_store, step_scratch_store_observed,
119        unpack_columns_into, AnticipationVelocityModel, CollisionFreeSpeedModel, CrowdAgent,
120        CrowdObserver, CrowdStep, GeneralizedCentrifugalForceModel, OptimalStepsModel,
121        SocialForceModel,
122    };
123    #[cfg(feature = "rayon")]
124    pub use crate::integration::{
125        step_scratch_store_observed_par, step_scratch_store_par, CrowdStepPar,
126    };
127    pub use crate::threed::{
128        step_layered, step_layered_scratch, step_layered_scratch_observed, LayeredObserver,
129        LayeredScratch, Pedestrian3D, WallPolygon3D,
130    };
131    pub use crate::{
132        anticipation_velocity, collision_free_speed, generalized_centrifugal_force, optimal_steps,
133        social_force, threed,
134    };
135}