- S4: TinesNode::trust_system_clock(now) and trust_wall_clock(wall, now)
give a ROS2-only fleet a local trusted-time source, with the same
plausibility bounds as the service (tines::trust).
- Decision J: poll collects peer estimates for a window (default 10 s,
set_peer_time_window_ms) from the first plausible one and adopts the
latest, once; implausible estimates (B3) are never adopted.
- S5: adoption goes through tines::trust::adopt_wall_clock, which flushes
the store right after set_wall_clock.
- has_trusted_time() reports whether a wall time was adopted.
The `ros2` feature is outside the default gate; the shared logic is
tested in `tines`, and these methods were type-checked against it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Task 10b reached LogStore::set_wall_clock through a general Node::store_mut.
Kyle: replace it with a narrower accessor. A WallClockStore trait (set_wall_clock
+ peer_time_estimate, implemented only by LogStore) now backs Node::set_wall_clock
and Node::peer_time_estimate, so no &mut Store escapes the facade.
Rewrite tines-ros2/src/node.rs against the rclrs 0.8 API (Context::
default_from_env -> create_basic_executor -> create_node; type-inferred
subscriptions; thiserror-based RclrsError) and switch payloads from
std_msgs String to UInt8MultiArray:
* live topics publish the raw Observation.bytes as data (no UTF-8 lossy);
* inbound callbacks use msg.data verbatim;
* receipts are a 32-byte UInt8MultiArray (peer[..16] ++ id[..16]);
* supply the required MultiArrayLayout { dim: [], data_offset: 0 }.
Bump ros_env 0.1 -> 0.3 so the crate's std_msgs pins rclrs 0.8's rosidl
runtime 0.7 (was 0.6), and update Cargo.lock. Add #[allow(dead_code)] on
ManagedTopic::subscriber (drop-guard for the rcl subscription handle).
Keep the ROS2-free build green; no changes outside tines-ros2/ (and the
Cargo.lock entry).
Adds the ninth fleet-deployment crate. Default build is ROS2-free: topic_name
hex-escapes arbitrary tines topics into valid ROS2 names under /tines/ (deterministic,
injective) and wires Node<LogStore, BtTransport>. The rclrs-backed self-contained
TinesNode lives under #[cfg(feature="ros2")] with an off-by-default ros2 feature, so
the crate builds/tests without a ROS2 toolchain. Adds scripts/check-ros2.sh (needs a
ROS2 toolchain; not run in CI), registers the crate in workspace members, and passes
sh scripts/ci.sh.