Advanced Metal Research
GitHub Contact AMR

Configuration files (drive, machine, cell)

On this page
  1. Templates
  2. Provenance siblings
  3. What compile writes
  4. Three digests
  5. Machine config
  6. Top level
  7. axes[], flat form
  8. axes[], robot-bound form
  9. limits
  10. jog
  11. brake and brake_override
  12. collision_watchdog
  13. diagnostics
  14. runtime
  15. robot
  16. control
  17. bus
  18. bus_bringup
  19. io
  20. Drive config
  21. Cell config
  22. Compile warnings
  23. Robot compile refusals

rt-core reads one compiled configuration. You write it as JSON in rt-core/config/, and rtctl compile turns it into an immutable directory named after its digest. This page lists every field of the machine, drive and cell layers. Robot descriptions have their own page: Robot description files.

Compile a shipped simulation machine and print its digest directory:

cd rt-core
make control
build/rtctl compile --config config/machines/simulation/simulation-program.json --out build/config
# /…/rt-core/build/config/<configuration_sha256>

How the layers fit together is explained in Cells, machines and positioners.

Templates#

rt-core/config/templates/ holds one annotated template per layer: machine.json, drive.json, cell.json and robot.json. Every field has a <field>_doc sibling that states its unit, allowed values and default. The tables below are drawn from those templates and the compiler.

The templates are class definitions, not deployable configs. They show mutually exclusive branches side by side (flat axes and robot-bound axes, for example), and <required> marks a value the example cannot choose. To use one, pick a branch, remove the _doc siblings and fill the values.

Tests in rt-core/tools/rtctl and rt-core/config/cells check the templates against the compiler's readers and compile their simulation branches. None of them touches hardware.

Provenance siblings#

Numeric robot facts and safety exceptions must say where they came from. Add a <field>_source ("cited: …") or <field>_unverified ("unverified: …") string beside the field. Missing provenance is a compile error. Free-text reasons (for example collision_watchdog.reason) must be non-empty.

What compile writes#

rtctl compile --out DIR writes DIR/<configuration_sha256>/:

FileContents
argv.jsonThe core's command line, from the compiled configuration.
axes.confPer-axis native profiles.
configuration.identityThe canonical text the configuration digest is computed over.
configuration.base.identityOnly for a machine with an io block: the identity before cell I/O was bound. The final digest covers that base digest plus the io block and its terminal profile.
machine.identity, deployment.identityCanonical texts for the machine and deployment digests.
coordinate.identity.jsonPer-axis coordinate identities and their SHA-256.
robot.jsonThe robot binding, when the machine pins a robot description.
resources.json, resources/<sha256>The robot description files (and cell calibration) as content-addressed resources. rt-control serves them through Describe and GET /v1/resources/<sha256>.

rt-control loads this directory through --compiled-config or ROSIE_RT_COMPILED_CONFIG.

Three digests#

The compiler produces three SHA-256 digests. Describe reports all three.

DigestCoversChanges when
configuration_sha256The original machine JSON and the resolved drive configs (and, for a robot-bound machine, the pinned description)Any byte of meaning in the machine or its drives changes. This is the pin in cell configs, rt-control --configuration-sha256 and every acquire binding.
machine_sha256Axis list and order, names, slave positions, units, scaling, gearing, sign, wrap; drive PDO, SDO, DC, Home, absolute, brake and coordinate blocks; limits, tolerances, jog durations, motor cap; cycle and lateness timing; bus bring-up policiesAnything that changes motion or drive behaviour.
deployment_sha256Runtime CPU and priority, host, NIC, sockets, pair id, service users, backend and other non-motion metadataOnly where and how the core runs.

Canonical identity text uses sorted keys, one key=value per line, %.17g doubles and decimal integers.

Machine config#

A machine config binds drives, and optionally a robot description, to bus positions, timing, limits, I/O and host policy. The shipped ones are in config/machines/, config/machines/bench/ and config/machines/simulation/.

A machine uses one of two axis forms:

  • Flat axes declare their own scaling and limits. Simulation fixtures and bare-motor benches use them.
  • Robot-bound axes name a robot_joint in a pinned robot description. They inherit travel, velocity, acceleration, gearing and Home policy from the description, and must not redeclare them.
config/machines/simulation/simulation-rosie1400.json (excerpt)JSON
{
  "schema_version": 1,
  "backend": "simulation",
  "cycle_ns": 1000000,
  "robot": {
    "robot_description": {
      "path": "robot_description/robots/rosie_1400_v3",
      "sha256": "sha256:<identity>",
      "source": "cited: …"
    }
  },
  "axes": [
    { "robot_joint": "J1", "slave_position": 0,
      "limits": { "max_target_lead": 0.02, "following_error": 0.04, "following_error_timeout_ms": 100,
                  "completion_tolerance": 0.0002, "completion_timeout_ms": 500 } }
  ],
  "max_cycle_lateness_ns": 20000000,
  "runtime": { "cpu": 2, "priority": 90 }
}

Note

On the simulated bus, simulation-rosie1400.json takes the real drive profile from the Rosie 1400 definition, and Home is refused on it, so nothing arms or jogs. For a simulated cell that homes, use the dev-stack machine described in Run everything in simulation.

Top level#

FieldTypeUnitAllowedDefault
schema_versioninteger—1Required
backendstring—simulation (synthetic drives) or live (hardware)Live admission. rtctl run --backend live, control-env and inventory require live.
cycle_nsintegerns250000 to 10000000, divisible by every nonzero drive DC quantumRequired. Shipped machines use 1000000 (1 kHz).
max_cycle_lateness_nsintegerns1 to 249999999Required
axesarray—1 to 16 ordered axesRequired
drive_speed_limit_motor_rpmnumbermotor rpm> 0; at most 6000 on the supported servo motor frame3000 for flat fixtures. Forbidden on robot-bound machines: their cap derives from the URDF velocity.
max_motor_rpmnumberlegacy wire rpm> 0; exclusive with drive_speed_limit_motor_rpmOmitted. Deprecated: compile warns.
runtimeobject—See runtimeRequired
robotobject—See robotAbsent for flat axes
controlobject—See controllan profile
busobject—See busUnknown slaves refused
bus_bringupobject—See bus_bringupDefaults below
ioobject—See ioAbsent

axes[], flat form#

FieldTypeUnitAllowedDefault
nametoken—ASCII letters, digits, _; uniqueRequired
slave_positionintegerEtherCAT position0 to 65535, unique across axes, I/O and unused slavesRequired
profilestring—A drive config basename in config/drives/, without .jsonRequired
typestring—rotary or linearRequired
wire_counts_per_revintegercounts per wire revolution1 to 2147483647Required
motor_encoder_counts_per_revintegercounts per motor revolution1 to 2147483647Required
wire_revs_per_axis_revnumberwire revolutions per axis revolution> 0; single_turn_absolute requires 1Required
gear_ratio.numerator, .denominatorintegerratio1 to 2147483647 each1 for flat simulation
lead_m_per_revnumberm per revolution> 0 for linear axes0 for rotary
signinteger—−1 or +1Required
coordinate_evidence_modestring—multi_turn or single_turn_absoluteRequired on flat axes. A generic simulation drive uses multi_turn.
position_tracking_modestring—Identity tokencontinuous in simulation; required otherwise
require_homeboolean—true requires the drive's native_homeRequired on flat axes
max_accelerationnumberrad/s² or m/s²> 0Flat fixtures only
limitsobject—See limitsRequired
startupobject—Per-axis drive startup overrides, constrained by the drive's startup_schemaDrive startup_defaults
jog, brake, collision_watchdog, diagnosticsobject—See belowOmitted

axes[], robot-bound form#

FieldTypeDescription
robot_jointtokenExactly one joint name from the pinned robot definition. No joint twice.
slave_positionintegerEtherCAT position, as above.
limitsobjectOnly the tracking fields: max_target_lead, following_error, following_error_timeout_ms, completion_tolerance, completion_timeout_ms.
startup, jog, brake, collision_watchdog, diagnosticsobjectAs for flat axes.

A robot-bound axis must omit limits.min, limits.max, limits.max_velocity, limits.jog_acceleration, max_acceleration and coordinate_evidence_mode. It inherits them:

  • travel and maximum velocity from robot.urdf
  • trajectory and jog acceleration from config.json → planning.joints.<joint>.acceleration_rad_s2 (required)
  • the per-axis drive speed cap, derived from the URDF velocity through the definition's gearing and encoder scale
  • Home policy and coordinate evidence mode from the definition

Every joint in the definition needs an axis, unless you list it in robot.absent_joints.

limits#

FieldTypeUnitAllowedDefault
min, maxnumberrad (rotary) or m (linear)Finite, min < maxRequired on flat axes; inherited on robot-bound axes
max_velocitynumberrad/s or m/s> 0Flat fixtures only
jog_accelerationnumberrad/s² or m/s²> 0Flat fixtures only
max_target_leadnumberrad or m> 0Required
following_errornumberrad or m> 0Required
following_error_timeout_msintegerms1 to 1000Required
completion_tolerancenumberrad or m> 0Required
completion_timeout_msintegerms1 to 4294967295Required

jog#

The ramp when jog input stops. Also settable per drive; the axis value wins.

FieldTypeUnitAllowedDefault
arrest_nsintegerns1 to 65535 × cycle_ns200000000 (200 ms)
quick_stop_nsintegerns1 to 65535 × cycle_ns300000000 (300 ms)

brake and brake_override#

Brake fields are taken from the drive config first, then overridden per axis.

FieldTypeUnitAllowedDefault
brake.presentboolean—false cannot keep gravity_axis or released_signalfalse
brake.gravity_axisboolean—true only with presentfalse
brake.release_delay_msintegerms0 to 4294967295100
brake.hold_delay_msintegerms0 to 4294967295100
brake.hold_displacement_tolerance_countsintegercounts0 to 21474836471
brake.released_signal.semanticstring—An existing TX PDO semantic containing the bitRequired with released_signal
brake.released_signal.bitintegerbit0 to 31 for mapped brake feedbackRequired with released_signal
brake_override.presentboolean—false onlyRequired with brake_override
brake_override.reasonstring—Non-empty, with a validated bench hold policyRequired with brake_override

brake_override exists for benches whose brake wiring is not yet verified. It disables brake handling on that axis and must say why.

collision_watchdog#

Faults the axis when torque or following error stays above a bound. It detects an impact after it happens; it does not avoid one. Also settable per drive.

FieldTypeUnitAllowedDefault
torque_abs_max_rawintegerraw drive torque units1 to 1000Required when enabled
following_error_counts_maxintegercounts1 to 2147483647Required when enabled
sustained_cyclesintegercycles2 to 1000Required when enabled
disabledboolean—true needs a reason and no thresholds; false needs thresholds and a torque PDOfalse
reasonstring—Non-emptyRequired when disabled

Both branches need _source and _unverified siblings. An axis with no watchdog at all compiles with a warning: axis <name>: collision_watchdog missing; disabled.

diagnostics#

FieldTypeAllowedDefault
external_enable_input.bit_indexinteger0 to the mapped digital-input width minus 1, at most 31Required with the block
external_enable_input.polaritystringactive_high or active_lowRequired with the block

This lets rt-core report the state of an external enable, such as an auxiliary contact on the cell's stop chain. It is a diagnostic only. It never gates motion and is not a safety function. See the safety model.

runtime#

FieldTypeUnitAllowedDefault
cpuintegerlogical CPU0 to 1023Required
priorityintegerSCHED_FIFO priority1 to 99Required
telemetry.retention_msintegerms100 to 3600000, within a 2 GiB ring ceiling100000
telemetry.dump_countintegerfiles1 to 10020
telemetry.dump_bytesintegerbytes529680 or more536870912
telemetry.directorystringabsolute pathNon-root, no NULThe runtime chooses

The core writes telemetry dumps (a .bin file and its .json index) to telemetry.directory. Convert one with rtctl telemetry dump-to-jsonl.

robot#

FieldTypeDescription
robot_description.pathpathRepository-relative robot_description/robots/<model_id>. The manifest must register rtcore_definition.json.
robot_description.sha256sha256:<64 hex>The description identity, as go run ./cmd/identity prints it. Compile refuses a mismatch with robot_description_mismatch.
robot_description.sourcestringProvenance.
absent_jointsstring[]Definition joints this machine has no axis for. Default empty.
bench_measurement_profilestringRestricted to one bare-motor bench measurement profile. Omit otherwise.
machine_planning_calibration.pathpathComponent-relative config/... path to this machine's machine_planning_calibration.json. Every joint it corrects must exist and its frames must name known links.
machine_planning_calibration.sha25664 hexSHA-256 of the file's exact bytes.
machine_planning_calibration.sourcestringProvenance: who measured it, how and when.

Omit machine_planning_calibration and the cell serves the empty calibration document for its model.

control#

The per-cell lease and jog-age ceilings. See Control authority.

FieldTypeUnitAllowedDefault
link_profilestring—lan or internetlan
max_grant_lease_nsintegerns1000000 to 10000000000, whole milliseconds500000000 on lan, 3000000000 on internet
max_jog_input_age_nsintegerns1 to 2000000000250000000 on lan, 750000000 on internet

Warning

A longer lease or jog age delays the unattended stop after a client or link failure by the same amount. Keep the lan defaults unless you have measured a reason not to. The internet values are marked unverified in the code.

bus#

FieldTypeAllowedDefault
unknown_slavesstringrefuse, or hold (needs unknown_slaves_note)refuse
unknown_slaves_notestringWhy extra slaves may stay on the bus—
hold_on_robot_acknowledgedbooleantrue plus hold_on_robot_note for a robot machine using holdfalse
unused_slaves[]array0 to 256 entries: slave_position, vendor_id, product_code, revision, noteEmpty

hold leaves unknown slaves in PREOP without outputs. It is meant for test benches; an assembled robot cell must use refuse.

bus_bringup#

FieldTypeUnitDefault
startup_passive_msintegerms0
explicit_pdo_configboolean—false. true is incompatible with fixed drive PDO presets.
disable_output_watchdogboolean—false. Use true only with a declared machine failure policy.
no_dcboolean—false. true disables distributed-clock setup.
wait_before_safeop_msintegerms250
preop_safeop_timeout_msintegerms5000
safeop_op_timeout_msintegerms5000

io#

Cell I/O through a digital I/O terminal. See Process I/O and sensing.

FieldTypeUnitAllowedDefault
profilestring—A terminal drive config in config/drives/Required
slave_positionintegerEtherCAT position0 to 65535, uniqueRequired
torch_qualifiedboolean—false onlyRequired
inputs[]array—0 to 8 unique bitsRequired
inputs[].nametoken—UniqueRequired
inputs[].bitintegerbit0 to 7Required
inputs[].polaritystring—active_high or active_lowRequired
inputs[].classstring—fast or supervisoryRequired
outputs[]array—0 to 8 unique bitsRequired
outputs[].name, .bittoken, integer—, bitAs for inputsRequired
outputs[].safe_stateboolean—false (OFF) onlyRequired
outputs[].expiry_nsintegerns1 to 1000000000Required
outputs[].classstring—process or torch. Torch outputs are always refused at runtime.Required
outputs[].readback_bitintegerbit0 to 7, unique per outputRequired
outputs[].readback_polaritystring—active_high or active_lowRequired

config/cell-io/simulation.json is a complete simulation machine with an io block, not a terminal descriptor.

Drive config#

A drive config describes one drive or I/O terminal model: its EtherCAT identity, PDO layout, scaling semantics, startup parameters, Home transaction and protective defaults. A machine axis selects one with profile; a robot definition with drive_profile. Names resolve only in config/drives/. The template is config/templates/drive.json.

FieldTypeDescription
schema_versioninteger1.
id, labelstringMetadata only. profile selects the file, not id.
simulation_onlybooleantrue requires backend: simulation. Default false.
ethercat.vendor_id, .product_code, .revision_nointegerExpected slave identity.
ethercat.rx_pdo, .tx_pdo, .rx_sync, .tx_syncintegerPDO assignment object indices and sync managers.
ethercat.dc_quantum_nsintegerns. A nonzero quantum must divide cycle_ns.
ethercat.dc_assign_activateintegerDC activation bit mask.
ethercat.rx_layout[], .tx_layout[]arrayMapped PDO entries: semantic, index, subindex, bits. At most 32 entries in total. RX must map cw, target_pos and mode; TX must map sw, pos and mode_disp.
ethercat.restore_assignment_on_exitbooleanDefault false.
home_truth_sign−1 | +1Direction of the drive's Home reference.
native_homeobjectThe Home transaction: steady_state_mode and commissioning_mode (CiA402 mode numbers), truth_source, and an ordered transaction[] of set_mode, restore_mode, write_sdo, wait_sdo, write_sdo_wrap_fraction, controlword_sequence, wait_statusword, refresh_truth and release_service_override steps.
feedback_counts_wrap, command_counts_wrapbooleanWhether position feedback and commands wrap. Linear axes require false.
startup_schema, startup_defaultsobjectWhich startup parameters the drive accepts, their types and ranges, and the default written at startup. A machine axis overrides them under startup.
absolute_feedback[], absolute_pair_fieldarray, stringAbsolute encoder readbacks used for coordinate evidence.
coordinate_evidenceobjectPolicy for accepting absolute position evidence.
position_semantics.drive_native_ratio_enabledbooleantrue when the drive scales to the output shaft; false when software scales from the motor shaft.
jog, brake, collision_watchdogobjectDefaults for the axis blocks above.
max_accelerationnumberSynthetic fixtures only. Never applies to a robot-bound axis.

The PDO semantics RX accepts are cw, target_pos, target_vel, target_torque, mode, tp_func and max_profile_vel. TX semantics include sw, pos, mode_disp, err, manufacturer_err, velocity_actual, following_error, torque, di and the drive's extended diagnostics.

Note

The shipped drive configs carry values measured on specific drive firmware. Treat them as the source of those values, and do not copy them into other documents.

Cell config#

A cell config binds one deployed cell to a machine config and its compiled digest. The template is config/templates/cell.json.

config/templates/cell.json (without _doc fields)JSON
{
  "name": "simulation-cell",
  "nodes": [
    {
      "runtime": "rt-core",
      "rt_core": {
        "machine_config": "rt-core/config/machines/simulation/simulation.json",
        "configuration_sha256": "<64 hex from rtctl compile>",
        "pair_id": "simulation-cell",
        "pair_revision": 1,
        "remote_listen": "127.0.0.1:8443"
      }
    }
  ]
}
FieldTypeAllowedDefault
namestringDisplay text. Ignored by the validator.Omitted
nodes[]arrayOrdered nodesRequired
nodes[].runtimestringrt-core for a native node—
nodes[].rt_core.machine_configpathRepository-relative path to an existing machine config, with no traversal or escaping symlinkRequired
nodes[].rt_core.configuration_sha25664 lowercase hexThe exact rtctl compile digestOptional to the reader. Pin it on every deployed cell.
nodes[].rt_core.pair_idtokenLetters, digits, _, ., -Required
nodes[].rt_core.pair_revisionintegerPositive uint64Required
nodes[].rt_core.remote_listenhost:portIP or DNS host, port 1 to 65535Required

The validator in Go package rosieos/rt-core/config/cells recompiles every node's machine config and refuses a mismatched digest, axis count, pair or listener:

cd rt-core
go test -count=1 ./config/cells -run TestRepositoryCompatibility

Cell configs in config/cells/ also carry deployment fields for the deploy tooling. Those fields select and pin a configuration but never enter its digest.

Compile warnings#

Warnings go to stderr, prefixed warning:. The compile still succeeds.

WarningMeaning
axis <name>: collision_watchdog missing; disabledThe axis has no collision watchdog.
max_motor_rpm is accepted for one release …Migrate to drive_speed_limit_motor_rpm (motor rpm).
legacy flat axes are accepted for one release …Migrate to a robot definition and robot_joint axes.
axis <name> motor speed cap <n> rpm exceeds … rated 3000 rpm …The axis speed cap is above the servo motor's rated speed but within its 6000 rpm maximum. Above the maximum, compile refuses.

Robot compile refusals#

When a machine pins a robot description, compile refuses with <reason>: <detail>:

ReasonCause
robot_description_unavailableThe description directory or its files cannot be read.
robot_description_mismatchThe pinned identity differs from the files, the definition's robot_id differs from the directory, or the directory has a robot.urdf its manifest does not register. The detail gives both hashes.
robot_definition_unavailableThe manifest does not register rtcore_definition.json.
robot_definition_fieldAn unexpected field, or a restricted field used where it is not allowed.
robot_duplicate_fieldA JSON key appears twice.
robot_reference_pathA path escapes the repository root or is not a valid relative path.
robot_hash_invalidA pinned hash is not lowercase SHA-256.
robot_hash_mismatchA pinned file hashes to something else.
robot_joint_mappingAn axis names an unknown, duplicate or absent robot_joint.
robot_joint_missingA definition joint has no axis. Declare it in robot.absent_joints.
robot_urdf_limits_requiredAn axis or definition tries to redeclare a limit, velocity or gearing it must inherit.
robot_limit_widenedA requested value exceeds the model's bound.
robot_acceleration_requiredconfig.json has no planning.joints.<joint>.acceleration_rad_s2 for a mapped axis.
robot_bench_inheritanceA bench machine redeclares a field it must inherit from the robot definition.
machine_planning_calibration_invalidThe pinned calibration fails its rules, or the description has no geometry to calibrate.

Other compile errors print a plain message and exit 1. Nothing is written until the whole configuration is valid.