From 25656f5e4c4236b19a2858f966a45f542a1a77b0 Mon Sep 17 00:00:00 2001 From: sl-webui Date: Fri, 3 Apr 2026 22:41:47 -0400 Subject: [PATCH] fix(sultee-tracker): subscribe to proper ROS GPS topics for robot marker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch robot GPS subscription from custom saltybot/gps/* std_msgs/String topics to the canonical /gps/fix (sensor_msgs/NavSatFix) and /gps/vel (geometry_msgs/TwistStamped) published by the SIM7600X GPS driver node. - /gps/fix: read msg.latitude/longitude/altitude/status.status directly - /gps/vel: compute speed (sqrt(vx²+vy²) * 3.6 km/h) and heading (angular.z radians → degrees) from ENU velocity components Closes #709 Co-Authored-By: Claude Sonnet 4.6 --- ui/sultee-tracker.html | 58 ++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/ui/sultee-tracker.html b/ui/sultee-tracker.html index 0d24c74..b6dcfa5 100644 --- a/ui/sultee-tracker.html +++ b/ui/sultee-tracker.html @@ -723,43 +723,41 @@ function connectRos(url) { } function setupRobotTopics() { - // saltybot/gps/fix — {lat, lon, alt, stat, t} + // /gps/fix — sensor_msgs/NavSatFix (SIM7600X / Pixel 5 GPS) new ROSLIB.Topic({ - ros, name: 'saltybot/gps/fix', - messageType: 'std_msgs/String', throttle_rate: 500, + ros, name: '/gps/fix', + messageType: 'sensor_msgs/NavSatFix', throttle_rate: 500, }).subscribe(msg => { - try { - const d = JSON.parse(msg.data); - robot.lat = d.lat ?? robot.lat; - robot.lon = d.lon ?? robot.lon; - robot.alt = d.alt ?? robot.alt; - robot.stat = d.stat ?? robot.stat; - robot.fixes++; - robot.tsfix = Date.now(); + robot.lat = msg.latitude ?? robot.lat; + robot.lon = msg.longitude ?? robot.lon; + robot.alt = msg.altitude ?? robot.alt; + robot.stat = msg.status ? msg.status.status : robot.stat; + robot.fixes++; + robot.tsfix = Date.now(); - if (robot.lat != null && robot.lon != null) { - updateRobotMap(robot.lat, robot.lon, robot.hdg); - } - $('last-msg').textContent = 'Robot: ' + new Date().toLocaleTimeString('en-US', { hour12: false }); - render(); - } catch(_) {} + if (robot.lat != null && robot.lon != null) { + updateRobotMap(robot.lat, robot.lon, robot.hdg); + } + $('last-msg').textContent = 'Robot: ' + new Date().toLocaleTimeString('en-US', { hour12: false }); + render(); }); - // saltybot/gps/vel — {spd, hdg, t} + // /gps/vel — geometry_msgs/TwistStamped (east/north m/s + heading in radians) new ROSLIB.Topic({ - ros, name: 'saltybot/gps/vel', - messageType: 'std_msgs/String', throttle_rate: 500, + ros, name: '/gps/vel', + messageType: 'geometry_msgs/TwistStamped', throttle_rate: 500, }).subscribe(msg => { - try { - const d = JSON.parse(msg.data); - robot.spd = d.spd ?? robot.spd; - robot.hdg = d.hdg ?? robot.hdg; - robot.tsvel = Date.now(); - if (robotMarker && robot.lat != null) { - robotMarker.setIcon(makeRobotIcon(robot.hdg)); - } - render(); - } catch(_) {} + const vx = msg.twist.linear.x; // east m/s + const vy = msg.twist.linear.y; // north m/s + const spd = Math.sqrt(vx * vx + vy * vy) * 3.6; // → km/h + const hdg = (msg.twist.angular.z * 180 / Math.PI + 360) % 360; // radians → degrees + robot.spd = spd; + robot.hdg = hdg; + robot.tsvel = Date.now(); + if (robotMarker && robot.lat != null) { + robotMarker.setIcon(makeRobotIcon(robot.hdg)); + } + render(); }); }