sl-uwb
|
65e0009118
|
feat: ESP-NOW to ROS2 serial relay (Issue #618)
New ROS2 package saltybot_uwb_espnow_relay:
- packet.py: EspNowPacket dataclass + FrameReader stateful decoder
- Parses 20-byte ESP-NOW packets: MAGIC, tag_id, msg_type, anchor_id,
range_mm (int32 LE), rssi_dbm (float32), timestamp_ms, battery_pct,
flags (bit0=estop), seq_num
- Serial framing: STX(0x02) + LEN(0x14) + DATA[20] + XOR-CRC(1)
- Sync recovery: re-hunts STX after bad LEN or CRC; byte-by-byte capable
- relay_node.py: /espnow_relay ROS2 node
- Reads from USB serial in background thread (auto-reconnects on error)
- MSG_RANGE (0x10): publishes UwbRange on /uwb/espnow/ranges
- MSG_ESTOP (0x20): publishes std_msgs/Bool on /uwb/espnow/estop
and /saltybot/estop (latched True for estop_latch_s after last packet)
- MSG_HEARTBEAT (0x30): publishes EspNowHeartbeat on /uwb/espnow/heartbeat
- Range validity gating: min_range_m / max_range_m params
- 16/16 unit tests passing (test/test_packet.py, no ROS2/hardware needed)
saltybot_uwb_msgs: add EspNowHeartbeat.msg
(tag_id, battery_pct, seq_num, timestamp_ms + std_msgs/Header)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-03-15 10:08:19 -04:00 |
|
|
|
9a68dfdb2e
|
feat(uwb): MaUWB ESP32-S3 DW3000 dual-anchor bearing driver (Issue #90)
## Summary
- saltybot_uwb_msgs: add UwbBearing.msg, add tag_id to UwbRange.msg,
register UwbBearing in CMakeLists.txt
- ranging_math.py: add bearing_from_pos(x, y) helper (atan2-based)
- uwb_driver_node.py: dual-rate architecture
• 100 Hz /uwb/ranges — raw TWR ranges with tag_id attribution
• 10 Hz /uwb/bearing — Kalman-fused bearing + range estimate
• enrolled_tag_ids parameter for tag pairing filter
• AT+RANGE_ADDR=<tag> pairing command on connect
- uwb_config.yaml: range_rate / bearing_rate / enrolled_tag_ids params
- uwb.launch.py: expose new params as launch arguments
- test_ranging_math.py: 7 new bearing_from_pos unit tests
Closes #90
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-03-01 23:25:08 -05:00 |
|
|
|
a00dbe6429
|
feat: UWB follow-me system (#57) — saltybot_uwb package + sensor fusion
New packages
------------
saltybot_uwb_msgs (ament_cmake)
• UwbRange.msg — per-anchor range reading (anchor_id, range_m, raw_mm, rssi)
• UwbRangeArray.msg — array of UwbRange published on /uwb/ranges
saltybot_uwb (ament_python)
• ranging_math.py — pure triangulate_2anchor() (height-compensated TWR
geometry, 2-anchor intersection) + KalmanFilter2D
(constant-velocity, numpy-free, 16 tests pass)
• uwb_driver_node.py — SerialReader threads poll MaUWB ESP32-S3 DW3000
anchors via AT+RANGE?, triangulate, Kalman-smooth,
publish /uwb/target (PoseStamped/base_link) + /uwb/ranges
• config/uwb_config.yaml, launch/uwb.launch.py
• test/test_ranging_math.py — 16 unit tests (triangulation + Kalman), all pass
Updated saltybot_follower
-------------------------
• person_follower_node.py — adds fuse_targets() pure helper + /uwb/target
subscriber (primary, weight=0.7); /person/target secondary (weight=0.3);
weighted blend when both fresh, graceful fallback to single source; new
params uwb_weight + uwb_timeout
• person_follower_params.yaml — uwb_weight: 0.7, uwb_timeout: 1.0s
• test_person_follower.py — 7 new TestFuseTargets cases; total 60 pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
2026-03-01 00:48:03 -05:00 |
|