This page gives the format of each map file that the game and ACRES Core read at the start of a session.
The ACRE Scene describes the contents of the map and the frames.
The tools of Tools/ACRE/Map write the runtime map files. The game, ACRES Core and two builders read them. Open the diagram
The runtime map files are in the folder Acres/Content/Simulation/ACRE. The examples use paths relative to the repository root.
Rule
Description
Binary grids
A grid file has no header. The values are in row sequence. Row 0 is the north edge of the tile and column 0 is the west edge.
Byte sequence
heights.f32 is little-endian. The other grids have one byte for each cell.
Survey grid
1000 x 1000 cells of 1.524003048 m. Cell \((u, v)\) is at column \(u\) and row \(v\).
4 m grid
382 x 382 cells of 4 m. Its north-west corner is the corner of the survey grid.
Units
Metres, unless the key name gives a different unit (_ft, _cm, _px, _ha, _deg).
Suffix _px or _uv
A position in survey grid cells: \(u\) east, \(v\) south.
Python
The examples need numpy. Use the conda environment torchenv.
The map tools read source data from the folder Acres/Raw/ACRE. That folder is not in the repository.
Thus a build of the game does not need the tools. The command python Tools/ACRE/Map/test_map.py tests the mathematics of the tools without the source data.
The site file gives the geometry of the survey grid and the georeference of the tile.
It also contains the road centrelines, the building boxes and the grain bins of the original map.
Name
Type
Unit
Default
Description
origin_source_ft
array
ftUS
2977500, 1902500, 705
The origin in EPSG:2968 and its NAVD88 height.
crs
text
EPSG:2968
The coordinate reference system.
grid_step_m
number
m
1.524003048
The size of a survey cell.
grid_x0_m, grid_y0_m
number
m
-762.001524
The world position of the north-west corner.
grid_width, grid_height
integer
node
1001
The size of heights.f32.
surface_width, surface_height
integer
cell
1000
The size of the survey grid.
spawn_uv, spawn_yaw_deg
array, number
cell, deg
625, 477; 180
The start pose when places.json is not available.
roads
array
35 items
name, kind, width_m, points_px. US 52 also has lane_offsets_m.
Core/Scripts/build_scene.py, Calibration/Polaris/geo.py, the building and tree tools.
Tool that writes it
None in the repository. The file is the survey product with the road review correction.
A point between the nodes has the height of one of the two triangles of its cell.
importnumpyasnpw,h=site["surface_width"],site["surface_height"]heights=np.fromfile(ACRE/"heights.f32",dtype="<f4")heights=heights.reshape(h+1,w+1)print(heights.shape,heights.dtype)# (1001, 1001) float32print(heights[500,500])# 0.32698855defheight_at(u,v):"""Height on the two triangles of the cell."""i,j=min(int(u),w-1),min(int(v),h-1)fx,fy=u-i,v-ja,b=heights[j,i],heights[j,i+1]c,d=heights[j+1,i],heights[j+1,i+1]iffx+fy<=1:returna+(b-a)*fx+(c-a)*fyreturnd+(c-d)*(1-fx)+(b-d)*(1-fy)print(round(float(height_at(474.6,592.2)),3))# 0.639 (the ICSC garage spawn)
The ground layer. The wheels, the implements and the farm read the surface class from these polygons.
The schema is acres-surface-polygons-1. The frame is the Unreal world in centimetres: X east, Y south.
Name
Type
Unit
Default
Description
classes
array
7 names
field, asphalt, concrete, gravel, grass_lane, grass, dirt. The index is the class code.
priority
object
60, 55, 40, 30, 20, 10
The priority of asphalt, concrete, gravel, dirt, grass_lane, grass.
polygons
array
521 items
The polygons. A later polygon has priority over an earlier one of the same priority.
polygons[].id
text
The identifier, for example G0017.
polygons[].class
text
The surface class.
polygons[].priority
integer
The priority of the polygon.
polygons[].ring
array
cm
The outer ring: integer points \([X, Y]\). The ring is open.
polygons[].holes
array
cm
none
Rings that the polygon does not contain. 28 polygons have holes.
polygons[].source
text
The origin of the polygon, for example verges:R0012.
polygons[].role
text
none
verge for a road verge.
polygons[].centreline
array
cm
none
The centre line of a grass lane.
polygons[].wheel_track_m
number
m
1.55
The distance between the wheel tracks of a grass lane.
polygons[].edge_source
text
none
The image that gave the edges. county2025 marks the county orthophoto.
Use
Item
Reader in the game
FAcresFieldSetup::SurfaceMap (one time for each process), then FSurfaceMap::ClassAt.
Reader in ACRES Core
FAcresWorld loads it into the same FSurfaceMap.
Other readers
Calibration/Polaris/geo.py, the scouting map builder.
Tools that write it
game_layer.py, then game_layer_fit.py, then site_edits.py.
All coordinates are in the range of ±76200 cm.
# These tools need the folder Acres/Raw/ACRE.pythonTools/ACRE/Map/game_layer.py
pythonTools/ACRE/Map/game_layer_fit.py
pythonTools/ACRE/Map/site_edits.py
layer=json.loads((ACRE/"surface_polygons.json").read_text())polygons=layer["polygons"]print(len(polygons))# 521definside(ring,x,y):"""Even-odd test of a point against one ring."""hit=Falsefor(xi,yi),(xj,yj)inzip(ring,ring[-1:]+ring[:-1]):if(yi>y)!=(yj>y)and \
x<(xj-xi)*(y-yi)/(yj-yi)+xi:hit=nothitreturnhitdefclass_at(x_cm,y_cm):"""Surface class at an Unreal world point (cm)."""best=Nonefork,pinenumerate(polygons):ifnotinside(p["ring"],x_cm,y_cm):continueifany(inside(q,x_cm,y_cm)forqinp.get("holes",[])):continuekey=(p["priority"],k)ifbestisNoneorkey>best[0]:best=(key,p["class"])returnbest[1]ifbestelse"field"print(class_at(-3871,14051))# concreteprint(class_at(0,0))# field
The surface code of each survey cell. game_layer.py makes it from the polygons with 4 x 4 samples in each cell.
The code with the most samples applies. If two codes have equal counts, the lower code applies.
Property
Value
Data type
uint8
Shape
1000 rows x 1000 columns
Index
surfaces[v, u]
Cell size
1.524003048 m
Code
Surface
Cells
0
asphalt
28233
1
concrete
1290
2
gravel
22851
3
dry_soil
947626
4
wet_soil
0
5
mud
0
Use
Item
Readers in the game
AAcresVehiclePawn::SampleSurface (only when surface_polygons.json is not available), AcresSoilVisuals.cpp (the vertex colours of the terrain).
Reader in ACRES Core
FAcresWorld, only when surface_polygons.json is not available.
with \(o\) = origin_m and \(\Delta\) = step_m. FAcresFarmRuntime::CellAt uses this equation.
The grid is 1528 m wide. Thus the last column and the last row go 4 m outside the tile.
grid=json.loads((ACRE/"field-grid.json").read_text())n,step=grid["width"],grid["step_m"]origin=grid["origin_m"]print(n,step,origin)# 382 4.0 -762.001524003048defcell_of(x_m,y_m):"""Row and column of an Unreal world point (m)."""return(int((y_m-origin)//step),int((x_m-origin)//step))print(cell_of(-38.71,140.513))# (225, 180)
The land cover of each 4 m cell. The water model of the farm reads the roughness and the interception of a cell from this code.
The LiDAR reads the material of a ground hit from it.
Property
Value
Data type
uint8
Shape
382 rows x 382 columns
Index
cover[row, column] of field-grid.json
Code
Cover
Cells
0
bare
68596
1
corn
4176
2
soybean
4252
3
grass
25422
4
woodland
35968
5
shrubs
0
6
asphalt
4111
7
concrete
164
8
gravel
3235
9
potato
0
Use
Item
Readers in the game
FAcresFarmRuntime::Initialize, AcresSensors.cpp (ground material of the LiDAR).
Reader in ACRES Core
FAcresWorld.
Tools that write it
game_layer.py (write_game_rasters, 8 x 8 samples in each cell), site_edits.py, field_edits.py.
At the start of a session, the game changes the codes of the field cells in memory to the crops of the session. It does not change the file.
The map image of the HUD and of the result page of the optimizer.
Property
Value
Format
PNG, RGB, 8 bits for each channel
Size
2048 x 2048 pixels
Extent
The full tile. North is up.
Scale
0.7441 m for each pixel, 2.048 pixels for each survey cell
Use
Item
Readers in the game
AcresHud.cpp, AcresMenu.cpp (SAcresOptMap). The game loads the file from the disk at run time.
Tools that write it
game_layer.py (write_minimap), site_edits.py.
The image shows the classes of the ground layer in fixed colours above a shaded image of the terrain.
fromPILimportImageimage=Image.open(ACRE/"minimap.png")print(image.size,image.mode)# (2048, 2048) RGBpx=2048/1000# pixels for each survey cellprint(round(474.6*px),round(592.2*px))# 972 1213 (the ICSC garage spawn)
The folder Acres/Content/Simulation/ACRE/Scouting contains the products of the scouting map: scouting_map.json, ground_classes.u8 and obstacles.json.
Scouting Map gives their format.
The file Core/Data/acre_scene.json gives ACRES Core the static obstacles of the map: buildings, grain bins and trees.
ACRES Core uses them for the ray-cast LiDAR and for the collision test of the vehicles.
The schema is acres-core-scene-1. The frame is the world ENU frame in metres. The values have a resolution of 1 cm.
Name
Type
Unit
Default
Description
materials
object
16 keys
The LiDAR properties of each material, from sensors_polaris.json.
material_names
array
16 names
The names of the materials. A material index refers to this list.
triangles
array
m
2072 triangles
A flat list with 10 numbers for each triangle: 3 points \((x, y, z)\) and the material index.
cylinders
array
m
7010 items
\([x, y, r, z_0, z_1, m]\): vertical cylinders with caps. 26 bin walls and 6984 trunks.
ellipsoids
array
m
6984 items
\([x, y, z, r_x, r_y, r_z, m]\): the crowns of the trees.
obstacles
array
m
89 items
\([\text{kind}, z_0, z_1, x_0, y_0, x_1, y_1, \dots]\): collision outlines. Kind 0 is a building and kind 1 is a bin.
The builder makes these shapes.
Buildings. Each part of a building is a rectangle with walls and a roof: flat, shed, gable or arch.
Bins. A bin is a cylinder to the eave with a cone roof of 24 triangles.
Trunks. A trunk is the collision cylinder of the tree in the level. It goes 0.3 m into the terrain.
Crowns. A crown is a sphere. Its radius is 0.25 of the tree height, limited to the range from 1.5 m to 5 m.
Use
Item
Reader
FAcresScene::Load. It builds a bounding volume hierarchy and a collision grid with cells of 8 m.
Tool that writes it
Core/Scripts/build_scene.py.
Inputs of the tool
Calibration/Map/Layers/building_models.json, Calibration/Map/Layers/tree_check.json, heights.f32, site.json, sensors_polaris.json and a dump of the tree instances of the level.
The dump of the tree instances is a local file. The option --episodes gives its folder. Without the dump, the builder writes no trees.
These two files are in Acres/Content/Simulation. They describe the roads of a map that is not in the game now.
The game loads them, but the level V03ACRE uses the ACRE files of this page.
Name
Type
Unit
Default
Description
x0, y0
number
m
-810
The world position of the first cell.
width, height
integer
cell
1620, 1160
The size of the mask.
step
number
m
1.0
The cell size.
eligible_m2, density_per_m2
number
m², 1/m²
481930, 10
Values of a grass generator. The game does not read them.
road_mask.bin is a uint8 grid with height rows and width columns. A value other than 0 is a road.
Use
Item
Reader in the game
AAcresVehiclePawn (configuration load), SampleSurface for a map other than V03ACRE.