Vehicle Bridge#
The vehicle bridge is a JSON socket that sends commands to one vehicle and returns its observations and reports. This page gives the protocol for the Maxxum and for the Polaris, the timing of the commands and the CAN transports.
Each agent has its own vehicle bridge. The option is -RlPort=<port>, and the game has no default port.
The tools and the ROS 2 launch files use port 5556 for the Polaris. The examples use port 5555 for the Maxxum.
The ROS 2 bridge connects to this socket and gives the commands and the reports as ROS 2 topics: refer to Topics.
The figure of the three sockets is on the page Simulator Control Channel.
| Item | Type | Function |
|---|---|---|
-RlPort= |
Option | Opens the vehicle bridge of agent 0. |
-RlPorts= |
Option | Opens one vehicle bridge for each agent. |
-RlCanUdp= |
Option | Opens the CAN transport on a UDP port. |
-RlCan= |
Option | Opens the CAN transport on a SocketCAN interface. |
| Transport | Protocol | TCP on 127.0.0.1, one JSON object in each line. |
| Command Timing | Protocol | The physics step at which a command applies. |
| Control and Timeouts | Protocol | The keyboard, the safety brake and a slow client. |
| Barrier | Game to client | The end of a lockstep step. |
| Driving Action | Client to game | Steering, pedal and differential lock. |
reset |
Client to game | Moves the vehicle to a pose and starts a new episode. |
implement |
Client to game | The hitch, the PTO and the operator controls of the Maxxum. |
| Session Commands | Client to game | Clock, workers, harvest function and HUD text. |
| Observation | Game to client | The state of the vehicle, each 0.1 s. |
dbw |
Client to game | Enables or disables the drive-by-wire of the Polaris. |
steering_cmd |
Client to game | The steering command of the Polaris. |
throttle_cmd |
Client to game | The throttle command of the Polaris. |
brake_cmd |
Client to game | The brake command of the Polaris. |
gear_cmd |
Client to game | The gear command of the Polaris. |
ulc_cmd |
Client to game | The speed command of the Polaris. |
drive_mode |
Client to game | The drive mode switch of the Polaris. |
dbw_report |
Game to client | The drive-by-wire reports of the Polaris, at 50 Hz. |
dbw_client.py |
Tool | A Python client for the Polaris. |
| CAN Transport | Protocol | J1939 frames on UDP or SocketCAN. |
| Differences in ACRES Core | Table | The behaviour of the Core server. |
Options#
-RlPort=#
Opens the vehicle bridge of agent 0 on 127.0.0.1 at the given port.
The game writes ACRES_RL_LISTENING port=<port> to its log when the socket is open.
In an agents file, the key rl_port of an agent does the same for that agent.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
-RlPort= |
integer | no bridge | The TCP port. |
-RlPorts=#
Opens one vehicle bridge for each agent of a session with more than one vehicle.
The list gives the ports in the sequence of the agents. An agent with its own rl_port or -RlPort= keeps that port.
The operation hello of the simulator control channel gives the port of each agent.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
-RlPorts= |
integer list | no bridge | The TCP ports, with commas between them. |
-RlCanUdp=#
Opens the CAN transport of agent 0 on a UDP port of 127.0.0.1.
In an agents file, the key can_udp of an agent opens a CAN transport for that agent.
This option is available only on Linux.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
-RlCanUdp= |
integer | no transport | The UDP port. |
-RlCan=#
Opens the CAN transport of agent 0 on a SocketCAN interface, for example a virtual interface vcan0.
The interface must exist before the game starts. This option is available only on Linux.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
-RlCan= |
string | no transport | The name of the SocketCAN interface. |
Protocol#
Transport#
The vehicle bridge is a TCP socket on the loopback address 127.0.0.1. A program on a different computer cannot connect.
Each message is one JSON object in one line of UTF-8 text. A newline character ends the line.
The socket accepts one client at a time.
A client message can contain the keys of more than one command.
The bridge ignores a line that is not a JSON object and writes ACRES_RL_BAD_MESSAGE to the log.
The bridge sends no reply to a command. The observation and the dbw_report show the effect.
The positions and angles of this socket use the Unreal convention, not the world frame of the simulator control channel.
The x axis points east and the y axis points south. The yaw angle is 0 for east and increases to the south.
The first line that a client of a Maxxum receives is an observation:
Command Timing#
A command has no time stamp field. A receiver thread reads the sockets 1000 times each second. It gives each line and each CAN frame the wall-clock time of its arrival.
The game processes the commands one time in each frame. One frame can contain as many as 12 physics steps. For each command, the game calculates a due time in simulation time from the arrival time. The command goes into the command queue of the agent. The first physics step that starts at or after the due time applies it. Thus the physics steps get the commands in the sequence and with the intervals of their arrival.
This rule applies to the driving action, to the drive-by-wire commands and to the CAN driving frames. The other commands apply when the frame processes them. In lockstep, each command applies at the next physics step.
read k-1 a command arrives read k
|----------------x----------------| wall clock
|<- fraction f ->|
|----------------x----------------| simulation time
t0 due = t0 + f T t0 + T
The game reads the sockets at the start of each frame.
The time T is the simulation time that frame k adds, 0.1 s maximum.
The fraction f is the position of the arrival between the two reads.
Control and Timeouts#
While the bridge of a Maxxum has a client, the driving action of the client replaces the keyboard.
The bridge holds the brake until the first driving action arrives.
The bridge also holds the brake when no driving action arrives for 1 s on the wall clock.
The observation then has stale equal to true. In lockstep, the 1 s limit does not apply.
For a client that sends only drive-by-wire commands, stale stays true.
A client that sends drive-by-wire commands to a Polaris has no 1 s limit. The drive-by-wire model stops a subsystem when no command for it arrives for 0.1 s of simulation time. Send each drive-by-wire command again at a rate from 20 Hz to 100 Hz. Refer to Drive-by-Wire and ULC.
When a client disconnects, the bridge applies the brake and gives the control back to the keyboard. For a Polaris, the bridge also disables the drive-by-wire.
| Limit | Value | Effect |
|---|---|---|
| No driving action | 1 s, wall clock | The bridge holds the brake. |
| No CAN command frame | 3 s, wall clock | The CAN controller loses the control. |
| No drive-by-wire command | 0.1 s, simulation time | The subsystem of the Polaris disengages. |
| Client does not read | 1 MiB of output waits | The bridge disconnects the client. |
| Line without a newline | 1 MiB | The bridge disconnects the client. |
An observation after 5 s of driving actions, and an observation 1.5 s after the last action:
{"t": 10.1167, "vx": 2.6861, "steer_rad": 0.06632,
"rpm": 1691.2, "stale": false}
{"t": 11.65, "vx": -0.0311, "stale": true}
The reports of a Polaris 0.4 s after the last drive-by-wire command:
{"t": 16.8833,
"steering_report": {"steering_wheel_angle": 60.0,
"cmd": 60.0, "cmd_type": 0, "enabled": false,
"override_active": false, "timeout": true},
"ulc_report": {"cmd_type": 0, "vel_ref": 2.0988,
"vel_meas": 2.0988, "accel_ref": 0.0,
"accel_meas": 0.2464, "enabled": false, "timeout": true},
"system_report": {"enabled": true, "override": false}}
Barrier#
In lockstep, the bridge sends a barrier line at the end of each step request.
All observations and reports of the steps are before the barrier.
A client that reads to the barrier has all data of the request.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
type |
string | barrier. |
||
step |
integer | The physics step that the world reached. It is equal to barrier in the reply of the step request. |
Maxxum#
The messages of this section also operate a Polaris, with the differences that each row gives.
Driving Action#
Sets the steering and the pedals. The bridge keeps the last value of each key. On the Maxxum, the bridge selects the forward gear F10. On the Polaris, the gear lever stays in its position.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
steer |
number | From -1 to 1. A fraction of one half of the maximum steering angle. Positive is left. | ||
curvature |
number | 1/m | The curvature of the path. Positive is left. The steering angle is atan(curvature × wheelbase). |
|
pedal |
number | From -1 to 1. A positive value is the throttle, a negative value is the brake. | ||
difflock |
number | A value above 0 locks the differential of the rear axle. Maxxum only. |
When one message has steer and curvature, the bridge uses curvature.
The action {"curvature": 0.05, "pedal": 0.4, "difflock": 1} for 2 s gives this observation:
reset#
Moves the vehicle to a pose on the ground and starts a new episode of the bridge. The marks and the crop damage of the fields stay. The pose applies at the next physics step.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
reset.x |
number | m | spawn pose | The east coordinate of the body origin. |
reset.y |
number | m | spawn pose | The south coordinate of the body origin. |
reset.yaw_deg |
number | deg | spawn pose | The yaw angle: 0 is east, 90 is south. |
reset.speed |
number | m/s | 0 | The start speed, from 0 to 8. |
reset.restore_field |
boolean | false |
true to remove the marks and the crop damage of the field below the pose. |
A reset without x and y puts the vehicle at its spawn pose.
The observation shows the progress: episode increases immediately, and reset_epoch increases when the physics applied the pose.
implement#
Sets the implement controls and the operator controls. The keys hand_throttle and park_brake apply to each vehicle.
The other keys apply to a Maxxum with an implement. The hitch keys apply to an implement on the hitch.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
implement.raise |
boolean | true lifts the implement. For the square baler: true lifts the pickup. |
||
implement.pto |
boolean | true engages the PTO. |
||
implement.transport |
boolean | true selects the transport position. |
||
implement.hitch_lever |
number | The position of the hitch lever, from 0 to 1. | ||
implement.hitch_mode |
string | position, draft or float. |
||
implement.draft_setpoint_n |
number | N | The draft set-point, from 1000 to 60000. | |
implement.hand_throttle |
number | The hand throttle, from 0 to 1. | ||
implement.park_brake |
boolean | true applies the park brake. |
The implement models are on the page Implement Mechanics.
The observation of a Maxxum with the chisel plow, 3 s later:
Session Commands#
These keys change the session or the HUD.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
env_clock.date |
string | The local date as YYYY-MM-DD. The weather starts again at this time. |
||
env_clock.hour |
number | h | 12 | The local hour of the day. |
workers |
list of [x, y] |
m | Replaces the workers of the bridge with workers at these points. | |
cmd |
string | harvester together with on sets the harvest function. |
||
on |
boolean | false |
The state for cmd. |
|
hud |
string | A status text for the HUD, 160 characters maximum. | ||
reward |
number | A number for the HUD. | ||
success_pct |
number | % | A success rate for the HUD. |
The workers are available only when the session has -NpcWorkers or -NpcVehicles.
The harvest function is available only when the session has -FarmHarvester.
Observation#
While the bridge has a client, it sends one observation for each 0.1 s of simulation time. This is 12 physics steps.
The observation has no key type. A Polaris client gets it together with the dbw_report lines.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
t |
number | s | The physics time of the vehicle. | |
episode_t |
number | s | The time since the last reset. | |
x, y, z |
number | m | The body origin: x east, y south, z up. | |
yaw_deg |
number | deg | The yaw angle: 0 is east, 90 is south. | |
vx, vy |
number | m/s | The velocity in the body frame: x forward, y right. | |
yaw_rate |
number | rad/s | Positive when the vehicle turns right. | |
cross_slope |
number | rad | Positive when the ground goes down to the right. | |
slip |
number list | The slip ratio of the four wheels: front left, front right, rear left, rear right. | ||
steer_rad |
number | rad | The steering angle. Positive is left. | |
rpm |
number | rev/min | The engine speed. | |
difflock |
integer | 0 open, 1 rear locked, 2 front and rear locked. | ||
theta_here, theta_5, theta_10 |
number | m³/m³ | The soil water content below the vehicle, 5 m ahead and 10 m ahead. | |
lidar |
number list | m | 16 ranges of the front half, from 90° left to 90° right, 30 m maximum. | |
bunker_kg, harvest_kg |
number | kg | The crop mass in the bunker and the total harvested mass. | |
crushed_m2 |
number | m² | The crop area that the session crushed. | |
draft_n |
number | N | The draft force of the implement. | |
implement |
string | The implement identifier. Empty without an implement. | ||
implement_depth_m |
number | m | The mean depth of the tools. | |
pto_kw, pto_rpm |
number | kW, rev/min | The power and the speed of the PTO shaft. | |
hitch_lever |
number | The hitch lever, from 0 to 1. | ||
hitch_lift_deg |
number | deg | The lift angle of the lower links. | |
hitch_mode |
integer | 0 position, 1 draft, 2 float. | ||
raised, pto_on |
boolean | The state of the implement and of the PTO switch. | ||
struck |
boolean | true when the vehicle hit a worker since the last observation. |
||
episode |
integer | The resets that clients requested on this bridge. | ||
reset_pending |
boolean | true until the physics applies the last reset. |
||
reset_epoch |
integer | The resets that the physics applied. | ||
workers |
integer | The number of workers of the bridge. | ||
stale |
boolean | true when no driving action is in effect. |
||
agent, vehicle |
string | The name of the agent and maxxum or polaris. |
The 16 lidar values are a fast summary for controllers, not the LiDAR of the sensor rig.
{"t":5.0167,"episode_t":5.0167,"x":-38.715,"y":132.8379,
"z":1.5157,"yaw_deg":-89.9152,"vx":0.5929,"vy":-0.0043,
"yaw_rate":0.00152,"cross_slope":-0.00587,
"slip":[0.00945,0.00844,-0.00569,-0.00595],
"steer_rad":0.0,"rpm":796.3,"difflock":0,
"theta_here":0.2,"theta_5":0.2,"theta_10":0.2,
"lidar":[30.0,30.0,25.129,20.258,30.0,30.0,30.0,30.0,
30.0,30.0,30.0,30.0,30.0,30.0,30.0,30.0],
"bunker_kg":0.0,"harvest_kg":0.0,"crushed_m2":0.0,
"draft_n":0.0,"struck":false,"episode":0,
"reset_pending":false,"reset_epoch":0,"workers":0,
"stale":true,"implement":"chisel_plow",
"implement_depth_m":0.0,"pto_kw":0.0,"hitch_lever":0.235,
"hitch_lift_deg":32.0,"hitch_mode":0,"raised":true,
"pto_on":false,"pto_rpm":0.0,"agent":"maxxum",
"vehicle":"maxxum"}
Polaris#
The Polaris uses the commands and the reports of the Dataspeed drive-by-wire.
The keys and the units are those of the ROS 2 messages of ds_dbw_msgs, thus the ROS 2 bridge passes each message without a change.
The model of the actuators and of the ULC is on the page Drive-by-Wire and ULC.
The bridge accepts the keys clear, ignore, enable_shift and enable_shift_park and ignores them.
The bridge refuses a command type that the model does not have and writes ACRES_DBW_REJECTED to the log one time, for example ACRES_DBW_REJECTED steering_cmd cmd_type 1 (not modelled).
A Maxxum refuses all commands of this section.
WARNING
The same messages move the real vehicle on the real ROS 2 topics. Keep the simulator traffic on the loopback address.
dbw#
Enables or disables the drive-by-wire system. This is the function of the topics /vehicle/enable and /vehicle/disable.
A driver input on the keyboard is an override. It disables the system until the next enable.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
dbw.enable |
boolean | false |
true enables the system. |
|
dbw.disable |
boolean | false |
true disables the system. |
steering_cmd#
The steering command, with the fields of ds_dbw_msgs/msg/SteeringCmd.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
steering_cmd.cmd |
number | by type | 0 | The command value. |
steering_cmd.cmd_type |
integer | 0 | 0 none, 2 steering wheel angle in deg, 3 curvature in 1/m, 4 yaw rate in rad/s, 14 percent. | |
steering_cmd.cmd_rate |
number | deg/s | 0 | The rate limit of the steering wheel. 0 selects the default. |
steering_cmd.cmd_accel |
number | deg/s² | 0 | The acceleration limit. 0 selects the default. |
steering_cmd.enable |
boolean | false |
true to let the actuator follow the command. |
The model does not have the type 1 (torque).
throttle_cmd#
The throttle command, with the fields of ds_dbw_msgs/msg/ThrottleCmd.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
throttle_cmd.cmd |
number | % | 0 | The command value. |
throttle_cmd.cmd_type |
integer | 0 | 0 none, 13 raw pedal percent, 14 percent of the full range. | |
throttle_cmd.rate_inc |
number | %/s | 0 | The rate limit for an increase. |
throttle_cmd.rate_dec |
number | %/s | 0 | The rate limit for a decrease. |
throttle_cmd.enable |
boolean | false |
true to let the actuator follow the command. |
brake_cmd#
The brake command, with the fields of ds_dbw_msgs/msg/BrakeCmd.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
brake_cmd.cmd |
number | by type | 0 | The command value. |
brake_cmd.cmd_type |
integer | 0 | 0 none, 1 pressure in bar, 14 percent. | |
brake_cmd.rate_inc |
number | by type | 0 | The rate limit for an increase, for each second. |
brake_cmd.rate_dec |
number | by type | 0 | The rate limit for a decrease, for each second. |
brake_cmd.enable |
boolean | false |
true to let the actuator follow the command. |
The model does not have the torque types and the acceleration types.
gear_cmd#
The gear command. The value is a number or an object with the key value, as in ds_dbw_msgs/msg/GearCmd.
The command has an effect only while the drive-by-wire system is on.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
gear_cmd.cmd |
integer | 0 | 0 none, 1 park, 2 reverse, 3 neutral, 4 high, 5 low. |
ulc_cmd#
The command of the ULC, with the fields of ds_dbw_msgs/msg/UlcCmd. The ULC controls the throttle and the brake.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
ulc_cmd.cmd |
number | by type | 0 | The command value. |
ulc_cmd.cmd_type |
integer | 0 | 0 none, 1 speed in m/s, 2 acceleration in m/s². | |
ulc_cmd.limit_accel |
number | m/s² | 0 | The acceleration limit. 0 selects the default. |
ulc_cmd.limit_decel |
number | m/s² | 0 | The deceleration limit. 0 selects the default. |
ulc_cmd.limit_jerk_throttle |
number | m/s³ | 0 | The jerk limit of the throttle. 0 selects the default. |
ulc_cmd.limit_jerk_brake |
number | m/s³ | 0 | The jerk limit of the brake. 0 selects the default. |
ulc_cmd.enable |
boolean | false |
true to let the ULC control the speed. |
|
ulc_cmd.coast_decel |
boolean | false |
true to decelerate without the brake. |
The ULC report and the steering report after 6 s:
drive_mode#
Sets the drive mode switch of the Polaris. This switch is not a part of the drive-by-wire. It applies immediately.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
drive_mode |
string | awd |
awd, 2wd or turf. |
dbw_report#
While the bridge has a client, it sends the reports at 50 Hz of simulation time.
One line contains all reports of one instant. Each object has the fields of the report message of ds_dbw_msgs with the same name.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
type |
string | dbw_report. |
||
agent |
string | The name of the agent. | ||
t |
number | s | The physics time of the report. | |
drive_mode |
integer | 0 turf, 1 two-wheel drive, 2 all-wheel drive. | ||
road_wheel_rad |
number | rad | The road wheel angle. Positive is left. | |
stop_hold |
boolean | true when the ULC holds the vehicle at a stop. |
steering_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
steering_wheel_angle |
number | deg | The angle of the steering wheel. | |
cmd |
number | deg | The steering wheel angle that the actuator follows. | |
cmd_type |
integer | The type of the active command. |
throttle_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
percent_input |
number | % | The pedal of the driver. | |
percent_cmd |
number | % | The command. | |
percent_output |
number | % | The output of the actuator. | |
cmd_type |
integer | The type of the active command. |
brake_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
pressure_input |
number | bar | The pressure from the pedal of the driver. | |
pressure_cmd |
number | bar | The command as a pressure. | |
pressure_output |
number | bar | The output of the actuator as a pressure. | |
percent_cmd |
number | % | The command as a percentage. | |
percent_output |
number | % | The output of the actuator as a percentage. | |
cmd_type |
integer | The type of the active command. |
gear_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
gear |
integer | The gear: 1 park, 2 reverse, 3 neutral, 4 high, 5 low. | ||
cmd |
integer | The gear command. | ||
driver |
integer | The position of the gear lever. |
ulc_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
cmd_type |
integer | The type of the active command. | ||
vel_ref |
number | m/s | The speed reference. | |
vel_meas |
number | m/s | The speed that the ULC measures. | |
accel_ref |
number | m/s² | The acceleration reference. | |
accel_meas |
number | m/s² | The measured acceleration. |
vehicle_velocity
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
vehicle_velocity_brake |
number | m/s | The speed from the wheel speed sensors. | |
vehicle_velocity_propulsion |
number | m/s | The speed from the drivetrain. | |
dir_src |
integer | The source of the direction: 1. |
system_report
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
enabled |
boolean | true while the drive-by-wire system is on. |
||
override |
boolean | true after an input of the driver. |
The reports for steering, throttle, brake and ULC also have the keys enabled and timeout.
The reports for steering, throttle and brake also have the key override_active.
timeout is true from 0.1 s to 1 s after the last command of the subsystem.
{"type":"dbw_report","agent":"polaris","t":16.4667,
"steering_report":{"steering_wheel_angle":60.0,"cmd":60.0,
"cmd_type":2,"enabled":true,"override_active":false,
"timeout":false},
"throttle_report":{"percent_input":0.0,
"percent_cmd":34.065,"percent_output":34.065,
"cmd_type":14,"enabled":true,"override_active":false,
"timeout":false},
"brake_report":{"pressure_input":0.0,"pressure_cmd":0.0,
"pressure_output":0.094,"percent_cmd":0.0,
"percent_output":0.117,"cmd_type":1,"enabled":true,
"override_active":false,"timeout":false},
"gear_report":{"gear":5,"cmd":5,"driver":5},
"ulc_report":{"cmd_type":1,"vel_ref":2.0,
"vel_meas":1.8815,"accel_ref":0.0,"accel_meas":0.7373,
"enabled":true,"timeout":false},
"vehicle_velocity":{"vehicle_velocity_brake":1.8815,
"vehicle_velocity_propulsion":1.8951,"dir_src":1},
"system_report":{"enabled":true,"override":false},
"drive_mode":2,"road_wheel_rad":0.06918,
"stop_hold":false}
dbw_client.py#
The file Learning/acres_learn/envs/dbw_client.py is a client for the Polaris. It uses only the standard library.
As a program, it sends the commands at 50 Hz and writes the reports to a CSV file.
At the end it commands a stop for 3 s and then disables the drive-by-wire.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
--port |
integer | 5556 | The port of the vehicle bridge. | |
--host |
string | 127.0.0.1 |
The address of the vehicle bridge. | |
--steps |
path or demo |
A JSON list of timed speeds and steering angles, or the demonstration of the program. | ||
--path |
path | A JSON file with a path that the client follows with curvature commands. | ||
--delay |
number | s | 0 | The time to wait after the connection. |
--log |
path | The CSV file for the reports. | ||
--hud |
string | empty | A status text for the HUD. |
The class Bridge of the file gives the same functions to a Python program.
| Member | Function |
|---|---|
Bridge(host, port) |
Connects to the vehicle bridge. |
Bridge.enable(on) |
Sends dbw.enable or dbw.disable. |
Bridge.command(speed, steer_deg, curvature, gear) |
Sends one ULC command with a steering command and a gear command. |
Bridge.poll(timeout) |
Reads the lines that arrived. |
Bridge.reports, Bridge.obs |
The list of all reports and the last observation. |
import sys, time
sys.path.insert(0, "Learning")
from acres_learn.envs.dbw_client import GEAR, Bridge
bridge = Bridge("127.0.0.1", 5556)
bridge.enable(True)
end = time.time() + 5.0
while time.time() < end:
bridge.command(speed=2.0, steer_deg=12.5, gear=GEAR["L"])
bridge.poll(0.02)
print(len(bridge.reports), "reports")
print(bridge.reports[-1]["ulc_report"])
bridge.enable(False)
The output of the program:
The output of the Python example:
J1939 CAN#
CAN Transport#
The CAN transport carries the observation and the driving action of the Maxxum as SAE J1939 frames. This page gives only the transport. The frames and their signals are on the page Wheel and CAN Signals.
Each frame is the 16 bytes of the Linux structure can_frame: a 4-byte identifier, a 1-byte length, 3 unused bytes and 8 data bytes.
The byte sequence is little-endian. The identifier has 29 bits and the flag 0x80000000 for the extended format.
The bridge ignores frames with an 11-bit identifier, remote frames and error frames.
| Transport | Option | Behaviour |
|---|---|---|
| UDP | -RlCanUdp=<port> |
One frame in each datagram on 127.0.0.1. The game sends its frames to the sender of the last datagram. |
| SocketCAN | -RlCan=<interface> |
Raw frames on the interface. The game sends its frames always. |
The game sends the 13 frames of one observation each 0.1 s of simulation time.
On UDP, the game sends no frame before it receives the first datagram.
The game accepts command frames only from the source address 0x2A.
In lockstep, the game sends the frame 0xFF1E with the step number as the barrier.
import socket, struct
CAN_EFF_FLAG = 0x80000000
udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp.settimeout(1.0)
# Guidance command: curvature 0, steering active.
data = struct.pack("<HB5x", 32128, 0xFD)
frame = struct.pack("<IB3x8s", 0x0CAC802A | CAN_EFF_FLAG, 8, data)
udp.sendto(frame, ("127.0.0.1", 5570))
can_id, length, data = struct.unpack("<IB3x8s", udp.recv(16))
print(hex(can_id & 0x1FFFFFFF), data.hex())
The identifiers of the 13 frames of one observation:
Differences in ACRES Core#
The Core server opens one vehicle bridge for each of its Polaris agents. The option is --rl-ports, and the default port is 5556.
| Item | Game | Core Server |
|---|---|---|
| Vehicles | Maxxum and Polaris. | Polaris only. |
| Commands | All commands of this page. | The drive-by-wire commands of the Polaris and reset. |
| Observation | One line each 0.1 s. | No observation. |
dbw_report |
50 Hz. | 50 Hz, the same format. |
| Barrier | JSON line and CAN frame. | JSON line. |
reset with only yaw_deg |
The vehicle goes to its spawn position with this yaw angle. | The vehicle turns at its position. |
| CAN transport | UDP and SocketCAN. | None. |
| Command timing | Arrival time, and the next step in lockstep. | The same rule. |