AcresFarmRuntime.h#
Acres/Source/Acres/AcresFarmRuntime.h Generated
The live farm: crops, soil water, ruts and the harvester, wired into the Unreal world.
FAcresFarmRuntime connects the pure maths in AcresFarmModel.h to the ACRE map. It reads farm.json and the ACRE rasters from Content/Simulation, finds the planted crop patches in the level, runs the terrain-routed water grid (382 x 382 cells of 4 m, plus a 0.25 m wheel sub-grid where wheels have passed) on its own worker thread, and answers the vehicle's questions: how wet and how rutted is the ground under this wheel, what did this tyre crush, what did the header cut.
Threads: - Physics thread (AcresVehicle's 120 Hz AsyncPhysicsTickActor, Unreal's fixed-step physics callback): calls Advance, Sample, Wheel, Cut, AddMud while holding Mutex. - Game thread (the main thread, where Unreal's per-frame Tick runs): calls Initialize, UpdateVisuals, Status, Replant, Save/Load/Export. - "AcresWater" worker thread: steps the water grid and publishes triple-buffered snapshots that the other threads read without locking (Water()).
Coordinates are Unreal world metres (Unreal itself works in centimetres; callers divide by 100): X east, Y south, Z up, origin at the centre of the 1524 m ACRE tile. Unreal container types used below: TArray (std::vector), TMap (std::unordered_map), TSet (std::unordered_set), FIntPoint (int x, y pair), FString (string), TSharedPtr / TUniquePtr (shared_ptr / unique_ptr), FCriticalSection (a recursive mutex).
FAcresCropProxy#
Snapshot of one crop patch for the LiDAR (sensor-only, never affects forces).
A patch is one authored 1.52 m x 1 m block of plants with 4 x 4 crush/harvest sample bits (see AcresFarm::CropState).
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
X, Y, Z, HeightM, Growth |
float |
X, Y, Z: patch origin in world metres. HeightM: full-grown plant height of the patch mesh, m. Growth: growth fraction 0..1 of the patch's field. | ||
Crushed, Harvested |
uint16 |
Crushed, Harvested: 16-bit sample masks, bit (J * 4 + I). | ||
Kind |
uint8 |
0 |
Crop kind (AcresCrops): 0 corn, 1 soybean, 2 potato. |
FAcresWorkDetail#
What one tool pass leaves in the cells it marks (FAcresFarmRuntime::Work), from the implement's physical state: the pawn fills it each step (AcresFieldWorkModel.h has the models). Lateral positions are along the pass's right-hand axis (Unreal Y for a pass heading +X), measured from the strip centre, m.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
TillPattern |
AcresSim::ETillagePattern |
Tillage: pattern (AcresSim::ETillagePattern; None for the drill and the sprayer), working depth, m, and the seedbed it leaves (ridge, clods, bulking rise, saturation of the turned soil). | ||
ToolSpacingM |
double |
m | .3 |
Tine spacing, or the packer's ring spacing for the disc harrow, m. |
ToolOriginM |
double |
m | 0 |
Lateral position of the first tine or ring, m. |
GrooveM |
double |
m | 0 |
Packer ring groove depth (the roller's sinkage), m. |
RowSpacingM, RowOriginM, PressSinkageM, SowingDepthM |
double |
Drill: row spacing, lateral position of the first row, press wheel sinkage and sowing depth, m. | ||
SprayM3M2 |
double |
0 |
Sprayer: liquid applied, m3/m2. |
FAcresBaleRecord#
A bale left on the field (the square baler's or a round bale the loader put down), for the save.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
Kind |
uint8 |
0 |
Kind: 0 round (loader), 1 square (baler). | |
PositionM |
FVector |
m | FVector::ZeroVector |
PositionM: centre, world m. Rotation: orientation. MassKg: bale mass, kg. |
FAcresWaterSnapshot#
Published state of the terrain-routed water grid (382 x 382 cells, 4 m).
The water worker thread fills one of three buffers and then flips an index, so readers always see a complete snapshot without taking a lock. Per-cell arrays are row-major, index V * W + U, with the cell origin at -762.0015 m on both axes (same layout as ACRE/field-grid.json).
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
W |
int |
0 |
Cells per side (382 in the shipped data; 0 until the first publish). | |
ClockS |
double |
s | 0 |
Water-grid environment time, s. |
MaxPondM |
double |
m | 0 |
Deepest pond on the grid, m. |
MeanPondM |
double |
m | 0 |
Mean pond depth over all cells, m. |
BacklogS |
double |
s | 0 |
Environment seconds requested but not yet simulated (the water lags the game by this much), s. |
Theta |
TArray<float> |
Surface-layer water content, m3/m3. | ||
PondM |
TArray<float> |
m | Pond depth, m. | |
Wetness |
TArray<float> |
0..1, (theta - antecedent) / (saturated - antecedent), clamped; 0 = as dry as at the start, 1 = saturated. | ||
Look |
TArray<float> |
Per cell, for the ground's look only (never the tyres): how wet the surface appears, 0..1, the larger of Wetness and the layer's free water above field capacity, (theta - fc) / (saturated - fc). A field that starts saturated looks wet although its Wetness (the change since the start) is 0. | ||
FieldTheta, FieldPond |
double |
Mean surface theta (m3/m3) and mean pond depth (m) per field id: 1-59 fields, 60 asphalt, 61 concrete, 62 gravel, 0 everything else. | ||
TotalRainM, TotalPondM, TotalStorageM, TotalEvapM, TotalDrainM, TotalTileM, ResidualM |
double |
Grid-mean cumulative ledgers, m of water: rain, current pond, storage change (both layers), evaporation, deep drainage, tile drainage. ResidualM: mean absolute per-cell mass-balance error, m. | ||
bValid |
bool |
false |
False until the first publish; readers fall back to defaults while false. | |
FineDiv |
int |
0 |
Wheel sub-grid (AcresFarm::WaterGrid::FineTile), published for the cells wheels have crossed. FineDiv: sub-cells per side of a tile (16, i.e. 0.25 m; 0 before the first publish). Sub-cell K of a tile is K = J * FineDiv + I, I along +X and J along +Y from the cell's corner. | |
FineCell |
TArray<int32> |
Parent cell index of each published tile, ascending (FineIndex binary-searches it). | ||
FineLevel |
TArray<float> |
Pond water level relative to the unrutted bed, m; the local pond depth over a sub-cell with rut depth r is max(0, level + r), and those depths average to the cell's PondM exactly. | ||
FineWetScale |
TArray<float> |
1 / (saturated - antecedent theta), turns a theta anomaly into a wetness anomaly. | ||
FineTheta |
TArray<float> |
Per tile, FineDiv * FineDiv surface theta anomalies relative to the cell's Theta, m3/m3 (zero mean per tile), tile after tile in FineCell order. |
FAcresWaterSnapshot::FineIndex#
Published tile of a cell.
| Argument | Description |
|---|---|
Cell |
Cell index, V * W + U. |
Returns: Index into FineCell (and FineLevel, FineWetScale, FineTheta / FineDiv^2), or -1 without a tile.
FAcresWaterSnapshot::LevelAt#
Water level of a cell relative to its unrutted bed, m: the tile's FineLevel, or PondM without a tile.
| Argument | Description |
|---|---|
Cell |
Cell index, V * W + U. |
Returns: Level, m (negative when the cell's water stands only in its ruts).
FAcresFarmRuntime#
Farm state shared by the tractor and its trailer: crops, soil water, ruts, harvester and bunker.
AAcresVehiclePawn creates one with MakeShared, calls Initialize() on the game thread at BeginPlay (the callback Unreal runs when an actor enters the world), then drives it every physics step. All numeric methods and public fields need Mutex held; only Initialize and UpdateVisuals touch Unreal objects (UObjects, the garbage-collected engine objects), and only on the game thread. The water grid advances on its own worker thread and publishes snapshots; Water() reads them lock-free.
Command-line switches read by Initialize (Unreal passes "-Name=value" arguments): -FarmRain=, -FarmTimeScale=, -FarmMinC=, -FarmMaxC=, -FarmEvap=, -FarmHarvester, -FarmHarvestOn, -FarmInitialTheta=, -FarmKsatScale=, -FarmInitialGrowth=, -FarmLoad=, -FarmPreDays=, -nullrhi (no rendering, so no visuals).
Example
Farm = MakeShared<FAcresFarmRuntime>();
Farm->Initialize(GetWorld(), 20, 12); // 20 mm of rain over the 12 h before start
// physics thread, every 1/120 s:
FScopeLock Lock(&Farm->Mutex);
Farm->Advance(Dt);
Farm->Sample(ContactM.X, ContactM.Y, Surface);
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
Mutex |
FCriticalSection |
Guards every field and method below except Water(). FScopeLock L(&Mutex) holds it for a scope. | ||
SessionYear, SessionMonth, SessionDay |
int |
Local date of the session (the environment clock), set before Initialize: -CropStage=date grows each field of the crop season from its planting date to this day. 0 = unknown. | ||
bLoadedAtStart |
bool |
false |
True when the farm began from a saved state (-FarmLoad=, or a replayed session's farm-start-state.json); the pawn then writes that start state into the new session's folder, so a replay of this session starts the same way. | |
WorkTilled, WorkSeeded, WorkSprayed |
static constexpr uint8 |
Field work flag bits in Worked. | ||
Worked |
TMap<FIntPoint, uint8> |
Field work per 25 cm cell (same keys as Ruts): WorkTilled / WorkSeeded / WorkSprayed bits. They last for the simulation (RL and R-key resets keep them), are saved by Save and restored by Load; only RestoreField (an RL reset that asks for it) clears a field's marks. | ||
double WorkedM2[3][60] = {}; |
double WorkedM2[3][60] |
Area marked per field bucket (0 outside fields, 1..59 fields), m2: [0] tilled, [1] seeded, [2] sprayed. Written to farm-fields.csv. | ||
FieldCells |
TMap<FIntPoint, FAcresFieldCell> |
What field work left in each 25 cm cell (same keys as Ruts): the visible trace of tillage, drilling, spraying, tyre prints and backhoe spoil, drawn by FAcresSoilVisuals. Saved and restored with the session (schema 4). | ||
Relief |
TMap<FIntPoint, float> |
Pits (negative) and spoil (positive) relative to the original surface per 25 cm cell, m (Dig, Spoil, ReliefAt). | ||
Bales |
TArray<FAcresBaleRecord> |
Bales on the field, written by the pawns that own them before a save (the pawns' physics bodies are the live state); a loaded save's bales are spawned again by the pawn. | ||
Ruts |
TMap<FIntPoint, double> |
Rut depth per 25 cm cell, m, keyed by (floor(X / 0.25 m), floor(Y / 0.25 m)). Wheels and the backhoe only deepen them and tillage (Work) levels them; they persist for the session and are saved. | ||
HasHarvester |
bool |
false |
Header fitted (-FarmHarvester). | |
HarvestEnabled |
bool |
false |
Header switched on (H key or -FarmHarvestOn). | |
bDigger |
bool |
false |
True when the harvester is the potato digger: it lifts only potato; the grain cutter skips potato. | |
TimeScale |
double |
1 |
Environment seconds per game second. | |
RainMmH |
double |
0 |
Rain rate, mm/h. MinC, | |
MinC |
double |
°C | 16 |
See above. |
MaxC |
double |
°C | 28 |
Daily minimum and maximum temperature, deg C. |
EvapMmDay |
double |
2 |
Potential evaporation, mm/day. AcresVehicle overwrites these from the environment model every physics step when one exists. | |
SurfaceFilm |
double |
0 |
Rain film on the ground surface, 0..1 (AcresEnv::State::SurfaceWetness: the weather model's 0.3 mm interception store over its capacity). Set by AcresVehicle with the weather above; Sample uses it on soil. | |
ClockS |
double |
s | 0 |
Farm environment time since start, s. |
HarvestKg |
double |
kg | 0 |
Total grain harvested, kg. |
BunkerKg |
double |
kg | 0 |
Grain in the bunker now, kg. |
UnloadedKg |
double |
kg | 0 |
Grain unloaded so far, kg (HarvestKg = BunkerKg + UnloadedKg). |
CrushedM2 |
double |
0 |
Crop area crushed by wheels, m2. | |
HeaderWidthM |
double |
m | 3 |
Cut width, m. HeaderOffsetXM, |
HeaderOffsetXM |
double |
-3.2 |
See above. | |
HeaderOffsetYM |
double |
2.5 |
Header centre relative to the tractor in its local frame, m. | |
HeaderPtoKW |
double |
kW | 35 |
Power the header draws from the PTO, kW. |
BunkerCapacityKg |
double |
kg | 600 |
Bunker size, kg. |
bLogEvents |
bool |
false |
Episode-log capture: while bLogEvents is set, Stamp (crop), Wheel (ruts, in 5 mm steps), Work (new flags) and RestoreFieldId append what they changed to LogEvents, tagged with LogStepKey and LogAgent, which each pawn sets when it takes Mutex for its physics step. Mutex held for all of them. | |
LogStamps |
TArray<FLogStamp> |
Wheel and Body calls while bLogEvents is set; LogWheel is the wheel index the pawn sets before each Wheel call. |
FAcresFarmRuntime::~FAcresFarmRuntime#
Stops and joins the water worker thread.
FAcresFarmRuntime::Initialize#
Load the farm and start the water thread. Game thread only, once.
Reads farm.json, ACRE/field-grid.json, field_ids.u8, cover.u8, soil_units.u8, soils.json and heights.f32 (crashes via check() if any is missing or malformed), applies command-line overrides and the menu's field setup (soil overrides, starting wetness, crop swaps, terrain edits), builds the water grid, replaces each crop HISM (hierarchical instanced static mesh: one component drawing thousands of copies of one mesh) with a movable ISM so patches can be squashed individually, optionally loads a save (-FarmLoad=), pre-runs -FarmPreDays= days and the prior rain, then starts the worker and the soil visuals.
| Argument | Description |
|---|---|
World |
The level holding the ACRE crop actors (tagged with a crop name, "corn"/"soybean"/"potato", and "Fxx"). |
PriorRainMm |
Rain assumed to have fallen before the start, mm. 0 skips the pre-run. |
PriorRainHours |
Hours over which PriorRainMm is spread evenly, h. |
Note
The pre-runs advance ClockS and crop degree days too; the session starts after them.
FAcresFarmRuntime::Advance#
Advance farm time by one physics step. Physics thread, Mutex held.
Scales Dt by TimeScale into environment seconds, hands them to the water thread, and grows crops in 10 s environment chunks: degree days times a water-stress factor from the field's mean theta and ponding. Appends an hourly row to the weather timeline.
| Argument | Description |
|---|---|
PhysicsDt |
Physics step, s of game time. |
FAcresFarmRuntime::Sample#
Fill the soil-water and rut fields of a wheel's surface sample. Physics thread, Mutex held.
Resolved at the tyre's scale, not the 4 m cell's: the cell fields are interpolated bilinearly between the four nearest cell centres (soil cells only, for theta and wetness), then the 0.25 m wheel sub-grid adds its detail where wheels have passed. WaterDepthM is the local pond depth, max(0, level + rut depth), so water stands in a rut and not on the ridge beside it when the cell's pond fits in its ruts. On soil (Surface.Soil true) Theta and Wetness add the sub-grid's moisture anomaly (bilinear between 0.25 m sub-cell centres: wet rut bottoms, drier compacted tracks), and RutDepthM comes from the 25 cm rut map. On soil Wetness is also at least the rain film (SurfaceFilm) and the local pond depth over 2 mm: the raindrop-wetted or ponded surface slicks the tread-soil interface before the 0.3 m layer's theta has risen (Wong 2008 Table 1.3, dry against wet earth). On a hard surface Wetness is the pond depth over 2 mm, clamped to 1. Water values are untouched outside the grid or before the first snapshot.
| Argument | Description |
|---|---|
X |
World X, m. |
Y |
World Y, m. |
Surface |
Wheel input, updated in place. Soil must already be set by the caller. |
FAcresFarmRuntime::Wheel#
Apply one tyre contact: crush crops, deepen ruts, compact soil. Physics thread, Mutex held.
Crops under the Width x Length rectangle are crushed if the contact pressure exceeds 10 kPa and the field is past 2 % growth. With Sinkage > 0 the 25 cm rut cells under the footprint deepen to min(0.35 m, 0.65 * Sinkage) (never shallower). Each deepened rut cell is sent to the water grid's wheel sub-grid with its rut depth and compaction min(1, rut / 0.065 m) (= min(1, Sinkage / 0.1 m)), so the 4 m cell's infiltration drops by the compacted share of its area and its ruts store ponded water.
| Argument | Description |
|---|---|
X |
Contact point X, m. |
Y |
Contact point Y, m. |
Z |
Contact point Z, m (patches more than 1 m above or below are ignored). |
ForwardX |
X component of the unit heading along the ground. |
ForwardY |
Y component of the unit heading along the ground. |
Width |
Footprint width across travel, m. |
Length |
Footprint length along travel, m. |
Pressure |
Mean contact pressure, Pa. |
Sinkage |
Tyre sinkage, m (0 on hard surfaces). |
TyreDiameterM |
Tyre diameter, m; with more than 5 mm of sinkage the footprint's cells also record the tread print (AcresSim::TreadPrintDepthM, lug pitch, heading and each cell's place across the tyre). 0 leaves no print. |
FAcresFarmRuntime::Body#
Push over the crop the machine's body and front axle ride through. Physics thread, Mutex held.
Tyres crush only their own tracks (Wheel); a tractor driven through corn also bends every stalk taller than the underbody across its full width. Plants shorter than ClearanceM pass under the body (soybean, potato, young corn) and are left alone.
| Argument | Description |
|---|---|
Width |
Body width across travel, m (outer tyre edge to outer tyre edge). |
Length |
Footprint length along travel this step, m (body length plus distance moved). |
ClearanceM |
Underbody / front axle clearance, m. |
FAcresFarmRuntime::Cut#
Run the harvester header over the crop. Physics thread, Mutex held.
Does nothing unless a harvester is fitted and switched on, engine speed is at least 1200 rpm, ground speed is 0.05-4 m/s and the bunker has room. Otherwise harvests mature samples under a HeaderWidthM x 0.8 m rectangle into the bunker.
| Argument | Description |
|---|---|
X |
Header centre X, m. |
Y |
Header centre Y, m. |
Z |
Header centre Z, m. |
ForwardX |
X component of the tractor heading. |
ForwardY |
Y component of the tractor heading. |
Speed |
Forward ground speed, m/s. |
Rpm |
Engine speed, rev/min. |
Returns: Grain added to the bunker this call, kg.
FAcresFarmRuntime::UpdateVisuals#
Push crop, rut, water and mud changes to the renderer. Game thread; takes Mutex itself.
Copies the rut map, dirty rut tiles and queued mud under the lock, ticks FAcresSoilVisuals outside it, then rescales at most 1024 changed crop instances per call (the rest wait for the next frame; all of them under simulator control, so lockstep sensor samples do not depend on the frame count).
| Argument | Description |
|---|---|
PhysicsTime |
Current simulation time, s (used for the visual time step, capped at 0.1 s). |
VehicleM |
Tractor position in world metres (tiles and effects are built around it). |
FAcresFarmRuntime::ReleaseVisuals#
Drop the soil visuals (and the material instances they keep alive). Game thread; takes Mutex itself.
Call from EndPlay: the visuals hold strong references into the world, and the owning pawn is only destroyed after the garbage collection that must free the old world on a level change.
FAcresFarmRuntime::AddMud#
Queue one cosmetic particle (mud clod, dust puff or water drop) for the next UpdateVisuals. Physics thread, Mutex held.
Ignored when there are no visuals (-nullrhi) or 512 particles are already queued.
| Argument | Description |
|---|---|
Spawn |
Kind, launch position (m) and velocity (m/s) of the particle. |
FAcresFarmRuntime::Save#
Write farm state to a JSON file plus a binary water sidecar in the same folder, named after the file with "state" replaced by "water" (farm-state.json -> farm-water.bin, farm-start-state.json -> farm-start-water.bin).
Game thread, Mutex held. Schema 3: fingerprint of the farm inputs, 11 scalar states, 60 GDD values, per-patch masks, ruts (with backhoe pits), field work marks (tilled / seeded / sprayed cells and areas; schema 2 saves lack them and load with none), harvest switch, and 11 float64 arrays of water state (the 11th, edge runoff, was added later; older saves have 10). The wheel sub-grid is not stored separately: its rut depths and compaction are rebuilt from the saved ruts on Load (compaction is a function of rut depth), and its moisture anomaly restarts at 0 (it is zero-sum within each cell, so no water is lost).
| Argument | Description |
|---|---|
Path |
Destination JSON path; written through a temp file and renamed. |
Returns: True if both files were written.
FAcresFarmRuntime::Load#
Restore state written by Save(). Game thread, Mutex held.
Validates the schema, input fingerprint, every value's range and the sidecar hash before changing anything; a failed load leaves the farm untouched. Accepts water sidecars with 11 arrays and older ones with 10, for which the edge-runoff ledger is rebuilt from each cell's water balance. Rebuilds the wheel sub-grid from the loaded ruts; whole-cell compaction from older saves is kept as a floor.
| Argument | Description |
|---|---|
Path |
JSON path written by Save(). |
Returns: False if the file is missing, from a different farm setup, or out of range.
FAcresFarmRuntime::Export#
Save state and write reports: farm-state.json, farm-fields.csv, farm-events.csv, farm-weather.csv, farm-water.json, water-depth.f32, theta.f32, farm-visuals.json and a copy of farm.json.
Game thread, Mutex held.
| Argument | Description |
|---|---|
Directory |
Output folder (created if needed). |
FAcresFarmRuntime::Status#
One-line HUD text for the field under a point: growth, theta, pond, rain, time scale, day, water lag, cutter and bunker.
| Argument | Description |
|---|---|
X |
World X, m. |
Y |
World Y, m. |
Returns: Human-readable status line.
FAcresFarmRuntime::Replant#
Reset the field under a point: clear every patch mask and restart its degree days at 0.
| Argument | Description |
|---|---|
X |
World X, m. |
Y |
World Y, m. |
FAcresFarmRuntime::RestoreField#
Undo the machine's marks on the field under a point, keeping the crop's growth: clear every patch's crushed and harvested masks and the field's ruts, and rebuild the water grid's wheel sub-grid from the ruts left elsewhere (as Load does). Used by the RL bridge so each episode starts on an untouched field. Call with Mutex held.
| Argument | Description |
|---|---|
X |
World X, m. |
Y |
World Y, m. |
Returns: The field id, or 0 when the point is not in a field.
FAcresFarmRuntime::FieldAt#
Field id under a point from the 4 m field raster.
| Argument | Description |
|---|---|
X |
World X, m. |
Y |
World Y, m. |
Returns: 1-59 for a field, 0 outside fields or outside the grid.
FAcresFarmRuntime::SnapshotCropProxies#
Append every crop patch within RadiusM + 1.5 m of (X, Y) to Out. Mutex must be held by the caller.
| Argument | Description |
|---|---|
X |
Centre X, m. |
Y |
Centre Y, m. |
RadiusM |
Search radius, m. |
Out |
Receives the patches (appended, not cleared). |
FAcresFarmRuntime::Water#
Latest water snapshot, lock-free (triple buffered). Any thread.
Returns: The most recently published snapshot, or an empty one (bValid false) before Initialize.
Note
The reference stays valid for two further publishes (at least ~0.4 s of wall time). Copy what you need rather than holding it across frames.
FAcresFarmRuntime::Work#
Mark field work on a rectangle of 25 cm cells (the rut map's cells). Physics thread, Mutex held.
Tillage (WorkTilled) loosens the soil: the vehicle then evaluates tyres and implements on these cells at the soil class's loose density (AcresSim::FSoilClass::LooseDensity), so the next pass sinks further, grips less and a second tillage pass pulls less. It also levels the surface: rut depths and tread prints under the strip are cleared (their render tiles redrawn), while the water grid's wheel sub-grid keeps the compaction it recorded (the subsoil below tillage depth stays compacted); earlier drill rows are buried. WorkSeeded and WorkSprayed record coverage. With Detail, every cell also records what the pass left for the visuals (FAcresFieldCell: the latest pass wins): the seedbed and the tool phase across the implement, the drill rows and the field's degree days at sowing, the spray rate and the farm clock.
| Argument | Description |
|---|---|
Width |
Worked width across travel, m. |
Length |
Strip length along travel, m (distance moved this step plus a margin). |
Flags |
WorkTilled, WorkSeeded and/or WorkSprayed. |
Detail |
What the tools left (may be null: coverage only). |
FAcresFarmRuntime::WorkedAt#
Work flags of the 25 cm cell under a point (0 when untouched). Any thread holding Mutex.
FAcresFarmRuntime::Dig#
Dig a pit (backhoe bucket): the relief of the 25 cm cells under the rectangle is lowered evenly by VolumeM3, but not below -MaxDepthM (nor 1.2 m below the original surface). The relief is part of the ground the vehicles stand on (ReliefAt: wheel contacts and implement ground traces follow it), is drawn by the rut tiles and stores ponded water like a rut. Physics thread, Mutex held.
| Argument | Description |
|---|---|
VolumeM3 |
Soil removed this call, m3 (in place). |
MaxDepthM |
Deepest floor, below the original surface, m (the bucket tip). |
Look |
Clod size and saturation of the exposed soil (Surface of a AcresSim::ETillagePattern::Spoil pass). |
FAcresFarmRuntime::Spoil#
Dump spoil (backhoe bucket): the loose volume joins the nearest pile within 1.2 m (or starts one) and the pile is laid out as a cone at the angle of repose (35 deg; AcresSim::SpoilConeRadiusM), raising the relief (pit cells under a wide cone stay open). Physics thread, Mutex held.
| Argument | Description |
|---|---|
VolumeM3 |
Loose volume dumped, m3 (AcresSim::SpoilVolumeM3). |
Look |
Clod size and saturation of the spoil. |
FAcresFarmRuntime::ReliefAt#
Height of the dug and heaped ground relative to the original surface at a point, m (pits negative, spoil positive), bilinear between 25 cm cell centres; 0 where nothing was dug. Any thread holding Mutex.
FAcresFarmRuntime::AvailableWaterAt#
Plant-available water of the surface layer at a point: (theta - wilting point) / (field capacity - wilting point) of the 4 m cell's mapped soil unit, clamped to 0..1.3 (-1 outside the grid, on pavement or before the first snapshot). Any thread.
FAcresFarmRuntime::ReliefVolumes#
Total volume of the pits (below the original surface) and of the spoil piles (above it), m3.
FAcresFarmRuntime::RestoreFieldId#
Clears one field's marks and crop damage, as RestoreField does for the field under a point. Mutex held.
Returns: The field id, or 0 when the id is out of range.
FAcresFarmRuntime::ApplyLogEvent#
Replays one logged farm event (episode-log replay): sets the crop sample bits, work flags or rut depth it recorded (the look of field work falls back to plain marks), or restores the field. Mutex held.
| Argument | Description |
|---|---|
EventKind |
FLogEvent kind. PatchIndex, Samples: crop events. Flags: work flags. X, Y: Unreal world m. |
Value |
rut depth, m. Field: field id (field restored). |
FAcresFarmRuntime::FieldStats#
Per-field ground truth for task scoring, fields 1-59. Crushed crop is split at the allowed band: a crushed sample (1/16 of a 1.52 m2 patch) counts as in the band when EdgeDistanceM(field, x, y) <= EdgeBandM (Unreal world m). Mutex held.
FAcresFarmRuntime::QueryPoint#
Fills Out for a point, Unreal world m. Mutex held.
FAcresFarmRuntime::SetSoilWetness#
Sets the surface-layer water content of the soil cells of some fields: theta = wilting point + Wetness x (saturated - wilting point) of each cell's water unit (pavement and gravel keep theirs). Takes the water grid's lock and publishes a snapshot. Any thread.
Returns: The number of cells changed.
FAcresFarmRuntime::SetDeterministicWater#
Lockstep (AcresSimControl.h): on, the water grid is stepped and published by Advance on the physics thread at fixed simulation times (10 s grid steps, a snapshot every 0.5 s) instead of by the worker on wall-clock time, so the same commands give the same soil under the tyres; off hands the grid back to the worker. Game thread.
FSpoilPile#
Spoil piles: centre (world m) and loose volume (m3).
FLogEvent#
One farm change for the episode log. Kind: 1 crop crushed, 2 crop harvested, 3 cell worked, 4 rut deepened, 5 field restored (AcresLog::FFarmEvent). Agent: agent index (-1 unknown). Field: field id. Patch: crop patch index (-1 for cells). Samples: the patch's newly set 4 x 4 sample bits. Flags: newly set work flags. X, Y: patch origin or cell centre, Unreal world m (Y south). Value: area, m2, or rut depth, m. StepKey: world time x 120.
FLogStamp#
One Wheel (Kind 0) or Body (Kind 1) call for the episode log (acres_interfaces/FarmStamp): its arguments (Unreal world m, Y south), the wheel index (-1 for the body), the crop it crushed, m2, and the tags as above.
FFieldStats#
Ground truth of one field (acres_interfaces/FieldState). Areas in m2; ThetaMean m3/m3 (-1 without soil cells); PondMeanM m.
FPointInfo#
Ground truth at one point (acres_interfaces/FieldQuery).