docs: document configuration and diagnostics contracts
This commit is contained in:
1 parent
13e4040ee3
commit
9646451645
11 files changed
+336
-15
No files matched your search
@@ -6,6 +6,9 @@
|
||||
- [Architecture](architecture.md)
|
||||
- [Safety boundary](safety-boundary.md)
|
||||
- [MAVLink and telemetry](mavlink.md)
|
||||
- [Configuration](configuration.md)
|
||||
- [Logs](logs.md)
|
||||
- [Errors](errors.md)
|
||||
- [Boards](boards/index.md)
|
||||
- [Kakute F7 Mini V3](boards/kakute-f7-mini-v3.md)
|
||||
- [GEPRC GEP-F722-HD V2](boards/geprc-f722-v2.md)
|
||||
|
||||
@@ -24,6 +24,59 @@ The data channel owns rate selection, mailbox consumption, message encoding,
|
||||
and bounded TX classification. Board code supplies physical routes and
|
||||
telemetry configuration; it does not receive generic output authority.
|
||||
|
||||
Configuration and runtime observability are separate, one-way planes:
|
||||
|
||||
```text
|
||||
Kaptan GCS custom MAVLink V2 messages
|
||||
│ (future: verified signing, source binding, replay state)
|
||||
▼
|
||||
kaptan-config-mavlink ──► state-only ConfigProtocol
|
||||
│ borrows
|
||||
kaptan-flight-runtime
|
||||
├── one ConfigManager ──► kaptan-config ──► flight schema/CBOR
|
||||
└── one kaptan-log hub
|
||||
│
|
||||
kaptan-log-mavlink payload adapter
|
||||
│
|
||||
platform-owned sole encoder / DMA TX link
|
||||
```
|
||||
|
||||
The generated dialect is intentionally custom rather than a `PARAM_*` or QGC
|
||||
adapter. The core uses numeric field IDs and typed scalar values; descriptor
|
||||
text is metadata, not a wire identity. Discovery/value reads, bounded
|
||||
descriptor pages, and structured results are custom-dialect records. Runtime
|
||||
logs use one bounded text message with MAVLink severity and flags. CBOR import uses a fixed
|
||||
4 KiB transaction buffer and
|
||||
fixed 192-byte chunks; its decoded candidate still goes through the same whole
|
||||
profile validation path. The core owns one RAM transaction and the distinction
|
||||
between boot-active, committed, and editable candidate snapshots. In the
|
||||
current P1 policy a commit is restart-only. It cannot mutate controller or
|
||||
estimator state in flight.
|
||||
|
||||
One current CBOR profile format is a bounded complete snapshot. There is no
|
||||
migration reader: any other format is rejected. SITL supplies the host file
|
||||
adapter and persists a nonzero generation alongside its raw profile payload.
|
||||
Motor allocation/mixer topology is immutable compiled
|
||||
vehicle capability data, never a scalar field or CBOR candidate member. The
|
||||
bare-metal receiver continues to reject inbound control authority. Target
|
||||
persistence, authenticated ingress, durable audit logging, disarmed
|
||||
activation, and atomic consumer reconstruction remain separate reviewed work
|
||||
and cannot be implied by a valid CBOR file or CRC.
|
||||
|
||||
The MAVLink dialect root includes `kaptan/config.xml` and `kaptan/log.xml`.
|
||||
The build watches every fragment and generates one `message::kaptan` module;
|
||||
fragments are never separately generated Rust modules. `kaptan-log` itself has
|
||||
no MAVLink, platform, time, allocation, filesystem, or configuration
|
||||
dependency. It assigns bounded Critical and BestEffort queues for text logs.
|
||||
The platform drains a record only after TX admission; the diagnostic wire
|
||||
contract deliberately contains only severity, flags, bounded text length, and
|
||||
text. Local saturation accounting remains inside the hub, facade, and producer
|
||||
mailboxes; heartbeat and safety telemetry remain separate from diagnostic text.
|
||||
|
||||
See [Configuration](configuration.md) for the deployment matrix and GCS upload
|
||||
contract, [Logs](logs.md) for the receiver contract, and [Errors](errors.md)
|
||||
for derived-error and failure-reporting scope.
|
||||
|
||||
## Ownership rules
|
||||
|
||||
- A peripheral owner is local to the platform runtime.
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
The GEPRC GEP-F722-HD V2 board declaration uses the ICM-42688-P on SPI3 and
|
||||
MAVLink telemetry on USART2. It declares no vertical sensor stream.
|
||||
|
||||
Its immutable board policy selects the ICM-42688-P yaw-180° mount, logical
|
||||
MAVLink `Serial2`, endpoint `1/1`, 115200 baud, the documented telemetry
|
||||
schedule, and an `INFO` optional-log threshold. The platform verifies these
|
||||
values against the checked SPI3/USART2 typestate route before it enables
|
||||
peripherals. They are compiled image policy, not ground-station parameters.
|
||||
|
||||
Build and package from the workspace root:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -5,6 +5,12 @@ MAVLink telemetry on USART1, and the MTF01 range/optical-flow route on UART4.
|
||||
The checked-in manufacturer datasheet is
|
||||
`boards/kakute-f7-mini-v3/datasheet.pdf`.
|
||||
|
||||
Its immutable board policy selects the MPU-6000 body-aligned mount, logical
|
||||
MAVLink `Serial1`, endpoint `1/1`, 115200 baud, the documented telemetry
|
||||
schedule, and an `INFO` optional-log threshold. The platform verifies these
|
||||
values against the checked SPI1/USART1/MTF01 typestate route before it enables
|
||||
peripherals. They are compiled image policy, not ground-station parameters.
|
||||
|
||||
## Build and package
|
||||
|
||||
From the workspace root:
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
# Configuration
|
||||
|
||||
Kaptan has one generic configuration lifecycle crate, `kaptan-config`. It
|
||||
owns descriptors, typed writes, transactions, validation, generations, and
|
||||
stores. It does not grow a crate per subsystem. Flight-specific values live in
|
||||
the single `kaptan-flight-config` candidate; board electrical topology remains
|
||||
in the immutable board declaration.
|
||||
|
||||
## Current deployment matrix
|
||||
|
||||
| Deployment | Configuration consumed today | Remote writes |
|
||||
| --- | --- | --- |
|
||||
| `kaptan-sitl serve --config FILE.cbor` | One validated Quad-X profile at process construction. | No live MAVLink endpoint is attached yet. |
|
||||
| `kaptan-sitl serve` | The validated factory Quad-X profile. | No persistent store; commits are rejected. |
|
||||
| STM32F722 telemetry image | Immutable compiled `BoardConfig` plus checked typestate routes. | Disabled: all inbound MAVLink remains discarded. |
|
||||
|
||||
The current SITL profile has only settings consumed by its estimator,
|
||||
controller, safety supervisor, allocator envelope, or log hub:
|
||||
|
||||
- prearm dwell;
|
||||
- IMU, local-aiding, and command freshness/timing;
|
||||
- position/velocity aiding variance;
|
||||
- outer-loop gains and acceleration limits;
|
||||
- mass, collective-thrust, and tilt limits;
|
||||
- rate PID gains and limits;
|
||||
- actuator minimum, maximum, and slew limits; and
|
||||
- the restart-only maximum optional log severity.
|
||||
|
||||
The fixed Quad-X mixer is intentionally not configurable. It is reviewed
|
||||
capability data, not an operator-editable array.
|
||||
|
||||
Each editable field declares its ID, display key, unit, default, scalar type,
|
||||
and local validation in one `#[config(...)]` attribute. The derive generates
|
||||
the descriptor registry and local validation from that declaration; the only
|
||||
handwritten checks are whole-profile physical relationships such as thrust
|
||||
margin, timing ordering, and actuator limits.
|
||||
|
||||
## Immutable F722 board policy
|
||||
|
||||
The checked-in F722 boards consume these compiled `BoardConfig` settings before
|
||||
peripheral initialization:
|
||||
|
||||
- IMU model and its fixed body mount (`BodyAligned` or `Yaw180`);
|
||||
- logical MAVLink port, endpoint IDs, and baud rate;
|
||||
- vertical-sensor capability and telemetry schedule; and
|
||||
- maximum optional MAVLink log severity.
|
||||
|
||||
The platform compares that metadata with the selected `F722BoardRoutes` before
|
||||
claiming pins, UARTs, DMA, or IRQs. A board declaration therefore cannot claim
|
||||
an MPU-6000 while selecting the ICM route, select the wrong serial port or
|
||||
mount, or request a baud rate that cannot carry the fixed link budget. The
|
||||
physical port, sensor driver, pins, DMA, timers, and calibration are not file
|
||||
configuration and are not GCS-editable.
|
||||
|
||||
F722’s log threshold is immutable board policy. It is deliberately separate
|
||||
from the SITL profile’s `observability.maximum_log_level`: the F722 image does
|
||||
not construct a runtime `ConfigManager` or profile store.
|
||||
|
||||
## One CBOR profile format
|
||||
|
||||
There is one unreleased raw profile blob format:
|
||||
|
||||
- it is a CBOR map keyed by the discovered numeric `FieldId`s;
|
||||
- key `0` is `profile_format = 1` and reserved key `65535` is the 16-byte
|
||||
`schema_id = "KAPTANPROFILE-01"`;
|
||||
- the complete blob is at most 4 KiB; and
|
||||
- malformed, trailing, wrong-format, non-finite, out-of-range, cross-field,
|
||||
and capability-invalid values are rejected.
|
||||
|
||||
The map is exact: it has those 26 keys once each. Unknown, duplicate, missing,
|
||||
or indefinite-map keys are rejected. That keeps the unreleased file contract
|
||||
unambiguous instead of silently accepting undeclared extensions.
|
||||
|
||||
There is no migration path because no version has shipped. The raw blob is the
|
||||
future GCS import/export representation. The SITL file is a
|
||||
private host envelope `[generation, raw-profile-blob]`; it is not an upload
|
||||
blob and must not be sent to `IMPORT_*` directly.
|
||||
|
||||
## Future GCS upload contract
|
||||
|
||||
The custom dialect is prepared for a first-party GCS without borrowing
|
||||
`PARAM_*` semantics. A client will:
|
||||
|
||||
1. send `KAPTAN_CONFIG_INFO_REQUEST` and require the exact protocol, profile
|
||||
format, and schema ID in the correlated `KAPTAN_CONFIG_INFO` reply;
|
||||
2. request descriptors and values as needed;
|
||||
3. open a transaction with `KAPTAN_CONFIG_BEGIN`;
|
||||
4. either issue typed setters or begin a raw-CBOR upload with the advertised
|
||||
schema ID, then send aligned idempotent chunks in any order;
|
||||
5. validate and commit; and
|
||||
6. treat `COMMITTED_RESTART_REQUIRED` as persistence only, never live
|
||||
activation.
|
||||
|
||||
An accepted import begin returns a server-issued transfer ID. Every chunk and
|
||||
finish request echoes it, preventing delayed data from an earlier transfer
|
||||
from entering the current one. The service validates CRC-32C and the entire
|
||||
candidate before it replaces the RAM transaction.
|
||||
|
||||
This is protocol groundwork, not a claim of active aircraft configuration:
|
||||
F722 needs authenticated ingress, source binding and replay protection,
|
||||
journalled target storage, a disarmed/inhibited activation permit, and atomic
|
||||
consumer rebuild/reset before it may accept any configuration command.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Errors
|
||||
|
||||
Public Kaptan error enums derive the pure `KaptanError` implementation:
|
||||
|
||||
```rust
|
||||
#[derive(Debug, kaptan_log::KaptanError)]
|
||||
enum SensorError {
|
||||
TransferFault,
|
||||
UnexpectedIdentity(u8),
|
||||
}
|
||||
```
|
||||
|
||||
The derive implements `core::error::Error`, `Display`, and `ErrorReport`. It
|
||||
creates a bounded human-facing `module::Type::Variant` message without
|
||||
allocating, publishing telemetry, exposing generic source values, or changing
|
||||
safety state. Renaming a module, type, or variant changes that text; it is not
|
||||
a stable machine protocol identity.
|
||||
|
||||
Normal-task code may use `log::error!("{error}")`; it is routed as a bounded
|
||||
`KAPTAN_ERROR`. ISR-adjacent flight paths may enqueue the derived static
|
||||
message through their existing bounded mailbox. Neither route is a replacement
|
||||
for safety state, actuator inhibit, or typed configuration results.
|
||||
|
||||
## What the receiver sees
|
||||
|
||||
- Configuration writes receive authoritative structured failures through
|
||||
`KAPTAN_CONFIG_RESULT`: operation, lifecycle state, field IDs, validation
|
||||
rule, and protocol error code.
|
||||
- Runtime driver and link faults reach the F722 MAVLink worker as
|
||||
`KAPTAN_ERROR` text, subject to bounded transport admission. The message
|
||||
carries no per-error numeric catalog: a `KaptanError` derive supplies its
|
||||
type/variant display identity.
|
||||
- A rejected configuration operation may enqueue a companion `KAPTAN_ERROR`
|
||||
containing the high-level `ProtocolError` identity. It is intentionally not
|
||||
correlated and carries no field/rule detail; the matching
|
||||
`KAPTAN_CONFIG_RESULT` remains the sole precise authority.
|
||||
- Control, navigation, safety, and simulator error types are derive-ready but
|
||||
their live owners are not yet attached to a MAVLink worker.
|
||||
- `KAPTAN_SHUTDOWN` represents only a future completed orderly,
|
||||
output-inhibited shutdown. It is not a shutdown request, panic, hard-fault,
|
||||
reset, or retention-record protocol. F722 still uses `panic-halt`; it does
|
||||
not claim a live panic frame or retained-record replay.
|
||||
|
||||
No diagnostic message may synchronously transmit from a panic handler, hard
|
||||
fault, ISR, DMA callback, or motor-inhibit path. A later target integration
|
||||
must inhibit outputs first, persist a validated crash record, then report it
|
||||
only after the next boot’s static board telemetry is available.
|
||||
+8
-3
@@ -14,6 +14,10 @@ Markdown.
|
||||
- New contributors should read [Getting started](getting-started.md).
|
||||
- Board work belongs under [Boards](boards/index.md).
|
||||
- The currently supported closed-loop simulation is [Host SITL](sitl.md).
|
||||
- [Configuration](configuration.md) distinguishes the current SITL profile
|
||||
from immutable F722 board policy.
|
||||
- [Logs](logs.md) and [Errors](errors.md) describe the custom MAVLink
|
||||
observability surface and its current safety scope.
|
||||
- Before submitting changes, follow [Development and verification](development.md).
|
||||
|
||||
## Documentation conventions
|
||||
@@ -22,6 +26,7 @@ Documentation is centralized in `docs/src/`; source directories do not carry
|
||||
README files. Keep pages in Markdown, add each page to `SUMMARY.md`, and place
|
||||
commands beside the assumptions and safety boundary they depend on.
|
||||
|
||||
`TODO(configuration)` marks a required configuration contract that has not
|
||||
been implemented. It is not permission for an operator to substitute runtime
|
||||
values or bypass an immutable build-time safety decision.
|
||||
The current configuration contract is intentionally deployment-specific. A
|
||||
SITL Quad-X profile is a bounded restart-only CBOR snapshot; F722 hardware
|
||||
selection remains immutable board policy. Neither is permission for an
|
||||
operator to substitute runtime values or bypass an immutable safety decision.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Logs
|
||||
|
||||
Normal host/SITL task code can use the standard facade:
|
||||
|
||||
```rust
|
||||
log::debug!("estimator waiting for IMU");
|
||||
log::info!("configuration loaded");
|
||||
log::warn!("range aid stale");
|
||||
log::error!("sensor transfer failed"); // emitted as KAPTAN_ERROR
|
||||
```
|
||||
|
||||
`kaptan-log` formats once into a fixed bounded buffer, queues locally, and
|
||||
never sends MAVLink, allocates, blocks, changes flight state, or touches DMA.
|
||||
The sole MAVLink worker drains admitted records. F722 deliberately does not
|
||||
link this facade in ISR, DMA, control, actuator, panic, hard-fault, or shutdown
|
||||
contexts; those paths use static fault mailboxes that the worker turns into
|
||||
messages later.
|
||||
|
||||
## Receiver contract
|
||||
|
||||
`definitions/kaptan/log.xml` separates ordinary logs from errors:
|
||||
|
||||
```text
|
||||
KAPTAN_LOG { level, flags, message_length, message[160] }
|
||||
KAPTAN_ERROR { flags, message_length, message[160] }
|
||||
KAPTAN_SHUTDOWN { reason }
|
||||
```
|
||||
|
||||
A receiver generated from the same `kaptan.xml` revision validates
|
||||
`message_length <= 160` and decodes exactly that UTF-8 prefix. `KAPTAN_LOG`
|
||||
displays its text at the MAVLink severity in `level`; `TRACE` is encoded as
|
||||
`DEBUG` plus the `TRACE` flag. `KAPTAN_ERROR` is error-only and accepts only
|
||||
`TRUNCATED` and `COALESCED`; a `TRACE` bit is never emitted there. Unknown
|
||||
future flag bits must be ignored.
|
||||
|
||||
The derived error display text is intentionally not a numeric error catalog;
|
||||
renaming its Rust module/type/variant changes the display identity. Error
|
||||
details requiring machine action stay in their owning protocol, notably
|
||||
`KAPTAN_CONFIG_RESULT`. `KAPTAN_SHUTDOWN` has only its typed reason and is
|
||||
valid only after an orderly output-inhibited completion. Delivery is bounded
|
||||
and lossy under link pressure; heartbeat and safety telemetry use separate
|
||||
paths.
|
||||
|
||||
## Filtering
|
||||
|
||||
The SITL profile’s restart-only `observability.maximum_log_level` accepts
|
||||
MAVLink severities Error (3) through Debug (7). For example, selecting Warning
|
||||
permits warning records while suppressing info and debug records. Error-level
|
||||
records always use `KAPTAN_ERROR` and remain non-filterable. F722 uses its
|
||||
immutable board log threshold instead, because it has no active runtime
|
||||
profile.
|
||||
|
||||
Cargo `log/max_level_*` features compile calls away before the facade sees
|
||||
them; they are not a supported filtering mechanism. The build policy keeps
|
||||
that decision out of workspace dependencies.
|
||||
|
||||
The tested `SitlConfigRuntime` composition proves `log!` reaches a generated
|
||||
`KAPTAN_LOG` payload, and rejected configuration replies enqueue a generated
|
||||
`KAPTAN_ERROR` companion without replacing their authoritative result. `kaptan-sitl
|
||||
serve` does not yet attach a config/diagnostic MAVLink link, and F722 emits only
|
||||
outbound telemetry/diagnostic frames while rejecting all inbound authority.
|
||||
@@ -18,3 +18,12 @@ Telemetry transmission uses bounded frame classes. A critical frame may
|
||||
replace pending best-effort traffic, but never the DMA-owned active buffer.
|
||||
Completion retries preserve ordering and retain a transiently busy frame for a
|
||||
later service turn.
|
||||
|
||||
The custom Kaptan configuration and log definitions are aggregated by
|
||||
`definitions/kaptan.xml` from `kaptan/config.xml` and `kaptan/log.xml`.
|
||||
`KAPTAN_LOG` is an outbound human-readable four-field record. `KAPTAN_ERROR`
|
||||
is its separate bounded error channel, while `KAPTAN_SHUTDOWN` represents only
|
||||
a completed orderly output-inhibited shutdown. Configuration messages are GCS
|
||||
groundwork only: the current F722 receiver rejects every inbound frame before
|
||||
configuration dispatch. See [Configuration](configuration.md), [Logs](logs.md),
|
||||
and [Errors](errors.md) for the exact contracts.
|
||||
+23
-12
@@ -1,19 +1,30 @@
|
||||
# Reference
|
||||
|
||||
## Build-time configuration
|
||||
This page collects stable limits and points to the detailed contracts.
|
||||
|
||||
Board configuration is immutable in the compiled image. Runtime parameter
|
||||
updates and ground-station tuning are not exposed by the checked-in firmware.
|
||||
| Surface | Current contract |
|
||||
| --- | --- |
|
||||
| Flight profile | One 4 KiB-or-smaller raw CBOR blob, `profile_format = 1`, schema ID `KAPTANPROFILE-01`. |
|
||||
| SITL file | Private `[generation, raw-profile-blob]` envelope; not a MAVLink upload blob. |
|
||||
| Config transaction | One owner-bound RAM transaction; typed writes or 192-byte idempotent CBOR chunks; commit is restart-required. |
|
||||
| Config discovery | Correlated `KAPTAN_CONFIG_INFO_REQUEST` / `KAPTAN_CONFIG_INFO`, then descriptor/value requests. |
|
||||
| Diagnostics | `KAPTAN_LOG` (51020) for ordinary severity/text, `KAPTAN_ERROR` (51021) for bounded errors, and `KAPTAN_SHUTDOWN` (51022) for completed orderly output-inhibited shutdowns. |
|
||||
| F722 configuration | Immutable compiled board policy only; inbound MAVLink configuration remains disabled. |
|
||||
|
||||
`TODO(configuration)`: a future configuration system must validate and stage
|
||||
an entire profile while disarmed, commit it atomically, and prove that outputs
|
||||
remain inhibited throughout staging, activation, and power-loss recovery.
|
||||
Read [Configuration](configuration.md) for the field/consumer matrix and GCS
|
||||
upload sequence, [Logs](logs.md) for receiver decoding and filtering, and
|
||||
[Errors](errors.md) for error propagation and panic scope.
|
||||
|
||||
## Simulation package reproducibility
|
||||
## Verification
|
||||
|
||||
The host SITL Docker build uses digest-pinned base images and the locked Rust
|
||||
dependency graph. The signed Gazebo APT feed is not snapshot-pinned.
|
||||
Before review, run:
|
||||
|
||||
`TODO(reproducibility)`: snapshot/version-pin the Gazebo package set and
|
||||
verify the repository signing-key fingerprint before treating the simulator
|
||||
image as byte-for-byte reproducible release input.
|
||||
```sh
|
||||
cargo fmt --all --check
|
||||
cargo test --workspace --locked --offline
|
||||
cargo clippy --workspace --all-targets --locked -- -D warnings
|
||||
```
|
||||
|
||||
The embedded no-std binaries require their target-specific build setup; the
|
||||
host workspace test suite continues to assert that the telemetry F722 image
|
||||
has no inbound authority or actuator path.
|
||||
@@ -32,6 +32,24 @@ never contributes a controller or truth observation.
|
||||
Open <https://app.gazebosim.org/visualization>, connect to
|
||||
`ws://localhost:9002`, and leave authorization blank to view the world.
|
||||
|
||||
## Quad-X profile
|
||||
|
||||
SITL starts through the same central `ConfigManager` composition used by the
|
||||
host protocol tests. Create and validate a private host profile file with:
|
||||
|
||||
```sh
|
||||
kaptan-sitl config write-default kaptan-sitl.cbor
|
||||
kaptan-sitl config validate kaptan-sitl.cbor
|
||||
kaptan-sitl serve --config kaptan-sitl.cbor
|
||||
```
|
||||
|
||||
The file selects the restart-only profile used to build the estimator,
|
||||
controller, allocator envelope, safety supervisor, and optional log filter at
|
||||
process start. It is not the raw GCS upload blob. `kaptan-sitl serve` retains
|
||||
the central manager for that boot but does not yet open a MAVLink config/log
|
||||
endpoint; see [Configuration](configuration.md) for the exact upload groundwork
|
||||
and safety boundary.
|
||||
|
||||
## Limits
|
||||
|
||||
This model does not validate terrain, vision, flow/range sensing, wind,
|
||||
|
||||
Reference in new issue
Block a user