Simulates emergency ambulance dispatch with two regional bays, prioritizing local units but allowing cross-zone dispatch.
Calls arrive at a dispatch center with two ambulance bays (North, South), each containing 2 units. Call location is 60% North / 40% South. The dispatch rule is: send a unit from the matching bay; if empty, send from the other bay; if both empty, the call waits. Round-trip time is shorter for same-zone and longer for cross-zone.
This model is based on the emergency services case study in Banks-DES.
The model uses a Call puck to represent the emergency request and a Generator to drive arrivals.
The Call puck (lines 53-108) evaluates bay availability in a specific order: it first attempts to seize a unit from its target zone, then falls back to the opposite zone. If both are full, it joins a shared queue in the DispatchCenter.
The DispatchCenter (lines 33-50) manages the shared state, including:
north_bay and south_bay: sim.Storage resources with capacity 2.wait_list: A sim.Set acting as a FIFO queue for calls that found both bays full.RV_Streams: Separate streams for inter-arrivals, zone determination, and the two service time profiles.The core of the dispatch logic relies on sim.try_enter (line 112). Unlike sim.enter, try_enter is a side-effect-free probe; it returns false if the resource is full without suspending the puck or adding it to the facility's internal wait list. This allows the Call puck to "shop around" for any available unit before finally deciding to wait.
The wait_list is implemented as a separate sim.Set rather than relying on the sim.Storage internal waiters. This is because the "wait" state is global; once a call is queued, it no longer cares about zone preference—it will take the first unit that becomes available from either bay.
sim.Storage of capacity 4, but this would lose the ability to model "local preference" and the differing travel times associated with cross-zone dispatch.sim.Storage would lock the puck to a specific bay, making it impossible to be "stolen" by a unit from the other bay while waiting.sim.try_enter to check availability without committing to a wait.odin run examples/ambulance_dispatch
./ambulance_dispatch [options]
Add --json to emit the uniform envelope (metadata, execution_stats,
metrics, details) instead of the default text output.
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
bool | false |
Emit uniform JSON envelope instead of text. |
Example runs:
./ambulance_dispatch # default text run
./ambulance_dispatch --json # uniform envelope
sim.Storage and sim.Set.