mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 10:00:46 -04:00
guh
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>webui</title>
|
<title>webui</title>
|
||||||
<script type="module" crossorigin src="/assets/index-BGrcbIm7.js"></script>
|
<script type="module" crossorigin src="/assets/index-C8plXa0F.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DEkIseQD.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DEkIseQD.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -5,13 +5,16 @@ const { getMode, modeEvents } = require('./modeManager');
|
|||||||
const roverManager = require('./roverManager');
|
const roverManager = require('./roverManager');
|
||||||
const { managerEvents } = roverManager;
|
const { managerEvents } = roverManager;
|
||||||
const assignmentService = require('./assignmentService');
|
const assignmentService = require('./assignmentService');
|
||||||
|
const { getActiveDrivers, turnEvents } = require('./turnService');
|
||||||
|
|
||||||
function buildSession(socket) {
|
function buildSession(socket) {
|
||||||
return {
|
return {
|
||||||
|
socketId: socket?.id || null,
|
||||||
role: getRole(socket),
|
role: getRole(socket),
|
||||||
mode: getMode(),
|
mode: getMode(),
|
||||||
roster: roverManager.getRoster(),
|
roster: roverManager.getRoster(),
|
||||||
assignment: assignmentService.describeAssignment(socket?.id || ''),
|
assignment: assignmentService.describeAssignment(socket?.id || ''),
|
||||||
|
activeDrivers: getActiveDrivers(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +64,11 @@ managerEvents.on('lock', ({ roverId, locked }) => {
|
|||||||
syncAll();
|
syncAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
turnEvents.on('activeDriver', () => {
|
||||||
|
logger.info('Active driver change; syncing all clients');
|
||||||
|
syncAll();
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
buildSession,
|
buildSession,
|
||||||
syncSocket,
|
syncSocket,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
const EventEmitter = require('events');
|
||||||
const io = require('../globals/io');
|
const io = require('../globals/io');
|
||||||
const { sendAlert, COLORS } = require('./alertService');
|
const { sendAlert, COLORS } = require('./alertService');
|
||||||
const { MODES, getMode, modeEvents } = require('./modeManager');
|
const { MODES, getMode, modeEvents } = require('./modeManager');
|
||||||
@@ -5,6 +6,7 @@ const { MODES, getMode, modeEvents } = require('./modeManager');
|
|||||||
const driverQueues = new Map(); // roverId -> { queue: [], current: socketId, timer: Timeout | null }
|
const driverQueues = new Map(); // roverId -> { queue: [], current: socketId, timer: Timeout | null }
|
||||||
const activeDrivers = new Map();
|
const activeDrivers = new Map();
|
||||||
const TURN_DURATION_MS = 60 * 1000;
|
const TURN_DURATION_MS = 60 * 1000;
|
||||||
|
const turnEvents = new EventEmitter();
|
||||||
|
|
||||||
function driverAdded(roverId, socketId, force) {
|
function driverAdded(roverId, socketId, force) {
|
||||||
const queue = ensureQueue(roverId);
|
const queue = ensureQueue(roverId);
|
||||||
@@ -104,7 +106,15 @@ function setActiveDriver(roverId, socketId) {
|
|||||||
} else {
|
} else {
|
||||||
activeDrivers.set(roverId, socketId);
|
activeDrivers.set(roverId, socketId);
|
||||||
}
|
}
|
||||||
io.emit('activeDriver', { roverId, socketId });
|
turnEvents.emit('activeDriver', { roverId, socketId });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getActiveDrivers() {
|
||||||
|
const map = {};
|
||||||
|
activeDrivers.forEach((socketId, roverId) => {
|
||||||
|
map[roverId] = socketId;
|
||||||
|
});
|
||||||
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopRover(roverId) {
|
function stopRover(roverId) {
|
||||||
@@ -126,4 +136,6 @@ module.exports = {
|
|||||||
driverRemoved,
|
driverRemoved,
|
||||||
cleanupRover,
|
cleanupRover,
|
||||||
canDrive,
|
canDrive,
|
||||||
|
getActiveDrivers,
|
||||||
|
turnEvents,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ export default function TelemetryPanel() {
|
|||||||
// const rawSnippet = frame?.raw ? (frame.raw.length > 80 ? `${frame.raw.slice(0, 80)}…` : frame.raw) : null;
|
// const rawSnippet = frame?.raw ? (frame.raw.length > 80 ? `${frame.raw.slice(0, 80)}…` : frame.raw) : null;
|
||||||
const rawSnippet = frame?.raw ? frame.raw : null;
|
const rawSnippet = frame?.raw ? frame.raw : null;
|
||||||
const roster = session?.roster ?? [];
|
const roster = session?.roster ?? [];
|
||||||
|
const activeDriverId = roverId ? session?.activeDrivers?.[roverId] : null;
|
||||||
|
const driverLabel = !roverId
|
||||||
|
? 'n/a'
|
||||||
|
: activeDriverId
|
||||||
|
? activeDriverId === session?.socketId
|
||||||
|
? 'You'
|
||||||
|
: activeDriverId.slice(0, 6)
|
||||||
|
: 'Available';
|
||||||
const isAdmin = useMemo(
|
const isAdmin = useMemo(
|
||||||
() => session?.role === 'admin' || session?.role === 'lockdown' || session?.role === 'lockdown-admin',
|
() => session?.role === 'admin' || session?.role === 'lockdown' || session?.role === 'lockdown-admin',
|
||||||
[session?.role],
|
[session?.role],
|
||||||
@@ -45,6 +53,7 @@ export default function TelemetryPanel() {
|
|||||||
<span> · role {session?.role || 'unknown'}</span>
|
<span> · role {session?.role || 'unknown'}</span>
|
||||||
<span> · mode {session?.mode || '--'}</span>
|
<span> · mode {session?.mode || '--'}</span>
|
||||||
{updated && <span> · sensors {updated}</span>}
|
{updated && <span> · sensors {updated}</span>}
|
||||||
|
<span> · driver {driverLabel}</span>
|
||||||
</div>
|
</div>
|
||||||
{!roverId ? (
|
{!roverId ? (
|
||||||
<p className="mt-1 text-[0.75rem] text-slate-400">Assign a rover to view sensors.</p>
|
<p className="mt-1 text-[0.75rem] text-slate-400">Assign a rover to view sensors.</p>
|
||||||
@@ -52,23 +61,21 @@ export default function TelemetryPanel() {
|
|||||||
<p className="mt-1 text-[0.75rem] text-slate-400">Waiting for sensor frames…</p>
|
<p className="mt-1 text-[0.75rem] text-slate-400">Waiting for sensor frames…</p>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
<div className="flex flex-wrap gap-0.5">
|
||||||
<div className="flex gap-0.5 flex-wrap">
|
|
||||||
<Metric label="Charge" value={formatMetric(charge != null && capacity != null ? `${charge}/${capacity}` : null)} />
|
<Metric label="Charge" value={formatMetric(charge != null && capacity != null ? `${charge}/${capacity}` : null)} />
|
||||||
<Metric label="Charging" value={formatMetric(sensors.chargingState?.label)} />
|
<Metric label="Charging" value={formatMetric(sensors.chargingState?.label)} />
|
||||||
<Metric label="OI mode" value={formatMetric(sensors.oiMode?.label)} />
|
<Metric label="OI mode" value={formatMetric(sensors.oiMode?.label)} />
|
||||||
<Metric label="Voltage" value={formatMetric(voltage)} />
|
<Metric label="Voltage" value={formatMetric(voltage)} />
|
||||||
<Metric label="Current" value={formatMetric(current)} />
|
<Metric label="Current" value={formatMetric(current)} />
|
||||||
<Metric label="Left Encoder" value={formatMetric(sensors.encoderCountsLeft)}/>
|
<Metric label="Left Encoder" value={formatMetric(sensors.encoderCountsLeft)} />
|
||||||
<Metric label="Right Encoder" value={formatMetric(sensors.encoderCountsRight)}/>
|
<Metric label="Right Encoder" value={formatMetric(sensors.encoderCountsRight)} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gap-0.5 mt-1">
|
<div className="mt-1 flex gap-0.5">
|
||||||
<CliffBar value={sensors.cliffLeftSignal} />
|
<CliffBar value={sensors.cliffLeftSignal} />
|
||||||
<CliffBar value={sensors.cliffFrontLeftSignal} />
|
<CliffBar value={sensors.cliffFrontLeftSignal} />
|
||||||
<CliffBar value={sensors.cliffFrontRightSignal} />
|
<CliffBar value={sensors.cliffFrontRightSignal} />
|
||||||
<CliffBar value={sensors.cliffRightSignal} />
|
<CliffBar value={sensors.cliffRightSignal} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
@@ -131,10 +138,6 @@ function CliffBar({ value }) {
|
|||||||
|
|
||||||
function Metric({ label, value }) {
|
function Metric({ label, value }) {
|
||||||
return (
|
return (
|
||||||
// <div className="flex items-center justify-between">
|
|
||||||
// <span className="text-slate-400">{label}</span>
|
|
||||||
// <span className="text-slate-200">{value}</span>
|
|
||||||
// </div>
|
|
||||||
<div className="bg-gray-700 rounded-sm p-0.5 text-sm">
|
<div className="bg-gray-700 rounded-sm p-0.5 text-sm">
|
||||||
{label}: {value}
|
{label}: {value}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user