The instructor
Day 2, hours 4 and 5 of the training path.
Day 2, hours 4 and 5 of the training path. The trainee drives. The instructor runs the session from a browser page, the instructor console: watching, pausing, sending hazards, changing the environment, and taking over a vehicle. Everything the instructor does is recorded with the run, so the review shows it and a playback repeats it.
You need Events, metrics and scorecards: the Training plugin added, and at least one injectable kind declared. Crossing Drive's is send-pedestrian.
1. Open the console
Run the scenario with its session server, from a terminal in the project folder:
argus run . --window --serve --port 7795 --ws-port 7796
The trainee drives in the window. The run prints the session's address (serving the raw query API on http://127.0.0.1:7795). Open the console in a web browser on the same PC at that address plus /plugins/training/:
http://127.0.0.1:7795/plugins/training/
The console is reachable from this PC only. It needs a run that draws: --window (or, with no window, --render-on-request). A --headless run has no picture for its view. Several consoles can be open at once, a lead instructor and a role-player for example. Each one's commands are recorded with its name.
Coming later: an Open instructor console button in the editor, and a one-time sign-in code for the address.
2. What the console shows
| Where | What |
|---|---|
| Top bar | the scenario, LIVE, the session clock and tick, Pause, step, the speed (×0.25 to ×4), Report |
| Left | the trainee: their live score against the pass mark, and the live scorecard, item by item |
| Centre | the trainee's view; under it, Telemetry: the scorecard's graphs (speed against the limit) and numbers (reaction, time over the limit) |
| Centre right | the Map, drawn from the scene's roads, with the trainee, others and people; under it the Event log |
| Right | three tabs: Inject, Take over, Environment; under them, Your actions |
| Bottom | the Session timeline: every event as a marker, in lanes (injected, instructor, scenario, session) |
The scorecard's display block decides what the gauge, graphs and map show (Events, metrics and scorecards, section 5). While the run is live the score is provisional: an item with no data yet is pending, and the report says "so far" until the end.
3. Pause, step and slow down
| Do | How | What happens |
|---|---|---|
| Pause, resume | Pause, or Space | the whole simulation holds, the trainee's too |
| Step | the step button, or . while paused | one tick (1/60 s) at a time |
| Slow down, speed up | ×0.25, ×0.5, ×1, ×2, ×4 | the clock's rate. The simulation is the same, only faster or slower to watch |
Pause, step and the speed change how fast the simulation runs against the clock on the wall. They never change what happens in it. They are still recorded, so the review shows when the instructor paused.
4. Inject an event
The Inject tab lists what this scenario lets you send: the kinds its journal.json marks injectable, with their settings. Crossing Drive has one, Send the pedestrian.
- Inject now sends it at the next tick. In 10 s sends it ten seconds from now.
- An injected event reaches the scenario's behaviours like any event: Crossing Drive's pedestrian listens for
send-pedestrianand steps out. What an injected event does is the scenario's own code. A kind nothing listens for appears in the log and does nothing else. - To make your own: declare a kind with
"injectable": true(and itsfields, which the palette turns into settings), and have a behaviour react to it inonEvent.
{ "kind": "send-pedestrian", "label": "Send the pedestrian", "severity": "critical", "injectable": true, "target": "world", "fields": {} }
A kind with "target": "entity" asks which entity it is for (a tyre blowout on one car, say). The behaviour reads the choice as target in the event's data.
The scenario can still send it itself. In Crossing Drive the hazard zone sends the pedestrian if the instructor has not. Set the car's autoHazard prop to false to leave it to the instructor.
5. Change the environment
The Environment tab sets the time of day, the visibility (fog), the rain and how wet the road is. Each change is a command at a tick, so the review shows the dusk coming in exactly when it did. The event log spells out each change ("visibility 300 m", "fog cleared", "rain 40 %").
- Time of day is in hours (0 to 24) and moves the sun: drag its slider, or pick Dawn, Morning, Noon, Afternoon, Dusk or Night.
- Visibility is Clear (no fog), a preset (Light haze, Aerial, Morning mist, Valley mist, Dense), or a distance on its slider, 30 to 1000 m, for a scene whose presets read too light or too heavy at its scale.
- Sea state (Beaufort 0 to 12) works in a scene with a sea. A scene with none refuses it, and the console then hides the slider.
Rain and Road wetness go from 0 to 1, and they change how the tyres grip:
- The rain wets the road gradually: most of the way in two or three minutes. Once the rain eases, the road dries about ten times as slowly.
- Road wetness makes the road that wet at once.
- A wet road grips less. On a soaked road, Crossing Drive's car brakes at about three quarters of its dry rate, and it picks up speed more slowly. From about 80 km/h, a car on a soaked road starts to aquaplane.
- For now the weather is felt, not seen: nothing draws the rain or the wet road.
A scene sets how fast its road wets and dries: wetTime and dryTime in its environment.weather, 60 s and 600 s unless it says otherwise (Vehicles, "Surfaces and weather").
6. Take over
On the Take over tab, pick a vehicle or character, or click it on the map, and drive it yourself.
- The console turns your keys into the scene's own input actions: W, S, A and D drive Crossing Drive's car, as they do for the trainee. The view says You have control of and the entity's name (Sam Taylor in Crossing Drive). Hand back (or Esc) returns it.
- Every console's trainee card says An instructor has taken over from and the trainee's name while it is held.
- While you hold it, the trainee's input to it is ignored, and the trainee's screen says Instructor has control (with the Training plugin's panel, section 7). On hand-back the entity's input starts again from neutral, so a key the trainee is still holding counts only once released and pressed again.
- One instructor at a time: a vehicle another console holds cannot be taken until it is handed back.
- An entity driven by another simulator (through DIS) cannot be taken over.
7. A message to the trainee
Message to trainee shows a line of text on the trainee's screen for a few seconds. It needs the Training plugin's panel, a behaviour the plugin carries, on the trainee's entity:
{ "type": "script", "module": "training:trainee-panel", "props": { "position": "top" } }
The same panel shows Instructor has control while an instructor holds the trainee's vehicle.
8. What gets recorded
Every action above is a session command: applied at a tick, kept in the session's journal with the console that sent it, and written into the recording when the session is recorded (--save-replay <file> on argus run, or the console's recording). In the event log, your own actions are marked You. Playing the recording back applies the same commands at the same ticks, so the review is the run as it happened, instructor included.
Without the console: the same commands go to POST /session/command on the session's port, from a client registered with POST /session/clients. The console registers a client so that every command it sends is recorded with who sent it: name yours with the x-argus-client header. A tool may send commands with no header; they are recorded without a name. The session API reference is crates/query/API.md (on the docs site, Query API), sections "Session control" and "The session journal". A script or a test can therefore run a session the way an instructor does:
P=http://127.0.0.1:7795; J='content-type: application/json'
curl -X POST $P/session/clients -H "$J" -d '{"role":"instructor","name":"Lead"}'
# {"client":"cl_1","name":"Lead","role":"instructor"}
C='x-argus-client: cl_1'
curl -X POST $P/session/command -H "$J" -H "$C" -d '{"cmd":"inject","kind":"send-pedestrian"}'
# {"applied_tick":82,"queued":true,"seq":null}
| Console | Body of POST /session/command |
|---|---|
| Pause, resume | {"cmd":"pause"}, {"cmd":"resume"} |
| Step | {"cmd":"step","n":5} (1 to 3600 ticks) |
| Speed | {"cmd":"scale","x":0.5} (0.1 to 10) |
| Inject now | {"cmd":"inject","kind":"send-pedestrian"} (with "params" for the kind's fields) |
| In 10 s | the same with "at_tick": the session's tick (from GET /session/control) plus 600 |
| Take over | {"cmd":"possess","entity":"car","client":"cl_1"}, then drive it with POST /input and the same header: {"actions":[{"type":"axis","name":"throttle","value":[1,0],"frames":60}]} |
| Hand back | {"cmd":"release","entity":"car"} |
| Environment | {"cmd":"environment","timeOfDay":19.5,"fog":"morning-mist"} (fog also {"visibilityM":300} or null; seaState 0 to 12 with a scene's sea; rain and wetness 0 to 1) |
GET /session/control answers the clock, whether it is paused, the queue of commands not yet applied, the clients and who holds what.
Where the console runs
The console is a page on the PC that runs the scenario, reachable from that PC only. Instructing from a second machine on the network comes later. A release export does not serve the console yet, so a session with a console runs in the editor, from argus run, or from a development export (Training scenarios, "The training room").
Next: Reviewing a run.