Skip to content

Vehicles#

ACRES has two vehicles: the Polaris Ranger utility vehicle and the Case IH Maxxum 150 tractor. Drive them by hand, from a program, or several at the same time.

Before you start

Package the game. Refer to Build the Game. ACRES Core and acres_simulator have the Polaris only.

The Two Vehicles#

Polaris Ranger Maxxum 150
Use Scouting, transport, the drive-by-wire research platform Field work with implements
Mass 1233 kg with one person 5820 kg
Drive CVT, two ranges (high, low), AWD 16-speed powershift, PTO, three-point hitch
Control from a program Drive-by-wire messages (ds_dbw_msgs): steering, throttle, brake, gear, ULC speed control Steering, pedal, brake, gear and implement commands
Sensors Helios LiDAR, front camera, GNSS, IMU, INS, CAN Camera, LiDAR, GNSS, IMU, CAN
In ACRES Core Yes No

The Polaris and Maxxum model pages give the physics of each vehicle.

Drive by Hand#

Packaged/Linux/Acres.sh -VehicleDemo -Vehicle=polaris
Packaged/Linux/Acres.sh -VehicleDemo -Vehicle=maxxum

The vehicle starts at the ICSC garage. The panel at the top left of the HUD shows the main keys. Hold Tab for all keys.

Action Polaris Maxxum
Throttle, brake, steer W, S, A D W, S, A D
Gear [ ]: lever P-R-N-H-L [ ]: gear 1 to 16
Reverse V: reverse or low range V: forward or reverse
Drive-by-wire on or off F3 No drive-by-wire
Hand throttle, park brake = -, P
Cab view or chase view C C
Site map M M
Pause menu Esc Esc

Keyboard and Mouse Controls gives every key.

The start place is a named place of ACRE/places.json. -SpawnAt=<place> selects a different place. -VehicleSpawnU=, -VehicleSpawnV= and -VehicleSpawnYaw= give a cell of the survey grid and a heading.

Drive from a Program#

Each vehicle can have a vehicle bridge: a TCP socket that sends observations and receives commands, one JSON object on each line. The Polaris takes the drive-by-wire messages of the real vehicle.

  1. Start the game with a bridge on port 5555. The spawn options put the Polaris on the central farm road, heading west.

    Packaged/Linux/Acres.sh -VehicleDemo -Vehicle=polaris -RlPort=5555 \
        -VehicleSpawnU=625 -VehicleSpawnV=477 -VehicleSpawnYaw=180
    
  2. Write the client polaris_client.py.

    polaris_client.py
    """Drive the Polaris of the game through its vehicle bridge: hold 2 m/s and turn left for 15 s."""
    import json
    import socket
    import threading
    import time
    
    sock = socket.create_connection(("127.0.0.1", 5555))
    stream = sock.makefile("rw")
    latest = {}
    
    
    def read_messages():
        """Read each line. The game sends observations and drive-by-wire reports. Read them all, all the time."""
        for line in stream:
            message = json.loads(line)
            latest["report" if message.get("type") == "dbw_report" else "observation"] = message
    
    
    def send(message):
        stream.write(json.dumps(message) + "\n")
        stream.flush()
    
    
    threading.Thread(target=read_messages, daemon=True).start()
    time.sleep(1.0)
    first = latest["observation"]
    send({"dbw": {"enable": True}})
    time.sleep(0.2)
    send({"gear_cmd": {"cmd": 5}})                                         # 5: low gear. The lever starts in park.
    start = time.monotonic()
    while time.monotonic() - start < 15.0:                                 # 20 Hz
        send({"ulc_cmd": {"cmd": 2.0, "cmd_type": 1, "enable": True},           # 2 m/s
              "steering_cmd": {"cmd": 0.05, "cmd_type": 3, "enable": True}})    # 0.05 1/m to the left
        time.sleep(0.05)
    last = latest["observation"]
    distance = ((last["x"] - first["x"]) ** 2 + (last["y"] - first["y"]) ** 2) ** 0.5
    left = -((last["yaw_deg"] - first["yaw_deg"] + 180.0) % 360.0 - 180.0)   # the bridge yaw increases to the right
    print(f"after 15 s: {distance:.1f} m from the start, {left:.0f} deg to the left, speed {last['vx']:.2f} m/s")
    send({"ulc_cmd": {"cmd": 0.0, "cmd_type": 1, "enable": True}})
    
  3. Run the client while the game runs.

    python polaris_client.py
    

    Expected result

    The Polaris accelerates to 2 m/s and drives a left curve.

    after 15 s: 24.8 m from the start, 62 deg to the left, speed 1.99 m/s
    

The Polaris driven from a program, with a tractor at work behind

Read all messages

The game sends approximately 70 messages each second. Read them all the time, as the thread of the example does. A client that does not read stops the drive.

The bridge uses the Unreal frame: x east, y south, and a yaw that increases to the right. A key on the keyboard is a driver override: it turns the drive-by-wire off until the next enable. The Vehicle Bridge reference gives each message. For exact, repeatable timing, use Lockstep Stepping.

Run Several Vehicles#

A session can have 8 vehicles. All vehicles share the world, the farm and the weather.

  1. Start the Maxxum and the Polaris, each with its own bridge port.

    Packaged/Linux/Acres.sh -VehicleDemo -Vehicles=maxxum,polaris -RlPorts=5555,5556 \
        -SessionLog -VehicleOutput=$PWD/two
    

    Expected result

    The Polaris starts 7 m to the side of the Maxxum. The log has one line for each vehicle.

    ACRES_VEHICLE_READY agent=maxxum index=0 trailer=0 mass_kg=5820.0 implement=none ...
    ACRES_VEHICLE_READY agent=polaris index=1 trailer=0 mass_kg=1233.0 implement=none ...
    ACRES_AGENT_SPAWNED index=1 name=polaris vehicle=polaris
    

The Maxxum and the Polaris at the ICSC garage

  1. Push F2 to go to the next vehicle. The keyboard, the camera and the HUD follow. The vehicle that you leave holds its brake.

The session folder has one folder for each vehicle: two/maxxum and two/polaris, each with its tractor.csv and session-summary.json. The Polaris folder also has dbw.csv. The farm files stay in two.

An entry of -Vehicles= can give a pose: polaris@533:470:-90 (survey cell and yaw), or polaris@utm:500577.5:4480144.6:0 (UTM zone 16N and heading).

Use an Agents File#

-Agents=<file> gives each vehicle its own settings. Write the file agents.json:

agents.json
{"agents": [
  {"name": "tractor", "vehicle": "maxxum", "implement": "chisel_plow", "spawn": [625, 477, 180],
   "rl_port": 5555},
  {"name": "scout", "vehicle": "polaris", "finish": "desert_tan", "rl_port": 5556,
   "drive_script": "/data/polaris-drive.json", "sensor_record": true}
]}
Key Function
name, vehicle The name in the logs and the HUD, and maxxum or polaris
spawn, utm, utm_frame The start pose: a survey cell and yaw, or UTM zone 16N in nad83_2011 or wgs84
implement, gear, finish The implement and the start gear of the Maxxum, the paint of the Polaris
rl_port, sensor_stream, can_udp The ports of the bridge, the sensor stream and the CAN frames
drive_script, replay_file, replay_mode A drive script or a replay for this vehicle
sensor_record, sensor_overlay Records the sensors of this vehicle. Changes values of the sensor file for this vehicle.

Next Steps#

  • Implements


    Attach a plow, a drill, a sprayer, a loader or a baler to the Maxxum.

  • Sensors


    The sensors of each vehicle and their settings.

  • Lockstep Stepping


    Step the game from a client.