Farm Traffic and Workers#
The farm traffic adds tractors, pickups, highway cars and walking workers to a session. The vehicles of the traffic are kinematic: the model moves them along paths and does not compute tyre forces.
Scope and Assumptions#
The model gives the sensors and the agent other road users to see and to avoid. It is not a traffic simulation.
- One actor,
AAcresNpcDirector, owns all vehicles and workers of the traffic. The vehicle of agent 0 creates it at the start of a session on the levelV03ACRE. - A traffic vehicle moves one time for each rendered frame. The time step \(\Delta t\) is the frame time, not the physics step.
- A traffic vehicle has no mass and no tyre model. A collision box stops the vehicle of the agent.
- The farm vehicles drive on the road graph of
site.json. They do not read the ground layer. - The model knows one vehicle of the agent: the pawn of the first player controller. This page names it the agent vehicle.
- All positions in this page are world metres with X east and Y south. A yaw is an Unreal yaw: 0 is east and 90° is south.
- The random seeds are constants. The sequence of the events thus depends only on the frame times.
Symbols#
| Symbol | Quantity | Unit |
|---|---|---|
| \(\mathbf{p}\) | Position of a vehicle or a worker | m |
| \(\psi\) | Yaw of a vehicle or a worker | rad |
| \(\mathbf{f}\) | Unit heading \((\cos\psi, \sin\psi)\) | - |
| \(v\) | Speed along the heading | m/s |
| \(v_c\) | Cruise speed | m/s |
| \(v_i\) | Speed limit at the path point \(i\) | m/s |
| \(\theta_i\) | Turn angle of the path at the point \(i\) | deg |
| \(d\) | Distance to the next path point | m |
| \(a_+\), \(a_-\) | Acceleration limit and braking limit | m/s² |
| \(R_{min}\) | Minimum turn radius | m |
| \(\Delta t\) | Frame time | s |
| \(L_h, W_h\) | Half length and half width of a footprint | m |
| \(S\) | Distance of a highway car along US 52 | m |
| \(v_0\) | Desired speed of a highway car | m/s |
| \(g\) | Gap to the leader of a highway car | m |
| \(s_0, T, a_{max}, b\) | Minimum gap, time headway, maximum acceleration and comfortable deceleration of the Intelligent Driver Model | m, s, m/s², m/s² |
| \(o_k\) | Offset of the lane \(k\) from the centreline of US 52 | m |
| \(L\) | Wheelbase | m |
| \(\delta\) | Steering angle of the front wheels | deg |
Members of the Traffic#
| Member | Count | Class | Behaviour |
|---|---|---|---|
| Tractor | 3 | AAcresNpcVehicle |
Drives to an empty field, makes five passes, drives back and parks. |
| Pickup | 4 | AAcresNpcVehicle |
Drives to a service point, waits, drives back and parks. |
| Parked pickup | 3 | AAcresNpcVehicle |
Stays in its stall for the full session. |
| Highway car | 16 | AAcresNpcCar |
Drives on US 52 in one lane. -NpcTraffic= changes the count. |
| Road walker | 5 | AAcresNpcWorker |
Walks along the side of a farm road. |
| Crop scout | 3 | AAcresNpcWorker |
Walks along the south edge of F27, F28 and F30 and examines the crop. |
| Staff | 2 | AAcresNpcWorker |
Walks between the parking lot and the Beck Agricultural Center. |
-NpcVehicles adds the tractors, the pickups and the highway cars. -NpcWorkers adds the ten workers.
A tractor is a copy of the Maxxum meshes of the level with a different paint. The highway cars use nine models from npc_cars.json.
Road Graph#
FAcresRoadGraph::Build makes a graph from the roads of site.json. It ignores a road with a width of 20 m or more. Only US 52 is that wide.
- It changes each point of a road from survey grid cells to world metres.
- It divides each segment of length \(\ell\) into \(n = \max(1, \lceil \ell / 8 \rceil)\) equal parts.
- It makes a node for each division point. A point nearer than 4.5 m to a node becomes that node.
- It links each node to the node before it on the same road.
Roads that cross or touch thus have a common node. A node keeps the largest width of its roads.
The graph of the shipped site.json has 2306 nodes.
FAcresRoadGraph::Route finds the shortest path between two nodes with the algorithm of Dijkstra. The cost of a link is its length.
AAcresNpcDirector::RouteBetween routes between the nodes that are nearest to two points.
The Optimizer uses the same graph for the field order.
Farm Vehicles#
Path and Speed Limits#
AAcresNpcVehicle::Plan receives the points of a path and the cruise speed.
It moves each interior point 1.6 m to the right of the direction of travel, so that two vehicles in opposite directions do not meet.
With \(\mathbf{t}_i\) the unit vector from \(\mathbf{c}_{i-1}\) to \(\mathbf{c}_{i+1}\) of the centre path:
The first point, the last point and the ten points of the field passes stay on the centre path.
The turn angle at a point sets its speed limit. The function \(\operatorname{smooth}\) is the cubic smoothstep.
The first point has the limit \(v_c\). The last point has the limit 0.
Motion along the Path#
AAcresNpcVehicle::Tick moves the vehicle to the next path point \(\mathbf{p}_n\). Let \(d = \lVert\mathbf{p}_n - \mathbf{p}\rVert\).
The target speed is the highest speed from which the vehicle can decrease to \(v_n\) in the distance \(d\) less 1 m.
\(v_{lim}\) is the cruise speed. During the field passes it is 2.2 m/s. The target speed is 0 when the corridor in front of the vehicle is not clear (see Right of Way).
The yaw turns to the path point. The turn rate is that of a vehicle on its minimum turn radius.
The vehicle goes to the subsequent path point when \(d < 2.2\) m. It also does so when \(d < 6\) m and \(|e| > 100^\circ\).
| Constant | Tractor | Pickup |
|---|---|---|
| Cruise speed \(v_c\) | 5 m/s | 8.3 m/s |
| Corner speed \(v_{turn}\) | 1.6 m/s | 2.5 m/s |
| Field pass speed | 2.2 m/s | |
| Acceleration limit \(a_+\) | 1.2 m/s² | 1.2 m/s² |
| Braking limit \(a_-\) | 3.5 m/s² | 3.5 m/s² |
| Minimum turn radius \(R_{min}\) | 4.8 m | 6 m |
| Footprint \(L_h \times W_h\) | 2.75 m x 1.3 m | 2.75 m x 1.1 m |
| Collision box, half sizes | 2.30 m x 1.25 m x 1.20 m | 2.65 m x 0.95 m x 0.95 m |
Pose on the Ground#
The body follows the terrain. GroundPose reads the ground height below the four wheel positions.
AAcresNpcDirector::GroundZ gives the height. It includes the terrain edits of the session.
With the mean heights \(z_f\) and \(z_r\) of the two axles at \(x_f\) and \(x_r\), and the half track \(w\):
The tractor has \(x_f = 1.548\) m, \(x_r = -1.032\) m and \(w = 0.95\) m. The pickup has \(x_f = 1.6\) m, \(x_r = -1.6\) m and \(w = 0.9\) m. The origin of a farm vehicle is 1.1 m above the ground.
FAcresNpcWheelRig::Update turns the wheels. The spin angle is the distance divided by the wheel radius.
The front wheels show the steering angle of a bicycle model with the yaw rate \(\dot\psi\).
Work in a Field#
A tractor selects one of the fields with the land cover empty at random. These are F29, F32, F39 and F48.
The work path uses the bounding box of the field, made smaller by 5 m on each side.
- The passes go along the longer side of the box.
- The road route ends at the node that is nearest to the point 6 m south of the box.
- The tractor makes five passes. Pass \(k\) is at the offset \(3 + 6k\) m from the edge of the box, for \(k = 0\) to 4.
- Each second pass goes in the opposite direction.
The passes start at the south edge when they go east and west. They start at the west edge when they go north and south. The tractor then waits 3 s to 8 s and drives back to the parking lot.
The work of a traffic tractor does not change the soil, the crops or the ruts. It has no implement model.
Errands of the Pickups#
A pickup selects a service point at random, drives there, waits 20 s to 50 s and drives back.
The first service point is the mean position of the first six bins of site.json.
The other service points are the centres of three buildings that have "east" or "north" in their names.
Parking#
The vehicles park in parking lot A, east of the Beck Agricultural Center. The lot has two rows of 17 stalls at the two sides of one aisle. The stalls are 2.75 m wide. The vehicles use each third stall, so that two free stalls are between two vehicles.
A parking manoeuvre follows a cubic Bézier curve at 1.3 m/s. AAcresNpcVehicle::StartManeuver sets the four control points.
\(\ell_B\) is the length of the curve, measured with 16 chords. The yaw follows \(\mathbf{B}'\). In reverse, the yaw follows \(-\mathbf{B}'\).
| Manoeuvre | \(\mathbf{P}_0\) | \(\mathbf{P}_1\) | \(\mathbf{P}_2\) | \(\mathbf{P}_3\) |
|---|---|---|---|---|
| Leave a stall in reverse | The stall | 3 m from the stall to the aisle | 3 m south of \(\mathbf{P}_3\) | On the aisle, 4 m north of the stall |
| Enter a stall | The position on the aisle | 2.5 m ahead | 3 m from the stall to the aisle | The stall |
One vehicle at a time uses the aisle. AAcresNpcDirector::RequestLot keeps a queue, and the first vehicle in the queue has the lot.
- A parked vehicle waits in its stall until it has the lot.
- A vehicle that drives back stops 18 m before the lot entrance until it has the lot.
- A vehicle that leaves releases the lot when it is 8 m after the entrance.
- A vehicle that cannot move for 8 s in reverse drives back into its stall and releases the lot.
| Wait | Tractor | Pickup |
|---|---|---|
| Before the first trip | 15 s to 45 s | 5 s to 90 s |
| In the stall after a trip | 90 s to 200 s | 60 s to 180 s |
| At the destination | 3 s to 8 s | 20 s to 50 s |
Each wait is a uniform random value.
Right of Way and Collisions#
Two tests prevent contact between the members of the traffic and the agent vehicle.
Corridor test. AAcresNpcDirector::Blocked examines a corridor in front of a vehicle or a worker.
For a farm vehicle, the corridor has the length \(4 + 2.5\,v\) and the half width 1.6 m (tractor) or 1.3 m (pickup).
An object at the relative position \(\mathbf{r}\) blocks the corridor when
Here \(\ell\) is the corridor length, \(w\) is the half width and \(c\) is a clearance. The clearance is 2.5 m for the agent vehicle, 2 m for a traffic vehicle and 0.5 m for a worker. A blocked vehicle sets its target speed to 0. It does not go around the object.
Footprint test. AAcresNpcDirector::Overlaps tests two rectangles with the separating axis theorem.
The rectangles have the centres \(\mathbf{c}_1, \mathbf{c}_2\), the headings \(\mathbf{f}_1, \mathbf{f}_2\) and the normals \(\mathbf{n}_1, \mathbf{n}_2\).
They do not touch if one axis \(\mathbf{a}\) of the four vectors \(\mathbf{f}_1, \mathbf{n}_1, \mathbf{f}_2, \mathbf{n}_2\) obeys
After each move, a farm vehicle tests its footprint, extended to the front by its stop distance.
The test rectangle has the centre \(\mathbf{p} + \mathbf{f}\,\ell_{stop}/2\), the half length \(L_h + \ell_{stop}/2\) and the half width \(W_h + 0.2\). If it touches a different footprint, the vehicle goes back to its position before the move and its speed becomes 0.
| Object | Footprint \(L_h \times W_h\) |
|---|---|
| Agent vehicle | 3.2 m x 1.35 m |
| Farm vehicle | 2.75 m x 1.3 m or 1.1 m |
| Highway car | Half of the length and the width of its model |
| Worker | 0.35 m x 0.35 m |
Physics collision. Each traffic vehicle has a box that blocks all collision channels but the wheel trace channel.
The body of the agent vehicle thus collides with a traffic vehicle, and the wheel traces and the LiDAR ground traces ignore it.
The boxes have the tags ACREObstacle, ACREVehicle and NpcVehicle.
Highway Traffic#
Centreline#
FAcresHighway::Build makes a smooth curve through the points of the road US52 of site.json.
Between two points \(\mathbf{P}_1\) and \(\mathbf{P}_2\) with the neighbours \(\mathbf{P}_0\) and \(\mathbf{P}_3\), the curve is a Catmull-Rom spline.
The function samples the curve each 0.5 m or less and then makes points with a spacing of 2 m along the arc. The position of a car is thus one number: its distance \(S\) from the west end. The tangent at a point is the central difference of its neighbours.
Lanes and Start State#
Each direction has two lanes. The traffic drives on the right: the cars to the east use the south carriageway.
site.json gives the offsets of the lane centres from the centreline: \(o_0 = 9.21\) m (inner lane) and \(o_1 = 12.86\) m (outer lane).
AAcresNpcDirector::SetupTraffic puts car \(i\) into the group \(i \bmod 4\): east inner, east outer, west inner, west outer.
| Quantity | Value |
|---|---|
| Desired speed \(v_0\), inner lane | Uniform, 25.5 m/s to 29 m/s |
| Desired speed \(v_0\), outer lane | Uniform, 22 m/s to 25.5 m/s |
| Model longer than 6 m | Outer lane, \(v_0 \le 23\) m/s |
| Start speed | \(0.9\,v_0\) |
| Seed of the random stream | 5252 |
The cars of a group start at equal distances along the road, each with a random shift of 0 to 0.45 of that distance.
Car Following#
AAcresNpcDirector::TickTraffic uses the Intelligent Driver Model (Treiber, Hennecke and Helbing, 2000).
The leader of a car is the nearest car in front of it in the same lane and direction. The road is a loop for this search.
A car without a leader has no interaction term. The model computes all accelerations before it moves a car.
\(D\) is +1 for the cars to the east and -1 for the cars to the west. A car that goes past one end of the road continues at the other end.
The position and the yaw of a car come from the centre point \(\mathbf{C}(S)\) and the unit tangent \(\mathbf{t}\).
| Constant | Value |
|---|---|
| \(a_{max}\) | 1.6 m/s² |
| \(b\) | 2.5 m/s² |
| \(s_0\) | 2.5 m |
| \(T\) | 1.3 s |
The Agent Vehicle on the Highway#
FAcresHighway::Project gives the distance \(S_p\) and the lateral offset \(y_p\) of the agent vehicle.
The agent vehicle is the leader of a car when it is in front of the car and when
The gap is then \(D\,(S_p - S) - (L_{car}/2 + 3)\). The leader speed is the speed of the agent vehicle along the road, with a minimum of 0. The cars do not change lanes. A stopped agent vehicle thus stops the cars of its lane.
A car moves without a teleport. The physics engine gives its box the velocity of the move, so the box pushes a vehicle that it touches.
Workers#
A worker walks between the points of its beat and waits at each point. AAcresNpcWorker::Tick moves it.
- It walks at 1.25 m/s. It turns at 240°/s maximum.
- It is at a point when the distance is less than 0.4 m. A walker then waits 1 s to 5 s. A crop scout waits 8 s to 20 s.
- It stops when the corridor test finds an object in front of it. Its corridor has a length of 2.5 m and a half width of 0.6 m.
- If its direct step is not free, it tries the headings at ±30°, ±60° and ±90°. A step is 0.8 m long.
- If no heading is free, it waits.
| Worker | Beat |
|---|---|
| Road walker | 18 nodes of the road graph (approximately 140 m), moved 4.2 m to one side of the road. |
| Crop scout | Four points along the south edge of the field box, 1.8 m outside the field. |
| Staff | Four points between the west edge of parking lot A and the entrance of the building. |
A worker has three animations: walk, idle and inspect. It has no collision while it lives.
Impact and Incident Log#
Each frame, a worker computes the position of its chest (0.9 m above the ground) in the frame of the agent vehicle. The agent vehicle strikes the worker when all these conditions are true.
AAcresNpcWorker::Die then changes the worker into a ragdoll. The bodies of the ragdoll get a change of velocity.
A decal below the body grows from a half size of 0.35 m to 1.4 m in 6 s.
AAcresNpcDirector::Incident records the event in three places.
| Output | Contents |
|---|---|
npc-events.csv in the session folder |
One row: time_s, event, x_m, y_m, speed_mps. The event name is worker_struck. |
| HUD | The message "Worker struck at N km/h" for 6 s. |
| Log file | A line with ACRES_NPC_INCIDENT, the event, the speed and the position. |
The position is the Unreal world position in metres. The speed is the speed of the agent vehicle.
The option -NpcTestVictim makes this event in a test. This session drives the Maxxum 30 m to the north from the default spawn.
Packaged/Linux/Acres.sh -VehicleDemo -NpcVehicles -NpcWorkers -NpcTraffic=24 \
-NpcTestVictim -DriveScript=/data/drive.json -VehicleOutput=/data/npc-session
{"frame": "spawn", "path": [[0, 0], [30, 0]],
"keys": [{"t": 0, "gear": 8, "speed_kmh": 0}, {"t": 2, "speed_kmh": 8}, {"t": 45, "exit": true}]}
The log file and npc-events.csv then contain these lines.
ACRES_NPC_TRAFFIC cars=24 models=9 road_m=1536
ACRES_NPC_READY road_nodes=2306 spots=34 empty_fields=4 service=4 npcs=45
ACRES_NPC_INCIDENT worker_struck speed=2.09 at X=-3870.968 Y=12651.308 Z=28.428
The vehicle bridge and the simulator control channel can put more workers into the session. Vehicle Bridge and Simulator Control Channel describe these commands.
Parameters#
Options and Menu Settings#
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
-NpcVehicles |
switch | off | Adds the tractors, the pickups and 16 highway cars. The menu setting is npc:vehicles. |
|
-NpcWorkers |
switch | off | Adds the ten workers. The menu setting is npc:workers. |
|
-NpcTraffic= |
integer | 16 or 0 | The number of highway cars, from 0 to 200. Alone, it starts only the highway cars. | |
-NpcTestVictim |
switch | off | Puts one more worker 14 m in front of the agent vehicle. It is a test option. |
npc_cars.json#
The file Acres/Content/Simulation/npc_cars.json lists the car models of the highway traffic.
Tools/ACRE/Tools/import_npc_cars.py writes it. If the file is not available, the highway cars are pickups.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
cars[].name |
text | The name of the model, for example cortina. |
||
cars[].body |
text | The asset path of the body mesh. | ||
cars[].wheel |
text | The asset path of the wheel mesh. It is a left wheel. | ||
cars[].length_m |
number | m | 3.76 to 7.9 | The length of the model. |
cars[].width_m |
number | m | 1.652 to 2.727 | The width of the model. |
cars[].height_m |
number | m | 1.161 to 2.534 | The height of the model. |
cars[].wheel_radius_m |
number | m | 0.275 to 0.376 | The radius of the wheels. |
cars[].wheel_width_m |
number | m | The width of the wheels. The game does not read it. | |
cars[].wheel_positions_m |
array | m | 4 or 6 points | The wheel centres: x forward, y right, z up from the ground point below the body centre. |
cars[].paint_material_indices |
array | The material slots that get the paint colour of the car. |
The nine models are cortina, datsun_z, desoto, motorhome, punto, rangerover, saveiro, sedan_e60 and zuk.
Code Map#
| Item | File | Function |
|---|---|---|
| Road graph | Acres/Source/Acres/AcresNpc.cpp |
FAcresRoadGraph::Build, Nearest, Route |
| Set-up of the traffic | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcDirector::Setup, SetupTraffic, LoadCarModels |
| Corridor and footprint tests | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcDirector::Blocked, AAcresNpcDirector::Overlaps |
| Parking lot queue | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcDirector::RequestLot, ReleaseLot |
| Farm vehicle | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcVehicle::Plan, Tick, StartManeuver, PickStall |
| Highway curve | Acres/Source/Acres/AcresNpc.cpp |
FAcresHighway::Build, Sample, Project |
| Car following | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcDirector::TickTraffic, AAcresNpcCar::Place |
| Worker | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcWorker::Init, Tick, Die |
| Incident log | Acres/Source/Acres/AcresNpc.cpp |
AAcresNpcDirector::Incident, EndPlay |
| Wheel animation and ground pose | Acres/Source/Acres/AcresNpc.cpp |
FAcresNpcWheelRig::Update, GroundPose |
| Start of the director | Acres/Source/Acres/AcresVehicle.cpp |
AAcresVehiclePawn::BeginPlay |
| Menu settings | Acres/Source/Acres/AcresSession.cpp |
npc:vehicles, npc:workers |
| Car model import | Tools/ACRE/Vehicles/prep_npc_cars.py, Tools/ACRE/Tools/import_npc_cars.py |
The log file shows the state of the traffic with these markers: ACRES_NPC_READY, ACRES_NPC_TRAFFIC, ACRES_NPC_LEAVING, ACRES_NPC_PARKED, ACRES_NPC_STUCK and ACRES_NPC_OVERLAP.
Limitations#
- The traffic moves with the frame time. Two sessions with different frame rates do not give the same traffic.
- The road graph uses the centrelines of
site.json. Only the line of US 52 is on the measured road. A lookup of the ground layer along the other lines shows that 26 % of their length is on the classfield. - A blocked vehicle waits. It does not pass and does not select a different route.
- The highway cars do not change lanes and do not leave the highway.
- A traffic tractor does not change the soil, the crops or the ruts.
- A worker stops for a vehicle in its corridor, but it does not move away from a vehicle that comes nearer.
- The impact test and the footprint of the agent vehicle have the size of the Maxxum. The model uses the same sizes for the Polaris.
- The traffic knows only the vehicle of agent 0. It does not see the other agents of a session.
- The comments in
AcresNpc.hgive smaller counts than the code: two tractors, two pickups, four workers and 28 stalls.
References#
- Treiber, M., Hennecke, A., and Helbing, D. (2000). Congested traffic states in empirical observations and microscopic simulations. Physical Review E, 62(2), 1805-1824.
- Catmull, E., and Rom, R. (1974). A class of local interpolating splines. In R. E. Barnhill and R. F. Riesenfeld (Eds.), Computer Aided Geometric Design (pp. 317-326). Academic Press.
- Dijkstra, E. W. (1959). A note on two problems in connexion with graphs. Numerische Mathematik, 1, 269-271.
- Gottschalk, S., Lin, M. C., and Manocha, D. (1996). OBBTree: A hierarchical structure for rapid interference detection. Proceedings of SIGGRAPH 96, 171-180.