The acres_simulator Package#
acres_simulator is the Python interface of the run-time library acres_runtime. It has no numerical code. The compiled library makes the plans, the routes, the command chain and the physics steps.
Before you start
- Build the run-time library and its Python module: Build ACRES Core.
- For a step-by-step introduction, read Use acres_core and acres_simulator.
Install#
The package needs no other package for its version and identity. A fleet gives its arrays as numpy arrays.
PYTHON=$(command -v python) Runtime/build.sh # the library and the module _acres_runtime
pip install --no-build-isolation --no-deps -e Simulator # the package, with no download
Without an install, set the path:
The package finds the module _acres_runtime in this order:
- On the Python path.
- In the folder of the variable
ACRES_RUNTIME_BUILD. - In
Runtime/Buildof the repository.
The variable ACRES_ROOT names the repository that has the world content and the configuration files. The default is the repository of the package.
Modules#
| Module or Name | Content |
|---|---|
acres_simulator |
Core, Fleet, Observation, Driver, run, Skills, SkillResult, run_skills, identity, repository, sweep_materials |
acres_simulator.plans |
Mission plans, routes, prepared paths, cost tables and the identity of the tree |
acres_simulator.maps |
The maps of the simulator by name |
acres_simulator.scenarios |
The other actors on the path of a mission: generator, run and contact class |
acres_simulator.scan |
The scan filter, the crop mask and the shield, for tools |
acres_simulator.vehicle |
The control step of one vehicle with inputs from outside (Vehicle) |
acres_simulator.learned |
Learned skills that propose chunks through the checker |
acres_simulator.training |
Many vehicles of one skill world as arrays (Training) |
acres_simulator.evaluate, acres_simulator.plot |
The evaluation of a learned skill and its figures |
acres_simulator.tables |
A command that drives the cost tables and writes them to the cache |
A Fleet of Missions#
A fleet drives many missions on one batch of ACRES Core. A model reads the observation and proposes chunks. The library checks each chunk, drives the command chain and the physics, and gives the scores.
import acres_simulator as acres
world = acres.Core(num_envs=64, threads=8) # ACRES Core in this process
fleet = acres.Fleet(world, grip="unknown")
fleet.load(missions=["single-F56"], condition="dry")
obs = fleet.observe() # arrays that view the memory of the library
chunks = fleet.default_chunks(n=16) # the chunk of the default driver for each slot
verdicts = fleet.propose(chunks) # the chunks of each vehicle, checked in parallel
command = fleet.step() # the best accepted chunk, or the default driver
scores = fleet.scores()
class MyDriver(acres.Driver): # the hook for a model
def propose(self, obs):
return fleet.default_chunks(n=16)
acres.run(fleet, driver=MyDriver(), deadline_s=0.05)
fleet.close()
| Name | Function |
|---|---|
acres.Core(num_envs, threads, root, config_dir, content_dir, scan_history) |
A world of ACRES Core for a fleet or a skill world. threads 0 uses one thread for each hardware thread. |
acres.Fleet(world, grip, order, shield_scan) |
A fleet. grip is a level name of envelope_v1.json or its index. order is "longest" or "queue". |
acres.Driver |
The hook: a class with propose(obs) that returns chunks or None. |
acres.run(fleet, driver, deadline_s, max_steps) |
Observes, proposes, checks and steps until no mission runs. Returns the scores. |
acres.identity() |
The versions of the package and the library, the ABI version, the simulation version, the build commit and the map hash. |
acres.repository() |
The ACRES repository that the package uses. |
One process has one fleet or one skill world at a time. Close a fleet with close(), or use a with block, before you make the next one.
Method of Fleet |
Function |
|---|---|
load(missions, condition, kind, append, chain, jobs) |
Puts missions into the queue and starts them. A mission is a name such as "single-F56" or a prepared mission. |
observe() |
Returns the Observation. Its arrays are views. |
default_chunks(n, step_m, copies) |
A new array [slots, copies] with the chunk of the default driver for each slot. |
propose(chunks, slots, deadline_s) |
Checks the chunks, one task for each slot. Returns the verdicts. |
step() |
Makes one control step of each slot. Returns the command of each slot. |
run(max_steps) |
Steps with the default driver until no mission runs. |
scores(), timing() |
The score of each mission in queue order, and the counts and times of the work. |
set_parameters(slot, overrides), set_steer_rate_scale(slot, scale), check_inputs(slot, chunk) |
Setters for a sensitivity study, and the checker inputs of a chunk. |
slots, threads, running, missions, close() |
The size of the fleet, the missions that run, and the release of the fleet. |
The argument kind selects the command chain of a mission:
"acceptance": the default driver, the launch hold, the shield and the gear logic, with the scan."single": the default driver and the gear logic.
The calls load, observe, default_chunks, propose, step and run release the Python GIL.
Warning
Do not set deadline_s in an evaluation. It is a wall-clock limit, thus a result then depends on the speed of the computer.
Observation#
Each array has one entry for each slot. The arrays are read-only views of the library memory. They get new values at the next call of observe or step.
| Attribute | Shape and Type | Content |
|---|---|---|
state |
[slots, 49] float64 |
The state rows of ACRES Core. obs.columns gives the index of each name (x, y, yaw, speed, ...). |
scan |
[slots] records |
The newest planar scan: ranges [360], material [360], stamp_s. |
history_scan, history_x, history_y, history_yaw |
[slots, K] |
The ring of the last K scans with the pose of each. |
projection |
[slots] records |
s_m, cross_track_m, segment, leg, direction, half_left_m, half_right_m. |
base |
[slots] records |
The command of the default driver: curvature_per_m, speed_mps, path_cap_mps. |
limits |
[slots] records |
The limits of the ground below the vehicle: speed, deceleration, obstacle margin, lateral acceleration, overshoot. |
active, phase, mission |
[slots] |
1 when the slot has a mission. The phase: 0 idle, 1 goto, 2 scout, 3 return, 4 done, 5 failed. The queue index, or -1. |
corridor(slot) |
dictionary | The corridor of the active leg: rasters, line, frame and speed limits. |
Caution
Copy a value of corridor(slot) that you keep. The library frees the corridor when the leg changes.
Chunks, Verdicts and Commands#
The records have the fields of the structures of Runtime/Include/acres_runtime/types.h.
| Record | Fields |
|---|---|
Chunk (AcresRtChunk) |
n, dt_s, station0_m, step_m, offset_m [64], speed_mps [64], t0_s, deadline_s |
Verdict (AcresRtVerdict) |
accept, reason, index, counterexample (x, y, s, value, limit, rule) |
Command (AcresRtCommand) |
curvature, speed, ulc, gear, obstacle_m, proposed_speed, held_speed, violated, shift, intervened, hold_changed, source |
A chunk gives a side offset from the mission path and a signed speed at n stations. The stations are step_m apart and start at station0_m.
- A verdict reason is 0 for an accepted chunk and 1 to 16 for the first failed rule of the checker.
- The reason 100 is a late answer. The reason 101 is "no checker": build with
ACRES_RUNTIME_LEAN=generatedto load the checker. - The command
sourceis 1 for the default driver and 2 for a chunk.
Scores#
A score has these keys:
| Keys | Content |
|---|---|
success, failure, truncated |
The result |
time_s, fuel_j, ground_j, crop_m2, edge_m2, distance_m, steps, reverse_m, gear_changes |
The totals |
min_obstacle_m, cmd_rms_change, max_cross_track_m, cross_track |
The smallest obstacle distance, the command changes and the cross-track error |
coverage, scouted, interventions, interventions_per_1000, rules, phases, t_ref_s |
Field coverage, shield interventions, phases and the reference time |
Skills of One Vehicle#
acres.Skills drives one vehicle of a world through skills: go to a field, scout it, return home, wait.
import acres_simulator as acres
world = acres.Core(num_envs=1, threads=1)
skills = acres.Skills(world, agent=0)
result = skills.scout("F56") # result.code, result.cause, result.counterexample
if result.code == "blocked": # the shield held the vehicle for 10 s
skills.wait(30.0)
result = skills.resume()
result = skills.return_home()
skills.close()
| Name | Function |
|---|---|
Skills(world, agent=0, planner=None, name="polaris", **options) |
The skills of one agent. The first agent of a Core makes the skill world. options has shield_scan ("config", "planar" or "sweep"). |
goto(place), scout(field), return_home(), wait(seconds), stop(), resume() |
Start a skill and step to its end. Each returns a SkillResult. |
start(skill, args), step(steps), advance(s), charge(s), run(...) |
A request that does not block, and control steps. |
events(since), observation(), clock(), truth(), route(), state(), active |
The interface documents and the truth of the simulator. |
set_objects(rows), set_scenario(scenario), scenario(), reset(pose) |
The objects on the path and a new episode. |
check(skill, args), refuse(skill, cause) |
The problem of a request, and a refusal with that sentence. |
scan(), sweep(pattern, noise, seed, crops, motion, intensity), command() |
The scan of the shield, a LiDAR sweep of ACRES Core, and the last command of the chain. |
start_log(path, metadata), stop_log(), flush_log() |
The episode log of the agent: an MCAP file that the game can replay. |
SkillResult |
code, cause, counterexample, skill, skill_id, time_s. |
acres.run_skills(agents, max_steps) |
Steps the world until a skill of an agent ends. The agents step in parallel. |
The skills, the result codes and the objects on the path are in Fleet, Skills and Routes.
Plans and Routes#
The module acres_simulator.plans connects to the planner and the routes of the library.
from acres_simulator import plans
missions = plans.prepare(["single-F56", "single-RF004"], condition="dry", kind="acceptance", jobs=8)
plans.save("my-plans", missions) # one .npz file for each mission
missions = plans.load("my-plans", kind="acceptance")
route = plans.route("F53", pose=(x, y, yaw)) # the route of a skill from a pose
| Function | Content |
|---|---|
prepare(missions, condition, kind, jobs, tables_dir) |
Plans each mission and prepares its path. Returns one dictionary for each mission with the path, the legs, the plan, the plan-check verdict and T_ref. |
route(mission, pose, back_off_m, speed_cap_mps, reverse, back_track) |
The route of a skill. "home" gives a Return alone. A refused mission raises plans.RouteRefused. |
order(fields, condition) |
The plan of the exact program for some fields, with no route. |
check(visits, return_home, condition) |
The plan check of the visits in the order of the caller. |
site(tables_dir), site_map() |
The planner of the process, and the map for a drawing: fields, loops, edges, scan frame and object kinds. |
tables(condition), tables_file(condition, tables_dir) |
The cost tables of a condition set. |
legs(mission), reasons() |
The legs of a prepared mission, and the reason names of the plan checker. |
save(folder, missions), load(folder, kind, condition) |
Prepared missions as files. |
identity(), map_hash(folder) |
The identity of the tree, and the map hash of a map folder. |
heights(xy), task_fields(), scout_study(...), command_curvature(xy, speed_mps) |
Getters for tools: terrain heights, field names, a study of a Scout loop, and the curvature of the default driver. |
Cost Tables#
prepare and route read the cost tables. The search order of the folder is:
- The argument
tables_dir. - The variable
ACRES_COST_TABLES. Acres/Saved/Learning/costsof the repository.
The cache has the tables in <map hash>/v<simulation version>/<condition>.npz. The planner refuses tables of a different map.
When the cache has no tables for the tree, the package drives them in a separate process (python -m acres_simulator.tables). The three condition sets take about 2 minutes on 8 threads.
| Variable | Default | Function |
|---|---|---|
ACRES_COST_TABLES |
Acres/Saved/Learning/costs |
The cache of the cost tables |
ACRES_DRIVE_TABLES |
8, at most the hardware threads | The threads of the table drive. 0 permits no drive: prepare and route then raise FileNotFoundError. |
Maps#
The module acres_simulator.maps selects a map by its name. One process has one map.
| Function | Content |
|---|---|
names() |
The default map and the variants in Acres/Content/SimulationMaps |
use(name) |
Selects the map of this process before a world is made. It also sets ACRES_MAP for child processes. |
current() |
The map of this process: that of use, else of ACRES_MAP, else default |
folder(name), content_dir(name), maps_dir() |
The folders of a map |
identity(name), tables_folder(name), drive_tables(name, threads, conditions) |
The identity and the cost tables of a map |
Run python -m acres_simulator.maps --help for the command form. The page Map Data describes the map folders.
Scenarios of Other Actors#
The module acres_simulator.scenarios makes persons, trucks, tractors and cars on the path of a mission.
| Function | Content |
|---|---|
generate(route, patterns, seed, mission, run, count, ...) |
The actors of one episode for a route |
save(scenario, path) |
Writes a scenario file (acres-path-scenario-1) |
config(override, path), config_path() |
The generator settings of path_objects_v1.json |
Run |
Steps the scripts of a scenario outside a skill world |
contact_class(vehicle, row, moving_mps) |
Who moved into whom: vehicle, actor, both or rest |
Give a scenario to a skill world with Skills.set_scenario. Farm Traffic and Workers describes the behaviour of the actors.
Identity#
The identity of a simulated result has two values.
from acres_simulator import plans
tree = plans.identity() # {"map_hash", "sim_version", "build_id", "commit"}
| Value | C Function | Content |
|---|---|---|
map_hash |
acres_runtime_map_hash |
16 hexadecimal digits. It covers the scouting map and each map file that a drive reads. |
sim_version |
acres_runtime_sim_version |
One whole number for the drives of the simulator and the command chain. It is the first line of Runtime/Reference/sim_version.txt. |
build_id, commit |
acres_runtime_build_id, acres_runtime_commit |
Information only. |
Only Runtime/Reference/refresh.sh changes the simulation version (Recorded Reference).
Warning
Run Runtime/Tests/baseline_regression.py before you commit a change of the library, ACRES Core, a configuration file or a map file. The regression test, not a hash, finds a change of a drive.
A cost table file and a dataset of simulated scans store map_hash and sim_version. The planner refuses a different map. A different simulation version gives a warning.
Commands#
| Command | Function |
|---|---|
python -m acres_simulator.tables |
Drives the cost tables of the tree into the cache |
python -m acres_simulator.maps |
Lists the maps, and runs a command for each map |
python -m acres_simulator.baseline --fields F56,F04 --threads 4 --out <folder> |
Drives a set of single-field missions and writes results and reports |
python -m acres_simulator.chunk_acceptance --out <folder> --threads 4 |
Counts the chunks of the default driver that the checker accepts |
python -m acres_simulator.evaluate, python -m acres_simulator.plot |
Evaluates a learned skill and draws its figures |
python Simulator/examples/noise_driver.py [<plans folder>] [<threads>] |
An example model: 64 vehicles with 16 chunks each |
Add --help to a command for its options.
Related Pages#
-
The C interface, the rules of the library and the game link.
-
Control steps, skills, objects on the path and prepared paths.
-
The exact program, the plan checker and the table drives.
-
One vehicle with inputs from outside, and the scan filter.