mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 01:21:20 -04:00
pairs
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -11,7 +11,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
|
||||||
<title>Multi Roomba Rover</title>
|
<title>Multi Roomba Rover</title>
|
||||||
<script type="module" crossorigin src="/assets/index-g_BNt5fE.js"></script>
|
<script type="module" crossorigin src="/assets/index-BI-hKdyV.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-BBEWYgmH.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-BBEWYgmH.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useControlSystem } from '../controls/index.js';
|
import { useControlSystem } from '../controls/index.js';
|
||||||
|
import { OVERCURRENT_GROUPS } from '../controls/overcurrentLimiter.js';
|
||||||
|
|
||||||
const MOTOR_LABELS = {
|
const GROUP_LABELS = {
|
||||||
leftWheel: 'Left wheel',
|
drive: 'Drive wheels',
|
||||||
rightWheel: 'Right wheel',
|
aux: 'Aux motors',
|
||||||
mainBrush: 'Main brush',
|
|
||||||
sideBrush: 'Side brush',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function formatPct(value) {
|
function formatPct(value) {
|
||||||
@@ -27,7 +26,7 @@ export default function OvercurrentLimiterPanel() {
|
|||||||
state: { roverId },
|
state: { roverId },
|
||||||
overcurrentLimiter,
|
overcurrentLimiter,
|
||||||
} = useControlSystem();
|
} = useControlSystem();
|
||||||
const motors = useMemo(() => Object.keys(MOTOR_LABELS), []);
|
const groups = useMemo(() => OVERCURRENT_GROUPS.map((group) => group.key), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="panel-section space-y-0.5 text-sm">
|
<section className="panel-section space-y-0.5 text-sm">
|
||||||
@@ -39,15 +38,15 @@ export default function OvercurrentLimiterPanel() {
|
|||||||
<p className="text-xs text-slate-500">Assign a rover to view limiter status.</p>
|
<p className="text-xs text-slate-500">Assign a rover to view limiter status.</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-0.5">
|
<div className="space-y-0.5">
|
||||||
{motors.map((key) => {
|
{groups.map((key) => {
|
||||||
const meterA = overcurrentLimiter?.meters?.[key]?.a ?? 0;
|
const meterA = overcurrentLimiter?.meters?.[key]?.a ?? 0;
|
||||||
const meterB = overcurrentLimiter?.meters?.[key]?.b ?? 0;
|
const meterB = overcurrentLimiter?.meters?.[key]?.b ?? 0;
|
||||||
const over = overcurrentLimiter?.overcurrent?.[key] ?? false;
|
const over = overcurrentLimiter?.overcurrent?.groups?.[key] ?? false;
|
||||||
const scale = overcurrentLimiter?.scales?.perMotor?.[key] ?? 1;
|
const scale = overcurrentLimiter?.scales?.perGroup?.[key] ?? 1;
|
||||||
return (
|
return (
|
||||||
<div key={key} className="surface space-y-0.5">
|
<div key={key} className="surface space-y-0.5">
|
||||||
<div className="flex items-center justify-between text-xs">
|
<div className="flex items-center justify-between text-xs">
|
||||||
<span className="text-slate-200">{MOTOR_LABELS[key] || key}</span>
|
<span className="text-slate-200">{GROUP_LABELS[key] || key}</span>
|
||||||
<span className={over ? 'text-red-300' : 'text-slate-400'}>
|
<span className={over ? 'text-red-300' : 'text-slate-400'}>
|
||||||
{over ? 'overcurrent' : 'ok'}
|
{over ? 'overcurrent' : 'ok'}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import { useEffect, useMemo, useRef, useState } from 'react';
|
|||||||
import { useTelemetryFrame } from '../context/TelemetryContext.jsx';
|
import { useTelemetryFrame } from '../context/TelemetryContext.jsx';
|
||||||
import { useSession } from '../context/SessionContext.jsx';
|
import { useSession } from '../context/SessionContext.jsx';
|
||||||
|
|
||||||
export const OVERCURRENT_MOTORS = ['leftWheel', 'rightWheel', 'mainBrush', 'sideBrush'];
|
export const OVERCURRENT_GROUPS = [
|
||||||
|
{ key: 'drive', motors: ['leftWheel', 'rightWheel'] },
|
||||||
|
{ key: 'aux', motors: ['mainBrush', 'sideBrush'] },
|
||||||
|
];
|
||||||
|
|
||||||
export const DEFAULT_OVERCURRENT_LIMITS = {
|
export const DEFAULT_OVERCURRENT_LIMITS = {
|
||||||
meterAChargeSec: 4,
|
meterAChargeSec: 4,
|
||||||
@@ -12,8 +15,8 @@ export const DEFAULT_OVERCURRENT_LIMITS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function createInitialMeters() {
|
function createInitialMeters() {
|
||||||
return OVERCURRENT_MOTORS.reduce((acc, key) => {
|
return OVERCURRENT_GROUPS.reduce((acc, group) => {
|
||||||
acc[key] = { a: 0, b: 0 };
|
acc[group.key] = { a: 0, b: 0 };
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
@@ -62,9 +65,9 @@ export function useOvercurrentLimiter(roverId, options = {}) {
|
|||||||
setMeters((prev) => {
|
setMeters((prev) => {
|
||||||
let changed = false;
|
let changed = false;
|
||||||
const next = {};
|
const next = {};
|
||||||
OVERCURRENT_MOTORS.forEach((key) => {
|
OVERCURRENT_GROUPS.forEach((group) => {
|
||||||
const prevEntry = prev[key] || { a: 0, b: 0 };
|
const prevEntry = prev[group.key] || { a: 0, b: 0 };
|
||||||
const over = Boolean(flagsRef.current?.[key]);
|
const over = group.motors.some((motor) => Boolean(flagsRef.current?.[motor]));
|
||||||
const nextA = clampUnit(
|
const nextA = clampUnit(
|
||||||
stepValue(
|
stepValue(
|
||||||
prevEntry.a,
|
prevEntry.a,
|
||||||
@@ -85,7 +88,7 @@ export function useOvercurrentLimiter(roverId, options = {}) {
|
|||||||
if (Math.abs(nextA - prevEntry.a) > 0.0001 || Math.abs(nextB - prevEntry.b) > 0.0001) {
|
if (Math.abs(nextA - prevEntry.a) > 0.0001 || Math.abs(nextB - prevEntry.b) > 0.0001) {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
next[key] = { a: nextA, b: nextB };
|
next[group.key] = { a: nextA, b: nextB };
|
||||||
});
|
});
|
||||||
return changed ? next : prev;
|
return changed ? next : prev;
|
||||||
});
|
});
|
||||||
@@ -94,32 +97,37 @@ export function useOvercurrentLimiter(roverId, options = {}) {
|
|||||||
}, [config.meterAChargeSec, config.meterADecaySec, config.meterBChargeSec, config.meterBDecaySec]);
|
}, [config.meterAChargeSec, config.meterADecaySec, config.meterBChargeSec, config.meterBDecaySec]);
|
||||||
|
|
||||||
const scales = useMemo(() => {
|
const scales = useMemo(() => {
|
||||||
const perMotor = OVERCURRENT_MOTORS.reduce((acc, key) => {
|
const perGroup = OVERCURRENT_GROUPS.reduce((acc, group) => {
|
||||||
acc[key] = clampUnit(1 - (meters?.[key]?.b ?? 0));
|
acc[group.key] = clampUnit(1 - (meters?.[group.key]?.b ?? 0));
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
return {
|
return {
|
||||||
perMotor,
|
perGroup,
|
||||||
drive: {
|
drive: {
|
||||||
left: perMotor.leftWheel ?? 1,
|
left: perGroup.drive ?? 1,
|
||||||
right: perMotor.rightWheel ?? 1,
|
right: perGroup.drive ?? 1,
|
||||||
},
|
},
|
||||||
aux: {
|
aux: {
|
||||||
main: perMotor.mainBrush ?? 1,
|
main: perGroup.aux ?? 1,
|
||||||
side: perMotor.sideBrush ?? 1,
|
side: perGroup.aux ?? 1,
|
||||||
vacuum: 1,
|
vacuum: 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}, [meters]);
|
}, [meters]);
|
||||||
|
|
||||||
const overcurrent = useMemo(
|
const overcurrent = useMemo(() => {
|
||||||
() =>
|
const motors = {};
|
||||||
OVERCURRENT_MOTORS.reduce((acc, key) => {
|
OVERCURRENT_GROUPS.forEach((group) => {
|
||||||
acc[key] = Boolean(overcurrentFlags?.[key]);
|
group.motors.forEach((motor) => {
|
||||||
|
motors[motor] = Boolean(overcurrentFlags?.[motor]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const groups = OVERCURRENT_GROUPS.reduce((acc, group) => {
|
||||||
|
acc[group.key] = group.motors.some((motor) => Boolean(overcurrentFlags?.[motor]));
|
||||||
return acc;
|
return acc;
|
||||||
}, {}),
|
}, {});
|
||||||
[overcurrentFlags],
|
return { motors, groups };
|
||||||
);
|
}, [overcurrentFlags]);
|
||||||
|
|
||||||
const adminImmune =
|
const adminImmune =
|
||||||
session?.role === 'admin' ||
|
session?.role === 'admin' ||
|
||||||
|
|||||||
Reference in New Issue
Block a user