Add a Vehicle#
This page gives the procedure to add a vehicle to the game and to ACRES Core. The procedure follows the steps that added the Polaris.
Before You Start#
- Build the game, ACRES Core and the ROS 2 workspace. Refer to Build the Game, Build ACRES Core and Build the ROS 2 Workspace.
- Read Polaris Ranger Dynamics and Architecture.
- Read the Coding and Naming Conventions and Unreal for C++ Developers.
- Collect the data of the real vehicle: dimensions, masses, powertrain data, tyre sizes and, if possible, recorded logs.
The game has two vehicles: the Maxxum and the Polaris. They use one pawn class, AAcresVehiclePawn.
The Polaris is the pattern for a new vehicle, because the project added it to a game that had only the Maxxum.
What a Vehicle Needs#
A vehicle has ten parts. The table gives each part with its Polaris example.
| Part | Function | Polaris Example |
|---|---|---|
| Engine-free model | The dynamics and the control interface in C++ without Unreal types | Acres/Source/Acres/AcresUtvModel.h and .cpp |
| Parameters file | Each parameter with its value and its source | Acres/Content/Simulation/polaris.json |
| Pawn branch | Connects the model to the Chaos body, the ground traces and the farm | AcresPolaris.cpp and the bUtv branches of AcresVehicle.cpp |
| Equipment rig | The skeletal mesh and its controls | Acres/Raw/farm-equipment/polaris/, Acres/Content/Simulation/rigs/polaris.json |
| Sensor rig overlay | The sensors of the vehicle with their mounting poses | Acres/Content/Simulation/sensors_polaris.json |
| Agents entry | The vehicle kind for -Vehicle=, -Vehicles= and -Agents= |
AcresAgents.cpp |
| Bridge messages | Commands and reports on the vehicle bridge and in ROS 2 | AcresRlBridge.cpp, ROS/acres_sim, ROS/acres_description |
| Core support | The same model on a rigid chassis without Unreal | Core/Source/AcresCorePolaris.h and .cpp |
| Tests | Model checks and replay of recorded logs | Tools/PolarisModel/, Core/Tests/ |
| Documentation | Model page, tutorial and reference entries | Polaris Ranger Dynamics |
Do the parts in this sequence. The engine-free model and its tests come first, because all other parts depend on them.
Write the Engine-Free Model#
An engine-free model is a C++ file that uses no Unreal types. The game, ACRES Core and the test tools compile the same file. The Polaris model uses the wheel, soil and energy functions of the Maxxum model again. It adds only the parts that are different.
| Model Part | Maxxum Function That the Polaris Uses | Polaris Function |
|---|---|---|
| Wheel contact on soil and hard ground | PrepareWheel |
PrepareUtvWheel |
| Wheel speeds and driveline | AxleCarrierTorqueNm, RisingRoot, SettleWheels |
SolveUtvDriveline |
| Energy ledger | FEnergyFlows, AccountChassis |
Same structure |
| Engine, CVT, gearbox, brakes | StepUtvPowertrain |
|
| Steering | StepUtvSteering |
|
| Drive-by-wire actuators and ULC | StepDbw |
|
| Parameters | SetUtvParameter, FinalizeUtvParameters |
|
| Reset | ResetUtv |
-
Make
Acres/Source/Acres/Acres<Name>Model.hand.cppin the namespaceAcresSim. -
Define a parameter structure, a state structure and a command structure.
-
Use the shared functions of
AcresVehicleModel.hfor the tyres, the soil and the energy ledger. -
Write a function that sets one parameter from a key and a value, such as
SetUtvParameter.The game, ACRES Core and the tools then read the parameters file through the same function.
-
Write a function that derives the dependent values, such as
FinalizeUtvParameters. -
Write the step functions. Keep the sequence of one physics step explicit.
The Polaris sequence is
StepDbw,StepUtvSteering,StepUtvPowertrain,PrepareUtvWheelfor each wheel andSolveUtvDriveline. -
Write the header comments in the format of Write Documentation. The reference pages come from these comments.
Obey these rules.
- Use SI units, and put the unit in each name, for example
MassKg. - Cite the publication or the data source of each sub-model in a comment.
- Give helper functions in an anonymous namespace a prefix. The unity build of Unreal joins the model files.
- Do not allocate memory in a step function.
- If the real vehicle has a control interface, model that interface with its message names and units.
Write the Parameters File#
The parameters file is Acres/Content/Simulation/<name>.json. In polaris.json, each parameter is an object with its source.
"wheelbase_m": {"value": 2.8702, "basis": "oem", "source": "owner_manual; product_page", "sd": 0.01}
| Key | Content |
|---|---|
value |
The number, the boolean or the array that the model reads. |
basis |
The type of the source: oem, dataspeed, fitted, installed, derived or estimate. |
source |
The document or the log of the value. |
sd, range, note |
The uncertainty and a remark. |
The model reads only value. The loader reads each value with its dotted path as the key, for example geometry.wheelbase_m. An array element has an index, for example engine.torque_curve_rpm[3].
The game writes ACRES_POLARIS_UNUSED_KEY to the log for each key that the model does not know.
-
Write the file with one block for each sub-model.
-
Give each value its basis and its source. Do not put a number without a source in the file.
-
Add an option for a different file and an option for single keys, such as
-PolarisConfig=and-PolarisSet=. -
Fit the parameters that no document gives to recorded logs. Refer to Calibrate against Real Logs.
Add the Tests of the Model#
Write the tests before the pawn branch. The tools compile the model with a standard compiler in some seconds.
-
Make a folder
Tools/<Name>Modelwith a test program and abuild.sh.Tools/PolarisModelis the pattern:polaris_tests.cppcontains the checks, andUtvBench.his a small test bench with a flat reader for the parameters file. -
Test each sub-model: limits, signs, conservation of energy and the results at different time steps.
-
If you have logs of the real vehicle, add extracts and a replay program.
Tools/PolarisModel/Datacontains the extracts.polaris_replay.cppreplays their commands through the model, andpolaris_dbw.pyfits the parameters. -
Build and run the tests.
-
Add the command to Tests and Regression Checklist.
WARNING
Do not connect a test tool to the real vehicle. Use only recorded logs. A command on the real drive-by-wire can move the vehicle.
Add the Pawn Branch#
AAcresVehiclePawn does the work that is the same for all vehicles.
This work includes the ground traces of the wheels, the soil below each wheel and the forces on the Chaos body.
It also includes the farm marks, the sensors and the logs.
A vehicle adds a flag and the functions that are different. The Polaris flag is bUtv, and its functions are in AcresPolaris.cpp.
| Function | Thread | Content |
|---|---|---|
LoadPolarisConfiguration |
Game | Reads the parameters file and the options. Copies the wheel parameters to the shared Parameters. |
ResetPolaris |
Physics | Resets the model state for a start speed. |
StepPolarisControls |
Physics | Takes the commands from the queue and steps the control interface, the steering and the powertrain. |
PublishPolaris |
Physics | Fills the telemetry and the reports of the control interface. |
FlushDbwReports |
Game | Sends the reports to the vehicle bridge and writes dbw.csv. |
CreatePolarisVisuals |
Game | Adds the colliders and loads the equipment rig. |
UpdatePolarisRig |
Game | Sets the rig controls from the telemetry. |
ReadPolarisKeys, StepPolarisKeys |
Game, physics | The keyboard as the driver of the vehicle. |
-
Add a flag for the vehicle to
AAcresVehiclePawnand set it inLoadConfigurationfrom the agent. -
Add a new source file for the functions of the vehicle. Do not make
AcresVehicle.cpplarger. -
Load the parameters. Copy the wheel layout, the mass and the inertia to the values that the shared code reads.
The Polaris keeps the ground of the session.
LoadPolarisConfigurationcopies the soil block oftractor.jsoninto its wheel parameters. -
Branch in
AsyncPhysicsTickActor: step the controls, prepare each wheel and solve the driveline with the functions of the new model. -
Set the collision shapes, the spawn box in
SpawnHalfExtentCmand the camera positions. -
Publish the telemetry of the vehicle and add its columns to the session log.
-
Add the keyboard controls and the HUD items: the card, the key help and the vehicle label in
VehicleLabel.
The physics step runs on the physics thread, and the keyboard and the rig run on the game thread.
Send commands to the physics thread through a queue with an apply time, as PostDbw does. Read the state under StateMutex.
Add the Equipment Rig#
The equipment rig comes from a Blender file through the same tools as an implement. Add an Implement gives the commands.
-
Put the Blender file, the FBX file and the vehicle data in
Acres/Raw/farm-equipment/<name>/.The Polaris folder also contains
vehicle-parameters.json,sensor-evidence.jsonandrecorded-calibration.json. -
Put the origin of the rig at the middle of the rear axle on the ground. Use the FLU frame in metres.
-
Add the asset to the export tool and the import tool in
Tools/ACRE/Vehicles.The four Polaris finishes share one mesh. The rig map lists them as material variants, and
LoadRigtakes the variant name. -
Run the export, the import and the option
-RigSelfTest. -
Load the rig in the visuals function. Compare the wheel centres of the rig with those of the physics.
-
Set the rig controls from the telemetry in each frame: steering, wheel roll, suspension travel and pedals.
Add the Sensor Rig Overlay#
The file sensors.json gives the default sensors. A vehicle with its own sensors has an overlay file that replaces some values.
sensors_polaris.json contains the mounting poses and the models of the Polaris sensors in the frame base_footprint.
-
Write
Acres/Content/Simulation/sensors_<name>.jsonwith only the keys that are different fromsensors.json. -
Load the overlay for the vehicle in
BeginPlay, and add an option for a different file, such as-PolarisSensorConfig=. -
Give the overlay a
profilename. The recordings store it as the sensor profile.
Add a Sensor describes the sensor code.
Add the Agents Entry#
AcresAgents.cpp reads the vehicles of a session. Each agent has a vehicle kind.
-
Add the name of the vehicle and its aliases to the function that normalises the vehicle kind in
AcresAgents.cpp. -
Add the name to the three error messages that list the vehicle kinds.
-
Add the keys of the vehicle to the table in
AcresAgents.h, such asfinishfor the Polaris. -
Add the vehicle to the menu choice
flag:vehicleand to the command line of the session inAcresSession.cpp.Expected Result
The game starts with
-VehicleDemo -Vehicle=<name>. A session with-Vehicles=maxxum,<name>has two agents, and F2 changes the vehicle.
Add the Bridge Messages#
A client controls a vehicle through the vehicle bridge. Each observation contains the keys agent and vehicle.
The Polaris uses the message names, the fields and the units of the Dataspeed drive-by-wire.
The ROS 2 bridge thus converts each message one to one.
-
Add the vehicle name to the observation in
AcresRlBridge.cpp. -
Add the command messages of the vehicle. Refuse them with a warning on a different vehicle.
-
Add the report messages at the rate of the real vehicle.
-
Add the vehicle to the sensor stream greeting in
BeginPlay. -
Add the topics to the ROS 2 bridge in
ROS/acres_sim, and a URDF toROS/acres_description. -
Use the timeouts of the real interface. A subsystem of the Polaris stops 0.1 s after its last command.
Add a ROS 2 Interface gives the procedure for the ROS 2 packages. The Vehicle Bridge reference lists the messages.
Add ACRES Core Support#
ACRES Core runs the same model without Unreal. Core/CMakeLists.txt compiles the model files of the game and the files in Core/Source.
FAcresPolaris does in plain C++ what the pawn does with Chaos.
It computes the wheel traces against the terrain, the forces, the farm stamps and the step of the rigid chassis.
-
Add the model source file to
ACRES_MODEL_SOURCESinCore/CMakeLists.txt. -
Write
Core/Source/AcresCore<Name>.hand.cppwith a class that hasInit,ResetandStep. -
Load the parameters file with the same key function as the game, as
LoadPolarisParametersdoes. -
Use the same sequence in
Stepas the pawn uses in the physics step. -
Add the vehicle to the batch class in
AcresCoreBatch.hand to the Python module inCore/Python/acres_core_module.cpp. -
Add tests in
Core/Tests, then build and run. -
Compare ACRES Core with the game for the same commands.
Core/Scripts/compare_unreal.pydoes this comparison for the Polaris.
Note
ACRES Core supports only the Polaris. The Maxxum and its implements run only in the game.
Update the Documentation#
-
Add a model page in
Documentation/Modelswith the full mathematics of the vehicle. -
Add a tutorial in
Documentation/Tutorialsfor the keyboard and the control interface. -
Add the options, the bridge messages, the topics and the file formats to the reference pages.
-
Do the checks of Write Documentation.
Checklist#
| Check | Command or Condition |
|---|---|
| Model tests pass | Tools/<Name>Model/build.sh has the exit code 0. |
| Portability | The same script with UE_CLANG= passes. |
| Rig | -RigSelfTest reports PASS for the rig. The layout line reports a wheel centre error near zero. |
| Session | -VehicleDemo -Vehicle=<name> starts and the vehicle drives. |
| Two vehicles | -Vehicles=maxxum,<name> starts and each agent has its own output folder. |
| Bridge | A client receives observations and reports, and the vehicle obeys its commands. |
| Core | Core/build.sh passes, and the comparison with the game agrees. |
| Documentation | The site builds in strict mode. |