output rate limit and override gating

This commit is contained in:
legop3
2026-01-21 02:38:37 -05:00
parent e0edbcfb28
commit 8326898403
5 changed files with 28 additions and 17 deletions
+10 -4
View File
@@ -142,6 +142,8 @@ export function ControlSystemProvider({ children }) {
const driveSpeedsRef = useRef(state.drive.speeds);
const auxValuesRef = useRef(state.aux);
const limiterScaleToken = useMemo(() => JSON.stringify(overcurrentLimiter.scales), [overcurrentLimiter.scales]);
const limiterDriveSentAtRef = useRef(0);
const limiterAuxSentAtRef = useRef(0);
useEffect(() => {
driveSpeedsRef.current = state.drive.speeds;
@@ -152,19 +154,23 @@ export function ControlSystemProvider({ children }) {
}, [state.aux]);
useEffect(() => {
if (!pipeline.roverId || overcurrentLimiter.adminImmune) return;
if (!pipeline.roverId || overcurrentLimiter.adminImmune || !overcurrentLimiter.isActive) return;
const outputRateMs = Math.max(0, Number(overcurrentLimiter?.config?.outputRateMs) || 0);
const now = typeof performance !== 'undefined' ? performance.now() : Date.now();
const drive = driveSpeedsRef.current || { left: 0, right: 0 };
const aux = auxValuesRef.current || { main: 0, side: 0, vacuum: 0 };
const driveActive = Boolean(drive.left || drive.right);
const auxActive = Boolean(aux.main || aux.side || aux.vacuum);
if (!driveActive && !auxActive) return;
if (driveActive) {
if (driveActive && now - limiterDriveSentAtRef.current >= outputRateMs) {
limiterDriveSentAtRef.current = now;
pipeline.sendDriveDirect(drive);
}
if (auxActive) {
if (auxActive && now - limiterAuxSentAtRef.current >= outputRateMs) {
limiterAuxSentAtRef.current = now;
pipeline.sendAuxMotors(aux);
}
}, [limiterScaleToken, overcurrentLimiter.adminImmune, pipeline]);
}, [limiterScaleToken, overcurrentLimiter.adminImmune, overcurrentLimiter.config, overcurrentLimiter.isActive, pipeline]);
const setDriveVector = useCallback(
(vector, meta = {}) => {
+7 -3
View File
@@ -8,10 +8,11 @@ export const OVERCURRENT_GROUPS = [
];
export const DEFAULT_OVERCURRENT_LIMITS = {
meterAChargeSec: 3,
meterAChargeSec: 9,
meterADecaySec: 9,
meterBChargeSec: 1,
meterBDecaySec: 10,
meterBChargeSec: 5,
meterBDecaySec: 5,
outputRateMs: 250,
};
function createInitialMeters() {
@@ -139,6 +140,7 @@ export function useOvercurrentLimiter(roverId, options = {}) {
meters,
overcurrent,
scales,
isActive: (scales?.drive?.left ?? 1) < 1 || (scales?.drive?.right ?? 1) < 1 || (scales?.aux?.main ?? 1) < 1 || (scales?.aux?.side ?? 1) < 1,
config,
adminImmune,
}),
@@ -150,6 +152,7 @@ export function applyDriveOvercurrentScale(speeds = {}, scales, adminImmune = fa
if (adminImmune || !scales?.drive) return speeds;
const leftScale = typeof scales.drive.left === 'number' ? scales.drive.left : 1;
const rightScale = typeof scales.drive.right === 'number' ? scales.drive.right : 1;
if (leftScale >= 0.999 && rightScale >= 0.999) return speeds;
return {
left: Math.round((speeds.left ?? 0) * leftScale),
right: Math.round((speeds.right ?? 0) * rightScale),
@@ -161,6 +164,7 @@ export function applyAuxOvercurrentScale(values = {}, scales, adminImmune = fals
const mainScale = typeof scales.aux.main === 'number' ? scales.aux.main : 1;
const sideScale = typeof scales.aux.side === 'number' ? scales.aux.side : 1;
const vacuumScale = typeof scales.aux.vacuum === 'number' ? scales.aux.vacuum : 1;
if (mainScale >= 0.999 && sideScale >= 0.999 && vacuumScale >= 0.999) return values;
return {
main: Math.round((values.main ?? 0) * mainScale),
side: Math.round((values.side ?? 0) * sideScale),