How do I place checkpoints?
A checkpoint is a polygon you draw in checkpoints.<id>.coordinates. The
routing pages call the same nodes crossings; this page calls
them checkpoints, after the JSON key.
Checkpoints are the nodes of the route graph between spawn areas and exits. Agents who explore a building they do not know learn the building from them. You do not need a checkpoint to get agents through a door: JuPedSim walks agents along the navigation mesh.
This page shows where to draw checkpoints, how large, and how they join the route graph. A badly placed checkpoint can change route lengths, exit choice and the evacuation time. The page ends with a check list.
Draw a checkpoint at a door
- Draw a box across the doorway that reaches into the rooms on both sides. Do not stop it at the wall faces.
- Keep the whole box inside the walkable area.
- Keep its node point (the centroid for a convex box, see below) more than one agent radius from any wall, and more than one visibility cell from any wall face.
- With a
sign, keep the sign point more than one visibility cell from any wall face.
The blind_spawn_discovery asset draws its door checkpoints this way:
2 m × 2 m boxes centred on 0.4 m thick doorways. Its geometry builder
(assets/blind_spawn_discovery/build_geometry.py, _check_premises) refuses
a checkpoint that is shallower than 1.5 m, because “agents jam aiming for the
same sliver”, and one that is not wholly inside the walkable area, because
“direct steering could pick a target point inside a wall”. The 1.5 m is that
builder’s own check. The shipped familiarity_test_* checkpoints
(0.55–1.22 m) are smaller than that, and agents pass through them in clear
air; do not use them as templates.
Why a thin checkpoint jams
Each agent steers to a random point inside the checkpoint, kept away from its edge by a clearance of 0.8 times the agent radius. In a checkpoint as deep as the wall, all these points lie on one thin strip, so the crowd aims at the same line in the doorway. A box that spans both rooms spreads the targets.
Issue #69 reports the same failure for earlier Station checkpoints: “1.5 m -> 4.0 m fixed 210 agents”. That number is from the issue and was not re-run.
The builder’s check and #69 predate the polygon arrival rule (#726), under which an agent arrives on entering the checkpoint. Whether a wall-deep checkpoint still jams has not been re-run.
Wire checkpoints into the route graph
You choose between two ways.
With a journey. A journeys_v2 sequence gives the from → to pairs from
the start area through its checkpoints to the exit (Journeys).
The graph has exactly these pairs, when both ends exist. Nothing else is
added. A route that splits at a checkpoint is two journeys with weights. In
the old format the pairs are the transitions, and a split needs routing
percentages (Old format); a journey
that places agents but that no transition names in its journey_id is
refused at load (simulation_init.py, check_journey_transitions).
Without a journey. The graph wires itself: spawn areas and checkpoints connect to checkpoints and exits, but not to a node when another checkpoint lies on the way to it. The rule is on the routing page, Graph construction without a journey. For placement it means:
- Each checkpoint you add on the walking line between two nodes removes their direct edge. Checkpoints therefore define which nodes are neighbours, and exploring agents learn the building neighbour by neighbour. Agents then walk from neighbour to neighbour, so the route bends through each such checkpoint.
- A checkpoint that lies a little off the walking line, so that the detour through it is more than 5 % longer, does not remove the direct edge.
- When a checkpoint has removed the direct edge from a spawn area to an
exit, agents who take that exit walk through the checkpoint, in clear air
too: their path bends to a random point inside it. A
waiting_timeormax_throughputset on that checkpoint applies to all of them. If agents must not pass through such a checkpoint, move it off the walking line so the detour through it exceeds 5 %, or give the start area a journey.
Shipped scenarios use both ways:
| Asset | Checkpoints | journeys_v2 entries |
|---|---|---|
blind_spawn_discovery | 2 × 2 m boxes at the doors | none |
familiarity_test_{full,discovery,no_journey} | boxes 0.55–1.22 m on a side | none |
station_fahy | circles of radius 0.24–0.36 m | none |
t_junction | one 3 × 3 m box | 2 |
schroeder2015_route (evac/config_*.json) | 0.6 × 2 m boxes across the 0.2 m wall at doors A and B | 4 |
Keep checkpoints and signs away from walls
Visibility is computed on a grid: the FDS mesh cells, or cell_size_m
(default 0.25 m) for the clear-air model (visibility.py,
VisibilityModel.clear_air). A sign or node point within about one cell of a
wall can fall onto the wall cell. Its sightlines then count as blocked at
every time, in clear air too: agents cannot see that checkpoint’s sign, and
an agent at the node cannot see signs from it.
Issue #100
reports the second case for checkpoint 3 of familiarity_test, placed at y = 13.095 m
next to a partition at 13.0–13.1 m on a 0.25 m mesh. The shipped decks now
have its centre near y = 13.5 m. The rounding happens inside fdsvismap and
was not re-checked for this page.
Keep the node point and any authored sign more than one visibility cell from any wall face. This margin is practice from #100. The software has no such constant.
Create a scenario asks that checkpoints lie inside the walkable area. The two warnings in the check above are the signs that one does not.
How many checkpoints
No code rule or measured study gives a spacing. A spacing number would be not established. What is known:
- With a visibility model, an exploring agent learns a neighbour only if it
can see that neighbour’s sign from where it stands, on arrival at a node or
while walking (
cognitive_map.py,expand_on_arrival,expand_from_visibility). Without one, arrival at a node reveals all its neighbours. An edge between two distant checkpoints rests on one long sightline. Fewer checkpoints mean fewer, longer sightlines. - Every shipped discovery scenario puts a checkpoint at each doorway or
junction that a route must pass (the
familiarity_testdecks andblind_spawn_discovery).
Crowds that stop at narrow doors
With the default CollisionFreeSpeedModel, a crowd can stop in an opening
several body widths wide
(#706). With
SocialForceModel under no_known_exit: explore, two agents can freeze
head-on in a doorway
(#359). The
rates are under Known defects, and how each
model behaves is on Movement models.
Checkpoint size or placement does not remove these defects. In station_fahy
#706 occurs with or without the vestibule checkpoint and with a looser arrival
rule. That scenario uses WarpDriverModel, which can complete by letting
agents overlap; its model is under review in
#761. What you
can do:
- Draw door checkpoints that span both sides of the opening.
- Run several seeds. A smaller agent radius does not remove the jam:
HUT_Libraryat 0.15 m still jams in 5 of 13 seeds. - Before you read the evacuation time, check that every agent left before
max_simulation_time. A deadlock stops the run early withend_reason"deadlock".
Check list
- The node point lies inside the walkable area by more than the largest agent radius.
- The node point and every authored sign lie more than one visibility cell from any wall face.
- Door checkpoints span both sides of the opening.
- The log has no “Routing … failed” warning and, with exploring agents, no “Node point … leaves no room” warning.
- Every agent is out before
max_simulation_time.
Reference: node point, target point and arrival
Node point
Every part of the software that needs one point for a checkpoint uses
node_position (geometry.py): the area centroid if it lies inside the
polygon, else the pole of inaccessibility (polylabel, tolerance 0.01 m),
else shapely’s representative_point(). The node point is
- the end of each route-graph edge (
route_graph.py,StageGraph.from_scenario,_make_edge). The edge follows the walkable path from JuPedSim’s routing engine. If the node point is off the navigation mesh, the edge falls back to a straight ray and its cost ignores walls; - the position of the default sign of a checkpoint without a
sign(none with"sign": false): omni-directional, c = 3 (visibility.py,_default_sign). An authoredsignkeeps its ownx, y(extract_sign_descriptors), so visibility is then computed at the sign; - the point an exploring agent walks to and looks from before it patrols on
(
route_graph.py,_look_point,_node_point_fits; #250; see Wayfinding)._node_point_fitsrequires an agent disc of radius r around the node point to fit in the walkable area.
Target point
Agents steer to a random target point inside the checkpoint, not to the node
point. The point is sampled inside the polygon shrunk by a clearance
(simulation_init.py, _random_point_in_polygon):
- max(0.05, 0.8 r) m for a stage after the first
(
direct_steering_runtime.py,pick_stage_target); - max(0.05, 0.8 r, 0.25) m for the first stage
(
simulation_init.py,_pick_initial_stage_target).
r is the agent’s own radius
(#732). If the
shrunk polygon is empty or sampling fails, the point is drawn from the whole
polygon, and then representative_point() is used.
Arrival
reached_stage (direct_steering_runtime.py) decides when an agent has
reached a stage:
- Checkpoint: the agent’s centre is within r + 0.5 m
(
TARGET_REACH_MARGIN_M) of its target point, or inside the checkpoint polygon. - Exit with a polygon: the centre is inside the exit polygon or within
0.03 m of it (
EXIT_REACH_TOLERANCE_M). - Spawn area walked to on a patrol, zone, exit without a polygon: the target-point test only.
A large checkpoint therefore does not delay arrival: agents arrive as they
enter it. A small checkpoint that fits inside the r + 0.5 m disc around the
target point, such as the station_fahy circles, is reached as before the
polygon test was added. The full steering loop is on
Models › Routing.
Next step
Run the scenario and read the log for the two warnings above. Then follow Create a scenario to run it, or look up every checkpoint key in Checkpoints and zones.