Update: Relocate AutoRun controls and cleanup
This commit is contained in:
73
App.tsx
73
App.tsx
@@ -8,6 +8,7 @@ import AgvControls from './components/AgvControls';
|
||||
import BmsPanel from './components/BmsPanel';
|
||||
import AcsControls from './components/AcsControls';
|
||||
import AgvStatusPanel from './components/AgvStatusPanel';
|
||||
import AgvAutoRunControls from './components/AgvAutoRunControls';
|
||||
import SystemLogPanel from './components/SystemLogPanel';
|
||||
import { SerialPortHandler } from './services/serialService';
|
||||
|
||||
@@ -184,12 +185,12 @@ const App: React.FC = () => {
|
||||
}, [addLog]);
|
||||
|
||||
const handleAgvData = useCallback((data: Uint8Array) => {
|
||||
for(let i=0; i<data.length; i++) {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
agvBufferRef.current.push(data[i]);
|
||||
}
|
||||
|
||||
const buf = agvBufferRef.current;
|
||||
while(true) {
|
||||
while (true) {
|
||||
const stxIdx = buf.indexOf(0x02);
|
||||
if (stxIdx === -1) {
|
||||
agvBufferRef.current = [];
|
||||
@@ -232,7 +233,7 @@ const App: React.FC = () => {
|
||||
|
||||
setAgvState(s => {
|
||||
const newBranch = (bunki === 'L' ? 'LEFT' : bunki === 'R' ? 'RIGHT' : bunki === 'S' ? 'STRAIGHT' : s.runConfig.branch);
|
||||
const newSpeed = (['L','M','H'].includes(speed) ? speed : s.runConfig.speedLevel) as any;
|
||||
const newSpeed = (['L', 'M', 'H'].includes(speed) ? speed : s.runConfig.speedLevel) as any;
|
||||
|
||||
// Treat '0' as placeholder for sensor if we want to preserve CBR logic,
|
||||
// BUT allow manual toggle via UI to override later.
|
||||
@@ -298,7 +299,7 @@ const App: React.FC = () => {
|
||||
setAgvState(s => {
|
||||
// Logic: Update if specific char provided, else keep existing
|
||||
const newBranch = (bunki === 'L' ? 'LEFT' : bunki === 'R' ? 'RIGHT' : bunki === 'S' ? 'STRAIGHT' : s.runConfig.branch);
|
||||
const newSpeed = (['L','M','H'].includes(speed) ? speed : s.runConfig.speedLevel) as any;
|
||||
const newSpeed = (['L', 'M', 'H'].includes(speed) ? speed : s.runConfig.speedLevel) as any;
|
||||
|
||||
const newLidar = sensor !== '0';
|
||||
|
||||
@@ -603,7 +604,7 @@ const App: React.FC = () => {
|
||||
const resp = new Uint8Array(34);
|
||||
resp[0] = 0xDD; resp[1] = 0x03; resp[2] = 0x00; resp[3] = 0x1b; //arrary 3value 0->1b
|
||||
|
||||
const totalV = Math.floor(s.cellVoltages.reduce((a,b)=>a+b, 0) * 100);
|
||||
const totalV = Math.floor(s.cellVoltages.reduce((a, b) => a + b, 0) * 100);
|
||||
resp[4] = (totalV >> 8) & 0xFF; resp[5] = totalV & 0xFF;
|
||||
|
||||
const remainAh = Math.floor(s.maxCapacity * (s.batteryLevel / 100));
|
||||
@@ -675,7 +676,7 @@ const App: React.FC = () => {
|
||||
|
||||
acsSerialRef.current.send(new Uint8Array(buffer));
|
||||
|
||||
const hex = buffer.map(b => b.toString(16).padStart(2,'0').toUpperCase()).join(' ');
|
||||
const hex = buffer.map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ');
|
||||
addLog('ACS', 'TX', `CMD:${cmd.toString(16).toUpperCase()} [${hex}]`);
|
||||
}, [addLog]);
|
||||
|
||||
@@ -735,7 +736,7 @@ const App: React.FC = () => {
|
||||
// Default Little Endian. So index len-3 is Low, len-2 is High.
|
||||
|
||||
if (receivedCrc !== 0xFFFF && calcCrc !== receivedCrc) {
|
||||
const hex = packetData.map(b => b.toString(16).padStart(2,'0').toUpperCase()).join(' ');
|
||||
const hex = packetData.map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ');
|
||||
addLog('ACS', 'ERROR', `CRC Fail: ${hex}`);
|
||||
acsParseErrorsRef.current++;
|
||||
if (acsParseErrorsRef.current > 3) buf.length = 0; // Reset on too many errors
|
||||
@@ -750,7 +751,7 @@ const App: React.FC = () => {
|
||||
const cmd = packetData[3];
|
||||
const payload = packetData.slice(4, totalPacketSize - 3);
|
||||
|
||||
const hexStr = packetData.map(b => b.toString(16).padStart(2,'0').toUpperCase()).join(' ');
|
||||
const hexStr = packetData.map(b => b.toString(16).padStart(2, '0').toUpperCase()).join(' ');
|
||||
addLog('ACS', 'RX', `[ID:${id} CMD:${cmd}] ${hexStr}`);
|
||||
|
||||
// Consume buffer
|
||||
@@ -890,7 +891,7 @@ const App: React.FC = () => {
|
||||
const [xStr, yStr] = l.Position.split(',').map(s => s.trim());
|
||||
newNodes.push({
|
||||
id: l.Id,
|
||||
x: parseFloat(xStr)||0, y: parseFloat(yStr)||0,
|
||||
x: parseFloat(xStr) || 0, y: parseFloat(yStr) || 0,
|
||||
type: NodeType.Label,
|
||||
name: "",
|
||||
rfidId: "",
|
||||
@@ -909,7 +910,7 @@ const App: React.FC = () => {
|
||||
const [xStr, yStr] = img.Position.split(',').map(s => s.trim());
|
||||
newNodes.push({
|
||||
id: img.Id,
|
||||
x: parseFloat(xStr)||0, y: parseFloat(yStr)||0,
|
||||
x: parseFloat(xStr) || 0, y: parseFloat(yStr) || 0,
|
||||
type: NodeType.Image,
|
||||
name: img.Name,
|
||||
rfidId: "",
|
||||
@@ -1047,7 +1048,7 @@ const App: React.FC = () => {
|
||||
NodeTextFontSize: n.fontSize || 7.0,
|
||||
AliasName: "",
|
||||
SpeedLimit: 0,
|
||||
CanDocking: [1,2,3,4,5].includes(n.type),
|
||||
CanDocking: [1, 2, 3, 4, 5].includes(n.type),
|
||||
DockDirection: n.type === NodeType.Charging || n.type === NodeType.ChargerStation ? 1 : 0,
|
||||
CanTurnLeft: true,
|
||||
CanTurnRight: true,
|
||||
@@ -1126,7 +1127,7 @@ const App: React.FC = () => {
|
||||
};
|
||||
|
||||
// --- Real-time updates to Serial (AGV Events) ---
|
||||
const prevSensors = useRef({ rfid: null as string|null, mark: false, line: false });
|
||||
const prevSensors = useRef({ rfid: null as string | null, mark: false, line: false });
|
||||
useEffect(() => {
|
||||
if (!agvConnected || !agvSerialRef.current) return;
|
||||
|
||||
@@ -1164,8 +1165,38 @@ const App: React.FC = () => {
|
||||
<div className="w-80 border-r border-gray-800 bg-gray-900 flex flex-col shrink-0">
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<AgvStatusPanel agvState={agvState} />
|
||||
|
||||
</div>
|
||||
|
||||
{/* Auto Run Controls (Left Sidebar) */}
|
||||
<div className="w-80 border-r border-gray-800 bg-gray-900 flex flex-col shrink-0">
|
||||
<div className="flex-1 overflow-hidden">
|
||||
<AgvAutoRunControls
|
||||
agvState={agvState}
|
||||
updateRunConfig={(key, value) => {
|
||||
if (agvState.error) return;
|
||||
setAgvState(s => ({ ...s, runConfig: { ...s.runConfig, [key]: value } }));
|
||||
}}
|
||||
toggleRun={() => {
|
||||
if (agvState.error) return;
|
||||
if (agvState.motionState === AgvMotionState.RUNNING || agvState.motionState === AgvMotionState.MARK_STOPPING) {
|
||||
setAgvState(s => ({ ...s, motionState: AgvMotionState.IDLE }));
|
||||
} else {
|
||||
const isFwd = agvState.runConfig.direction === 'FWD';
|
||||
const hasLine = isFwd ? agvState.sensorLineFront : agvState.sensorLineRear;
|
||||
if (!hasLine) {
|
||||
setAgvState(s => ({ ...s, error: 'LINE_OUT' }));
|
||||
return;
|
||||
}
|
||||
setAgvState(s => ({ ...s, motionState: AgvMotionState.RUNNING }));
|
||||
}
|
||||
}}
|
||||
isRunning={agvState.motionState === AgvMotionState.RUNNING || agvState.motionState === AgvMotionState.MARK_STOPPING}
|
||||
isError={agvState.error !== null}
|
||||
setLidar={(isOn) => setAgvState(s => ({ ...s, lidarEnabled: isOn, sensorStatus: isOn ? '1' : '0' }))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Middle 2: ACS Panel (Fixed) */}
|
||||
<div className="flex-shrink-0">
|
||||
@@ -1242,20 +1273,20 @@ const App: React.FC = () => {
|
||||
<div className="flex-1 overflow-y-auto">
|
||||
<AgvControls
|
||||
agvState={agvState}
|
||||
setMotion={(m) => 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={(m) => 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 }))}
|
||||
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 }))}
|
||||
setLiftStatus={(status) => setAgvState(s => ({ ...s, liftStatus: status }))}
|
||||
setLidar={(isOn) => setAgvState(s => ({ ...s, lidarEnabled: isOn, sensorStatus: isOn ? '1' : '0' }))}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Middle 1: BMS Panel (Fixed) */}
|
||||
<div className="flex-shrink-0">
|
||||
<BmsPanel state={agvState} setBatteryLevel={(l) => setAgvState(s => ({...s, batteryLevel: l}))} />
|
||||
<BmsPanel state={agvState} setBatteryLevel={(l) => setAgvState(s => ({ ...s, batteryLevel: l }))} />
|
||||
</div>
|
||||
|
||||
{/* Bottom: System Logs (Fixed Height) */}
|
||||
@@ -1263,7 +1294,7 @@ const App: React.FC = () => {
|
||||
<SystemLogPanel logs={logs.filter(l => l.source === 'SYSTEM')} onClear={() => clearLogs('SYSTEM')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
1
commit_msg_2.txt
Normal file
1
commit_msg_2.txt
Normal file
@@ -0,0 +1 @@
|
||||
Update: Relocate AutoRun controls and cleanup
|
||||
@@ -3,7 +3,7 @@ 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';
|
||||
import AgvAutoRunControls from './AgvAutoRunControls';
|
||||
|
||||
|
||||
interface AgvControlsProps {
|
||||
agvState: AgvState;
|
||||
@@ -29,22 +29,7 @@ const AgvControls: React.FC<AgvControlsProps> = ({ agvState, setMotion, setLift,
|
||||
});
|
||||
};
|
||||
|
||||
const toggleRun = () => {
|
||||
if (isError) return;
|
||||
|
||||
if (isRunning) {
|
||||
setMotion(AgvMotionState.IDLE);
|
||||
} else {
|
||||
const isFwd = agvState.runConfig.direction === 'FWD';
|
||||
const hasLine = isFwd ? agvState.sensorLineFront : agvState.sensorLineRear;
|
||||
|
||||
if (!hasLine) {
|
||||
setError('LINE_OUT');
|
||||
return;
|
||||
}
|
||||
setMotion(AgvMotionState.RUNNING);
|
||||
}
|
||||
};
|
||||
|
||||
const handleMarkStop = () => {
|
||||
if (agvState.motionState === AgvMotionState.RUNNING) {
|
||||
@@ -152,14 +137,7 @@ const AgvControls: React.FC<AgvControlsProps> = ({ agvState, setMotion, setLift,
|
||||
|
||||
{/* Auto Run Controls */}
|
||||
{/* Auto Run Controls (분리된 콤포넌트) */}
|
||||
<AgvAutoRunControls
|
||||
agvState={agvState}
|
||||
updateRunConfig={updateRunConfig}
|
||||
toggleRun={toggleRun}
|
||||
isRunning={isRunning}
|
||||
isError={isError}
|
||||
setLidar={setLidar}
|
||||
/>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user