Coding and Naming Conventions#
This page gives the rules for the source code, the names, the comments and the UI text of ACRES.
C++ Format#
The file .clang-format in the repository root sets the format. Run clang-format before each commit.
| Rule | Value |
|---|---|
| Braces | Allman. Each brace is on its own line. |
| Indent | 4 spaces. No tabs. |
| Line length | 120 columns. |
| Language standard | C++20. |
| Includes | The tool does not sort them. |
| String literals | Do not divide a long string literal. A search for a log message must find it. |
The markers UCLASS(), GENERATED_BODY() and UPROPERTY() must each be on their own line.
C++ Names#
The names obey the Unreal conventions.
| Item | Rule | Example |
|---|---|---|
| Actor class | Prefix A |
AAcresVehiclePawn |
UObject class |
Prefix U |
UAcresRigComponent |
| Struct or plain class | Prefix F |
FAcresSession |
| Enumeration | Prefix E |
EAcresRenderTier |
| Slate widget | Prefix S |
SAcresMenu |
| Boolean | Prefix b |
bLockstepActive |
| Physical quantity | The unit is a suffix of the name. | MassKg, SpeedMps, RadiusM, PressurePa, DraftKN |
| Unreal position | The suffix Cm |
PositionCm |
The models use SI units. Unreal centimetres appear only where a position enters or leaves the engine. World coordinates in metres use X east and Y south inside the game. Data that the simulator writes for users is ENU or FLU. The ACRE Scene gives the frames.
Engine-Free Models#
Keep the mathematics of a model in a file that uses no Unreal object. The file names end in Model.
ACRES Core and the model tests compile these files with a standard C++ compiler.
The Unreal layer owns the actors, the threads and the rendering. Keep it thin.
| Layer | Files | Rule |
|---|---|---|
| Engine-free model | Acres*Model.h/.cpp, AcresCommandTiming.h, AcresEpisodeLog.h/.cpp, AcresSurfaceMap.h/.cpp |
Standard C++ only. SI units. No Unreal headers. |
| Unreal layer | The other files of Acres/Source/Acres |
Actors, components, threads, rendering, UI. |
| ACRES Core | Core/Source |
Standard C++20. It replaces the Unreal layer for the Polaris. |
Core/CMakeLists.txt lists the model files that ACRES Core compiles. Add a new engine-free file to that list.
The Project Name in Code#
The project name has one form for each context.
| Context | Form | Examples |
|---|---|---|
| Text, UI, titles | ACRES |
"ACRES · Free-Fly Map View" |
| Unreal project, module, folder, packaged game | Acres |
Acres/Acres.uproject, /Script/Acres, Packaged/Linux/Acres.sh |
| C++ types, namespaces, source and shader files | Unreal prefix and Acres |
AAcresVehiclePawn, FAcresSession, AcresSim::, AcresLidar.usf |
| Macros, log tags, environment variables | ACRES_ |
ACRES_API, ACRES_SHELL_READY |
| Python and ROS 2 packages, modules, functions | acres_ |
acres_sim, acres_learn, acres_core |
| File-format identifiers, temporary folders | acres- |
acres-field-setup-1, acres-rig-map |
| Unreal assets | Asset-type prefix and Acres |
MPC_AcresWeather, NS_AcresRain |
A name contains the project name only when it must stay apart from the names of the engine or a library. Local functions, tool scripts and data files do not contain it.
ACRE without the S is the name of the farm. It keeps its spelling: V03ACRE, /Game/ACRE, Tools/ACRE, ACRE_WEATHER.
Folder and File Names#
Folder names are PascalCase, for example Calibration/Polaris/FieldDay and Tools/ImplementModel.
An acronym stays in capitals, for example ROS and Tools/ACRE.
Four types of folder keep a different name because tools or data depend on the name.
| Type | Examples |
|---|---|
| Python and ROS 2 package folders | ROS/acres_sim, ROS/acres_interfaces, Learning/acres_learn and the folders in them (src, launch, msg, test) |
| Third-party code | All folders in ROS/vendor |
| Folders that data names | The soil states in Demo/SoilWeather/Fields, the weather replays in Calibration/Weather/Replay |
| Folders outside the repository | $POLARIS_EPISODES, $POLARIS_LOGS |
File names are lower case with underscores for Python (camera_compare.py) and with hyphens for Markdown pages.
C++ files have the name of their main type without the prefix letter, for example AcresVehicleModel.cpp.
Comments in Headers#
Each public type, function and member in a header has a /// comment in Google style.
The C++ Headers reference comes from these comments.
/// Soil footprint and strength under one tyre.
///
/// Args:
/// WidthM: Tyre width, m.
/// LoadN: Vertical load on the tyre, N.
///
/// Returns:
/// Contact length and area, pressure, sinkage and maximum shear force, all SI.
FSoilContact SoilContact(const FGroundParameters& P, double WidthM, double RadiusM, double LoadN, double Theta);
- Start each header with a
/// @fileblock. State the purpose of the file, its callers and its thread. - Give the unit of each quantity.
- Explain an Unreal idiom the first time it is important in a file.
- Write one comment for members that share a line. Use the form
Name: meaning, unit.for each member. - Use
//comments for private members. They are not in the reference. - In a
.cppfile, explain the reason for the code. Do not describe lines that are clear. - Cite the publication of a physical model in the comment, for example Bekker or ASABE D497.
Python#
- Use the conda environments. Do not use other environment tools.
- Give each module a docstring that states its purpose and its usage line.
- Read paths from the repository root that the script finds from its own location.
- Keep the code free of unused names. The repository is clean under
pyflakes.
| Environment | Use |
|---|---|
torchenv |
General Python, ACRES Core, the learning stack, the map tools. |
ros2 |
ROS 2 Humble from RoboStack. Activation sets the DDS loopback fence. |
acres-docs |
The documentation build. |
Configuration and Data#
- Put each tunable value into a JSON file in
Acres/Content/Simulation. Do not put it into the code. - State the unit in the key name, for example
mass_kg. - The menu reads its settings from one table in
AcresSession.cpp. One row adds one setting. - Log lines, CSV column names, JSON keys, command-line options and message fields are data formats. Do not change their style.
UI Text#
All text that the user reads in the game obeys one style: the HUD, the menu, the messages and the captions.
The tool Tools/ui_text_check.py examines each visible string.
| Text | Rule | Example |
|---|---|---|
| Names of things: titles, tabs, buttons, labels, column headers | Title case with the rules of the documentation headings. | "Warm-up Frames" |
| Sentences: descriptions, help text, messages, HUD values | Sentence case. | "Tractor: maximum power cannot be below rated power." |
| Emphasis | No words in capitals. | "Worker struck", "on", "off" |
| Acronyms and proper nouns | They keep their capitals. | PTO, DBW, LiDAR, Case IH Maxxum 150 |
| Number and unit | SI symbols with a space between the number and the unit. | 7.8 L/h, 22 kN, 15 % |
| Plane angle | No space before the degree sign. | 12.5°, 40°/s |
| Range | An en dash. | 0–100 % |
| Dimensions and factors | The sign "×". | 1920 × 1080 |
| Spelling | Oxford spelling. Agricultural terms follow ASABE. | tyre, centre, optimize, plow |
The same quantity has the same precision in each place of the same type.
| Quantity | Format |
|---|---|
| Ground speed | Whole km/h on the speedometer. One decimal in rows and panels. |
| Engine, PTO and flywheel speed | Whole rpm. |
| Force | One decimal in kN. |
| Power | One decimal in kW in rows. Whole kW in summaries. |
| Fuel | L/h and L/ha with one decimal. Litres used with two decimals. |
| Slip and throttle | One decimal in %. |
| Temperature | Whole °C. |
| Mass | Whole kg. Tonnes with two decimals. |
Git#
- Work on a feature branch. Make one commit for each logical step.
- Write the commit message as one sentence that states the change and its reason.
- Do not commit build outputs, packaged games, session folders or licensed imagery.
- Git LFS stores the assets. The file
.gitattributeslists the LFS types.