Learn with ACRES#
Use the map data of acres_learn as input for a model. Make new maps for training. Train a learned skill that drives through the vehicle software.
Before you start
- Set the environment of Use the Python API.
- Install PyTorch for the training example. CPU only is sufficient.
What Each Package Gives#
| Package | Content | Use It For |
|---|---|---|
acres_learn |
The map products and their reader, the map-variant generator, the configuration files, the readers of vehicle recordings | Features of the map, new maps, settings |
acres_simulator.Training |
Many vehicles in one world, each with a task. Your model proposes path chunks. The checker accepts or refuses each chunk. | Training a driving model |
acres_simulator.evaluate, plot |
A fixed set of test cases for a skill, and the plots of the result | Evaluation |
Skills/ |
The schema of a skill and the example skill slow_pass |
A start for your skill |
acres_learn has no driving code. The run-time library drives the vehicles.
Read the Map Products#
The map products describe what a planner and a model can know of the farm. They give the fields and their scout loops, the route graph, the speed limits and a 0.5 m raster of ground classes.
"""Read the map products of the default map: a field loop, its path from an entry, and the ground classes."""
import numpy as np
from acres_learn.tasks.scouting.map_products import ScoutingMap
m = ScoutingMap.load()
print(len(m.task_fields), "task fields")
f = m.field("F56")
print("F56 loop:", len(f.loop_xy), "points,", round(f.loop_length_m), "m")
path = m.path("F56", entry=0, clockwise=True)
print("path keys:", sorted(path)[:6])
classes = m.ground_class(f.loop_xy[:5, 0], f.loop_xy[:5, 1])
print("ground classes of the first loop points:", classes.tolist())
Expected result
The ground classes are 0 crop, 1 lane, 2 verge, 3 edge band, 4 obstacle and 5 other. ScoutingMap.load(folder) reads a map variant. The Map Products reference gives each product.
Make and Describe a Map#
A map variant changes the fields, the lanes, the crops and the wet patches of the farm from a seed. Train on several maps to make a model that does not learn one map by heart.
Expected result
The numbers of the map structure, as JSON:
python -m acres_learn.maps.variants --config Learning/acres_learn/configs/map_variants_v1.json --only <name> makes a variant from its seed and recipe. Run it from the folder Learning. The Map Data reference gives the recipe keys and the cost tables of a new map.
The Learned Skill#
A learned skill is a folder. It describes a new skill for a planner, the rules of its run, and the code or the model that proposes its path chunks.
Skills/slow_pass/
skill.json the description
proposer.py the proposer as a Python function, and the same rule as a PyTorch module
cases.json the cases of the evaluation
train.py the example training loop
make_model.py exports the model
model.pt the exported model (TorchScript)
Key of skill.json |
Function |
|---|---|
name, text, use_when |
The name of the skill and its tool, and the text that a planner reads |
runs_on |
place (to a field entry or H), field (a field and its scout loop), home (to H) or pose (no path) |
arguments |
place or field, speed_cap_mps, seconds, and at most 4 more numbers for the proposer |
results, end |
The result codes, and the end conditions: the path end, a hold of the shield, a time or distance limit, a signal |
limits |
A lower speed cap, and the places where the skill can run |
chunk |
The number of samples (3 to 64) and their spacing |
proposer |
builtin, python (<module>:<function>) or model (an exported file) |
The library checks the description and names the line that is wrong:
The schema is Skills/skill.schema.json. The acres_simulator reference gives the full description.
Train on Many Vehicles#
Training holds one world with many vehicles. In each control step, your model reads one array of observations and gives one array of path chunks. The trajectory checker accepts or refuses each chunk. A refused chunk does not drive: the default driver drives that vehicle in that step.
"""The training loop of a learned skill on 8 vehicles: the default chunks, slowed to 1 m/s."""
import numpy as np
import acres_simulator as acres
from acres_simulator.learned import vector_layout
train = acres.Training(acres.Core(num_envs=8, threads=4), "Skills/slow_pass")
train.reset(range(8), tasks=[{"place": "F56"}] * 8, seeds=range(8))
layout = vector_layout()
n = train.skill.handle.chunk_samples
offsets = slice(layout["chunk_offset_m"].start, layout["chunk_offset_m"].start + n)
speeds = slice(layout["chunk_speed_mps"].start, layout["chunk_speed_mps"].start + n)
accepted = 0
for step in range(200):
vectors = train.observe() # [8, PROPOSER_VECTOR]: the input of a model
rows = np.concatenate([vectors[:, offsets], np.minimum(vectors[:, speeds], 1.0)], axis=1) # your model here
verdicts = train.propose(rows) # the trajectory checker checks each chunk
accepted += int(verdicts["accept"].sum())
train.step() # one control step of each vehicle
for slot in train.ended():
print("episode end:", slot, train.result(slot)["code"])
print(f"{accepted} of {8 * 200} chunks accepted")
| Call | Function |
|---|---|
reset(slots, tasks, seeds) |
Starts a new episode on some vehicles: a task (a place and a speed cap) and a seed of the other actors |
observe() |
The observation vector of each vehicle: its pose, its speed, the route ahead and the default chunk |
propose(rows) |
Your chunks: the side offsets, then the speeds. Returns accept and reason for each vehicle. |
step() |
One control step of each vehicle |
ended(), result(slot) |
The vehicles whose episode ended, and the result code, the cause and the counters |
The reset of one vehicle changes only that vehicle. A run with 1 thread and a run with 8 threads give the same numbers.
The Full Example#
Skills/slow_pass/train.py trains one parameter with PyTorch: the pace of the skill. It draws tasks from the training fields of Learning/acres_learn/configs/splits_v1.json and puts actors on the path.
-
Train on 8 vehicles for 300 steps.
-
Evaluate the trained model on the cases of the folder, and plot the result.
python -m acres_simulator.evaluate --skill runs/slow_pass_train/slow_pass --proposer model --out runs/slow_pass_eval python -m acres_simulator.plot runs/slow_pass_evalExpected result
f56_truck_beside done 185.0 s path error 0.33 m contact 0 proposer 100 % refused 0 f56_truck_on_path blocked 116.8 s path error 0.22 m contact 0 proposer 84 % refused 190 f04_person_on_path blocked 73.6 s path error 0.19 m contact 0 proposer 66 % refused 252The plot command writes
share.png,refusals.png,path_error.pngandresults.png.
A skill folder also works in the harness as a local planner. Refer to Use the Harness.
Next Steps#
-
Run your skill in full mission scenarios.
-
The checker and the shield that check each chunk.
-
Map folders, variants and their cost tables.