From 9873cd88d6db5b8e05e2846737e4eab549e1f216 Mon Sep 17 00:00:00 2001 From: Kiril Panayotov Date: Thu, 6 Jun 2024 20:39:27 +0200 Subject: [PATCH 1/5] feat: map multiple data points --- gs/package-lock.json | 4 +- gs/shell.nix | 5 +- gs/src/lib/components/BottomBar.svelte | 6 +- gs/src/lib/components/FSM.svelte | 7 +- gs/src/lib/components/Localiser.svelte | 10 ++- gs/src/lib/panels/VitalsPanel.svelte | 24 ++++-- gs/src/lib/panels/tabs/BatteriesTab.svelte | 21 +++-- gs/src/lib/panels/tabs/LocationTab.svelte | 9 ++- gs/src/lib/util/PlotBuffer.ts | 11 +++ gs/src/routes/+layout.svelte | 94 +++++++++++++++------- gs/station/Cargo.toml | 2 +- 11 files changed, 139 insertions(+), 54 deletions(-) diff --git a/gs/package-lock.json b/gs/package-lock.json index 727695900..e474db881 100644 --- a/gs/package-lock.json +++ b/gs/package-lock.json @@ -1,12 +1,12 @@ { "name": "gs-gui", - "version": "0.3.1", + "version": "0.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gs-gui", - "version": "0.3.1", + "version": "0.5.1", "dependencies": { "@tauri-apps/api": "^1.5.4", "svelte-splitpanes": "^0.8.0", diff --git a/gs/shell.nix b/gs/shell.nix index 1b3839548..8bc0dba52 100644 --- a/gs/shell.nix +++ b/gs/shell.nix @@ -13,7 +13,6 @@ let ]; packages = with pkgs; [ - nodejs_20 pkg-config dbus openssl_3 @@ -23,6 +22,8 @@ let webkitgtk appimagekit librsvg + rustc + cargo cargo-tauri ]; in @@ -34,4 +35,4 @@ pkgs.mkShell { export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath libraries}:$LD_LIBRARY_PATH export XDG_DATA_DIRS=${pkgs.gsettings-desktop-schemas}/share/gsettings-schemas/${pkgs.gsettings-desktop-schemas.name}:${pkgs.gtk3}/share/gsettings-schemas/${pkgs.gtk3.name}:$XDG_DATA_DIRS ''; -} +} \ No newline at end of file diff --git a/gs/src/lib/components/BottomBar.svelte b/gs/src/lib/components/BottomBar.svelte index 846e10c72..4888e66cb 100644 --- a/gs/src/lib/components/BottomBar.svelte +++ b/gs/src/lib/components/BottomBar.svelte @@ -1,5 +1,6 @@ @@ -19,7 +23,7 @@ justify-between px-4 gap-4 border-t border-black">

Delft Hyperloop: Helios III

-

Current state: NOT SET

+

Current state: {$fsmState}

{time}

\ No newline at end of file diff --git a/gs/src/lib/components/FSM.svelte b/gs/src/lib/components/FSM.svelte index 3f90266de..bbb454f19 100644 --- a/gs/src/lib/components/FSM.svelte +++ b/gs/src/lib/components/FSM.svelte @@ -1,5 +1,6 @@
@@ -128,8 +132,8 @@ - Location: NOT SET - Speed: NOT SET + Location: {loc} + Speed: {$velocity}
diff --git a/gs/src/lib/panels/VitalsPanel.svelte b/gs/src/lib/panels/VitalsPanel.svelte index dcdd9866b..904ebbd0e 100644 --- a/gs/src/lib/panels/VitalsPanel.svelte +++ b/gs/src/lib/panels/VitalsPanel.svelte @@ -19,15 +19,27 @@ const lvBattery = storeManager.getStore("BatteryBalanceLow"); const hvBattery = storeManager.getStore("BatteryBalanceHigh"); + const speed = storeManager.getStore("Velocity"); + const position = storeManager.getStore("Localisation"); + + const propTemp = storeManager.getStore("PropulsionTemperature"); + const leviTemp = storeManager.getStore("LevitationTemperature"); + const brakeTemp = storeManager.getStore("BrakeTemperature"); + let tableArr: any[][]; let tableArr2: any[][]; + + $: tableArr = [ - ["Upper drawer VB", 0], - ["Bottom drawer VB", 0], - ["outside of VB", 0], + ["Upper drawer VB", $propTemp], + ["Bottom drawer VB", $leviTemp], + ["Outside of VB", $brakeTemp], ["HEMS", 0], - ["Motor core", 0], + ["EMS", 0], + ["Motor Front", 0], + ["Motor Back", 0], ] + $: tableArr2 = [ ["Current State", 0], ["Bottom drawer VB", 0], @@ -89,8 +101,8 @@
-

Velocity: {0}

-

Position: {0}

+

Velocity: {$speed}

+

Position: {$position}

diff --git a/gs/src/lib/panels/tabs/BatteriesTab.svelte b/gs/src/lib/panels/tabs/BatteriesTab.svelte index b8162b962..eb06455b1 100644 --- a/gs/src/lib/panels/tabs/BatteriesTab.svelte +++ b/gs/src/lib/panels/tabs/BatteriesTab.svelte @@ -69,11 +69,20 @@ const max8Vol = storeManager.getStore("Module8MaxVoltage"); const min8Vol = storeManager.getStore("Module8MinVoltage"); + const avgLvTemp = storeManager.getStore("BatteryMinTemperatureLow"); + const minLvTemp = storeManager.getStore("BatteryMinTemperatureLow"); + const maxLvTemp = storeManager.getStore("BatteryMaxTemperatureLow"); + const avgLvVol = storeManager.getStore("BatteryMinVoltageLow"); + const minLvVol = storeManager.getStore("BatteryMinVoltageLow"); + const maxLvVol = storeManager.getStore("BatteryMaxVoltageLow"); + + const lvCurrent = storeManager.getStore("BatteryCurrentLow"); + const hvCurrent = storeManager.getStore("BatteryCurrentHigh"); let titles = ["Battery", "Avg cell V", "Max cell V", "Min cell V" , "Avg cell °C", "Max cell °C", "Min cell °C"]; $: tableArr = [ - ["LV", "12.5V", "13.5V", "10.5V", "30°C", "50°C", "20°C"], + ["LV", $avgLvVol, $maxLvVol, $minLvVol, $avgLvTemp, $maxLvTemp, $minLvTemp], ["HV mod 1", $avg1Vol, $max1Vol, $min1Vol, $avg1Temp, $max1Temp, $min1Temp], ["HV mod 2", $avg2Vol, $max2Vol, $min2Vol, $avg2Temp, $max2Temp, $min2Temp], ["HV mod 3", $avg3Vol, $max3Vol, $min3Vol, $avg3Temp, $max3Temp, $min3Temp], @@ -113,18 +122,18 @@
-

LV Current: NOT SET

-

HV Current: NOT SET

+

LV Current: {$lvCurrent}

+

HV Current: {$hvCurrent}

- + - + - \ No newline at end of file + diff --git a/gs/src/lib/panels/tabs/LocationTab.svelte b/gs/src/lib/panels/tabs/LocationTab.svelte index 1cc5ef8e9..0539a9579 100644 --- a/gs/src/lib/panels/tabs/LocationTab.svelte +++ b/gs/src/lib/panels/tabs/LocationTab.svelte @@ -1,5 +1,5 @@

Location & IMU

- + - + diff --git a/gs/src/lib/util/PlotBuffer.ts b/gs/src/lib/util/PlotBuffer.ts index 4bc89caf6..25c79bb0b 100644 --- a/gs/src/lib/util/PlotBuffer.ts +++ b/gs/src/lib/util/PlotBuffer.ts @@ -47,9 +47,20 @@ export class PlotBuffer { } public addSeries(series:uPlot.Series) { + const index: number = this._data.length; + this._data.push(new Int32Array(this._data[0].length)); this._opts.series.push(series); this._plot?.addSeries(series); + + setInterval(() => { + this.addEntry(index, this.lastEntryOf(index)) + }, 100) + } + + public lastEntryOf(seriesIndex:number):number { + if (seriesIndex >= this._data.length) throw new Error("Series index out of bounds"); + return this._data[seriesIndex]![this._data[0].length-1]!; } public updateSeries(seriesIndex:number, data:uPlot.TypedArray) { diff --git a/gs/src/routes/+layout.svelte b/gs/src/routes/+layout.svelte index b7e8f0311..e903960ae 100644 --- a/gs/src/routes/+layout.svelte +++ b/gs/src/routes/+layout.svelte @@ -47,7 +47,7 @@ const tempParse:dataConvFun = (data:bigint) => { return Number(data) - 100; } - + const voltParse:dataConvFun = (data:bigint) => { return Number(data) / 100 + 2; } @@ -62,71 +62,108 @@ gdd.stores.registerStore("Module2AvgTemperature", 0.0, tempParse); gdd.stores.registerStore("Module2MaxTemperature", 0.0, tempParse); gdd.stores.registerStore("Module2MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module3AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module3MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module3MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module4AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module4MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module4MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module5AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module5MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module5MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module6AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module6MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module6MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module7AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module7MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module7MinTemperature", 0.0, tempParse); - - gdd.stores.registerStore("Module8AvgTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module8MaxTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module8MinTemperature", 0.0, tempParse); - gdd.stores.registerStore("Module2AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module2MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module2MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module3AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module3MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module3MinTemperature", 0.0, tempParse); gdd.stores.registerStore("Module3AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module3MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module3MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module4AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module4MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module4MinTemperature", 0.0, tempParse); gdd.stores.registerStore("Module4AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module4MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module4MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module5AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module5MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module5MinTemperature", 0.0, tempParse); gdd.stores.registerStore("Module5AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module5MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module5MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module6AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module6MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module6MinTemperature", 0.0, tempParse); gdd.stores.registerStore("Module6AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module6MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module6MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module7AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module7MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module7MinTemperature", 0.0, tempParse) gdd.stores.registerStore("Module7AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module7MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module7MinVoltage", 0.0, voltParse); + gdd.stores.registerStore("Module8AvgTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module8MaxTemperature", 0.0, tempParse); + gdd.stores.registerStore("Module8MinTemperature", 0.0, tempParse); gdd.stores.registerStore("Module8AvgVoltage", 0.0, voltParse); gdd.stores.registerStore("Module8MaxVoltage", 0.0, voltParse); gdd.stores.registerStore("Module8MinVoltage", 0.0, voltParse); gdd.stores.registerStore("BatteryCurrentLow", 0.0, data => { const curr = Number(data) / 10; - $chartStore.get("LV Current")?.addEntry(1, curr); + $chartStore.get("LV Current")!.addEntry(1, curr); return curr; }); gdd.stores.registerStore("BatteryCurrentHigh", 0.0, data => { const curr = Number(data) / 10; - $chartStore.get("HV Current")?.addEntry(1, curr); + $chartStore.get("HV Current")!.addEntry(1, curr); return curr; }); + gdd.stores.registerStore("BatteryMaxTemperatureLow", 0.0) + gdd.stores.registerStore("BatteryMinTemperatureLow", 0.0) + // gdd.stores.registerStore("BatteryAvgTemperatureLow", 0.0) + gdd.stores.registerStore("BatteryMaxVoltageLow", 0.0) + gdd.stores.registerStore("BatteryMinVoltageLow", 0.0) + // gdd.stores.registerStore("BatteryAvgVoltageLow", 0.0) + + + gdd.stores.registerStore("Velocity", 0, data => { + const curr = Number(data); + $chartStore.get("Velocity")!.addEntry(1, curr); + return curr; + }); + + gdd.stores.registerStore("Localisation", 0); // or location? + gdd.stores.registerStore("BrakePressure", 0); + + // gdd.stores.registerStore("acceleration", 0) + gdd.stores.registerStore("FSMState", 0); + gdd.stores.registerStore("PropulsionTemperature", 0); + gdd.stores.registerStore("LevitationTemperature", 0); + gdd.stores.registerStore("BrakeTemperature", 0); + + // gdd.stores.registerStore("OffsetX", 0, data => { + // const curr = Number(data); + // $chartStore.get("Offset Horizontal")?.addEntry(1, curr); + // return curr; + // }); + + // gdd.stores.registerStore("OffsetZ", 0, data => { + // const curr = Number(data); + // $chartStore.get("Offset Horizontal")?.addEntry(2, curr); + // return curr; + // }); + + // gdd.stores.registerStore("OffsetY", 0, data => { + // const curr = Number(data); + // $chartStore.get("Offset Vertical")?.addEntry(1, curr); + // return curr; + // }); + + + + /* emit('speed', {data}) @@ -143,7 +180,6 @@ gdd.start(100); initializeStores(); - // main listener - update south bridge stores
diff --git a/gs/station/Cargo.toml b/gs/station/Cargo.toml index f24077561..0fdf9cf58 100644 --- a/gs/station/Cargo.toml +++ b/gs/station/Cargo.toml @@ -45,7 +45,7 @@ anyhow = "1.0.86" #resizable = true [features] -default = ["tui"] +default = ["backend"] tui = ["crossterm", "ratatui"] backend = ["tauri"] # this feature is used for production builds or when `devPath` points to the filesystem and the built-in dev server is disabled. From 5966ca2a5207a403f38c8d96c1bc9f8762df03d0 Mon Sep 17 00:00:00 2001 From: Kiril Panayotov Date: Thu, 6 Jun 2024 22:23:38 +0200 Subject: [PATCH 2/5] fix: bind charts to last 5 minutes --- gs/src/lib/panels/tabs/BatteriesTab.svelte | 5 +++++ gs/src/lib/util/PlotBuffer.ts | 9 ++++++--- gs/src/routes/+layout.svelte | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/gs/src/lib/panels/tabs/BatteriesTab.svelte b/gs/src/lib/panels/tabs/BatteriesTab.svelte index eb06455b1..ab84d357e 100644 --- a/gs/src/lib/panels/tabs/BatteriesTab.svelte +++ b/gs/src/lib/panels/tabs/BatteriesTab.svelte @@ -79,6 +79,9 @@ const lvCurrent = storeManager.getStore("BatteryCurrentLow"); const hvCurrent = storeManager.getStore("BatteryCurrentHigh"); + const imdV = storeManager.getStore("IMDVoltageDetails"); + const imdI = storeManager.getStore("IMDIsolationDetails") + let titles = ["Battery", "Avg cell V", "Max cell V", "Min cell V" , "Avg cell °C", "Max cell °C", "Min cell °C"]; $: tableArr = [ @@ -124,6 +127,8 @@

LV Current: {$lvCurrent}

HV Current: {$hvCurrent}

+

IMD Isolat: {$imdI}

+

IMD Voltag: {$imdV}

diff --git a/gs/src/lib/util/PlotBuffer.ts b/gs/src/lib/util/PlotBuffer.ts index 25c79bb0b..07da28ca5 100644 --- a/gs/src/lib/util/PlotBuffer.ts +++ b/gs/src/lib/util/PlotBuffer.ts @@ -1,5 +1,4 @@ import uPlot from 'uplot'; -import util from './util'; /** * This class is a wrapper around uPlot to make it easier to use. @@ -13,13 +12,17 @@ export class PlotBuffer { private readonly _opts: uPlot.Options; constructor(xDataLength: number, yRange: [number, number], showLegend: boolean = false) { - this._data = [util.range(xDataLength)]; + const span = 5 * 60 / xDataLength; + + // Initialize the x-axis data with a sequence of timestamps + const currentTime = Date.now() / 1000; + this._data = [Array.from({length: xDataLength}, (_, i) => currentTime - (xDataLength - i) * span)]; this._opts = { width: 500, height: 300, legend: {show: showLegend}, - scales: { "%": { auto: false }, y: { range: yRange }, x: { time: false } }, + scales: { "%": { auto: false }, y: { range: yRange }, x: { time: true } }, axes: [ { stroke: "#e4e6ee", diff --git a/gs/src/routes/+layout.svelte b/gs/src/routes/+layout.svelte index e903960ae..fcce9080e 100644 --- a/gs/src/routes/+layout.svelte +++ b/gs/src/routes/+layout.svelte @@ -161,8 +161,8 @@ // return curr; // }); - - + gdd.stores.registerStore("IMDVoltageDetails", 0); + gdd.stores.registerStore("IMDIsolationDetails", 0); /* emit('speed', {data}) From c22f70c51786f2500cffa355e25f2c22572e75c2 Mon Sep 17 00:00:00 2001 From: Kiril Panayotov Date: Thu, 6 Jun 2024 23:59:45 +0200 Subject: [PATCH 3/5] fix: ccharts buffer and update like they should --- gs/src/lib/components/generic/Chart.svelte | 5 +- gs/src/lib/util/GrandDataDistributor.ts | 2 +- gs/src/lib/util/PlotBuffer.ts | 61 ++++++++++++++-------- gs/src/routes/+layout.svelte | 16 +++--- 4 files changed, 50 insertions(+), 34 deletions(-) diff --git a/gs/src/lib/components/generic/Chart.svelte b/gs/src/lib/components/generic/Chart.svelte index b4f158bb3..ebba56d5e 100644 --- a/gs/src/lib/components/generic/Chart.svelte +++ b/gs/src/lib/components/generic/Chart.svelte @@ -6,10 +6,11 @@ export let title: string; export let refreshRate: number = 100; + export let span: number = 5*60*1000; export let background: string = "bg-surface-800"; export let height: number = 200; - export let chart: PlotBuffer = $chartStore.get(title) || new PlotBuffer(1000, [0, 100], false); + export let chart: PlotBuffer = $chartStore.get(title) || new PlotBuffer(refreshRate, span, [0, 100], false); let width: number; let resize = (width:number) => { @@ -20,7 +21,7 @@ let plotContainer: HTMLDivElement; onMount(async () => { - chart.draw(plotContainer, refreshRate); + chart.draw(plotContainer); resize(width) }) diff --git a/gs/src/lib/util/GrandDataDistributor.ts b/gs/src/lib/util/GrandDataDistributor.ts index a58ad11a3..f333a2e17 100644 --- a/gs/src/lib/util/GrandDataDistributor.ts +++ b/gs/src/lib/util/GrandDataDistributor.ts @@ -114,7 +114,7 @@ class StoreManager { * @param processFunction - the function to process the data */ public registerStore(name: NamedDatatype, initial: T, processFunction?: dataConvFun) { - if (this.stores.has(name)) throw new Error(`Store with name ${name} already exists`); + // if (this.stores.has(name)) throw new Error(`Store with name ${name} already exists`); this.stores.set(name, new Store(initial, processFunction)); } diff --git a/gs/src/lib/util/PlotBuffer.ts b/gs/src/lib/util/PlotBuffer.ts index 07da28ca5..6c6b7140b 100644 --- a/gs/src/lib/util/PlotBuffer.ts +++ b/gs/src/lib/util/PlotBuffer.ts @@ -10,14 +10,25 @@ export class PlotBuffer { private _intervalId: number | undefined; private readonly _data: uPlot.AlignedData; private readonly _opts: uPlot.Options; + private buffer: number[][] = []; + private readonly updateInterval:number; - constructor(xDataLength: number, yRange: [number, number], showLegend: boolean = false) { - const span = 5 * 60 / xDataLength; + /** + * + * @param updateInterval + * @param span + * @param yRange + * @param showLegend + */ + constructor(updateInterval:number, span:number, yRange: [number, number], showLegend: boolean = false) { + this.updateInterval = updateInterval; - // Initialize the x-axis data with a sequence of timestamps - const currentTime = Date.now() / 1000; - this._data = [Array.from({length: xDataLength}, (_, i) => currentTime - (xDataLength - i) * span)]; + const xDataLength = Math.round(span / updateInterval); + const currentTime = Date.now() / 1000; + this._data = [Array.from({length: xDataLength}, (_, i) => currentTime - (xDataLength - i) * (span / 1000))]; + console.log(xDataLength) + // this._data = [[0,2,4,6,9]]s this._opts = { width: 500, height: 300, @@ -50,15 +61,11 @@ export class PlotBuffer { } public addSeries(series:uPlot.Series) { - const index: number = this._data.length; - this._data.push(new Int32Array(this._data[0].length)); this._opts.series.push(series); this._plot?.addSeries(series); - setInterval(() => { - this.addEntry(index, this.lastEntryOf(index)) - }, 100) + this.buffer.push([]); } public lastEntryOf(seriesIndex:number):number { @@ -86,34 +93,42 @@ export class PlotBuffer { * @param value */ public addEntry(seriesIndex:number, value:number) { - let datum = this._data[seriesIndex]; - - for (let i = 0; i < datum.length-1; i++) { - datum[i] = datum[i+1]; - } - - datum[datum.length-1] = value; + this.buffer[seriesIndex].push(value); } /** * Draw the graph in the specified container. * @param plotContainer The HTML element in which the graph should be drawn. - * @param updateInterval The interval in milliseconds at which the graph should be updated. - * If 0 is passed, the graph will not be updated automatically! * This function should not take any arguments and return void. * @see [uPlot library](https://leeoniya.github.io/uPlot/) for more information on uPlot. * Documentation is severely lacking, but the examples should be helpful. */ - public draw(plotContainer: HTMLDivElement, - updateInterval:number) { + public draw(plotContainer: HTMLDivElement) { this._plot = new uPlot(this._opts, this._data, plotContainer); - if (updateInterval === 0) { + if (this.updateInterval === 0) { this.redraw(); return; } - this._intervalId = window.setInterval(() => this.redraw(), updateInterval); + // this._intervalId = window.setInterval(() => { + // for (let i = 0; i < this.buffer.length; i++) { + // const value = this.buffer[i].length > 0 ? + // this.buffer[i].reduce((a, b) => a + b, 0) / this.buffer[i].length : + // this.lastEntryOf(i); + // + // this.addEntry(i, value); + // + // this.buffer[i] = []; + // } + // + // for (let i = 0; i < this._data[0].length - 1; i++) { + // this._data[0][i] = this._data[0][i + 1]; + // } + // this._data[0][this._data[0].length - 1] = Date.now() / 1000; + // + // this.redraw(); + // }, this.updateInterval); } /** diff --git a/gs/src/routes/+layout.svelte b/gs/src/routes/+layout.svelte index fcce9080e..f26e2183c 100644 --- a/gs/src/routes/+layout.svelte +++ b/gs/src/routes/+layout.svelte @@ -6,8 +6,8 @@ import type {dataConvFun} from "$lib/types"; // CHARTS - let emsChart = new PlotBuffer(1000, [0, 100], false); - let hemsChart = new PlotBuffer(1000, [0, 100], false); + let emsChart = new PlotBuffer(1000, 300000, [0, 100], false); + let hemsChart = new PlotBuffer(1000, 300000, [0, 100], false); emsChart.addSeries(StrokePresets.theoretical()) emsChart.addSeries(StrokePresets.yellow()) emsChart.addSeries(StrokePresets.blue()) @@ -17,23 +17,23 @@ $chartStore.set("EMS", emsChart); $chartStore.set("HEMS", hemsChart); - let voffChart = new PlotBuffer(1000, [0, 100], false) - let hoffChart = new PlotBuffer(1000, [0, 100], false) + let voffChart = new PlotBuffer(100, 300000, [0, 100], false) + let hoffChart = new PlotBuffer(100, 300000, [0, 100], false) hoffChart.addSeries(StrokePresets.theoretical()) - let velChart = new PlotBuffer(1000, [0, 100], false) + let velChart = new PlotBuffer(100, 300000, [0, 100], false) $chartStore.set('Offset Horizontal', hoffChart); $chartStore.set('Offset Vertical', voffChart); $chartStore.set('Velocity', velChart); - let trr = new PlotBuffer(16000, [0, 50], false) + let trr = new PlotBuffer(1, 60000, [0, 50], false) trr.addSeries(StrokePresets.theoretical()) $chartStore.set('Theoretical vs Real run', trr) - let lvCurrent = new PlotBuffer(1000, [-4000, 4000], false) + let lvCurrent = new PlotBuffer(100, 300000, [-4000, 4000], false) $chartStore.set('LV Current', lvCurrent) - let hvCurrent = new PlotBuffer(1000, [-4000, 4000], false) + let hvCurrent = new PlotBuffer(100, 300000, [-4000, 4000], false) $chartStore.set('HV Current', hvCurrent) /////////////////////////////////////////////////////// From 9ec793864c599ddac7fe28c5c80171ac87d0a6ab Mon Sep 17 00:00:00 2001 From: Kiril Panayotov Date: Fri, 7 Jun 2024 02:04:42 +0200 Subject: [PATCH 4/5] fix: ccharts buffer and update like they should --- gs/src/lib/components/generic/Chart.svelte | 2 +- gs/src/lib/panels/LogsPanel.svelte | 6 +- gs/src/lib/util/GrandDataDistributor.ts | 2 +- gs/src/lib/util/PlotBuffer.ts | 80 ++++++++++++++-------- gs/src/routes/+layout.svelte | 16 ++--- 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/gs/src/lib/components/generic/Chart.svelte b/gs/src/lib/components/generic/Chart.svelte index ebba56d5e..31c97e284 100644 --- a/gs/src/lib/components/generic/Chart.svelte +++ b/gs/src/lib/components/generic/Chart.svelte @@ -5,7 +5,7 @@ import {chartStore} from "$lib/stores/state"; export let title: string; - export let refreshRate: number = 100; + export let refreshRate: number = 1000; export let span: number = 5*60*1000; export let background: string = "bg-surface-800"; diff --git a/gs/src/lib/panels/LogsPanel.svelte b/gs/src/lib/panels/LogsPanel.svelte index 01795ae70..f8174a2d8 100644 --- a/gs/src/lib/panels/LogsPanel.svelte +++ b/gs/src/lib/panels/LogsPanel.svelte @@ -23,7 +23,7 @@ let filters: Record = { 'STATUS': true, 'WARNING': true, 'INFO': true, 'ERROR': true }; // filter variable $: filteredLogs = logs.filter(log => filters[log.log_type]); -`` + function toggleFilter(type: string) { filters[type] = !filters[type]; } @@ -37,22 +37,18 @@ onMount(async () => { unlistens[0] = await listen('status_channel', (event) => { - console.log(event) //@ts-ignore logs = [...logs, {message: event.payload, status: 'STATUS', timestamp: Date.now().valueOf()}]; }); unlistens[1] = await listen(EventChannels.INFO, (event) => { - console.log(event) //@ts-ignore logs = [...logs, {message: event.payload, log_type: 'INFO', timestamp: Date.now().valueOf()}]; }); unlistens[2] = await listen(EventChannels.WARNING, (event) => { - console.log(event) //@ts-ignore logs = [...logs, {message: event.payload, log_type: 'WARNING', timestamp: Date.now().valueOf()}]; }); unlistens[3] = await listen(EventChannels.ERROR, (event) => { - console.log(event) //@ts-ignore logs = [...logs, {message: event.payload, log_type: 'ERROR', timestamp: Date.now().valueOf()}]; }); diff --git a/gs/src/lib/util/GrandDataDistributor.ts b/gs/src/lib/util/GrandDataDistributor.ts index f333a2e17..605e0c9ac 100644 --- a/gs/src/lib/util/GrandDataDistributor.ts +++ b/gs/src/lib/util/GrandDataDistributor.ts @@ -74,7 +74,7 @@ export class GrandDataDistributor { * @private */ private async fetchData() { - const data:Datapoint[] = await invoke('unload_buffer'); + const data:Datapoint[] = await invoke('generate_test_data'); this.processData(data); } diff --git a/gs/src/lib/util/PlotBuffer.ts b/gs/src/lib/util/PlotBuffer.ts index 6c6b7140b..fa218e44f 100644 --- a/gs/src/lib/util/PlotBuffer.ts +++ b/gs/src/lib/util/PlotBuffer.ts @@ -10,7 +10,7 @@ export class PlotBuffer { private _intervalId: number | undefined; private readonly _data: uPlot.AlignedData; private readonly _opts: uPlot.Options; - private buffer: number[][] = []; + private buffer: number[][]; private readonly updateInterval:number; /** @@ -20,15 +20,17 @@ export class PlotBuffer { * @param yRange * @param showLegend */ - constructor(updateInterval:number, span:number, yRange: [number, number], showLegend: boolean = false) { - this.updateInterval = updateInterval; + constructor(updateInterval:number, span:number, yRange: [number, number], showLegend: boolean = false) { this.updateInterval = updateInterval; + this.buffer = [[]]; - const xDataLength = Math.round(span / updateInterval); + const spanInSeconds = span / 1000; + const updateIntervalInSeconds = updateInterval / 1000; + + const xDataLength = Math.round(spanInSeconds / updateIntervalInSeconds); const currentTime = Date.now() / 1000; - this._data = [Array.from({length: xDataLength}, (_, i) => currentTime - (xDataLength - i) * (span / 1000))]; - console.log(xDataLength) - // this._data = [[0,2,4,6,9]]s + this._data = [Array.from({length: xDataLength}, (_, i) => currentTime - (xDataLength - i) * updateIntervalInSeconds)]; + this._opts = { width: 500, height: 300, @@ -61,16 +63,16 @@ export class PlotBuffer { } public addSeries(series:uPlot.Series) { + const index: number = this._data.length; this._data.push(new Int32Array(this._data[0].length)); this._opts.series.push(series); this._plot?.addSeries(series); - - this.buffer.push([]); + this.buffer[index] = []; } public lastEntryOf(seriesIndex:number):number { if (seriesIndex >= this._data.length) throw new Error("Series index out of bounds"); - return this._data[seriesIndex]![this._data[0].length-1]!; + return this._data[seriesIndex][this._data[0].length-1] || 0; } public updateSeries(seriesIndex:number, data:uPlot.TypedArray) { @@ -94,6 +96,16 @@ export class PlotBuffer { */ public addEntry(seriesIndex:number, value:number) { this.buffer[seriesIndex].push(value); + // let datum = this._data[seriesIndex]; + // + // for (let i = 0; i < datum.length-1; i++) { + // datum[i] = datum[i+1]; + // } + // + // datum[datum.length-1] = value; + // + // // Redraw the chart with the updated data + // console.log("") } /** @@ -111,24 +123,34 @@ export class PlotBuffer { return; } - // this._intervalId = window.setInterval(() => { - // for (let i = 0; i < this.buffer.length; i++) { - // const value = this.buffer[i].length > 0 ? - // this.buffer[i].reduce((a, b) => a + b, 0) / this.buffer[i].length : - // this.lastEntryOf(i); - // - // this.addEntry(i, value); - // - // this.buffer[i] = []; - // } - // - // for (let i = 0; i < this._data[0].length - 1; i++) { - // this._data[0][i] = this._data[0][i + 1]; - // } - // this._data[0][this._data[0].length - 1] = Date.now() / 1000; - // - // this.redraw(); - // }, this.updateInterval); + this._intervalId = window.setInterval(() => { + this.updateData(); + }, this.updateInterval); + } + + private updateData() { + for (let i = 1; i < this.buffer.length; i++) { + const value = this.buffer[i].length > 0 ? + this.buffer[i].reduce((a, b) => a + b, 0) / this.buffer[i].length : + this.lastEntryOf(i); + + // Update the _data array + let datum = this._data[i]; + for (let j = 0; j < datum.length - 1; j++) { + datum[j] = datum[j + 1]; + } + datum[datum.length - 1] = value; + + + + this.buffer[i] = []; + } + + for (let i = 0; i < this._data[0].length - 1; i++) { + this._data[0][i] = this._data[0][i + 1]; + } + this._data[0][this._data[0].length - 1] = Date.now() / 1000; + this.redraw(); } /** @@ -138,7 +160,7 @@ export class PlotBuffer { public redraw() { if (this._plot) { this._plot.batch(() => { - this._plot!.setData(this._data, false); + this._plot!.setData(this._data, true); this._plot!.redraw(false, false); }); } diff --git a/gs/src/routes/+layout.svelte b/gs/src/routes/+layout.svelte index f26e2183c..56a988cb2 100644 --- a/gs/src/routes/+layout.svelte +++ b/gs/src/routes/+layout.svelte @@ -6,8 +6,8 @@ import type {dataConvFun} from "$lib/types"; // CHARTS - let emsChart = new PlotBuffer(1000, 300000, [0, 100], false); - let hemsChart = new PlotBuffer(1000, 300000, [0, 100], false); + let emsChart = new PlotBuffer(100000, 300000, [0, 100], false); + let hemsChart = new PlotBuffer(100000, 300000, [0, 100], false); emsChart.addSeries(StrokePresets.theoretical()) emsChart.addSeries(StrokePresets.yellow()) emsChart.addSeries(StrokePresets.blue()) @@ -17,16 +17,16 @@ $chartStore.set("EMS", emsChart); $chartStore.set("HEMS", hemsChart); - let voffChart = new PlotBuffer(100, 300000, [0, 100], false) - let hoffChart = new PlotBuffer(100, 300000, [0, 100], false) + let voffChart = new PlotBuffer(10000, 300000, [0, 100], false) + let hoffChart = new PlotBuffer(10000, 300000, [0, 100], false) hoffChart.addSeries(StrokePresets.theoretical()) - let velChart = new PlotBuffer(100, 300000, [0, 100], false) + let velChart = new PlotBuffer(2000, 5*60*1000, [0, 100], false) $chartStore.set('Offset Horizontal', hoffChart); $chartStore.set('Offset Vertical', voffChart); $chartStore.set('Velocity', velChart); - let trr = new PlotBuffer(1, 60000, [0, 50], false) + let trr = new PlotBuffer(10000, 60000, [0, 50], false) trr.addSeries(StrokePresets.theoretical()) $chartStore.set('Theoretical vs Real run', trr) @@ -110,13 +110,13 @@ gdd.stores.registerStore("BatteryCurrentLow", 0.0, data => { const curr = Number(data) / 10; - $chartStore.get("LV Current")!.addEntry(1, curr); + lvCurrent.addEntry(1, curr + 150); return curr; }); gdd.stores.registerStore("BatteryCurrentHigh", 0.0, data => { const curr = Number(data) / 10; - $chartStore.get("HV Current")!.addEntry(1, curr); + $chartStore.get("Velocity")!.addEntry(1, curr + 10); return curr; }); From 25ac98486afab11a6e704dd1fdc12362bf8c5c8a Mon Sep 17 00:00:00 2001 From: Kiril Panayotov Date: Fri, 7 Jun 2024 02:07:57 +0200 Subject: [PATCH 5/5] fix: ccharts buffer and update like they should --- gs/src/lib/util/GrandDataDistributor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gs/src/lib/util/GrandDataDistributor.ts b/gs/src/lib/util/GrandDataDistributor.ts index 605e0c9ac..f333a2e17 100644 --- a/gs/src/lib/util/GrandDataDistributor.ts +++ b/gs/src/lib/util/GrandDataDistributor.ts @@ -74,7 +74,7 @@ export class GrandDataDistributor { * @private */ private async fetchData() { - const data:Datapoint[] = await invoke('generate_test_data'); + const data:Datapoint[] = await invoke('unload_buffer'); this.processData(data); }