Skip to content

Commit 1cf64ed

Browse files
made video widget and esc widget the same size on 8, also made sure it scales for > 4 esc's
1 parent 4f111f2 commit 1cf64ed

7 files changed

Lines changed: 112 additions & 87 deletions

File tree

gcs/electron/main.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import registerVibeStatusIPC, {
3939
destroyVibeStatusWindow,
4040
} from "./modules/vibeStatusWindow"
4141
import registerVideoIPC, { destroyVideoWindow } from "./modules/videoWindow"
42-
import registerEscIPC, { destroyEscWindow } from "./modules/escWindow"
4342
import { readParamsFile } from "./utils/paramsFile"
4443
import registerGraphWindowIPC, {
4544
destroyAllGraphWindows,
@@ -274,7 +273,6 @@ function createWindow() {
274273
})
275274

276275
registerVideoIPC(win)
277-
registerEscIPC(win)
278276
registerAboutIPC()
279277
registerLinkStatsIPC()
280278
registerEkfStatusIPC()
@@ -465,7 +463,6 @@ function startBackend() {
465463

466464
function closeWindows() {
467465
destroyVideoWindow()
468-
destroyEscWindow()
469466
destroyAboutWindow()
470467
destroyLinkStatsWindow()
471468
destroyEkfStatusWindow()

gcs/src/components/dashboard/EscTelemetryWidget.jsx

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
/*
2-
Floating ESC telemetry widget (same positioning + UI pattern as VideoWidget)
2+
Floating ESC telemetry widget (row-positioned like VideoWidget)
33
*/
44
import { useMemo, useState } from "react"
55
import { ActionIcon, Text } from "@mantine/core"
6-
import {
7-
IconBolt,
8-
IconMaximize,
9-
IconMinus,
10-
IconResize,
11-
} from "@tabler/icons-react"
6+
import { IconBolt, IconMaximize, IconMinus, IconResize } from "@tabler/icons-react"
127
import { useSelector } from "react-redux"
138
import GetOutsideVisibilityColor from "../../helpers/outsideVisibility"
149
import { selectEscTelemetry } from "../../redux/slices/droneInfoSlice"
@@ -32,12 +27,7 @@ function EscTile({ esc }) {
3227
return (
3328
<div className="rounded-md border border-falcongrey-700 bg-falcongrey-900 p-2">
3429
<div className="flex flex-row items-center justify-between mb-1">
35-
<div className="text-slate-200 text-xs font-semibold">
36-
ESC {esc.escId}
37-
</div>
38-
<div className="text-slate-500 text-[10px]">
39-
{esc.timestamp ? new Date(esc.timestamp).toLocaleTimeString() : "—"}
40-
</div>
30+
<div className="text-slate-200 text-xs font-semibold">ESC {esc.escId}</div>
4131
</div>
4232

4333
<div className="flex flex-col gap-y-0.5">
@@ -49,10 +39,6 @@ function EscTile({ esc }) {
4939
<div className="text-slate-500 text-[10px]">A</div>
5040
<div className="text-slate-200 text-xs">{fmt(esc.current, 2)}</div>
5141
</div>
52-
<div className="flex flex-row items-center justify-between">
53-
<div className="text-slate-500 text-[10px]">V</div>
54-
<div className="text-slate-200 text-xs">{fmt(esc.voltage, 2)}</div>
55-
</div>
5642
<div className="flex flex-row items-center justify-between">
5743
<div className="text-slate-500 text-[10px]">°C</div>
5844
<div className="text-slate-200 text-xs">{fmtTemp(esc.temperature)}</div>
@@ -62,31 +48,54 @@ function EscTile({ esc }) {
6248
)
6349
}
6450

65-
export default function EscTelemetryWidget({ telemetryPanelWidth }) {
66-
const escs = useSelector(selectEscTelemetry)
51+
export default function EscTelemetryWidget({
52+
telemetryPanelWidth, // unused now, kept so your callsites don’t break
53+
onMaximizedChange,
54+
}) {
55+
//const escs = useSelector(selectEscTelemetry)
56+
const realEscs = useSelector(selectEscTelemetry)
57+
58+
const escs = Array.from({ length: 8 }).map((_, i) => ({
59+
escId: i + 1,
60+
rpm: Math.floor(Math.random() * 6000),
61+
current: (Math.random() * 20).toFixed(2),
62+
temperature: Math.floor(30 + Math.random() * 20)
63+
}))
6764

6865
const [isMaximized, setIsMaximized] = useState(false)
6966
const [scale, setScale] = useState(1)
7067

71-
const dimensions = useMemo(() => {
72-
const baseWidth = 350
73-
const width = baseWidth * scale
74-
// make it a bit taller than video default so 2 rows of tiles fit nicely
75-
const height = Math.round((197 * 1.15) * scale)
76-
return { width, height }
77-
}, [scale])
68+
const setMaximized = (next) => {
69+
setIsMaximized(next)
70+
onMaximizedChange?.(next)
71+
}
7872

7973
const hasAnyData =
8074
Array.isArray(escs) &&
8175
escs.some(
8276
(e) =>
8377
e &&
84-
(e.rpm != null ||
85-
e.current != null ||
86-
e.voltage != null ||
87-
e.temperature != null),
78+
(e.rpm != null || e.current != null || e.temperature != null),
8879
)
8980

81+
const dimensions = useMemo(() => {
82+
const baseWidth = 350
83+
const width = baseWidth * scale
84+
85+
const cols = 4
86+
const count = Array.isArray(escs) ? escs.length : 0
87+
const rows = Math.max(1, Math.ceil(count / cols))
88+
89+
const tileH = 74 * scale
90+
const gapH = 8 * scale
91+
const paddingH = 32 * scale
92+
93+
const height = Math.round(rows * tileH + (rows - 1) * gapH + paddingH)
94+
const clampedHeight = Math.max(180 * scale, Math.min(420 * scale, height))
95+
96+
return { width, height: clampedHeight }
97+
}, [scale, escs])
98+
9099
function handleResizeStart(e) {
91100
const startX = e.clientX
92101
const startScale = scale
@@ -111,17 +120,23 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
111120
// Minimized view
112121
if (!isMaximized) {
113122
return (
114-
<div className="rounded-md" style={{ background: GetOutsideVisibilityColor() }}>
123+
<div
124+
className="rounded-md"
125+
style={{ background: GetOutsideVisibilityColor() }}
126+
>
115127
<div className="p-2 flex items-center gap-2">
116-
<IconBolt size={16} className={hasAnyData ? "text-slate-200" : "text-slate-500"} />
128+
<IconBolt
129+
size={16}
130+
className={hasAnyData ? "text-slate-200" : "text-slate-500"}
131+
/>
117132
<Text size="sm" className="truncate max-w-[150px]">
118133
{hasAnyData ? "ESC telemetry" : "No ESC telemetry"}
119134
</Text>
120135

121136
<ActionIcon
122137
size="sm"
123138
variant="subtle"
124-
onClick={() => setIsMaximized(true)}
139+
onClick={() => setMaximized(true)}
125140
className="text-slate-400 hover:text-slate-200"
126141
title="Maximize ESC widget"
127142
>
@@ -132,21 +147,18 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
132147
)
133148
}
134149

135-
// Full view
150+
// Full view (make it stretch nicely when parent uses items-stretch)
136151
return (
137-
<div
138-
className="min-w-[350px] rounded-md"
139-
style={{ background: GetOutsideVisibilityColor() }}
140-
>
141-
<div className="p-2">
152+
<div className="min-w-[350px] min-h-[225px] rounded-md flex flex-col" style={{ background: GetOutsideVisibilityColor() }}>
153+
<div className="p-2 h-full flex flex-col">
142154
<div className="flex items-center justify-between mb-2">
143155
<Text>ESC telemetry</Text>
144156

145157
<div className="flex items-center gap-1">
146158
<ActionIcon
147159
size="sm"
148160
variant="subtle"
149-
onClick={() => setIsMaximized(false)}
161+
onClick={() => setMaximized(false)}
150162
className="text-slate-400 hover:text-slate-200"
151163
title="Minimize ESC widget"
152164
>
@@ -166,7 +178,7 @@ export default function EscTelemetryWidget({ telemetryPanelWidth }) {
166178
</div>
167179

168180
<div
169-
className="rounded overflow-hidden mx-auto"
181+
className="rounded overflow-hidden mx-auto flex-1"
170182
style={{
171183
width: `${dimensions.width}px`,
172184
height: `${dimensions.height}px`,

gcs/src/components/dashboard/videoWidget.jsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,7 @@ export default function VideoWidget({ telemetryPanelWidth }) {
396396

397397
{/* Full view */}
398398
{isMaximized && (
399-
<div
400-
className={`min-w-[350px] rounded-md ${isPoppedOut ? "hidden" : ""}`}
401-
style={{ background: GetOutsideVisibilityColor() }}
402-
>
399+
<div className="min-w-[350px] min-h-[253px] rounded-md flex flex-col" style={{ background: GetOutsideVisibilityColor() }}>
403400
<div className="p-2">
404401
<div className="flex items-center justify-between mb-2">
405402
<Text>{videoSource?.name || "No video selected"}</Text>

gcs/src/dashboard.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import { ResizableBox } from "react-resizable"
2929

3030
// Redux
3131
import { useDispatch, useSelector } from "react-redux"
32-
import { selectConnectedToDrone } from "./redux/slices/droneConnectionSlice"
32+
import { selectConnectedToDrone,
33+
selectVideoMaximized } from "./redux/slices/droneConnectionSlice"
3334
import {
3435
selectAircraftTypeString,
3536
selectBatteryData,
@@ -105,6 +106,11 @@ export default function Dashboard() {
105106

106107
const secondaryGpsFixLabel = GPS_FIX_TYPES[gps2.fixType]
107108

109+
const videoMaximized = useSelector(selectVideoMaximized)
110+
const [escMaximized, setEscMaximized] = useState(false)
111+
112+
const stretchWidgets = videoMaximized || escMaximized
113+
108114
// Telemetry panel sizing
109115
const [telemetryPanelSize, setTelemetryPanelSize] = useLocalStorage({
110116
key: "telemetryPanelSize",
@@ -342,6 +348,7 @@ export default function Dashboard() {
342348
<EscTelemetryWidget telemetryPanelWidth={telemetryPanelSize.width} />
343349
</div>
344350

351+
345352
<div className="absolute bottom-0 right-0 z-20">
346353
<ResizableBox
347354
height={messagesPanelSize.height}

gcs/src/redux/slices/droneInfoSlice.js

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,44 @@ export const selectAttitudeDeg = createSelector(
432432
},
433433
)
434434

435+
export const selectEscTelemetry = createSelector(
436+
[
437+
droneInfoSlice.selectors.selectEscTelemetry1To4,
438+
droneInfoSlice.selectors.selectEscTelemetry5To8,
439+
],
440+
(esc1To4, esc5To8) => {
441+
const escs = []
442+
443+
function pushEscPacket(packet, baseIndex) {
444+
if (!packet) return
445+
446+
// Most fields are arrays of length 4, but guard anyway
447+
const rpm = packet.rpm ?? []
448+
const count = Math.min(4, rpm.length)
449+
450+
for (let i = 0; i < count; i++) {
451+
escs.push({
452+
escId: baseIndex + i + 1,
453+
rpm: packet.rpm?.[i] ?? null,
454+
current: packet.current?.[i] ?? null,
455+
voltage: packet.voltage?.[i] ?? null,
456+
temperature: packet.temperature?.[i] ?? null,
457+
totalcurrent: packet.totalcurrent?.[i] ?? null,
458+
timestamp: packet.timestamp ?? null,
459+
})
460+
}
461+
}
462+
463+
// ESC 1-4
464+
pushEscPacket(esc1To4, 0)
465+
466+
// ESC 5-8
467+
pushEscPacket(esc5To8, 4)
468+
469+
return escs
470+
},
471+
)
472+
435473
export const selectAlt = createSelector(
436474
[droneInfoSlice.selectors.selectGPS],
437475
({ alt, relativeAlt }) => {
@@ -501,44 +539,6 @@ export const calculateGpsTrackHeadingThunk = () => (dispatch, getState) => {
501539
}
502540
}
503541

504-
export const selectEscTelemetry = createSelector(
505-
[
506-
droneInfoSlice.selectors.selectEscTelemetry1To4,
507-
droneInfoSlice.selectors.selectEscTelemetry5To8,
508-
],
509-
(esc1To4, esc5To8) => {
510-
const escs = []
511-
512-
function pushEscPacket(packet, baseIndex) {
513-
if (!packet) return
514-
515-
// Most fields are arrays of length 4, but guard anyway
516-
const rpm = packet.rpm ?? []
517-
const count = Math.min(4, rpm.length)
518-
519-
for (let i = 0; i < count; i++) {
520-
escs.push({
521-
escId: baseIndex + i + 1,
522-
rpm: packet.rpm?.[i] ?? null,
523-
current: packet.current?.[i] ?? null,
524-
voltage: packet.voltage?.[i] ?? null,
525-
temperature: packet.temperature?.[i] ?? null,
526-
totalcurrent: packet.totalcurrent?.[i] ?? null,
527-
timestamp: packet.timestamp ?? null,
528-
})
529-
}
530-
}
531-
532-
// ESC 1-4
533-
pushEscPacket(esc1To4, 0)
534-
535-
// ESC 5-8
536-
pushEscPacket(esc5To8, 4)
537-
538-
return escs
539-
},
540-
)
541-
542542
export const {
543543
selectFlightSwVersion,
544544
selectAttitude,

node_modules/.yarn-integrity

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

yarn.lock

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1

0 commit comments

Comments
 (0)