Skip to content

Run Several Vehicles#

This tutorial starts the Maxxum and the Polaris in one session. Each vehicle is an agent with its own controls, ports, sensors and logs.

Before You Start#

All agents of a session use the same world, the same farm and the same weather. A session can have 8 agents at most. Agent 0 is the vehicle that the player controls first.

The Maxxum and the Polaris in one session

Start Two Vehicles#

  1. Start a session with the option -Vehicles=.

    Packaged/Linux/Acres.sh -VehicleDemo -Vehicles=maxxum,polaris
    

    Expected Result

    The Maxxum is in front of the ICSC garage. The Polaris is 7 m to its left. The log contains one line ACRES_VEHICLE_READY for each agent.

    ACRES_VEHICLE_READY agent=maxxum index=0 trailer=0 mass_kg=5820.0 implement=none surface=mapped physics_hz=120 ...
    ACRES_VEHICLE_READY agent=polaris index=1 trailer=0 mass_kg=1233.0 implement=none surface=mapped physics_hz=120 ...
    ACRES_AGENT_SPAWNED index=1 name=polaris vehicle=polaris
    
  2. Push F2 to go to the next vehicle. The keyboard, the camera and the HUD follow.

    Expected Result

    The HUD shows the line View with the name of the vehicle. The log contains the line ACRES_VIEW agent=polaris.

    Note

    The vehicle that you leave holds its brake. A bridge client, a replay or a drive script continues to drive it.

The game gives each agent a name. The default name is the vehicle type: maxxum or polaris. A name that occurs two times gets the agent number as a suffix, for example polaris_2.

An entry of -Vehicles= can contain a start pose.

Entry Pose
polaris No pose. The agent starts 7 m to the right of agent 0 with the same heading. When that place is not clear, the game uses the left side.
polaris@533:470:-90 The cell u, v of the survey grid and the Unreal yaw angle in degrees.
polaris@utm:500577.5:4480144.6:0 The UTM zone 16N easting and northing in metres and the heading in degrees, clockwise from grid north.

Note

The menu starts the same session: select New Simulation, the tab Vehicle and the value Both (Maxxum and Polaris, Multi-Agent).

Give Each Agent Its Ports#

Each agent can have a vehicle bridge and a sensor stream. A list option gives one port for each agent, in the sequence of the agents.

  1. Start the session with the port lists and the recordings.

    Packaged/Linux/Acres.sh -VehicleDemo -RenderOffscreen -Vehicles=maxxum,polaris \
      -RlPorts=5555,5556 -SensorStreams=5601,5602 -SimControl=5600 \
      -SensorRecord -SessionLog -VehicleOutput="$PWD/out/two" -DriveScript="$PWD/two.json"
    

    The file two.json holds the Maxxum and ends the session after 24 s.

    {"keys": [{"t": 0, "speed_kmh": 0, "steer": 0}, {"t": 24, "exit": true}]}
    

    Expected Result

    The game opens one port of each type for each agent. It stops after the drive script ends.

    ACRES_SENSOR_STREAM_LISTENING agent=maxxum port=5601
    ACRES_RL_LISTENING port=5555
    ACRES_SENSOR_STREAM_LISTENING agent=polaris port=5602
    ACRES_RL_LISTENING port=5556
    ACRES_AGENT_SPAWNED index=1 name=polaris vehicle=polaris
    ACRES_SIM_CONTROL_READY port=5600 lockstep=0 replay=0 log=
    ACRES_DRIVE_SCRIPT_DONE t=24.00
    
Option Function
-RlPorts=5555,5556 The port of the vehicle bridge of each agent.
-SensorStreams=5601,5602 The port of the sensor stream of each agent.
-SimControl=5600 The simulator control channel. One channel controls the session with all agents.
-SensorRecord Records the sensors of all agents.
-SessionLog Writes the session log of all agents.
-DriveScript= The drive script of agent 0.

The options -RlPort=, -SensorStream=, -Implement=, -ReplayFile= and -DriveScript= apply to agent 0 only. Use an agents file to set these values for the other agents.

Find the Logs of Each Agent#

A session with more than one agent writes one folder for each agent into the session folder.

  1. List the session folder.

    ls out/two out/two/maxxum out/two/polaris
    

    Expected Result

    out/two:
    farm-config.json  farm-fields.csv    farm-water.bin    maxxum     water-depth.f32
    farm-events.csv   farm-state.json    farm-water.json   polaris
    farm-field.bin    farm-visuals.json  farm-weather.csv  theta.f32
    
    out/two/maxxum:
    sensors  session-summary.json  tractor.csv
    
    out/two/polaris:
    dbw.csv  sensors  session-summary.json  tractor.csv
    
Path Content
<session>/<agent>/tractor.csv The session log of the agent at 120 Hz.
<session>/<agent>/session-summary.json The summary of the session log.
<session>/polaris/dbw.csv The drive-by-wire reports of the Polaris at 50 Hz.
<session>/<agent>/sensors/episode-NNN The sensor episodes of the agent.
<session>/farm-* The state of the farm. All agents use one farm.

With -SensorOutput=<folder>, the sensor episodes of an agent go into <folder>/<agent>. The session folder of this run uses 346 MB for 24 s.

CAUTION

Two vehicles that record a camera and a LiDAR in real time lose samples. In this run the game made 5 frames for each second. Each vehicle recorded 134 of 240 camera images and approximately 70 of 240 LiDAR scans. Read the drop counters of episode.json. Use lockstep when the dataset must be complete. Refer to Collect Data and Lockstep Stepping.

A drive script ends the session only while the player controls agent 0. When a key view moved the view to a different agent, move the view back before the key exit.

Write an Agents File#

The option -Agents= reads the agents from a JSON file. The file has more settings than -Vehicles=.

  1. Write the file agents.json.

    {"agents": [
      {"name": "maxxum", "vehicle": "maxxum", "implement": "chisel_plow", "spawn": [625, 477, 180],
       "drive_script": "/home/user/ACRES/Demo/Multi/maxxum.json", "rl_port": 5555,
       "sensor_overlay": "/home/user/ACRES/Demo/Multi/maxxum_sensors.json"},
      {"name": "polaris", "vehicle": "polaris", "finish": "desert_tan",
       "utm": [500577.540, 4480144.643, 0.054], "utm_frame": "nad83_2011", "rl_port": 5556,
       "drive_script": "/home/user/ACRES/Demo/Multi/polaris.json"}
    ]}
    
  2. Replace /home/user/ACRES with the absolute path of the repository.

The keys of an agent have these functions. For agent 0, an option of the command line sets the value when the key is absent.

Name Type Unit Default Description
name string the vehicle type The name of the agent in the logs, the folders, the HUD and the bridge messages.
vehicle string maxxum maxxum or polaris. Option for agent 0: -Vehicle=.
finish string graphite The paint of the Polaris: graphite, forest_green, desert_tan or deep_blue. Option: -PolarisFinish=.
implement string none The implement of the Maxxum. Option: -Implement=.
spawn array cell, cell, deg The start pose [u, v, yaw] on the survey grid. Options: -VehicleSpawnU=, -VehicleSpawnV=, -VehicleSpawnYaw=.
utm array m, m, deg The start pose [easting, northing, heading] in UTM zone 16N. The heading is clockwise from grid north.
utm_frame string nad83_2011 The datum of the UTM pose: nad83_2011 or wgs84.
drive_script path The drive script of the agent. Option: -DriveScript=.
replay_file path A replay file or a session folder. Option: -ReplayFile=.
replay_mode string commands commands or path. Option: -ReplayMode=.
rl_port number 0 The port of the vehicle bridge. Options: -RlPort=, -RlPorts=.
sensor_stream number 0 The port of the sensor stream. Options: -SensorStream=, -SensorStreams=.
can_udp number 0 The UDP port of the CAN frames of the agent. Option for agent 0: -RlCanUdp=.
gear number The start gear of the Maxxum. Option: -VehicleGear=.
sensor_record boolean the value of -SensorRecord Records the sensors of this agent.
sensor_overlay path A JSON file that changes values of sensors.json for this agent.

Note

A value of rl_port or sensor_stream in the file has priority over the list options -RlPorts= and -SensorStreams=.

Run the Worked Example#

The example has two vehicles at work. The Maxxum pulls the chisel plow on field F29 with a drive script. The Polaris follows the grass lanes at the edge of the field. A client drives it through its vehicle bridge with drive-by-wire commands.

  1. Start the session with the agents file.

    Packaged/Linux/Acres.sh -VehicleDemo -RenderOffscreen -Agents="$PWD/agents.json" \
      -FarmInitialTheta=0.8 -EnvHour=10 -SensorRecord -SessionLog -VehicleOutput="$PWD/out/multi" \
      > out/multi-game.log 2>&1 &
    
  2. Start the client of the Polaris in a second terminal.

    cd Learning
    python -m acres_learn.envs.dbw_client --port 5556 --path ../Demo/Multi/polaris_lane.json \
      --delay 8 --log ../out/multi-dbw-reports.csv
    

    Expected Result

    The client connects, waits 8 s and then drives the Polaris along the lanes. It prints these lines.

    connected to 127.0.0.1:5556
    done: 3246 DBW reports received
    
  3. Wait until the drive script of the Maxxum ends the session after 80 s. Then list the session folder.

    ls out/multi out/multi/maxxum out/multi/polaris
    

    Expected Result

    out/multi:
    farm-config.json  farm-fields.csv    farm-water.bin    maxxum     water-depth.f32
    farm-events.csv   farm-state.json    farm-water.json   polaris
    farm-field.bin    farm-visuals.json  farm-weather.csv  theta.f32
    
    out/multi/maxxum:
    sensors  session-summary.json  tractor.csv
    
    out/multi/polaris:
    dbw.csv  sensors  session-summary.json  tractor.csv
    

In this run the Maxxum moved 222 m and the Polaris moved 189 m. The session folder uses 1.5 GB. The Maxxum records no camera in this example: the file Demo/Multi/maxxum_sensors.json sets its camera off. The Polaris recorded 800 of 800 camera images and 557 of 801 LiDAR scans.

The worked example with two vehicles at work

The drive script of agent 0 can move the view between the agents. The key view gives the name of the agent.

{"t": 14, "view": "polaris"}

Note

The physics does a maximum of 0.1 s in one frame (MaxPhysicsDeltaTime in Acres/Config/DefaultEngine.ini). The simulation thus stays at real time down to 10 frames for each second. Below that rate, the simulation time is slower than the clock time. The session of this example made approximately 26 frames for each second.

The script Demo/multi_agent_demo.sh starts the game and the client with one command. It writes its own agents file.

Demo/multi_agent_demo.sh out/multi-demo

CAUTION

The agents file of the script has no key spawn for the Maxxum. The Maxxum then starts at the ICSC garage and does not get to field F29: in a test it stopped after 15 m. Use the agents file of this page, or add "spawn": [625, 477, 180] to the Maxxum in the script.

Connect the Agents to ROS 2#

The ROS 2 bridge connects all agents of a session from one process. It reads the agents and their ports from the simulator control channel.

WARNING

Do not send drive-by-wire commands outside the DDS loopback fence. The real vehicle can move. Do all ROS 2 commands in a terminal with the fence (source ROS/Env/setup_env.sh).

  1. Start the session of the section Give Each Agent Its Ports.

  2. Start the bridge in a second terminal.

    source ROS/Env/setup_env.sh
    ros2 launch acres_sim sim_bridge.launch.py agents:=auto control_port:=5600 vehicle:=maxxum
    

    Expected Result

    The bridge prints one line for each agent.

    [sim_bridge-1] [INFO] [sim_bridge]: agent 0 'maxxum' (maxxum): namespace /, sensor stream 5601, JSON bridge 5555, CAN UDP 0
    [sim_bridge-1] [INFO] [sim_bridge]: agent 1 'polaris' (polaris): namespace /polaris, sensor stream 5602, JSON bridge 5556, CAN UDP 0
    
  3. List the topics in a third terminal.

    source ROS/Env/setup_env.sh
    ros2 topic list
    

    Expected Result

    The list contains the topics of the Maxxum in the root namespace and the topics of the Polaris in the namespace /polaris. These are some of the topics.

    /camera/image_raw
    /clock
    /gnss/fix
    /imu/data
    /lidar/points
    /odom
    /polaris/camera/image_raw
    /polaris/lidar/points
    /polaris/oxts/fix
    /polaris/vehicle/odom
    /polaris/vehicle/steering/report
    /tf
    

Agent 0 uses the root namespace. Each other agent uses a namespace with its name and a frame prefix with its name. Only agent 0 publishes /clock. The argument vehicle:=maxxum tells the launch file that agent 0 is the Maxxum. Nodes and Launch Files describes the arguments of the launch file. First ROS 2 Session gives the procedure for one vehicle.

Next Steps#