From 8d9a177d64f07f76d99f58e543922494ed0388df Mon Sep 17 00:00:00 2001 From: Kwashie A <104215256+Kwash67@users.noreply.github.com> Date: Tue, 15 Apr 2025 18:49:32 +0100 Subject: [PATCH 1/4] shouldve put this in previous ticket lol --- gcs/src/fla.jsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gcs/src/fla.jsx b/gcs/src/fla.jsx index a5b2780bb..501a819bc 100644 --- a/gcs/src/fla.jsx +++ b/gcs/src/fla.jsx @@ -880,6 +880,11 @@ export default function FLA() { ), } + // Skip categories with no valid filters + if (filteredCategory.filters.length === 0) { + return null + } + return ( Date: Mon, 28 Apr 2025 21:56:48 +0100 Subject: [PATCH 2/4] added function to convert date --- gcs/src/components/fla/graphConfigs.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gcs/src/components/fla/graphConfigs.js b/gcs/src/components/fla/graphConfigs.js index c3d001ee0..efae70a55 100644 --- a/gcs/src/components/fla/graphConfigs.js +++ b/gcs/src/components/fla/graphConfigs.js @@ -21,6 +21,19 @@ function microsecondsToDisplayTime(microseconds, roundTo) { ).padStart(2, "0")}` } +function gpsToUTC(gpsWeek, gms, leapSeconds = 18) { + // GPS epoch starts at 1980-01-06 00:00:00 UTC + const gpsEpoch = new Date(Date.UTC(1980, 0, 6)); + + // Calculate total milliseconds since Unix epoch + const totalMs = gpsEpoch.getTime() + + gpsWeek * 604_800_000 + // Convert weeks to milliseconds + gms + // Add GPS milliseconds + - leapSeconds * 1_000; // Subtract leap seconds + + return new Date(totalMs); +} + const defaultOptions = { responsive: true, parsing: false, From d91531ab650aa6d4f481fda0e44c6deb472c48a8 Mon Sep 17 00:00:00 2001 From: Kwashie A <104215256+Kwash67@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:11:26 +0100 Subject: [PATCH 3/4] complete --- gcs/src/components/fla/graph.jsx | 40 ++++++++++++++++---- gcs/src/components/fla/graphConfigs.js | 15 +------- gcs/src/fla.jsx | 52 +++++++++++++++++++++++++- gcs/src/redux/logAnalyserSlice.js | 5 +++ 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/gcs/src/components/fla/graph.jsx b/gcs/src/components/fla/graph.jsx index 1e7e37ea9..1c5c2c78c 100644 --- a/gcs/src/components/fla/graph.jsx +++ b/gcs/src/components/fla/graph.jsx @@ -251,13 +251,43 @@ export default function Graph({ // https://stackoverflow.com/a/8179549/10077669 const labelColor = backgroundColor.replace(/[^,]+(?=\))/, "1") + // Critical fix: Convert timestamp to Date object for time scale + let xMinValue = flightMode.TimeUS; + let xMaxValue = xMax; + + // Check if we're using a time scale + const isTimeScale = config.scales?.x?.type === "time"; + + // Convert timestamps to Date objects when using time scale + if (isTimeScale) { + xMinValue = new Date(flightMode.TimeUS); + + // Handle xMax + if (nextFlightMode !== undefined) { + xMaxValue = new Date(nextFlightMode.TimeUS); + } else { + // Stretch to the latest date + const maxTime = Math.max( + ...data.datasets.flatMap(ds => ds.data.map(point => point.x)) + ); + const maxDate = new Date(maxTime); + xMaxValue = maxDate; + } + + } else { + // For non-time scales, handle next flight mode + if (nextFlightMode !== undefined) { + xMaxValue = nextFlightMode.TimeUS; + } + } + const flightModeChange = { type: "box", xScaleID: "x", yMin: "end", yMax: "start", - xMin: flightMode.TimeUS, - xMax: xMax, + xMin: xMinValue, + xMax: xMaxValue, backgroundColor: backgroundColor, borderWidth: 0, display: true, @@ -271,12 +301,6 @@ export default function Graph({ }, } - // If there is a next flight mode, then set the xMax of the current flight - // mode to the xMin of the next flight mode - if (nextFlightMode !== undefined) { - flightModeChange.xMax = nextFlightMode.TimeUS - } - annotations.push(flightModeChange) } } diff --git a/gcs/src/components/fla/graphConfigs.js b/gcs/src/components/fla/graphConfigs.js index efae70a55..638533d71 100644 --- a/gcs/src/components/fla/graphConfigs.js +++ b/gcs/src/components/fla/graphConfigs.js @@ -21,19 +21,6 @@ function microsecondsToDisplayTime(microseconds, roundTo) { ).padStart(2, "0")}` } -function gpsToUTC(gpsWeek, gms, leapSeconds = 18) { - // GPS epoch starts at 1980-01-06 00:00:00 UTC - const gpsEpoch = new Date(Date.UTC(1980, 0, 6)); - - // Calculate total milliseconds since Unix epoch - const totalMs = gpsEpoch.getTime() + - gpsWeek * 604_800_000 + // Convert weeks to milliseconds - gms + // Add GPS milliseconds - - leapSeconds * 1_000; // Subtract leap seconds - - return new Date(totalMs); -} - const defaultOptions = { responsive: true, parsing: false, @@ -106,7 +93,7 @@ export const fgcsOptions = { tooltip: { callbacks: { title: function (context) { - return moment(context[0].parsed.x).format("HH:mm:ss") + return moment(context[0].parsed.x).format("MMMM Do YYYY, h:mm:ss a") }, }, }, diff --git a/gcs/src/fla.jsx b/gcs/src/fla.jsx index 501a819bc..abd114169 100644 --- a/gcs/src/fla.jsx +++ b/gcs/src/fla.jsx @@ -48,6 +48,7 @@ import { setLogEvents, setFlightModeMessages, setLogType, + setUtcAvailable, setMessageFilters, setMessageMeans, setChartData, @@ -127,6 +128,7 @@ export default function FLA() { logEvents, flightModeMessages, logType, + utcAvailable, messageFilters, messageMeans, chartData, @@ -153,6 +155,8 @@ export default function FLA() { const updateFlightModeMessages = (newFlightModeMessages) => dispatch(setFlightModeMessages(newFlightModeMessages)) const updateLogType = (newLogType) => dispatch(setLogType(newLogType)) + const updateUtcAvailable = (newUtcAvailable) => + dispatch(setUtcAvailable(newUtcAvailable)) const updateMessageFilters = (newMessageFilters) => dispatch(setMessageFilters(newMessageFilters)) const updateMessageMeans = (newMessageMeans) => @@ -177,6 +181,8 @@ export default function FLA() { setLoadingFile(true) const result = await window.ipcRenderer.loadFile(file.path) + let gpsOffset = null; // To store the offset between TimeUS and TimeUTC + if (result.success) { // Load messages into states setLoadingFile(false) @@ -198,6 +204,7 @@ export default function FLA() { if (result.logType === "dataflash") { updateFlightModeMessages(loadedLogMessages.MODE) } else if (result.logType === "fgcs_telemetry") { + updateUtcAvailable(true) // Get the heartbeat messages only where index is the first or last or the mode changes const modeMessages = [] for (let i = 0; i < loadedLogMessages.HEARTBEAT.length; i++) { @@ -268,8 +275,33 @@ export default function FLA() { delete logMessageFilterDefaultState["ESC"] } + let tempLoadedLogMessages = { ...loadedLogMessages } + + if ("GPS" in loadedLogMessages && result.logType === "dataflash" && gpsOffset === null) { + const messageObj = tempLoadedLogMessages["GPS"][0] // Get the first GPS message + + // Calculate the offset + if (messageObj.GWk !== undefined && messageObj.GMS !== undefined) { + const utcTime = gpsToUTC(messageObj.GWk, messageObj.GMS); + gpsOffset = utcTime.getTime() - messageObj.TimeUS/1000; + } + + // Loop through all messages and replace TimeUS with UTC + Object.keys(tempLoadedLogMessages).forEach((key) => { + if (key !== "format" && key !== "units") { + tempLoadedLogMessages[key] = tempLoadedLogMessages[key].map((message) => { + return { + ...message, + TimeUS: message.TimeUS/1000 + gpsOffset, // Add the new property + }; + }); + } + }); + updateUtcAvailable(true) + updateFlightModeMessages(tempLoadedLogMessages.MODE) + } + if (loadedLogMessages["BAT"]) { - let tempLoadedLogMessages = { ...loadedLogMessages } let tempMsgFormat = { ...loadedLogMessages["format"] } // Load each BATT data into its own array @@ -286,6 +318,7 @@ export default function FLA() { tempLoadedLogMessages[battName].push({ ...battData, name: battName, + TimeUS: battData.TimeUS/1000 + gpsOffset }) // Add filter state for new BATT @@ -344,6 +377,20 @@ export default function FLA() { } } + function gpsToUTC(gpsWeek, gms, leapSeconds = 18) { + // GPS epoch starts at 1980-01-06 00:00:00 UTC + const gpsEpoch = new Date(Date.UTC(1980, 0, 6)); + + // Calculate total milliseconds since Unix epoch + const totalMs = + gpsEpoch.getTime() + + gpsWeek * 604_800_000 + // Convert weeks to milliseconds + gms - // Add GPS milliseconds + leapSeconds * 1_000; // Subtract leap seconds + + return new Date(totalMs); + } + // Get a list of the recent FGCS telemetry logs async function getFgcsLogs() { setRecentFgcsLogs(await window.ipcRenderer.getRecentLogs()) @@ -368,6 +415,7 @@ export default function FLA() { updateChartData({ datasets: [] }) updateMessageFilters(null) updateCustomColors({}) + updateUtcAvailable(false) updateColorIndex(0) updateLogEvents(null) updateLogType("dataflash") @@ -937,7 +985,7 @@ export default function FLA() { events={logEvents} flightModes={flightModeMessages} graphConfig={ - logType === "dataflash" ? dataflashOptions : fgcsOptions + utcAvailable ? fgcsOptions: dataflashOptions } clearFilters={clearFilters} canSavePreset={canSavePreset} diff --git a/gcs/src/redux/logAnalyserSlice.js b/gcs/src/redux/logAnalyserSlice.js index 603a36f65..404fcdbba 100644 --- a/gcs/src/redux/logAnalyserSlice.js +++ b/gcs/src/redux/logAnalyserSlice.js @@ -7,6 +7,7 @@ const logAnalyserSlice = createSlice({ units: {}, formatMessages: {}, logMessages: null, + utcAvailable: false, logEvents: null, flightModeMessages: [], logType: "dataflash", @@ -31,6 +32,9 @@ const logAnalyserSlice = createSlice({ setLogMessages: (state, action) => { state.logMessages = action.payload }, + setUtcAvailable: (state, action) => { + state.utcAvailable = action.payload + }, setLogEvents: (state, action) => { state.logEvents = action.payload }, @@ -69,6 +73,7 @@ export const { setUnits, setFormatMessages, setLogMessages, + setUtcAvailable, setLogEvents, setFlightModeMessages, setLogType, From bf40a0c622e74d64a570b0ed1b20407ed8bbd04b Mon Sep 17 00:00:00 2001 From: Kwashie A <104215256+Kwash67@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:38:34 +0100 Subject: [PATCH 4/4] Fix: Prevent stack overflow when calculating max timestamp for large datasets --- gcs/src/components/fla/graph.jsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gcs/src/components/fla/graph.jsx b/gcs/src/components/fla/graph.jsx index 1c5c2c78c..7f1895b38 100644 --- a/gcs/src/components/fla/graph.jsx +++ b/gcs/src/components/fla/graph.jsx @@ -267,9 +267,14 @@ export default function Graph({ xMaxValue = new Date(nextFlightMode.TimeUS); } else { // Stretch to the latest date - const maxTime = Math.max( - ...data.datasets.flatMap(ds => ds.data.map(point => point.x)) - ); + let maxTime = 0; + data.datasets.forEach((dataset) => { + dataset.data.forEach((point) => { + if (point.x > maxTime) { + maxTime = point.x; + } + }); + }); const maxDate = new Date(maxTime); xMaxValue = maxDate; }