rustsim-transit 0.0.1

Public-transit primitives for rustsim: stops, routes, schedules, boarding/alighting queues, dwell times, headway control
Documentation
//! Dwell-time models for transit vehicles at stops.
//!
//! The linear dwell-time formula (TCQSM, Transit Capacity and Quality of
//! Service Manual) is implemented:
//!
//! ```text
//! dwell = min_dwell + a * alighters + b * boarders
//! ```
//!
//! where `a` and `b` are the per-passenger service times.

/// Parameters of the linear dwell-time model.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DwellParams {
    /// Minimum dwell time regardless of passenger flow (s).
    pub min_dwell: f64,
    /// Service time per alighting passenger (s).
    pub per_alighter: f64,
    /// Service time per boarding passenger (s).
    pub per_boarder: f64,
}

impl Default for DwellParams {
    fn default() -> Self {
        Self {
            min_dwell: 8.0,
            per_alighter: 1.8,
            per_boarder: 2.6,
        }
    }
}

/// Computed dwell time with a breakdown for telemetry.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DwellTime {
    /// Total dwell (s).
    pub total: f64,
    /// Contribution from alighters (s).
    pub from_alighters: f64,
    /// Contribution from boarders (s).
    pub from_boarders: f64,
}

/// Compute the dwell time for a given alighter / boarder pair.
pub fn compute(alighters: u32, boarders: u32, params: &DwellParams) -> DwellTime {
    let a = params.per_alighter * alighters as f64;
    let b = params.per_boarder * boarders as f64;
    DwellTime {
        total: params.min_dwell + a + b,
        from_alighters: a,
        from_boarders: b,
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn default_params_match_tcqsm_range() {
        let d = compute(5, 10, &DwellParams::default());
        assert!((d.total - (8.0 + 5.0 * 1.8 + 10.0 * 2.6)).abs() < 1e-9);
    }

    #[test]
    fn zero_passengers_gives_min_dwell() {
        let d = compute(0, 0, &DwellParams::default());
        assert_eq!(d.total, 8.0);
    }
}