From ba2e25ace83c35a0fc5efcf53e748de1c74ea66b Mon Sep 17 00:00:00 2001 From: ConnorN Date: Thu, 28 May 2026 16:09:12 -0400 Subject: [PATCH] feat: enable odrive resets --- src/components/panels/MotorStatusPanel.tsx | 70 +++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/src/components/panels/MotorStatusPanel.tsx b/src/components/panels/MotorStatusPanel.tsx index 156adff..f2f12d7 100644 --- a/src/components/panels/MotorStatusPanel.tsx +++ b/src/components/panels/MotorStatusPanel.tsx @@ -79,6 +79,44 @@ const MotorStatusPanel: React.FC = () => { eef: null, }); + const [resettingMotors, setResettingMotors] = useState< + Partial> + >({}); + + const getClearErrorsServiceName = (topic: string) => + topic.replace(/\/status$/, '/clear_errors'); + + const handleResetErrors = (key: MotorKey, topic: string) => { + if (!ros || resettingMotors[key]) return; + + setResettingMotors(prev => ({ ...prev, [key]: true })); + + const service = new ROSLIB.Service({ + ros, + name: getClearErrorsServiceName(topic), + serviceType: 'std_srvs/srv/Trigger', + }); + + service.callService( + new ROSLIB.ServiceRequest({}), + () => { + setMotorStats(prev => ({ + ...prev, + [key]: prev[key] + ? { + ...prev[key], + active_errors: 0, + } + : prev[key], + })); + setResettingMotors(prev => ({ ...prev, [key]: false })); + }, + () => { + setResettingMotors(prev => ({ ...prev, [key]: false })); + }, + ); + }; + useEffect(() => { if (!ros) return; @@ -119,11 +157,12 @@ const MotorStatusPanel: React.FC = () => { Vel. Curr. Errors + Reset {(Object.entries(MOTORS) as [MotorKey, typeof MOTORS[MotorKey]][]).map( - ([key, { label }]) => { + ([key, { label, topic }]) => { const stat = motorStats[key]; var errorStr = '-'; if (stat) { @@ -138,6 +177,15 @@ const MotorStatusPanel: React.FC = () => { {stat ? stat.velocity.toFixed(2) : '-'} {stat ? `${stat.output_current.toFixed(2)}A` : '-'} {errorStr} + + + ); } @@ -187,9 +235,27 @@ const MotorStatusPanel: React.FC = () => { border-radius: 50%; display: inline-block; } + + .reset-button { + background: #3b3b3b; + color: #f1f1f1; + border: 1px solid #555; + border-radius: 4px; + padding: 4px 8px; + cursor: pointer; + } + + .reset-button:hover:not(:disabled) { + background: #4a4a4a; + } + + .reset-button:disabled { + opacity: 0.5; + cursor: not-allowed; + } `} ); }; -export default MotorStatusPanel; +export default MotorStatusPanel; \ No newline at end of file