feat: MQTT-to-ROS2 phone sensor bridge (Issue #601) #605
Loading…
x
Reference in New Issue
Block a user
No description provided.
Delete Branch "sl-android/issue-601-mqtt-ros2-bridge"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Jetson-side ROS2 node that bridges the three MQTT topics from
phone/sensor_dashboard.pyinto typed ROS2 messages.Files changed
saltybot_phone/mqtt_ros2_bridge_node.pylaunch/mqtt_bridge.launch.pysetup.pymqtt_ros2_bridgeconsole scriptpackage.xmlpython3-paho-mqttexec_dependTopic mapping
saltybot/phone/imu/saltybot/phone/imusensor_msgs/Imusaltybot/phone/gps/saltybot/phone/gpssensor_msgs/NavSatFixsaltybot/phone/battery/saltybot/phone/batterysensor_msgs/BatteryState/saltybot/phone/bridge/statusstd_msgs/String(JSON)Architecture
loop_start()runs MQTT network in its own thread;on_messagecallback only enqueues(topic, payload)— no rclpy calls from MQTT threadreconnect_delay_set(5s → 20s)Message details
IMU — accel + gyro with configurable diagonal covariance;
orientation_covariance[0] = -1(unknown, REP-145)NavSatFix — full 3×3 position covariance from
accuracy_m; STATUS_FIX for gps/fused/network providers;COVARIANCE_TYPE_APPROXIMATEDBatteryState —
percentage[0–1];temperaturein Kelvin; Android health string →POWER_SUPPLY_HEALTH_*;voltage/current= NaN (unavailable on Android)Timestamp alignment
Default: ROS2 wall clock (consistent with all other nodes).
use_phone_timestamp:=trueuses the phone's Unix epochtsfield when clock drift <warn_drift_s(default 1.0 s); warns and falls back to ROS2 clock if drift exceeds threshold.Input validation
Status topic (0.2 Hz)
Test plan
python3 -m py_compile saltybot_phone/mqtt_ros2_bridge_node.py— cleanpython3 phone/sensor_dashboard.py --broker <jetson_ip>ros2 launch saltybot_phone mqtt_bridge.launch.py mqtt_host:=localhostros2 topic hz /saltybot/phone/imu→ ~5 Hzros2 topic echo /saltybot/phone/gps→ valid lat/lon/covarianceros2 topic echo /saltybot/phone/battery→ percentage ∈ [0,1], temp in Kros2 topic echo /saltybot/phone/bridge/status→ JSON with mqtt_connected:truemqtt_connected:falsein status; restart → auto-reconnectuse_phone_timestamp:=truewith > 1s clock skew → warning logged, ROS2 clock used🤖 Generated with Claude Code
Add saltybot_phone/mqtt_ros2_bridge_node.py — ROS2 node bridging the three MQTT topics published by phone/sensor_dashboard.py into typed ROS2 messages: saltybot/phone/imu → /saltybot/phone/imu sensor_msgs/Imu saltybot/phone/gps → /saltybot/phone/gps sensor_msgs/NavSatFix saltybot/phone/battery → /saltybot/phone/battery sensor_msgs/BatteryState (status) → /saltybot/phone/bridge/status std_msgs/String Key design: - paho-mqtt loop_start() runs in dedicated network thread; on_message enqueues (topic, payload) pairs into a thread-safe queue - ROS2 timer drains queue at 50 Hz — all publishing stays on executor thread, avoiding any rclpy threading concerns - Timestamp alignment: uses ROS2 wall clock by default; opt-in use_phone_timestamp param uses phone epoch ts when drift < warn_drift_s - IMU: populates accel + gyro with diagonal covariance; orientation_cov[0]=-1 (unknown per REP-145) - GPS: NavSatStatus.STATUS_FIX for gps/fused/network providers; full 3×3 position covariance from accuracy_m; COVARIANCE_TYPE_APPROXIMATED - Battery: pct→percentage [0-1], temp Kelvin, health/status mapped from Android health strings, voltage/current=NaN (unavailable on Android) - Input validation: finite value checks on IMU, lat/lon range on GPS, pct [0-100] on battery; bad messages logged at DEBUG and counted - Status topic at 0.2 Hz: JSON {mqtt_connected, rx/pub/err counts, age_s per sensor, queue_depth} - Auto-reconnect via paho reconnect_delay_set (5 s → 20 s max) Add launch/mqtt_bridge.launch.py with args: mqtt_host, mqtt_port, reconnect_delay_s, use_phone_timestamp, warn_drift_s, imu_accel_cov, imu_gyro_cov. Register mqtt_ros2_bridge console script in setup.py. Add python3-paho-mqtt exec_depend to package.xml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>