As-built functional specification — reconstructed from acc-simulation, nine-axis decomposition, typed fills.
min_tick_ms → 0 — minimum valid system time in milliseconds (typically 0) (link_monitor.cpp:40-45: code computes age as (bus.tick_ms_ - last_frame_tick_ms_) and never validates a lower bound; if no frame ever received, ms_since_last defaults to cal_.link_lost_timeout_ms_ (a positive value), implying tick_ms_ >= 0. The uint64_t type (signal_bus.hpp) naturally enforces non-negativity.)max_tick_ms → USER-QUESTION — maximum valid system time in milliseconds before overflow concern (The code does not specify a practical maximum; this is a system integration decision (e.g., mission duration, reboot policy). The type permits up to UINT64_MAX.)min_packet_loss_pct → 0.0 — minimum packet loss percentage (typically 0.0) (link_monitor.cpp:53: packet_loss_pct = std::clamp(packet_loss_pct, 0.0f, 100.0f); explicitly clamps lower bound to 0.0.)max_packet_loss_pct → 100.0 — maximum packet loss percentage (typically 100.0) (link_monitor.cpp:53: packet_loss_pct = std::clamp(packet_loss_pct, 0.0f, 100.0f); explicitly clamps upper bound to 100.0.)max_latency_clamp_ms → FINDING — upper saturation limit for reported latency to prevent overflow artifacts (link_monitor.cpp:59: status.latency_ms_ = static_cast<float>(ms_since_last); no clamp is applied. The value is derived from ms_since_last (uint32_t), which can reach up to UINT32_MAX before cast to float.)max_age_clamp_ms → FINDING — upper saturation limit for frame age to prevent overflow artifacts (link_monitor.cpp:40-46: ms_since_last is computed as (bus.tick_ms_ - last_frame_tick_ms_) cast to uint32_t, or defaults to cal_.link_lost_timeout_ms_. Line 46: status.ms_since_last_frame_ = ms_since_last; no clamp is applied.)time_unit → milliseconds — unit of time measurement for all timing fields (expected: milliseconds) (Variable naming throughout: tick_ms_, rx_tick_ms_, last_frame_tick_ms_, link_lost_timeout_ms_, link_degraded_timeout_ms_, link_max_latency_ms_, ms_since_last_frame_, latency_ms_. The '_ms_' suffix uniformly denotes milliseconds.)auth_fail_value → false — value assigned to command_authentic_ on authentication failure (expected: false) (command_authenticator.cpp:14,22: bus.command_authentic_ = false; assigned on invalid command (line 14) and on replay/non-advancing sequence (line 22).)replay_true_value → true — value assigned to replay_detected_ when replay attack identified (expected: true) (command_authenticator.cpp:21: bus.replay_detected_ = true; assigned when cmd.sequence_ <= last_authentic_sequence_ (non-advancing sequence).)invalid_command_value → false — value assigned to command validity flag on decode failure (expected: false) (command_decoder.cpp:38: cmd.valid_ = false; assigned when frame.valid_ is false or frame.length_ < min_payload_length (decode failure).)link_lost_state → link_state_t::lost — state value indicating complete link loss (expected: lost or equivalent enum) (link_monitor.cpp:64: state = link_state_t::lost; assigned when ms_since_last >= cal_.link_lost_timeout_ms_.)degraded_threshold_ms → cal_.link_degraded_timeout_ms_ — time threshold in ms for ok-to-degraded transition based on frame age (link_monitor.cpp:65-66: else if (ms_since_last >= cal_.link_degraded_timeout_ms_) { state = link_state_t::degraded; } — transition to degraded when frame age exceeds this calibration parameter.)latency_threshold_ms → cal_.link_max_latency_ms_ — latency threshold in ms for ok-to-degraded transition (link_monitor.cpp:73: if (status.latency_ms_ > cal_.link_max_latency_ms_ || ...) { state = link_state_t::degraded; } — transition to degraded when latency exceeds this calibration parameter.)packet_loss_threshold_pct → cal_.link_max_packet_loss_pct_ — packet loss percentage threshold for ok-to-degraded transition (link_monitor.cpp:74: if (... || status.packet_loss_pct_ > cal_.link_max_packet_loss_pct_) { state = link_state_t::degraded; } — transition to degraded when packet loss exceeds this calibration parameter.)lost_threshold_ms → cal_.link_lost_timeout_ms_ — time threshold in ms for transition to lost state (link_monitor.cpp:63-64: if (ms_since_last >= cal_.link_lost_timeout_ms_) { state = link_state_t::lost; } — transition to lost when frame age exceeds this calibration parameter.)max_window_size → FINDING — maximum number of sequence numbers tracked in the sliding window for loss calculation (link_monitor.cpp:24-25,28-29: received_count_ and expected_count_ are unbounded uint32_t accumulators. No sliding window is implemented; counts grow monotonically without pruning old entries.)max_tracked_gaps → FINDING — maximum number of sequence gaps that can be tracked simultaneously (link_monitor.cpp:22-25: sequence gap is computed as (cmd.sequence_ - last_sequence_) and immediately folded into expected_count_. No data structure tracks individual gaps; only aggregate counts exist.)initial_link_state → REVIEW — initial state of link on module startup before any frames received (expected: lost or ok) (AMBIGUOUS: The code logic produces 'lost' on first cycle if no frame arrives, but the signal_bus_t constructor's initial state for link_status_.state_ is not visible in the provided files. Human must verify signal_bus default initialization.)state_transition_sequence → lost ↔ degraded ↔ ok (bidirectional between adjacent states; direct lost ↔ ok if conditions jump) — allowed state transition paths (e.g., lost↔degraded↔ok or ok→degraded→lost→ok) (link_monitor.cpp:63-79: State is recomputed each cycle from current conditions: ms_since_last determines base state (lost >= link_lost_timeout_ms_, degraded >= link_degraded_timeout_ms_, else ok); then quality metrics can downgrade ok → degraded. No hysteresis or state memory prevents any transition; fresh frame can immediately move lost → ok (ms_since_last = 0), and threshold violations can move ok → degraded or degraded → lost.)execution_order_sequence → USER-QUESTION — ordered list of submodule execution: radio_link_receiver, command_decoder, command_authenticator, link_monitor (The execution order is an integration-level decision made by the main control loop (likely in a module not provided here). The comms module does not self-schedule its submodules.)pose_min_confidence → cal_.pose_min_confidence_ — Minimum confidence level required for pose validity (fault_memory.cpp:50 - `if (!bus.pose_.valid_ || bus.pose_.confidence_ < cal_.pose_min_confidence_)` treats pose as invalid when confidence is below the calibration parameter)min_speed_mps → FINDING — Minimum admissible speed value (likely 0.0 m/s) (fault_memory.cpp:50-52, geofence_monitor.cpp:17-23 - no validation of speed range lower bound)max_speed_mps → FINDING — Maximum admissible speed value for validity checking (fault_memory.cpp:50-52, entire safety module - no validation of speed upper bound)min_decel_mps2 → FINDING — Minimum (least aggressive) deceleration value (safe_stop_controller.cpp:21-22, entire safety module - no validation of deceleration range)max_decel_mps2 → FINDING — Maximum (most aggressive) deceleration value (safe_stop_controller.cpp:21-22 - no validation of deceleration upper bound)valid_health_states → {health_state_t::ok, health_state_t::degraded, health_state_t::critical} — Set of valid health states: ok, degraded, critical (health_monitor.cpp:13-20 - `bus.health_ = health_state_t::critical` (line 14), `health_state_t::degraded` (line 17), `health_state_t::ok` (line 19))max_faults → 64 — Maximum number of concurrent faults allowed in fault list (src/app/ugv_types.hpp: `static constexpr uint32_t max_faults = 64;`)min_distance_m → FINDING — Minimum distance to boundary (non-negative requirement) (geofence_monitor.cpp:38-43 - distance_to_boundary_m_ is computed but never clamped to a minimum)min_safe_decel_mps2 → FINDING — Minimum safe stop deceleration (safe_stop_controller.cpp:21-22 - target_decel_mps2 is assigned but never clamped to a range)max_safe_decel_mps2 → FINDING — Maximum safe stop deceleration (safe_stop_controller.cpp:21-22 - no clamping of target_decel_mps2 to maximum)emergency_decel_mps2 → cal_.emergency_decel_mps2_ — Fixed emergency deceleration value for E-stop conditions (safe_stop_controller.cpp:22 - `emergency ? cal_.emergency_decel_mps2_ : cal_.safe_stop_decel_mps2_`)coordinate_frame → USER-QUESTION — Reference frame for X and Y coordinates (e.g., ENU, vehicle, map) (The code uses X and Y coordinates from pose but does not specify the coordinate frame (ENU, vehicle, map, etc.). This must be documented in the pose_t interface specification or system architecture.)speed_units → meters per second (m/s) — Units for speed field in pose (m/s assumed) (safe_stop_controller.cpp:24 - `bus.pose_.speed_mps_` field naming convention uses `_mps` suffix; estop_handler.cpp:31 compares against `cal_.standstill_speed_mps_`)pose_min_confidence_thresh → cal_.pose_min_confidence_ — Confidence threshold below which pose is treated as invalid (fault_memory.cpp:50 - `bus.pose_.confidence_ < cal_.pose_min_confidence_` is the exact threshold check for invalidity)link_lost_state → link_state_t::lost — Link status value indicating communication loss (estop_handler.cpp:22-23 - `if (bus.link_status_.state_ == link_state_t::lost)` triggers E-stop; fault_memory.cpp:37-38 same check for fault)critical_health_state → health_state_t::critical — Health state value indicating critical condition (health_monitor.cpp:13-14 - `if (bus.critical_fault_active_) { bus.health_ = health_state_t::critical; }`)confirmation_count → 3 — Number of consecutive cycles required to confirm a fault (src/safety/fault_memory.hpp: `static constexpr uint32_t confirmation_count_ = 3;`)standstill_speed_mps → cal_.standstill_speed_mps_ — Speed threshold for standstill detection (estop_handler.cpp:31 - `const bool standstill = bus.pose_.speed_mps_ <= cal_.standstill_speed_mps_;` and safe_stop_controller.cpp:24)standstill_duration_cycles → FINDING — Number of cycles vehicle must remain below standstill speed (estop_handler.cpp:45-46 - standstill check is instantaneous, no duration debouncing)cycle_period_ms → USER-QUESTION — Expected period between run() invocations in milliseconds (The modules do not control or know their own invocation period. This is a system-level scheduling parameter that must be provided by the integration/scheduling layer.)max_faults_limit → USER-QUESTION — Maximum number of fault entries in the fault list (The value max_faults is referenced but its definition is in signal_bus.hpp (not provided). This is a system-wide constant defining fault array capacity.)overflow_policy → ignore_new (drop new entries when full) — Behavior when max_faults is reached (e.g., ignore_new, drop_oldest, deduplicate) (fault_memory.cpp:86-88 - `if (bus.faults_.size() >= max_faults) { continue; }` drops new fault entries when the list is full)max_occurrence_count → USER-QUESTION — Maximum value for fault occurrence counter before saturation (The occurrence_count_ field is incremented unbounded (line 98). The maximum is determined by the fault_entry_t.occurrence_count_ field type, which must be specified in signal_bus.hpp.)counter_overflow_behavior → wrap (unsigned integer wraparound per C++ standard) — Behavior of alive counters at maximum value (wrap or saturate) (geofence_monitor.cpp:11, safe_stop_controller.cpp:9, estop_handler.cpp:13 - `++bus.alive_counters_[...]` with no saturation logic; uint32_t type wraps per C++ standard)initial_estop_state → INACTIVE (active_=false, source_=estop_source_t::none) — Initial state of E-stop state machine (estop_handler.hpp:24-26 - member initializers `bool active_ = false;`, `estop_source_t source_ = estop_source_t::none;`, `uint64_t activated_tick_ms_ = 0;`)inactive_state → INACTIVE (active_=false) — State identifier for normal operation (no E-stop) (estop_handler.cpp:34-41,46-47 - active_=false represents the inactive state; active_=true represents active/latched)active_latched_state → ACTIVE_LATCHED (active_=true) — State identifier for latched E-stop condition (estop_handler.cpp:34-41 - `active_ = true;` on trigger rising edge (line 36), latching logic in lines 42-50)estop_trigger_sources → {local_button_pressed_, collision_imminent_, link_lost, geofence_breach_, remote_estop_request_} — Set of all conditions that can trigger E-stop activation (estop_handler.cpp:18-28 - evaluates local_button_pressed_ (line 18), bus.collision_.collision_imminent_ (line 20), bus.link_status_.state_ == link_state_t::lost (line 22), bus.geofence_.breach_ (line 24), bus.remote_command_.estop_request_ (line 26))highest_priority_source → Priority order: local_button > obstacle > link_loss > geofence > remote_command (first-match in if-else chain) — Source selection logic based on evaluation order priority (estop_handler.cpp:18-28 - if-else chain: local_button (line 18), obstacle (line 20), link_loss (line 22), geofence (line 24), remote_command (line 26))standstill_threshold_mps → cal_.standstill_speed_mps_ — Speed threshold for standstill condition in state transition (estop_handler.cpp:31,45 - `const bool standstill = bus.pose_.speed_mps_ <= cal_.standstill_speed_mps_;` used in latch release guard)execution_order_aou → USER-QUESTION — Assumption of use defining deterministic module execution order (The code comment implies fault_memory runs after fault-generating modules, but no explicit AOU-002 reference exists in the source. This assumption must be documented in the system architecture or MODULES.md.)estop_injection_caller → USER-QUESTION — Entity responsible for calling inject_local_estop() before run() (The comment indicates simulation/tests call inject_local_estop() but does not specify the production integration entity. This must be defined in the hardware abstraction layer interface specification or AOU-008.)estop_injection_aou → USER-QUESTION — Assumption of use defining inject_local_estop() calling contract (The code does not reference AOU-008. The assumption that inject_local_estop() is called before run() must be documented in the system integration specification or assumptions of use document.)link_state_enum_set → {lost, degraded, nominal} — Complete enumeration of valid communication link states (lost, degraded, nominal) (degradation_manager.cpp:11-12 and takeover_monitor.cpp:22 check `link_state_t::lost` and `link_state_t::degraded`; implicit third state nominal (not checked but required for full coverage of a tri-state link health model). The code explicitly handles lost and degraded, leaving nominal as the remaining valid state.)health_state_enum_set → {critical, degraded, nominal} — Complete enumeration of valid system health states (critical, degraded, nominal) (degradation_manager.cpp:14 checks `health_state_t::critical`, line 20 checks `health_state_t::degraded`. Implicit third state nominal (not explicitly tested but required for completeness). The code handles critical and degraded explicitly, leaving nominal as the baseline.)estop_source_enum_set → {local_button, obstacle, remote} — Complete enumeration of valid emergency stop sources (local_button, obstacle, remote, etc.) (vehicle_state_machine.cpp:13-14 enumerates `estop_source_t::local_button` and `estop_source_t::obstacle` as emergency sources. Line 21 distinguishes soft_estop (non-emergency) via `!is_emergency_estop`, implying at least one other source (likely remote). The code explicitly names local_button and obstacle; remote is inferred from the safe_stop logic.)alive_counters_min_index → 0 — Minimum valid index into alive_counters_ array (typically 0) (watchdog.cpp:17 loop starts at `uint32_t i = 0`, standard C++ array indexing convention. The for-loop explicitly begins at index 0.)alive_counters_max_index → signal_bus_t::num_monitored_modules - 1 — Maximum valid index into alive_counters_ array (number of monitored modules minus 1) (watchdog.cpp:17 loop condition `i < signal_bus_t::num_monitored_modules` yields max valid index num_monitored_modules - 1. Standard zero-indexed array upper bound.)geofence_distance_min_m → FINDING — Minimum physically valid distance to geofence boundary (may be negative for breach) (degradation_manager.cpp:24 compares `bus.geofence_.distance_to_boundary_m_ <= cal_.geofence_margin_m_` but does not validate a minimum bound. No lower-bound check or clamp on distance_to_boundary_m_ is present.)geofence_distance_max_m → FINDING — Maximum physically valid distance to geofence boundary (degradation_manager.cpp:24 reads `bus.geofence_.distance_to_boundary_m_` without any upper-bound validation or sanitization.)speed_min_mps → 0.0 — Minimum valid vehicle speed (typically 0.0 or small negative for reverse) (vehicle_state_machine.cpp:39 tests `bus.pose_.speed_mps_ <= cal_.standstill_speed_mps_` for standstill; takeover_monitor.cpp:18 tests `std::fabs(bus.plausible_command_.speed_mps_) > 0.0f` (implying non-negative semantics). The code treats speed as non-negative magnitude (fabs usage, standstill test >= 0).)speed_max_mps → FINDING — Maximum valid vehicle speed from sensor or physical limit (vehicle_state_machine.cpp:39, vehicle_state_machine.cpp:42, takeover_monitor.cpp:18 all read speed values without any upper-bound validation or saturation.)vehicle_mode_enum_set → {init, idle, remote, autonomous, safe_stop, emergency, fault} — Complete enumeration of vehicle operating modes (init, idle, remote, autonomous, safe_stop, emergency, fault) (vehicle_state_machine.cpp:47-118 switch statement enumerates all seven modes: init (line 47), idle (55), remote (67), autonomous (68), safe_stop (88), emergency (98), fault (114). Complete coverage in state machine.)degradation_level_enum_set → {full, reduced_speed, geofence_hold, safe_stop_only} — Complete enumeration of functional degradation levels (full, reduced_speed, geofence_hold, safe_stop_only) (degradation_manager.cpp lines 9, 16, 22, 26, 28 assign all four values: full (line 28), reduced_speed (22), geofence_hold (26), safe_stop_only (16). Complete enumeration in degradation logic.)bool_value_set → {true, false} — Valid boolean values {true, false} (C++ bool type per language standard. watchdog.cpp:12,25 assigns true/false to watchdog_ok_; takeover_monitor.cpp:24-25 assigns boolean expression to remote_takeover_requested_.)init_cycles_max → FINDING — Maximum value for init_cycles_ counter before saturation (e.g., UINT32_MAX or a practical limit) (vehicle_state_machine.cpp:49 increments `init_cycles_` unconditionally with no saturation or overflow protection (uint32_t wraps at 2^32).)alive_counter_modulo → 2^32 (4294967296) — Modulo base for alive counter wraparound detection (typically 2^32 for uint32_t) (watchdog.cpp:18 compares uint32_t counters directly with `==`; vehicle_state_machine.cpp:28 increments `++bus.alive_counters_[module_id::state_machine]` (uint32_t). Natural modulo-2^32 wraparound per C++ unsigned integer semantics.)distance_unit → meters — Physical unit for distance measurements (meters as declared in interface) (Variable names: degradation_manager.cpp:24 `geofence_.distance_to_boundary_m_` and `cal_.geofence_margin_m_` (suffix `_m_` denotes meters). Standard SI unit naming convention.)speed_unit → meters per second — Physical unit for speed measurements (meters per second as declared in interface) (Variable names: vehicle_state_machine.cpp:39 `bus.pose_.speed_mps_` and `cal_.standstill_speed_mps_` (suffix `_mps_` denotes meters per second). Standard SI unit naming convention.)mode_on_invalid_input → FINDING — Operating mode to enter on invalid input detection (likely emergency or fault) (No input validation logic exists in the supervision module files. The code reads all inputs (link_status_, health_, estop_, geofence_, remote_command_, plausible_command_) without any validity checks or domain enforcement.)degradation_on_invalid_input → FINDING — Degradation level to set on invalid input detection (likely safe_stop_only) (No input validation or invalid-input handling exists in supervision module. degradation_manager.cpp reads inputs directly without validation.)watchdog_on_counter_anomaly → false — Watchdog status value on counter anomaly detection (must be false to indicate failure) (watchdog.cpp:19 sets `ok = false` when counter anomaly detected (line 18: `bus.alive_counters_[i] == last_counters_[i]`), then line 25 assigns `bus.watchdog_ok_ = ok`. False indicates watchdog failure.)supervision_cycle_period_ms → USER-QUESTION — Fixed cycle time for supervision module execution in milliseconds (The module code does not and should not hardcode its scheduling period. This is a deployment/integration configuration decision (RTOS tick rate, cyclic executive period, etc.).)self_test_cycles → 3 — Number of init cycles required for subsystem initialization before transitioning to idle (src/supervision/vehicle_state_machine.hpp: `static constexpr uint32_t self_test_cycles_ = 3;`)watchdog_timeout_cycles → 1 — Number of consecutive cycles without alive counter increment before declaring stall (watchdog.cpp:18 triggers fault immediately when `bus.alive_counters_[i] == last_counters_[i]` (no increment in a single cycle). No debounce or multi-cycle tolerance; one missed increment = fault.)standstill_confirmation_cycles → FINDING — Number of consecutive low-speed cycles required to confirm standstill state (vehicle_state_machine.cpp:39 evaluates standstill as instantaneous condition `bus.pose_.speed_mps_ <= cal_.standstill_speed_mps_` with no debounce or multi-cycle confirmation.)num_monitored_modules → 12 — Number of modules being monitored for liveness (determines array iteration bounds) (src/app/signal_bus.hpp: `static constexpr uint32_t num_monitored_modules = 12;`)alive_counters_array_length → signal_bus_t::num_monitored_modules — Declared length of alive_counters_ array (must match num_monitored_modules) (watchdog.cpp:17,23 references `signal_bus_t::num_monitored_modules` as the array length; watchdog.hpp:23 declares `std::array<uint32_t, signal_bus_t::num_monitored_modules> last_counters_`. Declared array size.)max_monitored_modules_limit → FINDING — Maximum number of modules that can be monitored (design or resource constraint) (No validation or limit check on num_monitored_modules exists in the supervision module. watchdog.cpp:17 loops to num_monitored_modules without bound checking.)alive_counters_min_index → 0 — Minimum valid array index (typically 0) (watchdog.cpp:17 loop starts at `uint32_t i = 0`. Standard array indexing from zero.)alive_counters_max_index → signal_bus_t::num_monitored_modules - 1 — Maximum valid array index (num_monitored_modules - 1) (watchdog.cpp:17 loop condition `i < signal_bus_t::num_monitored_modules` yields max index num_monitored_modules - 1.)initial_vehicle_mode → REVIEW — Initial operating mode on module startup (must be init per state machine diagram) (The supervision module does not initialize vehicle_mode_ to init; it assumes this is done by the signal bus or application initialization. This initialization responsibility is ambiguous and should be clarified.)init_entry_action → FINDING — Action performed on init state entry (reset init_cycles_ to 0 per state machine) (vehicle_state_machine.cpp:48-52 handles init state but does NOT reset init_cycles_ to 0 on entry. Line 49 only increments it. If the state machine re-enters init (e.g., after a reset), init_cycles_ will not be cleared.)emergency_estop_sources → {local_button, obstacle} — Set of estop_source_t values that trigger emergency mode (e.g., local_button, obstacle) (vehicle_state_machine.cpp:11-15 function `is_emergency_estop` explicitly lists `estop_source_t::local_button` and `estop_source_t::obstacle` as emergency triggers (line 13-14).)safe_stop_estop_sources → {remote} (and any estop_source_t not in {local_button, obstacle}) — Set of estop_source_t values that trigger safe_stop mode (e.g., remote soft estop) (vehicle_state_machine.cpp:21 defines soft_estop as `bus.estop_.active_ && !is_emergency_estop(bus.estop_)`, meaning any active estop source NOT classified as emergency is a safe-stop trigger. Only remote is named in the earlier slot resolution; code uses complement logic.)transition_priority_order → emergency_trigger > safe_stop_trigger > operational_transitions — Priority sequence for evaluating competing transitions (emergency > safe_stop > operational per description) (vehicle_state_machine.cpp:56-57, 69-72, 90-91 all check emergency_trigger first (highest priority), then safe_stop_trigger, then operational transitions (remote/autonomous requests). Consistent if-else ordering enforces priority.)fault_recovery_mechanism → none (no automatic recovery) — External intervention mechanism required to exit fault state (no automatic recovery per state machine) (vehicle_state_machine.cpp:114-117 fault state case always assigns `next = vehicle_mode_t::fault` with comment 'no automatic recovery'. Fault is a terminal state within the state machine.)have_snapshot_initial_value → false — Initial value of snapshot validity flag on first cycle (must be false per AOU-007) (watchdog.hpp:24 declares `bool have_snapshot_ = false;` (explicit member initialization). This prevents false watchdog faults on the first cycle (line watchdog.cpp:14 guards comparison with `if (have_snapshot_)`).)hard_plausibility_speed_limit_mps → 2.0 * max(max_command_speed_mps_, max_reverse_speed_mps_) — Gross out-of-range speed threshold for corruption detection (2x normal limits per declared behavior) (command_plausibility.cpp:28-29: `const float hard_speed_limit = 2.0f * std::max(cal_.max_command_speed_mps_, cal_.max_reverse_speed_mps_);` then checked at line 32 `std::fabs(req_speed) > hard_speed_limit`)hard_plausibility_yaw_limit_radps → 2.0 * max_command_yaw_rate_radps_ — Gross out-of-range yaw rate threshold for corruption detection (2x normal limits per declared behavior) (command_plausibility.cpp:30: `const float hard_yaw_limit = 2.0f * cal_.max_command_yaw_rate_radps_;` then checked at line 33 `std::fabs(req_yaw) > hard_yaw_limit`)plausibility_reject_value → false — Value assigned to plausible_command_.plausible_ flag when input is rejected (command_plausibility.cpp:34: `bus.plausible_command_.plausible_ = false;` when hard limits exceeded (lines 31-39))min_output_speed_mps → FINDING — Minimum (most negative) speed setpoint output, corresponding to maximum reverse (setpoint_generator.cpp:30: `bus.motion_setpoint_.target_speed_mps_ = target_speed;` — no clamping applied to output)max_output_speed_mps → FINDING — Maximum forward speed setpoint output (setpoint_generator.cpp:30: `bus.motion_setpoint_.target_speed_mps_ = target_speed;` — no clamping applied to output)min_output_yaw_radps → FINDING — Minimum (most negative) yaw rate setpoint output (setpoint_generator.cpp:31-32: `bus.motion_setpoint_.target_yaw_rate_radps_ = bus.arbitrated_command_.yaw_setpoint_radps_;` — no clamping)max_output_yaw_radps → FINDING — Maximum yaw rate setpoint output (setpoint_generator.cpp:31-32: `bus.motion_setpoint_.target_yaw_rate_radps_ = bus.arbitrated_command_.yaw_setpoint_radps_;` — no clamping)min_output_accel_mps2 → -max_decel_mps2_ — Minimum (most negative) acceleration setpoint, representing maximum deceleration (setpoint_generator.cpp:28: `accel = std::clamp(accel, -cal_.max_decel_mps2_, cal_.max_accel_mps2_);`)max_output_accel_mps2 → max_accel_mps2_ — Maximum acceleration setpoint output (setpoint_generator.cpp:28: `accel = std::clamp(accel, -cal_.max_decel_mps2_, cal_.max_accel_mps2_);`)min_clamp_speed_mps → -max_reverse_speed_mps_ — Normal operating minimum speed clamp (negative for reverse) (command_plausibility.cpp:43-45: `float speed = std::clamp(req_speed, -cal_.max_reverse_speed_mps_, cal_.max_command_speed_mps_);`)max_clamp_speed_mps → max_command_speed_mps_ — Normal operating maximum speed clamp (command_plausibility.cpp:43-45: `float speed = std::clamp(req_speed, -cal_.max_reverse_speed_mps_, cal_.max_command_speed_mps_);`)min_clamp_yaw_radps → -max_command_yaw_rate_radps_ — Normal operating minimum yaw rate clamp (command_plausibility.cpp:46-48: `float yaw = std::clamp(req_yaw, -cal_.max_command_yaw_rate_radps_, cal_.max_command_yaw_rate_radps_);`)max_clamp_yaw_radps → max_command_yaw_rate_radps_ — Normal operating maximum yaw rate clamp (command_plausibility.cpp:46-48: `float yaw = std::clamp(req_yaw, -cal_.max_command_yaw_rate_radps_, cal_.max_command_yaw_rate_radps_);`)max_speed_step_mps → max_command_speed_step_mps_ — Maximum allowed per-cycle speed change for rate limiting (command_plausibility.cpp:51-53: `const float speed_lo = last_speed_mps_ - cal_.max_command_speed_step_mps_; const float speed_hi = last_speed_mps_ + cal_.max_command_speed_step_mps_; speed = std::clamp(speed, speed_lo, speed_hi);`)max_yaw_step_radps → max_command_yaw_step_radps_ — Maximum allowed per-cycle yaw rate change for rate limiting (command_plausibility.cpp:55-57: `const float yaw_lo = last_yaw_rate_radps_ - cal_.max_command_yaw_step_radps_; const float yaw_hi = last_yaw_rate_radps_ + cal_.max_command_yaw_step_radps_; yaw = std::clamp(yaw, yaw_lo, yaw_hi);`)reverse_speed_magnitude_mps → max_reverse_speed_mps_ — Maximum magnitude of reverse speed (stored as positive value per description) (command_plausibility.cpp:44: `-cal_.max_reverse_speed_mps_` used as lower clamp bound; negative speed values represent reverse motion with magnitude up to this limit)yaw_rate_sign_convention → USER-QUESTION — Sign convention for yaw rate: which direction (left/right turn) corresponds to positive radians per second (USER DECISION REQUIRED: The code treats yaw rate as a signed value in radians/sec but does not specify the vehicle coordinate frame convention (positive left turn vs. positive right turn). This is a vehicle-level configuration choice.)accel_computation_formula → (target_speed_mps - last_target_speed_mps) / period_s — Formula used to derive acceleration from speed delta in setpoint generation (setpoint_generator.cpp:27: `float accel = (target_speed - last_target_speed_mps_) / period_s_;` where period_s_ = 0.020f (line 20))auth_fail_plausible_value → false — Value of plausible_ flag when authentication fails (command_plausibility.cpp:13-14: `if (!bus.command_authentic_ || !bus.remote_command_.valid_) { bus.plausible_command_.plausible_ = false;`)auth_fail_condition → false — Value of command_authentic_ that indicates authentication failure (command_plausibility.cpp:13: `if (!bus.command_authentic_` — authentication failure detected when command_authentic_ is false)invalid_command_condition → false — Value of remote_command_.valid_ that indicates invalid command (command_plausibility.cpp:13: `if (!bus.command_authentic_ || !bus.remote_command_.valid_)` — invalid when valid_ is false)safe_stop_source_value → command_source_t::safe_stop_controller — Arbitration source enumeration value indicating safe-stop has control (command_arbiter.cpp:16-17: `if (bus.safe_stop_.active_) { out.source_ = command_source_t::safe_stop_controller;`)safe_stop_active_condition → true — Value of safe_stop_.active_ flag that indicates emergency stop condition (command_arbiter.cpp:16: `if (bus.safe_stop_.active_)` — safe-stop triggered when active_ flag is true)fault_setpoint_values → {speed: 0.0, yaw: 0.0} — Set of motion setpoint values applied during fault conditions (safe-stop, auth failure, invalid command) (command_arbiter.cpp:18-19 (safe-stop), 32-33 (none source), command_plausibility.cpp:15-16 (auth fail): all set speed and yaw to 0.0f)cycle_period_ms → 20 — Fixed cycle time in milliseconds (setpoint_generator.hpp:20: `static constexpr float period_s_ = 0.020f;` — 20 milliseconds (0.020 seconds))cycle_jitter_tolerance_ms → USER-QUESTION — Acceptable timing jitter around nominal cycle period (USER DECISION REQUIRED: The code assumes exactly 20ms cycles (setpoint_generator.hpp:20) but does not implement jitter detection or tolerance enforcement. Timing tolerance is a scheduler / RTOS configuration decision not enforced by this module.)heartbeat_increment → 1 — Value added to alive counter each cycle (command_arbiter.cpp:11: `++bus.alive_counters_[module_id::command_arbiter];` — pre-increment operator adds 1)command_staleness_timeout_ms → FINDING — Maximum age of remote_command_ before considered stale (command_plausibility.cpp entire file — no timestamp checking or staleness detection implemented)stale_command_plausible_value → FINDING — Value of plausible_ flag when command input is stale (command_plausibility.cpp — no staleness detection, therefore no plausible_ assignment for stale condition)command_arbiter_module_id → module_id::command_arbiter — Array index corresponding to command_arbiter module ID (command_arbiter.cpp:11: `++bus.alive_counters_[module_id::command_arbiter];` — enum or constant value used as array index)heartbeat_overflow_value → 4294967295 (UINT32_MAX) — Maximum value of uint32_t counter before overflow (command_arbiter.cpp:11: `++bus.alive_counters_[module_id::command_arbiter];` operates on implicit uint32_t array (standard practice); overflow at 2^32-1)overflow_behavior → wrap_to_zero — Behavior when heartbeat counter reaches maximum value (natural wrap, explicit reset, etc.) (command_arbiter.cpp:11: `++bus.alive_counters_[...]` — C++ unsigned integer overflow wraps to 0 per language standard (well-defined modulo arithmetic))arbitration_priority_order → safe_stop > autonomous > remote_operator > none — Ordered list of command source priorities from highest to lowest (command_arbiter.cpp:16-34: if-else chain: safe_stop_ (line 16) checked first, then autonomous mode (line 20), then plausible remote (line 26), else none (line 31))autonomous_source_value → command_source_t::autonomous_mission — Arbitration source enumeration value for autonomous mode (command_arbiter.cpp:22: `out.source_ = command_source_t::autonomous_mission;` when vehicle_mode_ == autonomous)autonomous_mode_condition → vehicle_mode_t::autonomous — Value of vehicle_mode_ that indicates autonomous operation (command_arbiter.cpp:20: `} else if (bus.vehicle_mode_ == vehicle_mode_t::autonomous) {`)remote_operator_source_value → command_source_t::remote_operator — Arbitration source enumeration value for remote operator control (command_arbiter.cpp:27: `out.source_ = command_source_t::remote_operator;` when plausible_command_.plausible_ is true)remote_mode_condition → REVIEW — Value of vehicle_mode_ that permits remote operator control (AMBIGUITY: Remote operator is selected based only on plausible_command_.plausible_ (line 26), with NO explicit vehicle_mode_ check. This differs from the requirement pattern which expects a mode check. The code allows remote commands in any mode (other than safe-stop or autonomous), which may be intentional but contradicts the requirement's expectation of a specific remote_mode_condition.)none_source_value → command_source_t::none — Arbitration source enumeration value when no command source is active (command_arbiter.cpp:31: `out.source_ = command_source_t::none;` in final else clause)cycle_time_ms → 20 — Cycle period within which ordered execution must complete (setpoint_generator.hpp:20: `static constexpr float period_s_ = 0.020f;` — 20 milliseconds)shared_state_elements → {last_speed_mps_, last_yaw_rate_radps_, last_target_speed_mps_} — Set of state variables shared across plausibility, arbitration, and setpoint generation stages that require data coherency (command_plausibility.hpp:21-22 (last_speed_mps_, last_yaw_rate_radps_); setpoint_generator.hpp:25 (last_target_speed_mps_) — private member state persisting across cycles)min_accel_mps2 → FINDING — Minimum admissible longitudinal acceleration input (typically negative for deceleration) (drive_arbitrator.cpp:27-28 and brake_arbitrator.cpp:17)max_accel_mps2 → FINDING — Maximum admissible longitudinal acceleration input (drive_arbitrator.cpp:27-28)min_steering_input_rad → FINDING — Minimum admissible steering angle input (typically negative for left) (steering_arbitrator.cpp:21-23)max_steering_input_rad → FINDING — Maximum admissible steering angle input (typically positive for right) (steering_arbitrator.cpp:21-23)min_safe_stop_decel_mps2 → FINDING — Minimum admissible safe-stop deceleration (typically zero or slightly negative) (brake_arbitrator.cpp:21)max_safe_stop_decel_mps2 → FINDING — Maximum admissible safe-stop deceleration magnitude (brake_arbitrator.cpp:21)min_drive_torque_nm → 0.0 — Minimum motor torque command (typically negative for regenerative braking) (drive_arbitrator.cpp:27-28, 'std::max(0.0f, bus.limited_motion_.limited_accel_mps2_)' — only non-negative acceleration produces drive torque; negative values are clamped to zero)max_drive_torque_nm → FINDING — Maximum motor torque command (drive_arbitrator.cpp:31, actuator_interface.cpp:28)min_brake_force_n → 0.0 — Minimum brake force (typically zero) (brake_arbitrator.cpp:17, 'std::max(0.0f, -bus.limited_motion_.limited_accel_mps2_)' — deceleration is clamped to non-negative, so brake_force_n ≥ 0)max_brake_force_n → FINDING — Maximum brake force (brake_arbitrator.cpp:29-31, actuator_interface.cpp:29)min_steering_output_rad → -cal_.max_steering_rad_ — Minimum output steering angle (negative limit) (steering_arbitrator.cpp:21-23, 'std::clamp(bus.limited_motion_.limited_steering_rad_, -cal_.max_steering_rad_, cal_.max_steering_rad_)' — output is clamped to [-max_steering_rad_, +max_steering_rad_])max_steering_output_rad → cal_.max_steering_rad_ — Maximum output steering angle (positive limit) (steering_arbitrator.cpp:21-23, 'std::clamp(..., -cal_.max_steering_rad_, cal_.max_steering_rad_)' — output upper limit is +max_steering_rad_)neg_max_steering_rad → -cal_.max_steering_rad_ — Negative mechanical steering limit (typically -max_steering_rad_) (steering_arbitrator.cpp:21-23, 'std::clamp(..., -cal_.max_steering_rad_, cal_.max_steering_rad_)' — negative limit is -max_steering_rad_)pos_max_steering_rad → cal_.max_steering_rad_ — Positive mechanical steering limit (max_steering_rad_) (steering_arbitrator.cpp:21-23, 'std::clamp(..., -cal_.max_steering_rad_, cal_.max_steering_rad_)' — positive limit is +max_steering_rad_)max_brake_force_limit_n → FINDING — Upper saturation limit for brake force command (brake_arbitrator.cpp:29-31, actuator_interface.cpp:29)holding_brake_force_n → 700.0 — Brake force applied when actuators disabled (per AOU-005, 700 N) (actuator_interface.cpp:11-14, 'holding_brake_force_n = vehicle_mass_kg * holding_decel_mps2 = 350.0f * 2.0f = 700.0f')vehicle_mass_kg → 350.0 — Vehicle mass used in drivetrain torque calculation (per AOU-003, 350 kg) (src/actuation/brake_arbitrator.cpp: `static constexpr float vehicle_mass_kg = 350.0f;`)wheel_radius_m → 0.15 — Wheel radius used in torque calculation (per AOU-003, 0.15 m) (src/actuation/drive_arbitrator.cpp: `static constexpr float wheel_radius_m = 0.15f;`)gear_ratio → 10.0 — Gear ratio used in torque calculation (per AOU-003, 10:1) (src/actuation/drive_arbitrator.cpp: `static constexpr float gear_ratio = 10.0f;`)vehicle_mass_for_brake_kg → 350.0 — Vehicle mass used in brake force calculation (likely same as vehicle_mass_kg) (brake_arbitrator.cpp:9, 'static constexpr float vehicle_mass_kg = 350.0f' — used in line 29: brake_force_n = decel_mps2 * vehicle_mass_kg)positive_steering_direction → USER-QUESTION — Interpretation of positive steering angle (right or left turn) (The code passes steering angle through without interpretation or sign convention enforcement. The physical meaning (left/right) depends on vehicle hardware configuration and is not specified in the actuation module code. This is a system-level convention that must be provided by integration documentation.)negative_accel_meaning → deceleration — Interpretation of negative acceleration (deceleration or reverse thrust) (drive_arbitrator.cpp:25-26 comment 'deceleration is handled by the brake_arbitrator', brake_arbitrator.cpp:16-17 'Deceleration demanded by the motion controller (negative accel)' and 'std::max(0.0f, -bus.limited_motion_.limited_accel_mps2_)')fault_mode_value → vehicle_mode_t::fault — vehicle_mode_t enumeration value indicating fault state (actuator_interface.cpp:23, 'bus.vehicle_mode_ != vehicle_mode_t::fault' — actuators disabled when mode equals fault)init_mode_value → vehicle_mode_t::init — vehicle_mode_t enumeration value indicating initialization state (actuator_interface.cpp:24, 'bus.vehicle_mode_ != vehicle_mode_t::init' — actuators disabled when mode equals init)emergency_decel_value_mps2 → USER-QUESTION — Calibration parameter for E-stop deceleration magnitude (The emergency deceleration is a calibration parameter (cal_.emergency_decel_mps2_) whose value must be supplied by the customer/integrator via ugv_calibration_t. The code does not hardcode this safety-critical tuning value.)safe_stop_decel_source → safe_stop_.target_decel_mps2_ — Source of deceleration value during safe-stop (input field) (brake_arbitrator.cpp:20-21, 'if (bus.safe_stop_.active_) { decel_mps2 = std::max(decel_mps2, bus.safe_stop_.target_decel_mps2_); }')drive_torque_on_disable → 0.0 — Drive torque value when actuators disabled (typically zero) (actuator_interface.cpp:35, 'bus.actuator_command_.drive_torque_nm_ = 0.0f' in the else branch (disabled case))cycle_time_ms → 20 — Module execution period (20 ms per description) (drive_arbitrator.hpp:10, brake_arbitrator.hpp:10-11, steering_arbitrator.hpp:10, actuator_interface.hpp:10-11 — all comments state 'Task module (20 ms period)')alive_counter_increment → 1 — Increment value for alive counter each cycle (typically 1) (actuator_interface.cpp:21, '++bus.alive_counters_[module_id::actuation]' — prefix increment by 1)alive_counter_modulo → USER-QUESTION — Wrap-around value for alive counter (e.g., 256 for uint8_t) (The wrap-around modulo depends on the data type of alive_counters_[]. The code uses native unsigned integer overflow behavior, but the array element type is not visible in these files. The modulo value (256 for uint8_t, 65536 for uint16_t, etc.) must be determined from the signal_bus_t definition.)actuation_module_id_value → USER-QUESTION — Enumeration value for actuation module ID used as array index (The numeric value of the module_id::actuation enumeration constant is not defined in the provided source files. This must come from the module_id enum definition (likely in app/signal_bus.hpp or app/ugv_config.hpp not provided).)alive_counters_array_size → USER-QUESTION — Size of the alive_counters array to prevent out-of-bounds access (The size of the alive_counters_ array is not defined in the provided source files. This must come from the signal_bus_t structure definition (not provided in these files).)normal_operation_modes → {init, idle, remote, autonomous, safe_stop, emergency, fault} — Set of vehicle_mode_t values that permit actuator enable (e.g., {DRIVE, REVERSE}) (src/app/ugv_types.hpp: enum vehicle_mode_t)drive_torque_zero_conditions → (estop_.active_ || safe_stop_.active_ || !actuators_enabled_) — Logical conditions under which drive torque is set to zero (e.g., during braking or stops) (drive_arbitrator.cpp:20-22 'if (bus.estop_.active_ || bus.safe_stop_.active_) { bus.drive_torque_request_nm_ = 0.0f; }' and actuator_interface.cpp:35 'bus.actuator_command_.drive_torque_nm_ = 0.0f' when not enabled)input_read_phase → USER-QUESTION — Point in cycle when inputs are sampled (e.g., start, post-arbitration) (The actuation modules read inputs via signal_bus_t& reference, but the code does not enforce or document the timing of when this snapshot is taken relative to the cycle. This is a system-level integration concern determined by the task scheduler/executor, not implemented in the actuation module itself.)output_write_deadline → USER-QUESTION — Point in cycle by which all outputs must be written (e.g., before actuator_interface call) (The code writes all outputs before returning from actuator_interface::run(), but the deadline relative to other system tasks (e.g., before actuator_interface is invoked) is a system-level scheduling constraint not enforced in this module code.)execution_sequence_reference → AOU-002 — Reference to the fixed call sequence (arbitrators → actuation → actuator_interface) (REQ-ACT-009 requirement text itself references 'per the fixed sequence in AOU-002')min_tick_ms → FINDING — minimum valid system timestamp in milliseconds (wheel_odometry.cpp:38, imu_interface.cpp:29, pose_estimator.cpp:15 — tick_ms_ is read from bus without any validation)max_tick_ms → FINDING — maximum valid system timestamp in milliseconds (typically uint64_t max or practical system limit) (wheel_odometry.cpp:38, imu_interface.cpp:29, pose_estimator.cpp:15 — tick_ms_ is read from bus without any validation)min_encoder_ticks → FINDING — minimum valid encoder tick count value (wheel_odometry.cpp:8-11 — inject_ticks accepts int64_t left/right without validation)max_encoder_ticks → FINDING — maximum valid encoder tick count value (wheel_odometry.cpp:8-11 — inject_ticks accepts int64_t left/right without validation)min_yaw_rate → FINDING — minimum valid IMU yaw rate in radians per second (imu_interface.cpp:8-10 — inject_imu accepts imu_data_t without validation of yaw_rate_radps_)max_yaw_rate → FINDING — maximum valid IMU yaw rate in radians per second (imu_interface.cpp:8-10 — inject_imu accepts imu_data_t without validation of yaw_rate_radps_)min_speed → FINDING — minimum valid odometry speed value (wheel_odometry.cpp:42 — speed_mps_ computed without bounds validation)max_speed → FINDING — maximum valid odometry speed value (wheel_odometry.cpp:42 — speed_mps_ computed without bounds validation)min_x_position → FINDING — minimum valid x coordinate in meters (pose_estimator.cpp:36-47 — x_m_ accumulated without bounds checking)max_x_position → FINDING — maximum valid x coordinate in meters (pose_estimator.cpp:36-47 — x_m_ accumulated without bounds checking)min_y_position → FINDING — minimum valid y coordinate in meters (pose_estimator.cpp:37-48 — y_m_ accumulated without bounds checking)max_y_position → FINDING — maximum valid y coordinate in meters (pose_estimator.cpp:37-48 — y_m_ accumulated without bounds checking)min_heading → -π (approximately -3.14159) — minimum valid heading angle in radians (typically -π) (pose_estimator.cpp:30-33 — while (heading_rad_ < -static_cast<float>(M_PI)) heading_rad_ += two_pi;)max_heading → +π (approximately +3.14159) — maximum valid heading angle in radians (typically +π) (pose_estimator.cpp:30-32 — while (heading_rad_ > static_cast<float>(M_PI)) heading_rad_ -= two_pi;)min_pose_speed → 0.0 — minimum valid pose speed value (pose_estimator.cpp:23-24,50 — const float speed_mps = odo_ok ? bus.odometry_.speed_mps_ : 0.0f; out.speed_mps_ = speed_mps;)max_pose_speed → FINDING — maximum valid pose speed value (pose_estimator.cpp:23,50 — speed_mps copied from bus.odometry_.speed_mps_ without upper limit check)min_confidence → 0.0 — minimum confidence value (typically 0.0) (pose_estimator.cpp:44 — confidence = std::clamp(confidence, 0.0f, 1.0f);)max_confidence → 1.0 — maximum confidence value (typically 1.0) (pose_estimator.cpp:44 — confidence = std::clamp(confidence, 0.0f, 1.0f);)clamp_min_x → FINDING — lower clamp limit on x position in meters (pose_estimator.cpp:36-47 — x_m_ is integrated and assigned without clamping)clamp_max_x → FINDING — upper clamp limit on x position in meters (pose_estimator.cpp:36-47 — x_m_ is integrated and assigned without clamping)clamp_min_y → FINDING — lower clamp limit on y position in meters (pose_estimator.cpp:37-48 — y_m_ is integrated and assigned without clamping)clamp_max_y → FINDING — upper clamp limit on y position in meters (pose_estimator.cpp:37-48 — y_m_ is integrated and assigned without clamping)clamp_min_conf → 0.0 — lower clamp limit on confidence (typically 0.0) (pose_estimator.cpp:44 — confidence = std::clamp(confidence, 0.0f, 1.0f);)clamp_max_conf → 1.0 — upper clamp limit on confidence (typically 1.0) (pose_estimator.cpp:44 — confidence = std::clamp(confidence, 0.0f, 1.0f);)wheel_ticks_unit → ticks/meter — unit of wheel_ticks_per_meter parameter (ticks/meter) (wheel_odometry.cpp:27-28,35 — ticks_per_meter = cal_.wheel_ticks_per_meter_; ds_m = avg_ticks / ticks_per_meter;)heading_unit → radians — unit of heading angle (radians or degrees) (pose_estimator.cpp:29-33 — heading_rad_ += yaw_rate * dt_s; comparison with M_PI)positive_rotation_direction → counterclockwise — sign convention for positive rotation (counterclockwise or clockwise) (pose_estimator.cpp:29 — heading_rad_ += yaw_rate * dt_s;)yaw_rate_unit → radians/second — unit of IMU yaw rate (rad/s or deg/s) (pose_estimator.cpp:24,29 — const float yaw_rate = ... bus.imu_.yaw_rate_radps_; heading_rad_ += yaw_rate * dt_s;)position_unit → meters — unit of position coordinates (meters) (pose_estimator.cpp:20-21,47-48 — float x_m_ = 0.0f; float y_m_ = 0.0f; out.x_m_ = x_m_; out.y_m_ = y_m_;)time_unit → milliseconds — unit of time for delta calculations (milliseconds) (pose_estimator.cpp:15 — static_cast<float>(bus.tick_ms_ - last_tick_ms_) / 1000.0f;)imu_invalid_value → false — value to assign to imu_.valid when IMU data is stale (typically false) (imu_interface.cpp:24,31 — out.valid_ = false; out.valid_ = latest_.valid_ && fresh;)odo_invalid_value → false — value to assign to odometry_.valid when odometry data fails checks (typically false) (wheel_odometry.cpp:21 — out.valid_ = false;)odo_validity_condition → !injected_ (no fresh sensor data injected) — condition under which odometry is marked invalid (e.g., tick delta out of range, non-monotonic) (wheel_odometry.cpp:19-24 — if (!injected_) { out.valid_ = false; ... })confidence_degradation_per_invalid_sensor → 0.5 — amount by which confidence is reduced per invalid sensor (described as 0.5) (pose_estimator.cpp:41-43 — float confidence = 1.0f; if (!odo_ok) confidence -= 0.5f; if (!imu_ok) confidence -= 0.5f;)pose_invalid_value → false — value to assign to pose_.valid when confidence is below threshold (typically false) (pose_estimator.cpp:52 — out.valid_ = confidence >= cal_.pose_min_confidence_;)fallback_integration_strategy → zero substitution — strategy when sensor invalid: zero-order hold, use last valid, skip update, etc. (pose_estimator.cpp:23-24 — const float speed_mps = odo_ok ? bus.odometry_.speed_mps_ : 0.0f; const float yaw_rate = imu_ok ? bus.imu_.yaw_rate_radps_ : 0.0f;)dt_calculation_formula → (current_tick_ms - last_tick_ms) / 1000.0 — formula for computing time delta from tick_ms_ (e.g., current - previous) (pose_estimator.cpp:14-16 — const float dt_s = have_last_ ? static_cast<float>(bus.tick_ms_ - last_tick_ms_) / 1000.0f : 0.0f;)staleness_threshold_ms → USER-QUESTION — timeout value in milliseconds for marking IMU data stale (The staleness threshold is read from calibration parameter cal_.imu_stale_timeout_ms_. This is a tuning parameter that must be supplied by the user/configuration; the code does not hardcode a specific value.)nominal_cycle_time_ms → USER-QUESTION — expected cycle time in milliseconds (from AOU-002) (The code computes actual cycle time dynamically from timestamp deltas; no nominal cycle time constant is hardcoded. This is an operational assumption external to the code (depends on scheduler/caller behavior).)non_monotonic_tick_behavior → FINDING — behavior when tick_ms_ is non-monotonic: clamp dt, skip update, error flag (pose_estimator.cpp:14-16, wheel_odometry.cpp:37-38 — tick_ms_ subtraction performed without monotonicity check)validity_debounce_count → FINDING — number of consecutive cycles required to confirm sensor validity state change (imu_interface.cpp:31, wheel_odometry.cpp:21,43 — valid_ set immediately without debouncing logic)alive_counter_index → module_id::localization — array index used for localization alive counter (pose_estimator.cpp:12 — ++bus.alive_counters_[module_id::localization];)alive_counter_min_index → FINDING — minimum valid index for alive_counters_ array (pose_estimator.cpp:12 — alive_counters_ accessed without bounds check)alive_counter_max_index → FINDING — maximum valid index for alive_counters_ array (pose_estimator.cpp:12 — alive_counters_ accessed without bounds check)max_alive_counter_value → UINT64_MAX (18446744073709551615) — maximum value for uint64_t alive counter (typically UINT64_MAX) (pose_estimator.cpp:12 — ++bus.alive_counters_[module_id::localization]; (uint64_t type, no explicit limit))counter_overflow_behavior → wrap to 0 — behavior on counter overflow: wrap to 0, saturate, etc. (pose_estimator.cpp:12 — ++bus.alive_counters_[module_id::localization]; (uint64_t increment))initial_x → 0.0 — initial x position at startup (assumed 0 per AOU-006) (pose_estimator.cpp:20 — float x_m_ = 0.0f;)initial_y → 0.0 — initial y position at startup (assumed 0 per AOU-006) (pose_estimator.cpp:21 — float y_m_ = 0.0f;)initial_heading → 0.0 — initial heading at startup (assumed 0 per AOU-006) (pose_estimator.cpp:22 — float heading_rad_ = 0.0f;)initial_confidence → REVIEW — initial confidence value at startup (Confidence is computed from scratch each cycle (starting at 1.0, then degraded). There is no explicit initialization of a persistent confidence state. The first output will have confidence based on first-cycle sensor validity (potentially 0.0, 0.5, or 1.0). Ambiguous what 'initial confidence' means: first output value or a persistent initial state.)state_after_first_valid_sensor → FINDING — module state after first valid sensor injection (e.g., INITIALIZED, RUNNING) (pose_estimator.cpp — no explicit state machine or state transition logic present)heading_wrap_behavior → iterative while-loop normalization — method for wrapping heading to [-π, π] (modulo, conditional branch) (pose_estimator.cpp:31-33 — while (heading_rad_ > M_PI) heading_rad_ -= two_pi; while (heading_rad_ < -M_PI) heading_rad_ += two_pi;)heading_wrap_min → -π (approximately -3.14159) — minimum heading value after wrapping (typically -π) (pose_estimator.cpp:33 — while (heading_rad_ < -static_cast<float>(M_PI)) heading_rad_ += two_pi;)heading_wrap_max → +π (approximately +3.14159) — maximum heading value after wrapping (typically +π) (pose_estimator.cpp:32 — while (heading_rad_ > static_cast<float>(M_PI)) heading_rad_ -= two_pi;)state_reset_values → FINDING — values to which pose state is reset (x, y, heading, confidence) (pose_estimator.cpp — no reset logic present; x_m_, y_m_, heading_rad_ accumulate indefinitely)state_reset_condition → FINDING — condition under which pose state is reset (e.g., external command, prolonged invalidity) (pose_estimator.cpp — no reset logic present; x_m_, y_m_, heading_rad_ accumulate indefinitely)injection_order_enforcement → flag check with safe default — method to enforce injection before run: assertion, flag check, error return (wheel_odometry.cpp:19-24 — if (!injected_) { out.valid_ = false; ... return; })tick_read_point → at run() entry (from bus) — when tick_ms_ is read: at run() entry, before integration, cached from injection (pose_estimator.cpp:15,17 — dt_s = ... (bus.tick_ms_ - last_tick_ms_) ...; last_tick_ms_ = bus.tick_ms_;)pose_update_atomicity → single write (struct assignment) — atomicity guarantee for pose_ updates: single write, mutex, lock-free (pose_estimator.cpp:46-54 — pose_estimate_t out{}; ... bus.pose_ = out;)alive_counter_sync → REVIEW — synchronization for alive_counters_ access: atomic increment, mutex, none (if single-threaded) (The counter is incremented with plain ++ operator, no std::atomic or mutex protection. If the code is single-threaded this is safe; if multi-threaded this is a data race. The code does not indicate thread safety provisions—requires review of system architecture.)min_target_speed_mps → -max_reverse_speed_mps_ — Minimum admissible target speed (negative, derived from reverse limit) (trajectory_limiter.cpp:36 — std::clamp(bus.motion_setpoint_.target_speed_mps_, -cal_.max_reverse_speed_mps_, max_speed). The code enforces the lower bound as the negative of max_reverse_speed_mps_.)max_target_speed_mps → max_speed_mps_ — Maximum admissible target speed (forward) (trajectory_limiter.cpp:19,36 — max_speed defaults to cal_.max_speed_mps_ and is used as the upper bound in the clamp. The setpoint is clamped to [−max_reverse_speed_mps_, max_speed].)min_target_yaw_rate_radps → -max_command_yaw_rate_radps_ — Minimum admissible target yaw rate (negative of symmetric limit) (trajectory_limiter.cpp:54-55 — std::clamp(bus.motion_setpoint_.target_yaw_rate_radps_, -cal_.max_command_yaw_rate_radps_, cal_.max_command_yaw_rate_radps_). Lower bound is the negative of the command limit.)max_target_yaw_rate_radps → max_command_yaw_rate_radps_ — Maximum admissible target yaw rate (positive) (trajectory_limiter.cpp:54-55 — the upper bound of the clamp is cal_.max_command_yaw_rate_radps_.)min_pose_speed_mps → FINDING — Minimum admissible pose speed feedback value (speed_controller.cpp:19 — const float measured = bus.pose_.speed_mps_; no clamping or validation occurs. The PID simply reads it.)max_pose_speed_mps → FINDING — Maximum admissible pose speed feedback value (speed_controller.cpp:19 — measured is read directly without validation.)min_imu_yaw_rate_radps → FINDING — Minimum admissible IMU yaw rate feedback value (steering_controller.cpp:19 — const float measured = bus.imu_.yaw_rate_radps_; no clamping or validation.)max_imu_yaw_rate_radps → FINDING — Maximum admissible IMU yaw rate feedback value (steering_controller.cpp:19 — measured is used directly without bounds checking.)min_speed_output_mps2 → -max_decel_mps2_ — Minimum speed controller output (maximum deceleration, negative) (speed_controller.cpp:14,24 — pid_(..., -cal.max_decel_mps2_, ...) and std::clamp(output, -cal_.max_decel_mps2_, cal_.max_accel_mps2_). The minimum is the negative of max_decel_mps2_.)max_speed_output_mps2 → max_accel_mps2_ — Maximum speed controller output (maximum acceleration, positive) (speed_controller.cpp:14,24 — pid_(..., cal.max_accel_mps2_) and clamp upper bound is cal_.max_accel_mps2_.)min_steering_output_rad → -max_steering_rad_ — Minimum steering controller output (negative of symmetric limit) (steering_controller.cpp:14,24 — pid_(..., -cal.max_steering_rad_, ...) and std::clamp(output, -cal_.max_steering_rad_, cal_.max_steering_rad_). The minimum is the negative.)max_steering_output_rad → max_steering_rad_ — Maximum steering controller output (positive) (steering_controller.cpp:14,24 — clamp upper bound is cal_.max_steering_rad_.)min_limited_accel_mps2 → -max_decel_mps2_ — Minimum limited acceleration after jerk and envelope constraints (trajectory_limiter.cpp:40-41 — std::clamp(bus.speed_control_output_mps2_, -cal_.max_decel_mps2_, cal_.max_accel_mps2_). The jerk limiter (lines 44-48) further constrains but does not reduce this minimum.)max_limited_accel_mps2 → max_accel_mps2_ — Maximum limited acceleration after jerk and envelope constraints (trajectory_limiter.cpp:40-41 — clamp upper bound is cal_.max_accel_mps2_. Jerk limiting can reduce the actual value per cycle but not exceed this.)min_limited_steering_rad → -max_steering_rad_ — Minimum limited steering angle after envelope constraints (trajectory_limiter.cpp:59-61 — std::clamp(bus.steering_control_output_rad_, -cal_.max_steering_rad_, cal_.max_steering_rad_).)max_limited_steering_rad → max_steering_rad_ — Maximum limited steering angle after envelope constraints (trajectory_limiter.cpp:59-61 — clamp upper bound is cal_.max_steering_rad_.)speed_clamp_min_mps2 → -max_decel_mps2_ — Lower saturation limit for speed PID output (deceleration) (pid_controller.cpp:7-9,29 — pid_controller constructor receives out_min, out_max; speed_controller.cpp:14 passes -cal.max_decel_mps2_. Line 29 in pid_controller.cpp applies std::clamp(raw_output, out_min_, out_max_).)speed_clamp_max_mps2 → max_accel_mps2_ — Upper saturation limit for speed PID output (acceleration) (pid_controller.cpp:29, speed_controller.cpp:14 — upper clamp is cal.max_accel_mps2_.)steer_clamp_min_rad → -max_steering_rad_ — Lower saturation limit for steering PID output (pid_controller.cpp:29, steering_controller.cpp:14 — lower clamp is -cal.max_steering_rad_.)steer_clamp_max_rad → max_steering_rad_ — Upper saturation limit for steering PID output (pid_controller.cpp:29, steering_controller.cpp:14 — upper clamp is cal.max_steering_rad_.)jerk_limit_mps3 → max_jerk_mps3_ — Maximum permitted rate of change of acceleration command (trajectory_limiter.cpp:45 — const float max_delta = cal_.max_jerk_mps3_ * kLoopPeriodS; then clamp to ±max_delta around prev_accel_mps2_. The rate of change per cycle is limited to max_jerk_mps3_ * 0.02.)speed_unit → meters per second — Physical unit for velocity signals (expected: meters per second) (Variable names consistently use _mps_ suffix (e.g., target_speed_mps_, speed_mps_) across all files. This is the conventional abbreviation for meters per second.)positive_yaw_direction → USER-QUESTION — Rotation direction for positive yaw rate (expected: counterclockwise or left) (The code treats yaw rate as a signed scalar but does not specify whether positive is left (CCW) or right (CW). This is a vehicle coordinate frame convention that must be supplied by the integration team or system spec.)yaw_rate_unit → radians per second — Physical unit for angular velocity (expected: radians per second) (Variable names consistently use _radps_ suffix (e.g., target_yaw_rate_radps_, yaw_rate_radps_). This is the conventional abbreviation for radians per second.)positive_steer_direction → USER-QUESTION — Steering direction for positive angle (expected: left or right) (The code treats steering as a signed scalar but does not specify whether positive is left or right. This is a vehicle-specific mechanical convention.)steering_unit → radians — Physical unit for steering angle (expected: radians) (Variable names consistently use _rad_ suffix (e.g., max_steering_rad_, steering_control_output_rad_). This is the conventional abbreviation for radians.)accel_unit → meters per second squared — Physical unit for acceleration (expected: meters per second squared) (Variable names consistently use _mps2_ suffix (e.g., max_accel_mps2_, speed_control_output_mps2_). This is the conventional abbreviation for m/s².)reduced_speed_limit_mps → reduced_max_speed_mps_ — Maximum speed enforced in reduced-speed degradation modes (trajectory_limiter.cpp:21-23 — case degradation_level_t::reduced_speed: max_speed = std::min(max_speed, cal_.reduced_max_speed_mps_). The effective speed is limited to reduced_max_speed_mps_.)reduced_speed_degradation_set → {full, reduced_speed, geofence_hold, safe_stop_only, disabled} — Set of degradation_level_t enum values triggering reduced speed (e.g., reduced_speed, geofence_hold) (src/app/ugv_types.hpp: enum degradation_level_t)stopped_speed_mps → 0.0 — Speed limit (expected zero) when vehicle must halt (trajectory_limiter.cpp:25-27 — case degradation_level_t::safe_stop_only: case degradation_level_t::disabled: max_speed = 0.0f. The vehicle is commanded to stop.)stopped_degradation_set → {full, reduced_speed, geofence_hold, safe_stop_only, disabled} — Set of degradation_level_t enum values forcing zero speed (e.g., emergency_stop, critical) (src/app/ugv_types.hpp: enum degradation_level_t)degradation_envelope_formula → FINDING — Mapping from degradation level to max_accel, max_decel, max_yaw_rate envelopes (trajectory_limiter.cpp:18-32 — degradation level affects only max_speed (lines 19-32). Acceleration (max_accel_mps2_, max_decel_mps2_) and yaw rate (max_command_yaw_rate_radps_) envelopes are NOT modified by degradation_level_.)failsafe_accel_mps2 → FINDING — Safe acceleration command on invalid input (expected: zero or gentle decel) (speed_controller.cpp, steering_controller.cpp, trajectory_limiter.cpp — no input validation or failsafe logic for invalid/NaN/stale inputs.)failsafe_steering_rad → FINDING — Safe steering command on invalid input (expected: zero or hold) (steering_controller.cpp, trajectory_limiter.cpp — no input validation or failsafe steering command logic.)invalid_input_condition → FINDING — Condition defining invalid inputs (e.g., NaN, out-of-range, stale timestamp) (All motion source files lack input validation checks.)cycle_period_ms → 20 — Module execution period in milliseconds (expected: 20) (speed_controller.cpp:9, steering_controller.cpp:9, trajectory_limiter.cpp:9 — constexpr float kLoopPeriodS = 0.02f; (0.02 seconds = 20 milliseconds). This constant is used throughout for time-step calculations.)derivative_time_step_s → 0.02 — Time delta for PID derivative calculation in seconds (expected: 0.02) (pid_controller.cpp:17 — derivative = (error - prev_error_) / dt_s; where dt_s is passed as kLoopPeriodS (0.02f) from speed_controller.cpp:21 and steering_controller.cpp:21.)integral_time_step_s → 0.02 — Time delta for PID integral accumulation in seconds (expected: 0.02) (pid_controller.cpp:23 — const float candidate_integral = integral_ + error * dt_s; where dt_s is kLoopPeriodS (0.02f).)derivative_kick_avoid_value → 0.0 — Derivative term value on first cycle to avoid kick (expected: 0.0) (pid_controller.cpp:15-16 — float derivative = 0.0f; if (has_prev_ && dt_s > 0.0f) { derivative = ...; }. On first cycle (has_prev_ == false), derivative remains 0.0f.)has_prev_flag → has_prev_ — Flag indicating whether previous cycle data exists for derivative computation (pid_controller.hpp:28 — bool has_prev_ = false; pid_controller.cpp:16,20 — checked and set to true after first compute call.)alive_counter_increment → 1 — Increment step for alive counter per cycle (expected: 1) (trajectory_limiter.cpp:16 — ++bus.alive_counters_[module_id::motion]; pre-increment operator increments by 1.)jerk_rate_limit_per_cycle_mps2 → max_jerk_mps3_ * 0.02 — Maximum acceleration change per 20 ms cycle (max_jerk * 0.02) (trajectory_limiter.cpp:45 — const float max_delta = cal_.max_jerk_mps3_ * kLoopPeriodS; (kLoopPeriodS = 0.02f). The maximum acceleration change per cycle is max_jerk_mps3_ * 0.02.)speed_integral_min → FINDING — Lower bound on speed PID integral accumulator to prevent underflow (pid_controller.cpp:23,38 — integral accumulation occurs but no explicit lower bound on integral_ itself is enforced. The anti-windup logic (lines 33-39) prevents accumulation when saturated but does not bound the integral term directly.)speed_integral_max → FINDING — Upper bound on speed PID integral accumulator to prevent overflow (pid_controller.cpp:23,38 — no explicit upper bound on integral_.)steer_integral_min → FINDING — Lower bound on steering PID integral accumulator to prevent underflow (pid_controller.cpp — same PID implementation used for steering (steering_controller.cpp:14,21). No explicit integral bounds.)steer_integral_max → FINDING — Upper bound on steering PID integral accumulator to prevent overflow (pid_controller.cpp — same PID implementation. No explicit integral bounds.)alive_counter_modulo → REVIEW — Modulo for alive counter wraparound (expected: 256 for uint8_t) (The alive counter is incremented but the type of alive_counters_[module_id::motion] is not defined in the provided motion source files. The modulo depends on the underlying type (likely uint8_t -> 256, but must be confirmed from signal_bus definition).)alive_counter_type → REVIEW — Data type of alive counter (expected: uint8_t) (The data type of alive_counters_[module_id::motion] is not visible in the motion module source files. Must be determined from the signal_bus definition.)pid_init_integral_value → 0.0 — Initial value of speed PID integral accumulator (expected: 0.0) (pid_controller.hpp:26 — float integral_ = 0.0f; member initializer. The integral starts at zero.)pid_init_derivative_value → 0.0 — Initial value of speed PID derivative term (expected: 0.0) (pid_controller.cpp:15 — float derivative = 0.0f; on first call (has_prev_ == false), derivative remains 0.0f and is used in the output calculation (line 27).)degradation_transition_policy → preserve — Policy for PID state handling during degradation transitions (e.g., preserve, reset, conditional) (pid_controller.cpp — the PID state (integral_, prev_error_, has_prev_) is never reset except via explicit reset() call. No reset() call appears in speed_controller.cpp, steering_controller.cpp, or trajectory_limiter.cpp. State persists across degradation transitions.)steer_pid_init_integral → 0.0 — Initial value of steering PID integral accumulator (expected: 0.0) (pid_controller.hpp:26 — same PID class used for steering (steering_controller.cpp:14). integral_ = 0.0f.)steer_pid_init_derivative → 0.0 — Initial value of steering PID derivative term (expected: 0.0) (pid_controller.cpp:15 — same PID class. derivative = 0.0f on first cycle.)first_cycle_flag → false — Flag indicating module is executing its first cycle (has_prev_ = false) (boolean flag polarity from interface contract)execution_order_dependency → USER-QUESTION — Mechanism enforcing sub-module execution order (e.g., explicit sequencing, dependency graph) (The motion module source does not contain scheduling logic. The requirement states speed_controller and steering_controller must execute before trajectory_limiter, but the mechanism enforcing this (e.g., explicit sequencing in main.cpp, dependency graph) is not visible in the motion module code. This is a system-level integration detail.)output_atomicity_mechanism → single-writer, no concurrency — Mechanism ensuring atomic writes to output structure (e.g., mutex, single-writer, copy-on-write) (trajectory_limiter.cpp:63-66 — all fields of bus.limited_motion_ are written sequentially in a single function without interruption. No mutex or lock is visible. Atomicity is achieved by single-threaded execution (implied by 20 ms task model).)alive_counter_writer → trajectory_limiter — Sub-module responsible for incrementing alive counter (expected: trajectory_limiter) (trajectory_limiter.cpp:16 — ++bus.alive_counters_[module_id::motion]; This is the only increment of the motion alive counter in the provided source.)min_ego_speed_mps → FINDING — minimum admissible ego vehicle speed (expected 0.0 per AOU-003) (collision_predictor.cpp:16 reads bus.pose_.speed_mps_ without any validation or range check)max_ego_speed_mps → FINDING — maximum admissible ego vehicle speed for validity check (collision_predictor.cpp:16 reads bus.pose_.speed_mps_ without any validation or range check)max_tick_backwards_ms → FINDING — maximum allowable backwards jump in system timestamp before triggering fault (lidar_interface.cpp:28 computes age_ms = bus.tick_ms_ - last_update_tick_ms_ without checking monotonicity)min_ttc_s → 0.0 — minimum time-to-collision value (likely 0.0 or special sentinel) (collision_predictor.cpp:14,21: out{} uses safe defaults via collision_prediction_t default constructor, min_ttc initialized to out.time_to_collision_s_ which defaults to a large sentinel (likely std::numeric_limits or a config constant). TTC is only reduced (line 38: min_ttc = std::min(min_ttc, ttc)) when positive closing speed yields a finite value. The computed ttc (line 37) is always non-negative (range/speed, both non-negative). Minimum observed TTC is implicitly 0.0 when an obstacle is at zero range or infinitely fast closing.)max_ttc_s → collision_prediction_t default value (large sentinel, likely 999.9 or FLT_MAX from signal_bus.hpp definition) — maximum or invalid sentinel for time-to-collision (collision_predictor.cpp:14,21: collision_prediction_t out{}; initializes with safe defaults; out.time_to_collision_s_ is the default-constructed value from collision_prediction_t. Line 45 writes this value to bus.collision_ when no collision threat found. This is the sentinel 'no collision' value, effectively the maximum reportable TTC.)min_collision_range_m → 0.0 — minimum physically valid range for collision prediction (collision_predictor.cpp:26-29: nearest_range initialized to out.nearest_range_m_ (default safe value), then updated only if obs.range_m_ < nearest_range. Obstacle ranges come from clusters which require p.range_m_ > 0.0f (obstacle_detector.cpp:39). The code permits ranges arbitrarily close to zero; no explicit minimum is enforced. Practical minimum is 0.0 (exclusive in clustering, but nearest can approach zero).)max_collision_range_m → collision_prediction_t default nearest_range_m_ (likely 999.9 or similar large sentinel from signal_bus.hpp) — maximum range for collision prediction reporting (collision_predictor.cpp:19: nearest_range = out.nearest_range_m_; where out is default-constructed collision_prediction_t{}. This is the 'no obstacle' sentinel. Line 26 only updates if obs.range_m_ < nearest_range, so the default value is the effective maximum reportable range.)min_obstacle_range_m → 0.0 (exclusive, enforced as > 0.0f) — minimum physically valid obstacle range (obstacle_detector.cpp:39: if (!p.valid_ || p.range_m_ <= 0.0f) { close_cluster(); continue; })max_obstacle_range_m → FINDING — maximum LiDAR detection range for obstacles (obstacle_detector.cpp:39-42 and entire cluster_scan() function show no upper-bound validation on p.range_m_)min_bearing_rad → FINDING — minimum bearing angle (likely -π or -π/2) (obstacle_detector.cpp:38-60 processes p.bearing_rad_ without any range validation)max_bearing_rad → FINDING — maximum bearing angle (likely +π or +π/2) (obstacle_detector.cpp:38-60 processes p.bearing_rad_ without any range validation)ttc_clamp_max_s → FINDING — upper saturation limit for time-to-collision to avoid infinity (collision_predictor.cpp:37-38: const float ttc = obs.range_m_ / std::max(closing_speed, eps); min_ttc = std::min(min_ttc, ttc); — no upper clamp applied to ttc)min_relative_speed_mps → FINDING — lower clamp on relative speed (negative = approaching) (obstacle_detector.cpp:113: trk.relative_speed_mps_ = c.range_m_ - prev_range; — no clamp applied; collision_predictor.cpp:34 uses obs.relative_speed_mps_ directly)max_relative_speed_mps → FINDING — upper clamp on relative speed (positive = receding) (obstacle_detector.cpp:113: trk.relative_speed_mps_ = c.range_m_ - prev_range; — no clamp applied; collision_predictor.cpp:34 uses obs.relative_speed_mps_ directly)bearing_sign_convention → USER-QUESTION — bearing sign convention (e.g., 'positive_counterclockwise', 'positive_clockwise', 'RHR') (The code does not specify whether positive bearing is left/right or clockwise/counterclockwise. This is a coordinate-frame / sensor-mounting decision that must be provided by the integration specification or calibration documentation.)relative_speed_sign_convention → positive = opening (receding), negative = closing (approaching) — relative speed sign interpretation (e.g., 'negative_approaching', 'positive_approaching') (obstacle_detector.cpp:113: trk.relative_speed_mps_ = c.range_m_ - prev_range; (current_range - previous_range). If range increases, relative_speed is positive (object moving away). collision_predictor.cpp:34: closing_speed = ego_speed - obs.relative_speed_mps_; subtracts relative_speed from ego_speed, consistent with relative_speed being the rate-of-opening.)ttc_computation_formula → ttc = range / closing_speed, where closing_speed = ego_speed - relative_speed — formula used for TTC computation (e.g., 'range / closing_speed' or 'range / (ego_speed - relative_speed)') (collision_predictor.cpp:34,37: const float closing_speed = ego_speed - obs.relative_speed_mps_; const float ttc = obs.range_m_ / std::max(closing_speed, eps);)stale_status_value → sensor_status_t::stale — enum value assigned to lidar_status_ when data is stale (lidar_interface.cpp:31: bus.lidar_status_ = ... : sensor_status_t::stale; when age_ms > cal_.lidar_stale_timeout_ms_)failed_status_value → sensor_status_t::failed — enum value assigned to lidar_status_ when sensor has failed (lidar_interface.cpp:22: bus.lidar_status_ = sensor_status_t::failed; when !have_scan_ (no scan ever received))lidar_failure_conditions → {ok, degraded, stale, failed} — set of conditions triggering failed status (e.g., 'empty_scan_N_cycles', 'invalid_scan_structure') (src/app/ugv_types.hpp: enum sensor_status_t)imminent_default_on_fault → FINDING — safe default value for imminent flag when sensor is faulted (collision_predictor.cpp:46-48 sets collision_imminent_ based on TTC/range thresholds but does NOT check bus.lidar_status_)ok_status_value → sensor_status_t::ok — enum value representing healthy sensor status (lidar_interface.cpp:30: bus.lidar_status_ = ... ? sensor_status_t::ok : ...; when age_ms <= timeout)obstacle_list_fault_behavior → FINDING — action taken on obstacle list during fault (e.g., 'clear', 'freeze', 'mark_unconfirmed') (obstacle_detector.cpp:73-163 unconditionally processes bus.lidar_scan_ and publishes bus.obstacles_ without checking bus.lidar_status_)lidar_stale_timeout_ms → USER-QUESTION — calibration parameter: max age before LiDAR data is stale (This is a calibration parameter from the ugv_calibration_t structure. The value is application-specific (depends on sensor update rate, latency tolerance, safety margins). The customer/integrator must specify this timeout based on system requirements.)obstacle_confirmation_cycles → USER-QUESTION — calibration parameter: consecutive cycles to confirm obstacle (This is a calibration parameter from ugv_calibration_t. The number of consecutive detection cycles required to confirm a track is a tuning decision balancing false-positive suppression vs. detection latency. The customer must specify this based on operational requirements.)obstacle_deletion_cycles → USER-QUESTION — calibration parameter: consecutive cycles without match to delete track (This is a calibration parameter from ugv_calibration_t. The number of non-detection cycles before deleting a track is a tuning decision balancing memory/clutter vs. track persistence through occlusions. The customer must specify this based on operational requirements.)alive_counter_increment → 1 — increment value for heartbeat counter each cycle (collision_predictor.cpp:12: ++bus.alive_counters_[module_id::perception]; (pre-increment operator increments by 1))run_cycle_period_ms → USER-QUESTION — expected module execution period for alive counter timing (The module execution period is determined by the application scheduler (not visible in perception source). This is an integration/deployment parameter that the customer must specify based on the control loop design and real-time requirements.)max_obstacles → 32 — maximum number of simultaneously tracked obstacles (per AOU-006) (src/app/ugv_types.hpp: `static constexpr uint32_t max_obstacles = 32;`)max_lidar_points → 360 — maximum number of LiDAR points accepted in one scan (src/app/ugv_types.hpp: `static constexpr uint32_t max_lidar_points = 360;`)overflow_behavior_obstacles → reject_new (stop creating new tracks when limit reached) — action when max_obstacles reached (e.g., 'reject_new', 'evict_oldest', 'evict_farthest') (obstacle_detector.cpp:62-66,146: if (clusters.size() + 1 >= max_obstacles) { close_cluster(); break; } and line 146: if (tracks_.size() >= max_obstacles) break; — when capacity is reached, clustering stops emitting new clusters and new track creation is halted.)overflow_behavior_scan → FINDING — action when max_lidar_points reached (e.g., 'truncate', 'reject_scan', 'subsample') (lidar_interface.cpp:26: bus.lidar_scan_ = latest_scan_; — unconditional copy with no size check; obstacle_detector.cpp:74 processes bus.lidar_scan_ with no size validation)unconfirmed_state → confirmed_ == false — state value representing an unconfirmed obstacle track (obstacle_detector.cpp:118,133,155: trk.confirmed_ is a boolean; set to false when consecutive_matches_ < confirm_cycles (line 133, 155 for new tracks))confirmed_state → confirmed_ == true — state value representing a confirmed obstacle track (obstacle_detector.cpp:118: trk.confirmed_ = trk.consecutive_matches_ >= confirm_cycles; — confirmed state is confirmed_ == true)collision_eligible_states → confirmed_only (confirmed_ == true) — set of obstacle states eligible for collision prediction (e.g., 'confirmed_only' or 'confirmed_and_provisional') (collision_predictor.cpp:24: if (!obs.confirmed_) continue; — only confirmed obstacles are considered for collision prediction and nearest-obstacle search)recovery_condition → fresh_scan_received (injected_ == true and age <= timeout) — condition for sensor status recovery (e.g., 'fresh_scan_received', 'N_consecutive_valid_scans') (lidar_interface.cpp:14-18,29-31: when inject_scan() is called, injected_ is set true, then run() updates last_update_tick_ms_ and sets status to ok if age_ms <= timeout. Transition from stale→ok happens immediately when a fresh scan arrives and age constraint is satisfied.)ok_status_value → REVIEW — (Slot left unresolved by the fill pass; manual review required.)stale_status_value → REVIEW — (Slot left unresolved by the fill pass; manual review required.)injection_run_ordering → REVIEW — enforced ordering between inject_scan and run (e.g., 'inject_before_run_required', 'inject_optional') (The code is designed expecting inject_scan() before run() (line 14-18 checks injected_ flag), but it is permissive: if inject_scan() was not called, run() uses stale data or marks sensor as failed. There is no explicit error or enforcement of the ordering. The requirement's intent ('required' vs. 'optional') is ambiguous in the implementation.)scan_read_critical_section → entire_run_cycle (from cluster_scan entry to obstacles_ publication) — phase during which lidar_scan_ must remain stable (e.g., 'during_clustering', 'entire_run_cycle') (obstacle_detector.cpp:74: const std::vector<cluster_t> clusters = cluster_scan(bus.lidar_scan_); — lidar_scan_ is read once at the start and clustering operates on that snapshot. No further modification to bus.lidar_scan_ occurs during run().)output_atomicity_boundary → end_of_run (all outputs written at function exit) — synchronization boundary for output updates (e.g., 'end_of_run', 'per_field_independent') (collision_predictor.cpp:12,51: alive counter incremented at line 12, collision_ written at line 51; obstacle_detector.cpp:162: obstacles_ written at line 162; lidar_interface.cpp:21-22,26,29-31: lidar_scan_ and lidar_status_ written during run(). Each module's run() method writes its outputs before returning, providing a per-module atomicity boundary at function exit.)reentrancy_policy → FINDING — reentrancy handling (e.g., 'not_reentrant_error', 'not_reentrant_ignored', 'reentrant_safe') (obstacle_detector.cpp:73-163, collision_predictor.cpp:11-52, lidar_interface.cpp:8-32: no mutex, no reentrancy guard, no state checks to detect concurrent calls)min_physical_voltage_v → USER-QUESTION — Minimum physically plausible voltage for rail measurements, lower bound of sensor range (The code uses min_voltage_v_ as an undervoltage fault threshold but does NOT implement input validation to reject physically implausible sensor readings. The actual minimum plausible voltage must be supplied by the customer based on sensor specifications and expected operating environment. The fault threshold (min_voltage_v_) may differ from sensor range limits.)max_physical_voltage_v → USER-QUESTION — Maximum physically plausible voltage for rail measurements, upper bound of sensor range (The code uses max_voltage_v_ as an overvoltage fault threshold but does NOT implement input validation to reject physically implausible sensor readings. The actual maximum plausible voltage must be supplied by the customer based on sensor specifications and expected operating environment. The fault threshold (max_voltage_v_) may differ from sensor range limits.)output_min_voltage_v → FINDING — Minimum voltage value reported in power status outputs (power_supply.cpp:15-22, evaluate() function directly assigns voltage_v to status.voltage_v_ without any clamping or bounds checking.)output_max_voltage_v → FINDING — Maximum voltage value reported in power status outputs (power_supply.cpp:15-22, evaluate() function directly assigns voltage_v to status.voltage_v_ without any clamping or bounds checking.)clamp_min_v → FINDING — Lower saturation limit for voltage measurements (power_supply.cpp:15-22, evaluate() function assigns status.voltage_v_ = voltage_v without any clamping logic.)clamp_max_v → FINDING — Upper saturation limit for voltage measurements (power_supply.cpp:15-22, evaluate() function assigns status.voltage_v_ = voltage_v without any clamping logic.)voltage_unit → volts — Physical unit for voltage (volts), confirmed from calibration parameter unit annotation (power_supply.hpp:17 parameter names 'main_v, backup_v' and power_supply.cpp:17 'status.voltage_v_'; struct member naming convention '_v_' suffix; power_distribution.cpp:15 'voltage_v_' and 'backup_switch_voltage_v_' all use '_v' or '_v_' suffix consistently indicating volts as the unit.)nominal_voltage_v → USER-QUESTION — Nominal operating voltage defining the reference point for normal operation (The nominal_voltage_v_ is a calibration parameter (cal_.nominal_voltage_v_) used as the default/initialization value for voltage measurements. This is a system design parameter that must be supplied by the customer based on the electrical architecture (e.g., 12V, 24V, 48V system). The code references it but does not define a concrete value.)undervoltage_threshold_v → cal_.min_voltage_v_ — Voltage threshold below which undervoltage fault is declared (power_supply.cpp:18 'status.undervoltage_ = (voltage_v < cal_.min_voltage_v_);' — undervoltage flag is set when measured voltage falls below cal_.min_voltage_v_.)overvoltage_threshold_v → cal_.max_voltage_v_ — Voltage threshold above which overvoltage fault is declared (power_supply.cpp:19 'status.overvoltage_ = (voltage_v > cal_.max_voltage_v_);' — overvoltage flag is set when measured voltage exceeds cal_.max_voltage_v_.)main_unhealthy_state → false — Boolean state indicating main rail is unhealthy (false) (power_supply.cpp:20 'status.ok_ = !status.undervoltage_ && !status.overvoltage_;' and power_distribution.cpp:17 '!bus.power_main_.ok_' — health/ok is true when healthy, false when unhealthy. Backup activates when main is NOT ok (line 17).)backup_activation_threshold_v → cal_.backup_switch_voltage_v_ — Voltage threshold for triggering backup power switchover (power_distribution.cpp:14-15 'const bool main_below_switch = (bus.power_main_.voltage_v_ < cal_.backup_switch_voltage_v_);' and line 17 activates backup when 'main_below_switch' is true.)backup_healthy_state → true — Boolean state indicating backup rail is healthy (true) (power_distribution.cpp:17 'bus.backup_power_active_ = (!bus.power_main_.ok_ || main_below_switch) && bus.power_backup_.ok_;' — backup activates only when 'bus.power_backup_.ok_' is true (healthy).)default_voltage_v → cal_.nominal_voltage_v_ — Default voltage value used when no measurement has been injected (power_supply.cpp:7-8 constructor initializes 'main_v_(cal.nominal_voltage_v_), backup_v_(cal.nominal_voltage_v_)' and power_supply.hpp:24-25 shows default member initialization to 'default_calibration.nominal_voltage_v_'. These values are used by run() when inject_voltage() has not been called.)heartbeat_increment → 1 — Increment value for heartbeat counter per cycle (typically 1) (power_supply.cpp:25 '++bus.alive_counters_[module_id::power];' — pre-increment operator increments by 1 each cycle.)cycle_period_ms → USER-QUESTION — Expected execution period of the power management task in milliseconds (The execution period of the power management task is a system-level configuration parameter not defined in the power_supply or power_distribution modules. This must be specified in the task scheduler configuration or system integration layer by the customer based on timing requirements.)counter_max_value → REVIEW — Maximum value of the heartbeat counter before wraparound (2^32-1 for uint32_t) (The alive_counters_ array element is incremented but its underlying data type is not defined in the provided sources. If uint32_t, the max is 2^32-1 (4294967295). If uint8_t, max is 255. The actual type must be confirmed from signal_bus_t definition to determine the exact maximum value before wraparound.)counter_wrap_value → 0 — Value to which counter resets after overflow (0 for unsigned types) (power_supply.cpp:25 '++bus.alive_counters_[module_id::power];' — C++ unsigned integer overflow behavior wraps to 0 by standard (modulo arithmetic). For any unsigned type (uint8_t, uint16_t, uint32_t), overflow wraps to 0.)backup_inactive_state → false — State value when backup is not active (false) (power_distribution.cpp:17 'bus.backup_power_active_ = (!bus.power_main_.ok_ || main_below_switch) && bus.power_backup_.ok_;' — backup_power_active_ is assigned false when the condition is not met (inactive state).)backup_active_state → true — State value when backup is actively powering the system (true) (power_distribution.cpp:17 'bus.backup_power_active_ = (!bus.power_main_.ok_ || main_below_switch) && bus.power_backup_.ok_;' — backup_power_active_ is assigned true when activation conditions are met.)trigger_unhealthy → false — Main rail health state that triggers backup activation (false/unhealthy) (power_distribution.cpp:17 '!bus.power_main_.ok_' — backup activates when main ok_ is NOT true (i.e., when ok_ is false/unhealthy).)switchover_voltage_v → cal_.backup_switch_voltage_v_ — Main rail voltage threshold for backup activation (power_distribution.cpp:14-15 'const bool main_below_switch = (bus.power_main_.voltage_v_ < cal_.backup_switch_voltage_v_);' used in backup activation condition at line 17.)backup_ok → true — Backup rail health state required for activation (true/healthy) (power_distribution.cpp:17 'bus.backup_power_active_ = (!bus.power_main_.ok_ || main_below_switch) && bus.power_backup_.ok_;' — requires 'bus.power_backup_.ok_' to be true for activation.)deactivation_condition → bus.power_main_.ok_ == true AND bus.power_main_.voltage_v_ >= cal_.backup_switch_voltage_v_ — Condition under which backup power is deactivated (e.g., main restored above threshold) (power_distribution.cpp:17 'bus.backup_power_active_ = (!bus.power_main_.ok_ || main_below_switch) && bus.power_backup_.ok_;' — the assignment is re-evaluated every cycle, so backup deactivates when the condition becomes false: when main is healthy (ok_==true) AND main voltage is at or above switch threshold AND (implicitly) backup remains healthy.)task_sequence_position → USER-QUESTION — Sequence position in task schedule ensuring power_supply runs before power_distribution (The task execution order is a system-level scheduler configuration not defined within the power_supply or power_distribution modules. The customer must configure the task scheduler to ensure power_supply::run() executes before power_distribution::run() in each cycle. The specific sequence position or priority values depend on the RTOS/scheduler implementation.)voltage_access_pattern → latest value (single-buffered, last-write-wins) — Concurrency pattern for voltage data (e.g., 'snapshot at cycle start', 'latest value', 'double-buffered') (power_supply.cpp:10-12 'inject_voltage()' directly writes to main_v_ and backup_v_ member variables; power_supply.cpp:27-28 'run()' reads these same variables. No double-buffering, locking, or snapshot mechanism exists. The pattern is single-buffered last-write-wins.)base_period_ms → 10 — The fundamental scheduler tick period against which all task periods must align (cyclic_scheduler.hpp:31 — constructor default parameter `base_period_ms = 10`; this is the fundamental tick period stored in base_period_ms_ and used throughout the scheduler.)valid_priority_values → {high, medium, low} — The enumerated set of valid priority levels (e.g., high, medium, low) (ugv_types.hpp:81-85 — `enum class task_priority_t : uint8_t { high = 0, medium = 1, low = 2 };` — this is the exhaustive set of valid priority values.)cycle_time_ms → base_period_ms_ (constructor parameter, defaults to 10) — The fixed time increment applied to tick_ms_ each scheduler cycle (cyclic_scheduler.cpp:17 — `const uint64_t now_ms = tick_counter_ * base_period_ms_;` — the tick advances by base_period_ms_ each cycle; line 43 shows `++tick_counter_` increments by 1, thus tick_ms_ advances by base_period_ms_ each tick.)tick_overflow_bound → 2^64 — The maximum value before tick_ms_ wraps (per AOU-006 overflow is acceptable) (cyclic_scheduler.hpp:42 — `uint64_t tick_counter_ = 0;` and cyclic_scheduler.cpp:17 — `const uint64_t now_ms = tick_counter_ * base_period_ms_;` — both are uint64_t, wrapping at 2^64.)max_registered_tasks → FINDING — Maximum number of tasks that can be registered with the scheduler (cyclic_scheduler.cpp:11-14 — `register_task` unconditionally appends to `tasks_` (std::vector) with no capacity check or rejection logic.)max_tasks_per_tick → FINDING — Maximum number of task callbacks executed in a single tick (may equal max_registered_tasks or be separately limited) (cyclic_scheduler.cpp:21-34 — `due` vector is built from all tasks that meet timing condition, with no iteration limit or early-exit; lines 36-41 execute all tasks in `due` with no cap.)time_unit → milliseconds — The fundamental time unit used throughout the scheduler (milliseconds) (cyclic_scheduler.cpp:17 — `const uint64_t now_ms = tick_counter_ * base_period_ms_;` then line 18 `bus.tick_ms_ = now_ms;` — the `_ms_` suffix and computation confirm milliseconds.)base_period_ms → 10 — The base period for converting time durations to tick counts (Same as REQ-CYC-001 fill: cyclic_scheduler.hpp:31 default parameter `base_period_ms = 10`.)hz_to_ms_formula → FINDING — Formula to convert frequency in Hz to period in milliseconds (e.g., period_ms = 1000 / freq_hz) (No frequency-based registration API exists in cyclic_scheduler.hpp or cyclic_scheduler.cpp. The register_task interface (cyclic_scheduler.hpp:13-19, cyclic_scheduler.cpp:11-14) accepts only period_ms_, not frequency_hz.)fault_log_destination → FINDING — Destination for logging task callback exceptions (likely faults_ output) (cyclic_scheduler.cpp:36-41 — task callbacks are invoked with no try-catch block; exceptions are not caught, contradicting requirement.)task_fault_status → FINDING — The status value assigned to a task that has thrown an exception (No task status tracking exists in task_config_t (cyclic_scheduler.hpp:13-19) or task_stats_t (hpp:21-24). The code does not mark tasks with fault status.)fault_task_policy → FINDING — Policy determining whether a faulted task is skipped once or permanently disabled (No exception handling or fault policy logic exists (see cyclic_scheduler.cpp:36-41). The code unconditionally executes all due tasks each tick.)uninitialized_bus_error_code → FINDING — Error code returned when run_tick is called with uninitialized signal_bus_t (cyclic_scheduler.cpp:16 — `run_tick(signal_bus_t& bus)` returns void and performs no initialization check on the bus parameter.)task_registration_time_ms → 0 (implicit baseline) — The tick_ms_ value at which task registration occurred, used as timing baseline (cyclic_scheduler.cpp:24-27 — condition is `if (now_ms < t.offset_ms_) continue;` then line 27 `if (((now_ms - t.offset_ms_) % t.period_ms_) == 0)` — the modulo uses offset_ms_ as the phase shift from tick zero, implying registration time is effectively tick 0.)scheduling_jitter_ms → 0 — Acceptable timing jitter for task execution (typically zero for integer modulo) (cyclic_scheduler.cpp:27 — exact equality check `((now_ms - t.offset_ms_) % t.period_ms_) == 0` with no tolerance.)priority_order_sequence → high (0), then medium (1), then low (2) — The execution order sequence for task priorities (e.g., descending from high to low) (cyclic_scheduler.cpp:31-34 — `std::stable_sort` with comparator `tasks_[a].priority_ < tasks_[b].priority_` (ascending by uint8_t value); ugv_types.hpp:81-85 defines high=0, medium=1, low=2, thus sorts high first.)max_tick_execution_time_ms → FINDING — Maximum allowed execution time for all tasks in a single tick (per AOU-002) (cyclic_scheduler.cpp:36-41 — tasks execute in a loop with no timeout check, deadline enforcement, or execution time measurement.)max_alive_counter_modules → 12 — Fixed number of module alive counters (12 per interface description) (signal_bus.hpp:73-74 — `static constexpr uint32_t num_monitored_modules = 12; std::array<uint32_t, num_monitored_modules> alive_counters_ = {};` — fixed array of size 12.)max_lidar_points → 360 — Maximum number of lidar points that can be stored in lidar_scan_ vector (src/app/ugv_types.hpp: `static constexpr uint32_t max_lidar_points = 360;`)max_obstacles → 32 — Maximum number of obstacle entries that can be stored in obstacles_ vector (src/app/ugv_types.hpp: `static constexpr uint32_t max_obstacles = 32;`)uninitialized_state → FINDING — Initial state before signal_bus_t initialization (per AOU-004) (No state machine or state tracking exists in cyclic_scheduler (cyclic_scheduler.hpp, cyclic_scheduler.cpp). The scheduler has no state field or initialization tracking.)registration_state → FINDING — State after initialization where task registration is allowed (per AOU-005) (Same as uninitialized_state: no state machine exists in the scheduler.)running_state → FINDING — State after first run_tick() where execution occurs and registration is prohibited (Same as uninitialized_state: no state machine exists. Additionally, register_task (cyclic_scheduler.cpp:11-14) has no state check or rejection logic preventing registration after run_tick starts.)bus_sync_mechanism → NONE — Synchronization mechanism protecting signal_bus_t if multi-threaded access is possible (cyclic_scheduler.cpp:16-44 and signal_bus.hpp:12-78 — no mutex, lock_guard, atomic, or synchronization primitive is present. The signal_bus_t is a plain struct with no thread-safety mechanisms.)bus_access_mode → non-const reference (READ_WRITE) — Access mode provided to task callbacks for signal_bus_t (e.g., non-const reference, pointer) (cyclic_scheduler.cpp:16 — `void run_tick(signal_bus_t& bus)` and line 38 — `tasks_[idx].run_(bus)` passes non-const reference; task_config_t::run_ (cyclic_scheduler.hpp:18) is `std::function<void(signal_bus_t&)>` — non-const reference gives full read-write access.)