rover descriptions

This commit is contained in:
legop3
2026-05-13 02:06:47 -04:00
parent fb996469d8
commit 1b296d5010
19 changed files with 211 additions and 134 deletions
BIN
View File
Binary file not shown.
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+1
View File
@@ -3,6 +3,7 @@ package roverd
type helloMessage struct {
Type string `json:"type"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Color string `json:"color,omitempty"`
Battery BatteryConfig `json:"battery"`
MaxWheelSpeed int `json:"maxWheelSpeed"`
+1
View File
@@ -145,6 +145,7 @@ type PrivateSafetyConfig struct {
type Config struct {
Name string `yaml:"name"`
Description string `yaml:"description" json:"description,omitempty"`
Color string `yaml:"color" json:"color,omitempty"`
ServerURL string `yaml:"serverUrl"`
Serial SerialConfig `yaml:"serial"`
+1
View File
@@ -1,5 +1,6 @@
# Sample configuration for roverd
name: roomba-alpha
description: "Loves corners, hates cords."
color: "#4DB6AC"
serverUrl: ws://control-server.local:8080/rover
serial:
+1
View File
@@ -1,5 +1,6 @@
# Sample configuration for roverd
name: roomba-alpha
description: "Loves corners, hates cords."
serverUrl: ws://control-server.local:8080/rover
serial:
device: /dev/ttyAMA0
+1
View File
@@ -113,6 +113,7 @@ func (c *WSClient) sendHello(ctx context.Context, conn *websocket.Conn) error {
msg := helloMessage{
Type: "hello",
Name: c.cfg.Name,
Description: c.cfg.Description,
Color: c.cfg.Color,
Battery: c.cfg.Battery,
MaxWheelSpeed: c.cfg.MaxWheelMMs,
+2
View File
@@ -5,6 +5,8 @@
5. change replay title for ones requested from discord, something other than "requester driving rover"
6. fix rover request spam queue cheat
7. rover descriptions. show in the HUD at the bottom or top for a few seconds, then fade away.
8. reorganize internal structure of video, HUD stuff...
9. button box reward: ping @everyone, 7567 presses
# relative pipe dreams:
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
+2 -2
View File
@@ -11,8 +11,8 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Roomba Rover" />
<title>Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-BL4tb3vF.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DlqwZ560.css">
<script type="module" crossorigin src="/assets/index-D73ka6iH.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D-TUqmtz.css">
</head>
<body>
<div id="root"></div>
@@ -211,6 +211,7 @@ function createRosterLifecycle(deps) {
return Array.from(rovers.values()).map((record) => ({
id: record.id,
name: record.meta?.name || record.id,
description: record.meta?.description,
color: record.meta?.color || null,
battery: record.meta?.battery,
batteryState: record.batteryState,
@@ -183,6 +183,7 @@ export default function DriverVideoPanel({ layoutFormat = 'desktop' }) {
snapshotFeed={snapshotFeed}
audioSessionInfo={audioInfo}
label={roverLabel}
roverDescription={batteryRecord?.description}
roverColor={batteryRecord?.color || null}
telemetryFrame={frame}
batteryConfig={batteryConfig}
@@ -0,0 +1,56 @@
import { useEffect, useState } from 'react';
const LARGE_VISIBLE_MS = 3500;
const LARGE_FADE_MS = 700;
export default function RoverDescriptionOverlay({
description,
variant = 'default',
mobileHud = false,
displayKey = '',
}) {
const [largeVisible, setLargeVisible] = useState(false);
const [largeFading, setLargeFading] = useState(false);
useEffect(() => {
if (variant !== 'default' || !description) {
setLargeVisible(false);
setLargeFading(false);
return undefined;
}
setLargeVisible(true);
setLargeFading(false);
const fadeTimer = setTimeout(() => setLargeFading(true), LARGE_VISIBLE_MS);
const hideTimer = setTimeout(() => setLargeVisible(false), LARGE_VISIBLE_MS + LARGE_FADE_MS);
return () => {
clearTimeout(fadeTimer);
clearTimeout(hideTimer);
};
}, [description, displayKey, variant]);
if (!description) return null;
if (variant === 'spectator') {
return (
<div className="pointer-events-none absolute inset-x-0 top-1 z-50 flex justify-center">
<div className="surface max-w-[92%] border border-slate-600/80 px-1 py-0.5 text-center text-[0.62rem] leading-tight text-slate-100 shadow-lg">
{description}
</div>
</div>
);
}
if (variant !== 'default' || !largeVisible) return null;
return (
<div className="pointer-events-none absolute inset-x-0 top-2 z-50 flex justify-center">
<div
className={`surface max-w-[94%] border border-slate-500/85 px-2 py-1 text-center font-semibold text-slate-100 shadow-2xl transition-opacity duration-700 ${
largeFading ? 'opacity-0' : 'opacity-100'
} ${mobileHud ? 'text-[1rem] leading-tight' : 'text-[1.5rem] leading-tight'}`}
>
{description}
</div>
</div>
);
}
+11
View File
@@ -12,6 +12,7 @@ import BatteryBar from '../BatteryBar/index.jsx';
import { buildBatteryVisual } from '../../lib/battery.js';
import TurnCueOverlay from './TurnCueOverlay.jsx';
import HudOverlay from './HudOverlay.jsx';
import RoverDescriptionOverlay from './RoverDescriptionOverlay.jsx';
import OvercurrentOverlay from './OvercurrentOverlay.jsx';
import LowBatteryOverlay from './LowBatteryOverlay.jsx';
import LightBumpBars from './LightBumpBars.jsx';
@@ -31,6 +32,7 @@ export default function VideoTile({
snapshotFeed = null,
qualityNotice = null,
label,
roverDescription = null,
roverColor = null,
forceMute = false,
telemetryFrame,
@@ -594,6 +596,7 @@ export default function VideoTile({
: audioStatus;
const showVerticalBattery = hudVariant === 'spectator';
const noHud = hudVariant === 'none';
const descriptionDisplayKey = `${label || ''}::${roverDescription || ''}`;
return (
<div className={`flex flex-col gap-0.5 ${fitParent ? 'h-full' : ''}`}>
@@ -631,6 +634,14 @@ export default function VideoTile({
idleSkipSeconds={idleSkipSeconds}
/>
) : null}
{!noHud ? (
<RoverDescriptionOverlay
description={roverDescription}
variant={hudVariant}
mobileHud={mobileHud}
displayKey={descriptionDisplayKey}
/>
) : null}
{!noHud ? (
<HudOverlay
sensors={sensors}
@@ -15,6 +15,7 @@ export default function RoverSpectatorCard({ rover, frame, sessionInfo, videoMod
snapshotFeed={snapshotFeed}
audioSessionInfo={audioInfo}
label={rover.name}
roverDescription={rover.description}
roverColor={rover.color || null}
telemetryFrame={frame}
batteryConfig={rover.battery}