Skip to content

Vehicle Handle and Sensors#

The vehicle handle is the control step of one vehicle whose quantities come from outside: the pose, the speed, the rates and the scan. It has no ROS, no ACRES Core batch and no Python. The game link and the ROS 2 Vehicle Node drive it in the simulator. The sensor functions change raw sensor data into the pose and the scan that the control step reads.

Header Content
Runtime/Include/acres_runtime/vehicle.h The handle, the mission, the control step, the skills and the scan of a vehicle
Runtime/Include/acres_runtime/proposal.h The default chunk of the handle
Runtime/Include/acres_runtime/sensors.h The NCOM decoder, the georeference, the pose selector, the scan filter and the crop mask

Handle#

Make the route handle first (acres_runtime_routes_create). The vehicle reads the map and the configuration through it. Keep the route handle until you destroy the vehicle.

Function Use
acres_runtime_vehicle_options_default, acres_runtime_vehicle_inputs_default The default options, and the inputs of a step with no pose and no scan
acres_runtime_vehicle_create, acres_runtime_vehicle_destroy Reads the configuration and the limits of the run, and frees the vehicle
acres_runtime_vehicle_limits The limits of the run after the options
acres_runtime_vehicle_start Plans, checks and starts a mission from a pose
acres_runtime_vehicle_path The prepared path and the plan of the mission
acres_runtime_vehicle_propose Checks the chunks of a model for the next step
acres_runtime_vehicle_step Makes one control step
acres_runtime_vehicle_finding_name, acres_runtime_vehicle_finding_sentence The name and the sentence of a finding
acres_runtime_vehicle_raw_default, acres_runtime_vehicle_inputs_from_raw The inputs of a step from raw vehicle values

The options select the limits of the run: a limits file such as first_test_v1.json, or the limits of a simulator (the speed cap alone). An option can make a limit of the file tighter. A wider value is refused. Each run has the launch hold, the shield and the gear logic.

Mission#

acres_runtime_vehicle_start takes a text and a pose in the map frame.

Text Mission
F56 GoTo, Scout and Return for one field
F53,F12 The same for two or more fields. The planner selects the order.
home A Return alone from the pose
goto:F53 The GoTo alone. The vehicle stops at the entry of the field.
  1. The planner makes the plan on the cost tables of the options.
  2. The plan checker is the gate. A refused plan does not start (refused_plan).
  3. The routes make the path from the pose. The speed cap of the run is the cruise speed.
  4. The limits of the run are the last gate (refused_limit). Each path point must be in the operating area.

A refusal has a code and a sentence. A mission of fields needs the cost tables. Without them, only home can start.

Control Step#

Call acres_runtime_vehicle_step every 0.1 s. Give it the pose, the speed, the rates, the scan with its reason text, the ages and the clock.

  1. With no pose, or a pose older than odom_max_age_s, the step sends nothing and reports odom_stale.
  2. The tracker goes to the pose that the last command gave.
  3. The default driver gives the base command.
  4. The chain runs the launch hold, then the shield, then the gear logic. A scan that is not usable makes the shield stop the vehicle.
  5. The limits of the run decrease the speed. They are the speed cap, the lateral acceleration cap, no reverse, and the operating area.
  6. The checks give the findings. odom_stale, scan, area, mission, driver_error and blocked stop each run.
  7. The record has the drive-by-wire commands: the steering curvature, the ULC speed and the gear command.

When stops is not 0, send a stop and end the run. The step is serial: the proofs fix its order.

Model Hook#

A model gives chunks to acres_runtime_vehicle_propose in the order of its preference. The checker tests each chunk against the corridor of the active leg, the pose and the scan points. The first accepted chunk is the proposal of the chain in the next step. The launch hold, the shield and the gear logic stay after it.

With no accepted chunk, a late chunk, or no checker in the process, the default driver drives. acres_runtime_vehicle_default_chunk (proposal.h) gives the chunk of the default driver as a start value.

Skills#

The vehicle handle has the skills of the skill world: goto, scout, return_home, wait, stop and continue. The two use the same skill server (Runtime/Source/skill_server.h), thus each result code has the same rules.

Function Use
acres_runtime_vehicle_skill_request, acres_runtime_vehicle_skill_request_json Asks for a skill with the inputs of now. The reply is accepted, or refused with the result.
acres_runtime_vehicle_skill_plan_begin, _skill_plan_make, _skill_plan_take, _skill_plan_destroy The request in parts: a second thread makes the plan while the control thread keeps its period.
acres_runtime_vehicle_skill_refuse, acres_runtime_vehicle_skill_abort Refuses a request, or ends the skill that runs.
acres_runtime_vehicle_skill_step One control step of the skills
acres_runtime_vehicle_skill_active, _skill_result, _skill_events, _skill_observe The state, the result, the events and the observation
acres_runtime_vehicle_skill_event_json, _skill_observation_json, _skill_result_json The documents acres-event-1, acres-observation-1 and the result as JSON
  • A driving skill uses the control step of the handle in the same order.
  • Each other step is a stop: speed 0 and the last curvature.
  • blocked: the shield held the vehicle for blocked_s of the limits, or 10 s.
  • stall: the command asks for more than 0.1 m/s, but the speed stays below 0.1 m/s. The shield does not hold the vehicle, and the drive-by-wire is on. After stall_s (default 5 s) the step gives the finding stall.
  • A stop finding ends the skill with failed. The finding area gives refused_limit. A step with no pose gives the event lost_pose.

Rear Rule#

The LiDAR of the Polaris does not see the ground behind the vehicle. The rear rule permits backward motion only on ground that the vehicle drove over in this run. The values are in rear of reverse_test_v1.json.

  • The vehicle moves backward only while the rear edge of its plan box is in a plan box of the trace. slack_m (0.15 m) is permitted at each side.
  • A pose of the trace stays valid for trace_s (60 s). The longest backward stretch is trace_m (10 m).
  • The backward speed is at most speed_cap_mps (0.5 m/s). The vehicle stops stop_m (0.3 m) before the end of the trace.
  • A path can reverse only in the reverse stretch at its start. A path with a three-point turn is refused with refused_limit.
  • When the trace ends, the step gives the finding reverse, and a skill ends with blocked.

kturn_test_v1.json selects the observed-space mode (rear.rule=observed_or_trace). It permits a three-point turn when a grid of observed ground clears the full swept body:

Value Setting
Cell size 0.2 m, with at least three ground returns for a free cell
Veto A return more than 0.05 m above the ground vetoes its cell
Memory 2 s
Margin 0.15 m plus three horizontal standard deviations of the pose
Reverse speed At most 0.5 m/s. The vehicle stops 0.3 m before the known area ends.

acres_runtime_vehicle_observe_free_space takes body-frame ground points. acres_runtime_real_scan_observe_free_space makes them from an organised cloud.

Scan of a Vehicle#

The key connection.real_scan of control_v1.json selects the scan of the obstacle rule. acres_runtime_real_scan_create reads it. The shipped file has no such key, thus the default level_rings applies.

Switch Scan Obstacle Distance
level_rings (default) The returns within 1 degree of the horizontal, the nearest in each bin of 1 degree The eighth-nearest return in the straight corridor ahead of the front
height_band The scan filter of sensors.h with the stale-scan rule The obstacle distance of the shield in the straight corridor at the measured speed

acres_runtime_real_scan_run takes the cloud in the sensor frame, its age and the pose. It gives the 360 ranges, the reason and the obstacle distance (AcresRtRealScanResult). The mount of the LiDAR comes from sensors_polaris.json.

Inputs from Raw Values#

acres_runtime_vehicle_inputs_from_raw fills AcresRtVehicleInputs from AcresRtVehicleRaw:

Raw Value Input
The pose state of the selector, or the odometry pose with its age The pose, the speed, the yaw rate, the pitch, the roll, the pose age, the RTK flag and the sigma
The steering wheel angle in degrees The angle in radians
The gear The gear. With no report the gear is 5.
The four wheel speeds in rad/s The speeds in m/s, from the tyre radius
The result of acres_runtime_real_scan_run, and the cloud age The scan of the shield and the obstacle distance
dbw_enabled, safety_stop, the findings of the caller The same values

The geometry, the tyre radius and the steering come from polaris.json.

Sensor Functions#

Each function that can fail gives a status. acres_runtime_last_error gives the sentence of an error.

Function of sensors.h Result
acres_runtime_ncom_decode The values of one OxTS NCOM packet of 72 bytes
acres_runtime_georef_create, _destroy The georeference handle
acres_runtime_georef_geographic_to_enu, _utm_to_enu, _enu_to_utm, _geographic_to_utm, _utm_pose_to_enu Conversions between latitude and longitude, UTM 16N and the map grid
acres_runtime_decimal_year The epoch of a time in Unix seconds
acres_runtime_pose_from_odom, acres_runtime_pose_from_ncom The pose from /vehicle/odom values, or from one decoded packet
acres_runtime_pose_limits_default The default limits of the pose
acres_runtime_pose_selector_create, _destroy, _update, _select, _counts, _fix_state The pose source (/vehicle/odom, OxTS packets or auto) with its validity and reasons
acres_runtime_pose_reason_name, acres_runtime_rtk_name The text of a reason and of a receiver mode
acres_runtime_scan_filter_create, _destroy, _shape, _blind, _crop_mask The scan filter from the configuration
acres_runtime_scan_filter_run, _batch The 360 ranges and the reason of one sweep, or of many sweeps
acres_runtime_shield_scan The scan of one control step: no cloud, a stale cloud, or the filter scan
acres_runtime_scan_reason_name The text of a scan reason
acres_runtime_crop_mask_create, _destroy, _fields, _ground_class, _height, _drop The map mask of standing crop
acres_runtime_scan_filter_run_crop One sweep with the crop mask at a pose
acres_runtime_scan_filter_value_count, _value_at, _set_value, _mount, _body_mask, _crop_kind, _points The values of the filter, the mount, the body mask, and the points of the last sweep
acres_runtime_sweep_points, acres_runtime_sweep_along, acres_runtime_shield_scan_step Planar-scan returns in the body frame, points along an arc, and the shield sequence of one step

A cloud is the structure AcresRtCloud: pointers to x, y and z with a stride in bytes, 1800 columns and 32 rings. The library reads the data of a sensor_msgs/PointCloud2 message with no copy. A scan that is not usable has NaN in each beam, and the shield then stops the vehicle.

Crop Mask#

The mask drops a point of the height band that is in standing crop of the map. It drops a point when each of these conditions is true:

  • The point is in the crop class of the ground-class raster, at least crop_inner_margin_m inside the edge of that class.
  • The point is inside the outline of a field whose crop kind is in the table crop_heights_m.
  • The point is lower than the height of that crop plus crop_height_margin_m.

The switch crop_mask of scan_filter_v1.json is off.

Python Classes#

The module _acres_runtime has the same functions as the classes Georef, PoseSelector, ScanFilter, CropMask and ShieldTools. The module acres_simulator.scan gives three of them to the tools:

Class of acres_simulator.scan Members
ScanFilter(config, check_control) Call it with a sweep (columns, rings, 3) to get the planar scan of the shield. cfg, blind, body_mask, set_values(**values)
CropMask(filter, content) ground_class, crop_height, drop, and the property fields
Shield(config) shield_scan, and the shield and corridor parameters as attributes

The class acres_simulator.vehicle.Vehicle is the Python form of the handle:

from acres_simulator.vehicle import Vehicle

vehicle = Vehicle(tables="<costs>/dry.npz", limits="first_test")
answer = vehicle.start("F56", pose=(east, north, yaw))
record = vehicle.step({"now_s": t, "pose": (east, north, yaw), "speed_mps": v,
                       "yaw_rate_radps": r, "shield_ranges": ranges,
                       "lidar_age_s": 0.05, "rtk_fixed": True})
record["dbw"]      # the commands, or None: send nothing
record["stops"]    # the findings that stop the run