From 5c6794d7c920d60827a2f22104e4dd488b36a1f7 Mon Sep 17 00:00:00 2001 From: ConnorN Date: Mon, 25 May 2026 22:38:29 -0400 Subject: [PATCH] feat: more useful default page feat: 240 sample option for science readings feat: eef distance display --- src/components/TelemetryGraph.tsx | 1 + src/components/panels/ArmControlPanel.tsx | 59 +++++++++++++++++++++++ src/components/panels/MosaicDashboard.tsx | 8 +-- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/src/components/TelemetryGraph.tsx b/src/components/TelemetryGraph.tsx index dba80ce..67f05eb 100644 --- a/src/components/TelemetryGraph.tsx +++ b/src/components/TelemetryGraph.tsx @@ -92,6 +92,7 @@ const TelemetryGraph: React.FC = ({ topic, label, color = '#4da3ff' }) => + diff --git a/src/components/panels/ArmControlPanel.tsx b/src/components/panels/ArmControlPanel.tsx index bfc7894..a690a53 100644 --- a/src/components/panels/ArmControlPanel.tsx +++ b/src/components/panels/ArmControlPanel.tsx @@ -9,6 +9,8 @@ const ArmControlPanel: React.FC = () => { const [poseNames, setPoseNames] = useState([]); const [selectedPose, setSelectedPose] = useState(''); + const [distance, setDistance] = useState(null); + const [distanceStatus, setDistanceStatus] = useState(null); const [response, setResponse] = useState<{ success: boolean; message: string } | null>(null); const refreshPoseNames = () => { @@ -36,6 +38,38 @@ const ArmControlPanel: React.FC = () => { refreshPoseNames(); }, [ros]); + useEffect(() => { + if (!ros) return; + + const distanceTopic = new ROSLIB.Topic({ + ros, + name: '/eef_distance', + messageType: 'interfaces/msg/Distance', + }); + + const handleDistance = (msg: any) => { + setDistance(msg.distance); + setDistanceStatus(msg.status); + }; + + distanceTopic.subscribe(handleDistance); + + return () => { + distanceTopic.unsubscribe(handleDistance); + }; + }, [ros]); + + const getDistanceDisplay = () => { + const GRIPPER_OFFSET = 0.18; + if (distance === null) return 'No data'; + const distance_with_offset = distance - GRIPPER_OFFSET; + + if (distanceStatus === 1) return `Error (${distance_with_offset.toFixed(3)})`; + if (distanceStatus === 2) return `Invalid (${distance_with_offset.toFixed(3)})`; + + return distance_with_offset.toFixed(3); + }; + const handleGo = () => { if (!ros) { alert('ROS is not connected'); @@ -108,6 +142,11 @@ const ArmControlPanel: React.FC = () => { +
+ Distance: + {getDistanceDisplay()} +
+ @@ -152,6 +191,26 @@ const ArmControlPanel: React.FC = () => { color: #f1f1f1; } + .display-row { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0.75rem; + padding: 0.5rem; + border: 1px solid #333; + border-radius: 4px; + background: #2b2b2b; + } + + .display-row span { + color: #ccc; + } + + .display-row strong { + color: #f1f1f1; + font-weight: 600; + } + button { background: #0070f3; color: #f1f1f1; diff --git a/src/components/panels/MosaicDashboard.tsx b/src/components/panels/MosaicDashboard.tsx index 1657fb5..327b80a 100644 --- a/src/components/panels/MosaicDashboard.tsx +++ b/src/components/panels/MosaicDashboard.tsx @@ -131,7 +131,7 @@ function buildDefaultLayout(makeTileId: (type: TileType) => TileId): MosaicNode< }, second: makeTileId('networkHealthMonitor'), }, - second: makeTileId('rosMonitor'), + second: makeTileId('waypointList'), splitPercentage: 55, }, splitPercentage: 55, @@ -141,11 +141,11 @@ function buildDefaultLayout(makeTileId: (type: TileType) => TileId): MosaicNode< first: makeTileId('videoControls'), second: { direction: 'row', - first: makeTileId('waypointList'), + first: makeTileId('pdbRails'), second: { direction: 'row', - first: makeTileId('gasSensor'), - second: makeTileId('goalSetter'), + first: makeTileId('espSensorPanel'), + second: makeTileId('armControlPanel'), }, splitPercentage: 50, },