From a43c2d769e46b93a93592abd428daea81ae44ad8 Mon Sep 17 00:00:00 2001 From: backuppc Date: Fri, 19 Dec 2025 10:35:19 +0900 Subject: [PATCH] Refactor AgvControls and update manual operation UI --- App.tsx | 15 +- components/AgvControls.tsx | 145 ------------------- components/AgvManualControls.tsx | 241 ++++++++++++++++++++----------- 3 files changed, 167 insertions(+), 234 deletions(-) delete mode 100644 components/AgvControls.tsx diff --git a/App.tsx b/App.tsx index 39a2ddc..af3e75c 100644 --- a/App.tsx +++ b/App.tsx @@ -4,7 +4,7 @@ import { INITIAL_MAP, MAX_SPEED } from './constants'; import EditorToolbar from './components/EditorToolbar'; import SimulationCanvas from './components/SimulationCanvas'; import SerialConsole from './components/SerialConsole'; -import AgvControls from './components/AgvControls'; +import AgvManualControls from './components/AgvManualControls'; import BmsPanel from './components/BmsPanel'; import AcsControls from './components/AcsControls'; import AgvStatusPanel from './components/AgvStatusPanel'; @@ -1326,16 +1326,15 @@ const App: React.FC = () => { {/* Top: Controls (Scrollable if needed) */}
- setAgvState(s => ({ ...s, motionState: m }))} - setLift={(h) => setAgvState(s => ({ ...s, liftHeight: h }))} - setRunConfig={(c) => setAgvState(s => ({ ...s, runConfig: c }))} - setError={(e) => setAgvState(s => ({ ...s, error: e }))} + setMotion={(state) => setAgvState(s => ({ ...s, motionState: state }))} + setRunConfig={(config) => setAgvState(s => ({ ...s, runConfig: config }))} + setError={(err) => setAgvState(s => ({ ...s, error: err }))} onTurn180={handleTurn180} - setMagnet={(isOn) => setAgvState(s => ({ ...s, magnetOn: isOn }))} setLiftStatus={(status) => setAgvState(s => ({ ...s, liftStatus: status }))} - setLidar={(isOn) => setAgvState(s => ({ ...s, lidarEnabled: isOn, sensorStatus: isOn ? '1' : '0' }))} + setMagnet={(isOn) => setAgvState(s => ({ ...s, magnetOn: isOn }))} />
diff --git a/components/AgvControls.tsx b/components/AgvControls.tsx deleted file mode 100644 index 5c34527..0000000 --- a/components/AgvControls.tsx +++ /dev/null @@ -1,145 +0,0 @@ - -import React from 'react'; -import { StopCircle, Play, Square, AlertTriangle, ChevronsUp, ChevronsDown, Magnet, Radar, ArrowLeft, ArrowRight } from 'lucide-react'; -import { AgvState, AgvMotionState, AgvRunConfig } from '../types'; -import AgvManualControls from './AgvManualControls'; - - -interface AgvControlsProps { - agvState: AgvState; - setMotion: (state: AgvMotionState) => void; - setLift: (val: number) => void; - setRunConfig: (config: AgvRunConfig) => void; - setError: (error: string | null) => void; - onTurn180: (direction: 'LEFT' | 'RIGHT') => void; - setMagnet: (isOn: boolean) => void; - setLiftStatus: (status: 'IDLE' | 'UP' | 'DOWN') => void; - setLidar: (isOn: boolean) => void; -} - -const AgvControls: React.FC = ({ agvState, setMotion, setLift, setRunConfig, setError, onTurn180, setMagnet, setLiftStatus, setLidar }) => { - const isRunning = agvState.motionState === AgvMotionState.RUNNING || agvState.motionState === AgvMotionState.MARK_STOPPING; - const isError = agvState.error !== null; - - const updateRunConfig = (key: keyof AgvRunConfig, value: any) => { - if (isError) return; - setRunConfig({ - ...agvState.runConfig, - [key]: value - }); - }; - - - - const handleMarkStop = () => { - if (agvState.motionState === AgvMotionState.RUNNING) { - setRunConfig({ - ...agvState.runConfig, - speedLevel: 'L' - }); - setMotion(AgvMotionState.MARK_STOPPING); - } - }; - - const resetError = () => { - setError(null); - }; - - const handleLiftSliderChange = (e: React.ChangeEvent) => { - if (agvState.liftStatus !== 'IDLE') { - setLiftStatus('IDLE'); - } - setLift(parseInt(e.target.value)); - }; - - return ( -
- - {/* Error Overlay */} - {isError && ( -
-
- - {agvState.error} -
- -
- )} - - {/* Manual Operation (분리된 콤포넌트) */} - - - {/* Lift & Magnet */} -
-
- Lift Height - {Math.round(agvState.liftHeight)}% -
- -
- - - - - -
- - -
- -
- - {/* Auto Run Controls */} - {/* Auto Run Controls (분리된 콤포넌트) */} - -
- ); -}; - -export default AgvControls; diff --git a/components/AgvManualControls.tsx b/components/AgvManualControls.tsx index bbaa07c..de726b6 100644 --- a/components/AgvManualControls.tsx +++ b/components/AgvManualControls.tsx @@ -1,27 +1,51 @@ import React from 'react'; -import { ArrowUp, ArrowDown, RotateCcw, RotateCw, StopCircle, Disc } from 'lucide-react'; +import { ArrowUp, ArrowDown, RotateCcw, RotateCw, StopCircle, Disc, ChevronsUp, ChevronsDown, Magnet, AlertTriangle } from 'lucide-react'; import { AgvState, AgvMotionState, AgvRunConfig } from '../types'; interface AgvManualControlsProps { agvState: AgvState; setMotion: (state: AgvMotionState) => void; - updateRunConfig: (key: keyof AgvRunConfig, value: any) => void; + setRunConfig: (config: AgvRunConfig) => void; + setError: (error: string | null) => void; onTurn180: (direction: 'LEFT' | 'RIGHT') => void; - handleMarkStop: () => void; - isRunning: boolean; - isError: boolean; + setLiftStatus: (status: 'IDLE' | 'UP' | 'DOWN') => void; + setMagnet: (isOn: boolean) => void; } const AgvManualControls: React.FC = ({ agvState, setMotion, - updateRunConfig, + setRunConfig, + setError, onTurn180, - handleMarkStop, - isRunning, - isError, + setLiftStatus, + setMagnet, }) => { + const isRunning = agvState.motionState === AgvMotionState.RUNNING || agvState.motionState === AgvMotionState.MARK_STOPPING; + const isError = agvState.error !== null; + + const updateRunConfig = (key: keyof AgvRunConfig, value: any) => { + if (isError) return; + setRunConfig({ + ...agvState.runConfig, + [key]: value + }); + }; + + const handleMarkStop = () => { + if (agvState.motionState === AgvMotionState.RUNNING) { + setRunConfig({ + ...agvState.runConfig, + speedLevel: 'L' + }); + setMotion(AgvMotionState.MARK_STOPPING); + } + }; + + const resetError = () => { + setError(null); + }; const setManualMotion = (motion: AgvMotionState, direction?: 'FWD' | 'BWD') => { setMotion(motion); if (direction) { @@ -30,86 +54,141 @@ const AgvManualControls: React.FC = ({ }; return ( -
-
-

Manual Operation

-
-
-
-
- -
+
- - - +
+ )} -
- -
+
+
+

Manual Operation

- {/* Extra Actions */} -
- - - + + + + + + + + + + +
+ + {/* Extra Actions */} +
+ + + + }`} + > + {agvState.motionState === AgvMotionState.MARK_STOPPING ? 'Stopping at Mark...' : 'Drive to Next Mark'} + +