Software-complete implementation of the two-anchor UWB ranging stack. All ROS2 / serial code written against an abstract interface so tests run without physical hardware (anchors on order). New message - UwbTarget.msg: valid, bearing_deg, distance_m, confidence, anchor0/1_dist_m, baseline_m, fix_quality (0=none 1=single 2=dual) Core library — _uwb_tracker.py (pure Python, no ROS2/runtime deps) - parse_frame(): ASCII RANGE,<id>,<tag>,<mm> protocol decoder - bearing_from_ranges(): law-of-cosines 2-anchor bearing with confidence (penalises extreme angles + close-range geometry) - bearing_single_anchor(): fallback bearing=0, conf≤0.3 - BearingKalman: 1-D constant-velocity Kalman filter [bearing, rate] - UwbRangingState: thread-safe per-anchor state + stale timeout + Kalman - AnchorSerialReader: background thread, readline() interface (real or mock) ROS2 node — uwb_node.py - Opens /dev/ttyUSB0 + /dev/ttyUSB1 (configurable) - Non-fatal serial open failure (will publish FIX_NONE until plugged in) - Publishes /saltybot/uwb_target at 10 Hz (configurable) - Graceful shutdown: stops reader threads Tests — test/test_uwb_tracker.py: 64/64 passing - Frame parsing: valid, malformed, STATUS, CR/LF, mm→m conversion - Bearing geometry: straight-ahead, ±45°, ±30°, symmetry, confidence - Kalman: seeding, smoothing, convergence, rate tracking - UwbRangingState: single/dual fix, stale timeout, thread safety - AnchorSerialReader: mock serial, bytes decode, stop() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Description
SaltyLab self-balancing bot firmware (STM32F722)
Languages
Python
67.1%
C
11.4%
JavaScript
9.2%
OpenSCAD
7.8%
HTML
1.5%
Other
2.9%