Automation
Automation in Anolis is a behavior-tree layer above core runtime services.
Contract and Build Context
- Runtime config contract:
schemas/runtime/runtime-config.schema.json - Runtime HTTP contract:
schemas/http/runtime-http.openapi.v0.yaml - Runtime mode/parameter endpoints:
GET/POST /v0/modeGET/POST /v0/parametersGET /v0/automation/statusGET /v0/automation/tree
Build-time option:
cmake -DANOLIS_ENABLE_AUTOMATION=OFF ...When compiled out, automation endpoints return UNAVAILABLE.
Architecture Boundaries
Automation is a consumer of kernel services, not a replacement for them.
- Reads: through
StateCache. - Writes: through
CallRouter. - Inventory/capabilities: through
ProviderRegistry. - Parameters: through
ParameterManager. - No provider-specific behavior is encoded in the BT runtime engine.
Runtime Modes
| Mode | Automation | Manual Calls | Control Behavior |
|---|---|---|---|
IDLE | Stopped | Blocked | Startup mode; outputs set by safety.on_startup |
MANUAL | Stopped | Allowed | Operator control |
AUTO | Running | Policy-gated | Automated control |
FAULT | Stopped | Allowed | Manual recovery state |
Transition rules:
IDLE <-> MANUALMANUAL <-> AUTOAny -> FAULT(valid transition target)FAULT -> MANUALFAULT -> AUTOis not allowed directly.AUTO -> IDLEis not allowed directly.
Startup is always IDLE.
Manual Gating Policy in AUTO
automation.manual_gating_policy controls manual calls while mode is AUTO.
BLOCK(default): manualPOST /v0/callrejected.OVERRIDE: manual calls allowed during AUTO.
Control-operation guardrails in current runtime:
IDLEblocks control operations atCallRouter.AUTOapplies manual-call gating policy (BLOCK/OVERRIDE).FAULTis primarily a recovery mode; transition constraints apply, but control calls are not globally blocked byCallRouter.
Runtime Parameters
Parameters are declared in runtime YAML and mutable via HTTP.
Values set over HTTP are not persisted. Every start begins at the config defaults, and the startup log lists each parameter with its default value. GET /v0/parameters reports source: default until a POST changes a value, then source: operator. The runtime always starts in IDLE, so a value that reverted on restart takes effect only once an operator re-enters AUTO.
Example:
automation:
enabled: true
behavior_tree: ./tests/integration/fixtures/behaviors/demo.xml
- name: temp_setpoint
type: double
default: 25.0
min: 10.0
max: 50.0
- name: control_enabled
type: bool
default: trueSafe-state hooks (required to enter AUTO with actuators). Automation that drives actuating outputs must declare safe-state mode_transition_hooks; the runtime refuses MANUAL -> AUTO (HTTP 409) without them — see safety.md. Add a *->FAULT hook that drives actuators to a safe value:
This hook is not the software stop's safe state.
POST /v0/estoprunssafety.safe_state, which this gate does not check — declare both. A machine with the hook and nosafety.safe_statepasses the gate while its software stop has no safe state of its own: the stop runs this hook on its way into FAULT (except in IDLE, where the IDLE gate refusesbefore_transitioncalls) and reportssafe_state_achieved: false. Oncesafety.safe_statedeclares a rung, the stop's latch refuses this hook and the rung alone drives the outputs.
automation:
mode_transition_hooks:
before_transition:
- to: FAULT
fail_on_error: false
calls:
- device_handle: sim0/motorctl0
function_name: set_motor_duty
args: { motor_index: 1, duty: 0.0 }Supported types:
doubleint64boolstring
Constraint rules:
min/maxare numeric-only.allowed_valuesis string-only.
Custom BT Nodes (Runtime)
Core runtime nodes include:
CallDeviceReadSignalCheckQualityGetParameterGetParameterBoolGetParameterInt64CheckBoolPeriodicPulseWindow
Use runtime capability metadata and parameter constraints to keep BT logic generic.
Quick Walkthrough
1) Start runtime with automation enabled
# Linux
./build/dev-release/core/anolis-runtime --config ./examples/anolis-runtime.yaml
# Windows
.\build\dev-windows-release\core\Release\anolis-runtime.exe --config .\examples\anolis-runtime.yaml2) Verify startup mode
curl -s http://127.0.0.1:8080/v0/mode | jqExpected mode at startup: IDLE.
3) Inspect and update parameters
curl -s http://127.0.0.1:8080/v0/parameters | jq
curl -s -X POST http://127.0.0.1:8080/v0/parameters \
-H "Content-Type: application/json" \
-d '{"name":"temp_setpoint","value":30.0}' | jq4) Move into AUTO
curl -s -X POST http://127.0.0.1:8080/v0/mode \
-H "Content-Type: application/json" \
-d '{"mode":"MANUAL"}' | jq
curl -s -X POST http://127.0.0.1:8080/v0/mode \
-H "Content-Type: application/json" \
-d '{"mode":"AUTO"}' | jq5) Check automation status
curl -s http://127.0.0.1:8080/v0/automation/status | jq6) Optional: inspect loaded tree
curl -s http://127.0.0.1:8080/v0/automation/tree | jqTroubleshooting
UNAVAILABLEfrom automation endpoints:- automation disabled in config or compiled out.
- BT load failure:
- invalid tree path/XML or port type mismatch.
- Manual calls blocked unexpectedly:
- verify mode and
manual_gating_policy.
- verify mode and
- Parameter update rejected:
- check type/constraint mismatch against declared parameter.
Safety Reminder
Automation provides orchestration policy, not safety certification. External safety systems (E-stop/interlocks/watchdogs) remain required for real hardware deployments.
