mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-15 17:12:59 -04:00
better dock resolving
This commit is contained in:
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<!-- site-metadata:inject -->
|
||||
<!-- analytics:inject -->
|
||||
<script type="module" crossorigin src="/assets/index-DtnnIgZU.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BNuqn1jZ.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-D2qTDWX0.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { useTelemetrySelector } from '../../context/TelemetryContext.jsx';
|
||||
import { dockTelemetryEqual, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { dockTelemetryEqual, isDockedChargingState, resolveDocked, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
|
||||
export function deriveDriveDockStateFromTelemetry(dockTelemetry) {
|
||||
const oiLabel = dockTelemetry?.oiModeLabel || 'Unknown';
|
||||
const oiNormalized = oiLabel.toLowerCase();
|
||||
const chargingLabel = dockTelemetry?.chargingStateLabel || '';
|
||||
const docked = Boolean(dockTelemetry?.homeBase);
|
||||
const charging = docked && chargingLabel.toLowerCase() !== 'not charging' && chargingLabel !== '';
|
||||
const docked = resolveDocked(dockTelemetry);
|
||||
const charging = isDockedChargingState(chargingLabel);
|
||||
const driving = oiNormalized === 'full';
|
||||
const dockedNotCharging = docked && !charging;
|
||||
const dockingInProgress = !docked && !charging && oiNormalized === 'passive';
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createElement, useMemo } from 'react';
|
||||
import { FaArrowDown, FaArrowUp, FaBatteryHalf, FaBolt, FaExclamationTriangle, FaMemory, FaThermometerHalf, FaWifi } from 'react-icons/fa';
|
||||
import { useSessionSelector } from '../../../../context/SessionContext.jsx';
|
||||
import { useTelemetrySelector } from '../../../../context/TelemetryContext.jsx';
|
||||
import { hostStatsEqual, selectHostStats, selectSpectatorTelemetry, spectatorTelemetryEqual } from '../../../../context/telemetryViews.js';
|
||||
import { hostStatsEqual, resolveDocked, selectHostStats, selectSpectatorTelemetry, spectatorTelemetryEqual } from '../../../../context/telemetryViews.js';
|
||||
import CornerPodToggle from './CornerPodToggle.jsx';
|
||||
import ExpansionToggle from './ExpansionToggle.jsx';
|
||||
import usePodVisibility from './usePodVisibility.js';
|
||||
@@ -101,7 +101,7 @@ export default function TopRightPod({ roverId }) {
|
||||
const memoryTone = memoryUsed >= 90 ? 'bg-red-400' : memoryUsed >= 75 ? 'bg-amber-400' : 'bg-violet-400';
|
||||
const download = finite(wifi.downloadMbps);
|
||||
const upload = finite(wifi.uploadMbps);
|
||||
const docked = Boolean(electrical?.homeBase);
|
||||
const docked = resolveDocked(electrical);
|
||||
const warningMessage = urgentBattery ? 'BATTERY CRITICAL, DOCK NOW' : 'Battery low, please dock soon.';
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,7 +7,7 @@ import { FaChargingStation, FaChevronDown } from 'react-icons/fa';
|
||||
import { useControlActions, useControlSelector } from '../../../../controls/index.js';
|
||||
import { formatKeyLabel } from '../../../../controls/keymapUtils.js';
|
||||
import { useTelemetrySelector } from '../../../../context/TelemetryContext.jsx';
|
||||
import { dockTelemetryEqual, selectDockTelemetry } from '../../../../context/telemetryViews.js';
|
||||
import { dockTelemetryEqual, resolveDocked, selectDockTelemetry } from '../../../../context/telemetryViews.js';
|
||||
import { useManualDockAssist } from '../../../../features/manualDockAssist/useManualDockAssist.js';
|
||||
import { useSettingsNamespace } from '../../../../settings/index.js';
|
||||
import useCanControlRover from '../../../../hooks/useCanControlRover.js';
|
||||
@@ -256,7 +256,7 @@ export default function DockingHud({ roverId }) {
|
||||
const [error, setError] = useState('');
|
||||
const [showUndockTransition, setShowUndockTransition] = useState(false);
|
||||
|
||||
const docked = Boolean(dockTelemetry?.homeBase);
|
||||
const docked = resolveDocked(dockTelemetry);
|
||||
const oiMode = String(dockTelemetry?.oiModeLabel || '').toLowerCase();
|
||||
// The established UI contract treats exactly passive + undocked as the Roomba's
|
||||
// autonomous docking attempt. Unknown telemetry must not fabricate that state.
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FaBullhorn, FaCrosshairs, FaLightbulb } from 'react-icons/fa';
|
||||
import './mobileControls.css';
|
||||
import { useControlActions, useControlSelector } from '../../controls/index.js';
|
||||
import { useTelemetrySelector } from '../../context/TelemetryContext.jsx';
|
||||
import { dockTelemetryEqual, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { dockTelemetryEqual, resolveDocked, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { useManualDockAssist } from '../../features/manualDockAssist/useManualDockAssist.js';
|
||||
import useCanControlRover from '../../hooks/useCanControlRover.js';
|
||||
import HornControl from '../HornControl/index.jsx';
|
||||
@@ -37,7 +37,7 @@ function AuxColumnContent() {
|
||||
// column. Dock and OI state are applied separately only where the hardware
|
||||
// command itself depends on the Roomba being able to drive.
|
||||
const controlsDisabled = !roverId || !canControl;
|
||||
const docked = Boolean(dockTelemetry?.homeBase);
|
||||
const docked = resolveDocked(dockTelemetry);
|
||||
const drivingMode = String(dockTelemetry?.oiModeLabel || '').toLowerCase() === 'full';
|
||||
const vacuumDisabled = controlsDisabled
|
||||
|| docked
|
||||
|
||||
@@ -5,7 +5,7 @@ import { FaChargingStation } from 'react-icons/fa';
|
||||
import { useControlSelector } from '../../controls/index.js';
|
||||
import { useSessionSelector } from '../../context/SessionContext.jsx';
|
||||
import { useTelemetrySelector } from '../../context/TelemetryContext.jsx';
|
||||
import { dockTelemetryEqual, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { dockTelemetryEqual, resolveDocked, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { useManualDockAssist } from '../../features/manualDockAssist/useManualDockAssist.js';
|
||||
import useCanControlRover from '../../hooks/useCanControlRover.js';
|
||||
import { triggerTouchHaptic } from '../../lib/touchHaptics.js';
|
||||
@@ -22,7 +22,7 @@ function MovementColumnContent({ layout }) {
|
||||
});
|
||||
const batteryUrgent = Boolean(batteryState?.urgentActive);
|
||||
const batteryLow = Boolean(batteryState?.warnActive || batteryUrgent);
|
||||
const docked = Boolean(dockTelemetry?.homeBase);
|
||||
const docked = resolveDocked(dockTelemetry);
|
||||
const drivingMode = String(dockTelemetry?.oiModeLabel || '').toLowerCase() === 'full';
|
||||
|
||||
/*
|
||||
|
||||
@@ -37,6 +37,27 @@ const EMPTY_MAIN_BRUSH_AUDIO = Object.freeze({
|
||||
mainBrushOvercurrent: false,
|
||||
});
|
||||
|
||||
// These labels represent an active charging relationship reported by the
|
||||
// Roomba. That is independently useful dock evidence: some already-docked
|
||||
// rovers report charging before the home-base contact bit changes again.
|
||||
const DOCKED_CHARGING_STATES = new Set([
|
||||
'reconditioning charging',
|
||||
'full charging',
|
||||
'trickle charging',
|
||||
'waiting',
|
||||
]);
|
||||
|
||||
export function isDockedChargingState(chargingStateLabel) {
|
||||
return DOCKED_CHARGING_STATES.has(String(chargingStateLabel || '').trim().toLowerCase());
|
||||
}
|
||||
|
||||
export function resolveDocked(dockTelemetry) {
|
||||
// Dock contact and active charging are complementary sensor evidence, not
|
||||
// fallback state. Treating either as sufficient prevents UI controls from
|
||||
// claiming a charging rover should be driven onto a dock it already occupies.
|
||||
return Boolean(dockTelemetry?.homeBase) || isDockedChargingState(dockTelemetry?.chargingStateLabel);
|
||||
}
|
||||
|
||||
function bucketNumber(value, step) {
|
||||
// Visual widgets do not benefit from repainting for tiny analog jitter. The
|
||||
// bucket step intentionally applies only to display selectors; raw telemetry
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
||||
import { useControlActions, useControlSelector } from '../../controls/index.js';
|
||||
import { useTelemetrySelector } from '../../context/TelemetryContext.jsx';
|
||||
import { dockTelemetryEqual, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
import { dockTelemetryEqual, isDockedChargingState, resolveDocked, selectDockTelemetry } from '../../context/telemetryViews.js';
|
||||
|
||||
export function useManualDockAssist(options = {}) {
|
||||
const { manageLifecycle = false } = options;
|
||||
@@ -10,8 +10,10 @@ export function useManualDockAssist(options = {}) {
|
||||
const actions = useControlActions();
|
||||
const dockTelemetry = useTelemetrySelector(roverId, selectDockTelemetry, dockTelemetryEqual);
|
||||
const chargingLabel = dockTelemetry.chargingStateLabel || '';
|
||||
const docked = Boolean(dockTelemetry.homeBase);
|
||||
const charging = docked && chargingLabel.toLowerCase() !== 'not charging' && chargingLabel !== '';
|
||||
const docked = resolveDocked(dockTelemetry);
|
||||
// Use the same explicit charging labels that can establish dock presence.
|
||||
// A non-empty fault or unknown label must not masquerade as active charging.
|
||||
const charging = isDockedChargingState(chargingLabel);
|
||||
const wasDockedRef = useRef(false);
|
||||
|
||||
const enterAssist = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user