Skip to content

Commit

Permalink
Merge pull request #41 from delft-hyperloop/chart_persistance
Browse files Browse the repository at this point in the history
Chart persistance
  • Loading branch information
FranciscoAmaro24 authored May 29, 2024
2 parents 61087d8 + 6f49d9a commit 32d0c23
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 125 deletions.
10 changes: 1 addition & 9 deletions gs/src/lib/components/TheoreticalRun.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import {Chart, PlotBuffer, StrokePresets} from "$lib";
import {onMount} from "svelte";
import {type TypedArray} from "uplot";
import {z} from "zod";
export let xDataCount = 100;
Expand Down Expand Up @@ -31,11 +30,4 @@
</script>

<Chart eventCallback={(event) => {
// @ts-ignore
let speed = z.number().parse(event.payload.speed);
// @ts-ignore
let timestamp = z.number().parse(event.payload.timestamp);

chart.setEntry(1, timestamp, speed)
}} eventChannel="start_run" height={250} background="bg-surface-900" yRange={[0, 50]} dataPointsCount={xDataCount} title="Theoretical vs Real run" bind:chart={chart} refreshRate={100} />
<Chart height={250} background="bg-surface-900" title="Theoretical vs Real run" bind:chart={chart} refreshRate={100} />
28 changes: 6 additions & 22 deletions gs/src/lib/components/generic/Chart.svelte
Original file line number Diff line number Diff line change
@@ -1,47 +1,31 @@
<script lang="ts">
import {onDestroy, onMount} from 'svelte';
import 'uplot/dist/uPlot.min.css';
import {type EventCallback, listen, type UnlistenFn} from '@tauri-apps/api/event';
import {z} from "zod";
import {PlotBuffer, StrokePresets} from "$lib";
import {PlotBuffer} from "$lib";
import {chartStore} from "$lib/stores/state";
export let title: string;
export let eventChannel = "south_bridge";
export let eventCallback: EventCallback<unknown> = (event) => {
// @ts-ignore
chart.addEntry(1, z.number().parse(event.payload.data));
};
export let dataPointsCount: number = 1000;
export let refreshRate: number = 100;
export let background: string = "bg-surface-800";
export let height: number = 200;
export let yRange: [number, number] = [0, 100];
export let showLegend: boolean = false;
export const chart = new PlotBuffer(dataPointsCount, yRange, showLegend);
export let chart: PlotBuffer = $chartStore.get(title) || new PlotBuffer(1000, [0, 100], false);
let width: number;
let resize = (width:number) => {
chart?.setSize(width-25, height);
chart.setSize(width-15, height);
}
$: resize(width);
let unlisten: UnlistenFn;
let plotContainer: HTMLDivElement;
onMount(async () => {
chart.addSeries(StrokePresets.hyperLoopGreen());
chart.draw(plotContainer, refreshRate);
resize(width)
unlisten = await listen(eventChannel, eventCallback);
})
onDestroy(() => {
unlisten();
chart.destroy();
chart!.destroy();
});
</script>

Expand Down
3 changes: 3 additions & 0 deletions gs/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ import type {Payload, NamedCommand, EventChannel, Log} from "$lib/types";
// Stores
import {south_bridge_payload} from "$lib/stores/data";
import {detailTabSet, inputSpeed, details_pane, vitals_pane, inputTurn} from "$lib/stores/state";
import uPlot from "uplot";

export const chartDataStore = new Map<string, uPlot.AlignedData>();

// Export all
export {
Expand Down
4 changes: 2 additions & 2 deletions gs/src/lib/panels/LogsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import Icon from "@iconify/svelte";
import {listen, type UnlistenFn} from "@tauri-apps/api/event";
import {afterUpdate, onDestroy, onMount} from "svelte";
import {EventChannels, type Log} from "$lib/types";
import {type Log} from "$lib/types";
let unlistens: UnlistenFn[];
let logContainer: HTMLElement;
Expand Down Expand Up @@ -46,7 +46,7 @@
onDestroy(() =>
unlistens.forEach(u => u())
);
);
afterUpdate(() => {
// Only scroll to the bottom if the user has not scrolled up
Expand Down
21 changes: 3 additions & 18 deletions gs/src/lib/panels/VitalsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@
south_bridge_payload,
TileGrid,
Tile,
Command, PlotBuffer, StrokePresets, GrandDataDistributor
Command, GrandDataDistributor
} from "$lib";
import {AppBar, getToastStore} from "@skeletonlabs/skeleton";
import Icon from "@iconify/svelte";
import {invoke} from "@tauri-apps/api/tauri";
import Keydown from "svelte-keydown";
import {onMount} from "svelte";
import {z} from "zod";
let width: number;
Expand All @@ -41,11 +39,6 @@
const toastStore = getToastStore();
let offsetXChart:PlotBuffer;
onMount(() => {
offsetXChart.addSeries(StrokePresets.theoretical())
})
</script>

<Keydown on:combo={({detail}) => {
Expand Down Expand Up @@ -121,16 +114,8 @@
</Tile>
<!-- OFFSET GRAPHS -->
<Tile containerClass="py-1 col-span-{width < 550 ? 2 : 1}" bgToken={800}>
<Chart bind:chart={offsetXChart}
eventCallback={(event) => {
// @ts-ignore
offsetXChart.addEntry(1, z.number().parse(event.payload.x));

// @ts-ignore
offsetXChart.addEntry(2, z.number().parse(event.payload.y));
}}
title="Offset horizontal"
eventChannel="current_hv" refreshRate={100}/>
<Chart title="Offset Horizontal"
refreshRate={100}/>
</Tile>
<Tile containerClass="py-1 h-full w-full col-span-{width < 550 ? 2 : 1}" bgToken={800}>
<Chart title="Offset Vertical" refreshRate={100}/>
Expand Down
76 changes: 67 additions & 9 deletions gs/src/lib/panels/tabs/BatteriesTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,87 @@
} from "$lib";
const storeManager = GrandDataDistributor.getInstance().stores;
const hvModulesTemp = storeManager.getStore("BatteryTemperatureHigh")
const hvModulesVol = storeManager.getStore("BatteryVoltageHigh")
const lvBattery = storeManager.getStore("BatteryBalanceLow");
const hvBattery = storeManager.getStore("BatteryBalanceHigh");
const avg1Temp = storeManager.getStore("Module1AvgTemperature");
const max1Temp = storeManager.getStore("Module1MaxTemperature");
const min1Temp = storeManager.getStore("Module1MinTemperature");
const avg1Vol = storeManager.getStore("Module1AvgVoltage");
const max1Vol = storeManager.getStore("Module1MaxVoltage");
const min1Vol = storeManager.getStore("Module1MinVoltage");
const avg2Temp = storeManager.getStore("Module2AvgTemperature");
const max2Temp = storeManager.getStore("Module2MaxTemperature");
const min2Temp = storeManager.getStore("Module2MinTemperature");
const avg2Vol = storeManager.getStore("Module2AvgVoltage");
const max2Vol = storeManager.getStore("Module2MaxVoltage");
const min2Vol = storeManager.getStore("Module2MinVoltage");
const avg3Temp = storeManager.getStore("Module3AvgTemperature");
const max3Temp = storeManager.getStore("Module3MaxTemperature");
const min3Temp = storeManager.getStore("Module3MinTemperature");
const avg3Vol = storeManager.getStore("Module3AvgVoltage");
const max3Vol = storeManager.getStore("Module3MaxVoltage");
const min3Vol = storeManager.getStore("Module3MinVoltage");
const avg4Temp = storeManager.getStore("Module4AvgTemperature");
const max4Temp = storeManager.getStore("Module4MaxTemperature");
const min4Temp = storeManager.getStore("Module4MinTemperature");
const avg4Vol = storeManager.getStore("Module4AvgVoltage");
const max4Vol = storeManager.getStore("Module4MaxVoltage");
const min4Vol = storeManager.getStore("Module4MinVoltage");
const avg5Temp = storeManager.getStore("Module5AvgTemperature");
const max5Temp = storeManager.getStore("Module5MaxTemperature");
const min5Temp = storeManager.getStore("Module5MinTemperature");
const avg5Vol = storeManager.getStore("Module5AvgVoltage");
const max5Vol = storeManager.getStore("Module5MaxVoltage");
const min5Vol = storeManager.getStore("Module5MinVoltage");
const avg6Temp = storeManager.getStore("Module6AvgTemperature");
const max6Temp = storeManager.getStore("Module6MaxTemperature");
const min6Temp = storeManager.getStore("Module6MinTemperature");
const avg6Vol = storeManager.getStore("Module6AvgVoltage");
const max6Vol = storeManager.getStore("Module6MaxVoltage");
const min6Vol = storeManager.getStore("Module6MinVoltage");
const avg7Temp = storeManager.getStore("Module7AvgTemperature");
const max7Temp = storeManager.getStore("Module7MaxTemperature");
const min7Temp = storeManager.getStore("Module7MinTemperature");
const avg7Vol = storeManager.getStore("Module7AvgVoltage");
const max7Vol = storeManager.getStore("Module7MaxVoltage");
const min7Vol = storeManager.getStore("Module7MinVoltage");
const avg8Temp = storeManager.getStore("Module8AvgTemperature");
const max8Temp = storeManager.getStore("Module8MaxTemperature");
const min8Temp = storeManager.getStore("Module8MinTemperature");
const avg8Vol = storeManager.getStore("Module8AvgVoltage");
const max8Vol = storeManager.getStore("Module8MaxVoltage");
const min8Vol = storeManager.getStore("Module8MinVoltage");
let titles = ["Battery", "Avg cell V", "Max cell V", "Min cell V"
, "Avg cell °C", "Max cell °C", "Min cell °C"];
let tableArr:any[][] = [
$: tableArr = [
["LV", "12.5V", "13.5V", "10.5V", "30°C", "50°C", "20°C"],
["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],
["HV mod 4", $avg4Vol, $max4Vol, $min4Vol, $avg4Temp, $max4Temp, $min4Temp],
["HV mod 5", $avg5Vol, $max5Vol, $min5Vol, $avg5Temp, $max5Temp, $min5Temp],
["HV mod 6", $avg6Vol, $max6Vol, $min6Vol, $avg6Temp, $max6Temp, $min6Temp],
["HV mod 7", $avg7Vol, $max7Vol, $min7Vol, $avg7Temp, $max7Temp, $min7Temp],
["HV mod 8", $avg8Vol, $max8Vol, $min8Vol, $avg8Temp, $max8Temp, $min8Temp],
]
$: {
for (let i = 0; i < 8; i++) {
tableArr[i+1] = [`HV mod ${i}`, $hvModulesVol[i].avg, $hvModulesVol[i].max, $hvModulesVol[i].min, $hvModulesTemp[i].avg, $hvModulesTemp[i].max, $hvModulesTemp[i].min];
}
}
let dcStatus:boolean = false;
let connectorStatus:boolean = false;
</script>

<div class="p-4">
<h2 class="text-xl font-semibold mb-4">Batteries</h2>
{$avg1Vol}
<TileGrid columns="1fr 1fr 1fr 1fr" rows="auto 1fr auto">
<Tile insideClass="flex h-full items-center gap-4">
<div class="flex flex-col items-center">
Expand Down
4 changes: 2 additions & 2 deletions gs/src/lib/panels/tabs/LocationTab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
<Localiser loc={$south_bridge_payload.value} max={50} turning={$inputTurn !== RunMode.ShortRun}/>
</Tile>
<Tile>
<Chart eventChannel="speed" title="Speed" background="bg-surface-900" />
<Chart title="Speed" background="bg-surface-900" />
</Tile>
<Tile>
<Chart eventChannel="speed" title="Acceleration" background="bg-surface-900" />
<Chart title="Acceleration" background="bg-surface-900" />
</Tile>
<Tile containerClass="col-start-1 col-span-2">
<Table tableArr={tableArr2} background="bg-surface-900" titles={["Important", "Variable"]}/>
Expand Down
37 changes: 3 additions & 34 deletions gs/src/lib/panels/tabs/MotorsTab.svelte
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
<script lang="ts">
import {south_bridge_payload, Chart, TileGrid, Tile, PlotBuffer, StrokePresets} from "$lib";
import {onMount} from "svelte";
import {z} from "zod";
import {Chart, TileGrid, Tile, PlotBuffer} from "$lib";
let width:number;
let updateSizes:((w:number)=>void)[] = [];
$: updateSizes.forEach(updateSize => updateSize(width));
let hemsChart:PlotBuffer;
let emsChart:PlotBuffer;
onMount(() => {
hemsChart.addSeries(StrokePresets.theoretical())
hemsChart.addSeries(StrokePresets.yellow())
hemsChart.addSeries(StrokePresets.blue())
emsChart.addSeries(StrokePresets.theoretical())
emsChart.addSeries(StrokePresets.yellow())
emsChart.addSeries(StrokePresets.blue())
})
</script>

<div class="p-4">
<h2 class="text-xl font-semibold mb-4">Current</h2>
<TileGrid columns="3" rows="">
<Tile>
<Chart eventCallback={(event) => {
// @ts-ignore
hemsChart.addEntry(1, z.number().parse(event.payload.values[0]));
// @ts-ignore
hemsChart.addEntry(2, z.number().parse(event.payload.values[1]));
// @ts-ignore
hemsChart.addEntry(3, z.number().parse(event.payload.values[2]));
// @ts-ignore
hemsChart.addEntry(4, z.number().parse(event.payload.values[3]));
}} bind:chart={hemsChart} eventChannel="hems" title="HEMS" background="bg-surface-900" />
<Chart bind:chart={hemsChart} title="HEMS" background="bg-surface-900" />
</Tile>
<Tile>
<Chart eventCallback={(event) => {
// @ts-ignore
emsChart.addEntry(1, z.number().parse(event.payload.values[0]));
// @ts-ignore
emsChart.addEntry(2, z.number().parse(event.payload.values[1]));
// @ts-ignore
emsChart.addEntry(3, z.number().parse(event.payload.values[2]));
// @ts-ignore
emsChart.addEntry(4, z.number().parse(event.payload.values[3]));
}} bind:chart={emsChart} eventChannel="ems" title="EMS" background="bg-surface-900" />
<Chart bind:chart={emsChart} title="EMS" background="bg-surface-900" />
</Tile>
</TileGrid>
</div>
3 changes: 3 additions & 0 deletions gs/src/lib/stores/state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { writable, type Writable } from 'svelte/store';
import {RunMode} from "$lib/types";
import {PlotBuffer} from "$lib";

export const detailTabSet: Writable<number> = writable(1);
export const inputSpeed: Writable<number> = writable(50);
Expand All @@ -9,3 +10,5 @@ export const inputTurn: Writable<RunMode> = writable(RunMode.ShortRun);

export const vitals_pane: Writable<number> = writable(40)
export const details_pane: Writable<number> = writable(80)

export const chartStore = writable(new Map<string, PlotBuffer>());
2 changes: 1 addition & 1 deletion gs/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export type NamedCommand = "DefaultCommand" | "Levitate" | "StopLevitating" | "C
/* debug commands */ | 'establish_connection' | 'start_north_bridge' | 'start_south_bridge' | 'abort'

/*AUTO GENERATED USING npm run generate:datatypes */
export type NamedDatatype = "DefaultDatatype" | "PropulsionTemperature" | "LevitationTemperature" | "IMDGeneralInfo" | "IMDIsolationDetails" | "IMDVoltageDetails" | "DefaultBMSLow" | "DiagonosticBMSLow" | "DefaultBMSHigh" | "DiagonosticBMSHigh" | "BatteryVoltageLow" | "BatteryVoltageHigh" | "TotalBatteryVoltageLow" | "TotalBatteryVoltageHigh" | "BatteryTemperatureLow" | "BatteryTemperatureHigh" | "BatteryBalanceLow" | "BatteryBalanceHigh" | "SingleCellVoltageLow" | "SingleCellTemperatureLow" | "ChargeStateLow" | "SingleCellVoltageHigh" | "SingleCellTemperatureHigh" | "ChargeStateHigh" | "BatteryCurrentLow" | "BatteryCurrentHigh" | "BatteryEnergyParamsLow" | "BatteryEnergyParamsHigh" | "BatteryMaxVoltageLow" | "BatteryEstimatedChargeLow" | "BatteryMinTemperatureLow" | "BatteryMaxTemperatureLow" | "BatteryMinBalancingLow" | "BatteryMaxBalancingLow" | "BatteryMinVoltageLow" | "BatteryMinVoltageHigh" | "BatteryMaxVoltageHigh" | "BatteryEstimatedChargeHigh" | "BatteryMinTemperatureHigh" | "BatteryMaxTemperatureHigh" | "BatteryMinBalancingHigh" | "BatteryMaxBalancingHigh" | "BrakeTemperature" | "PropulsionSpeed" | "BrakePressure" | "FSMState" | "FSMEvent" | "PodDropTriggered" | "Localisation" | "UnknownCanId" | "Info"
export type NamedDatatype = "DefaultDatatype" | "PropulsionTemperature" | "LevitationTemperature" | "IMDGeneralInfo" | "IMDIsolationDetails" | "IMDVoltageDetails" | "InsulationNegative" | "InsulationPositive" | "InsulationOriginal" | "DefaultBMSLow" | "DiagonosticBMSLow" | "DefaultBMSHigh" | "DiagonosticBMSHigh" | "BatteryVoltageLow" | "BatteryVoltageHigh" | "TotalBatteryVoltageLow" | "TotalBatteryVoltageHigh" | "BatteryTemperatureLow" | "BatteryTemperatureHigh" | "BatteryBalanceLow" | "BatteryBalanceHigh" | "SingleCellVoltageLow" | "SingleCellTemperatureLow" | "ChargeStateLow" | "ChargeStateHigh" | "BatteryCurrentLow" | "BatteryCurrentHigh" | "BatteryEnergyParamsLow" | "BatteryEnergyParamsHigh" | "BatteryMaxVoltageLow" | "BatteryEstimatedChargeLow" | "BatteryMinTemperatureLow" | "BatteryMaxTemperatureLow" | "BatteryMinBalancingLow" | "BatteryMaxBalancingLow" | "BatteryMinVoltageLow" | "BatteryMinVoltageHigh" | "BatteryMaxVoltageHigh" | "BatteryEstimatedChargeHigh" | "BatteryMinTemperatureHigh" | "BatteryMaxTemperatureHigh" | "BatteryMinBalancingHigh" | "BatteryMaxBalancingHigh" | "BatteryEventLow" | "BatteryEventHigh" | "BrakeTemperature" | "PropulsionSpeed" | "FSMState" | "FSMEvent" | "EndOfTrackTriggered" | "Localisation" | "Velocity" | "Direction" | "BrakePressure" | "UnknownCanId" | "Info" | "TempPCB1" | "TempPCB2" | "TempPCB3" | "TempPCB4" | "TempPCB5" | "TempPCB6" | "TempPCB7" | "TempPCB8" | "TempPCB9" | "TempPCB10" | "TempPCB11" | "TempPCB12" | "TempPCB13" | "TempPCB14" | "TempPCB15" | "TempPCB16" | "TempPCB17" | "TempPCB18" | "TempPCB19" | "TempPCB20" | "TempPCB21" | "TempPCB22" | "TempPCB23" | "TempPCB24" | "TempPCB25" | "TempPCB26" | "TempPCB27" | "TempPCB28" | "TempPCB29" | "TempPCB30" | "location" | "velocity" | "SingleCellVoltageHigh_1" | "SingleCellTemperatureHigh_1" | "SingleCellVoltageHigh_2" | "SingleCellTemperatureHigh_2" | "SingleCellVoltageHigh_3" | "SingleCellTemperatureHigh_3" | "SingleCellVoltageHigh_4" | "SingleCellTemperatureHigh_4" | "SingleCellVoltageHigh_5" | "SingleCellTemperatureHigh_5" | "SingleCellVoltageHigh_6" | "SingleCellTemperatureHigh_6" | "SingleCellVoltageHigh_7" | "SingleCellTemperatureHigh_7" | "SingleCellVoltageHigh_8" | "SingleCellTemperatureHigh_8" | "SingleCellVoltageHigh_9" | "SingleCellTemperatureHigh_9" | "SingleCellVoltageHigh_10" | "SingleCellTemperatureHigh_10" | "SingleCellVoltageHigh_11" | "SingleCellTemperatureHigh_11" | "SingleCellVoltageHigh_12" | "SingleCellTemperatureHigh_12" | "SingleCellVoltageHigh_13" | "SingleCellTemperatureHigh_13" | "SingleCellVoltageHigh_14" | "SingleCellTemperatureHigh_14" | "Module1MaxVoltage" | "Module2MaxVoltage" | "Module3MaxVoltage" | "Module4MaxVoltage" | "Module5MaxVoltage" | "Module6MaxVoltage" | "Module7MaxVoltage" | "Module8MaxVoltage" | "Module1MinVoltage" | "Module2MinVoltage" | "Module3MinVoltage" | "Module4MinVoltage" | "Module5MinVoltage" | "Module6MinVoltage" | "Module7MinVoltage" | "Module8MinVoltage" | "Module1MaxTemperature" | "Module2MaxTemperature" | "Module3MaxTemperature" | "Module4MaxTemperature" | "Module5MaxTemperature" | "Module6MaxTemperature" | "Module7MaxTemperature" | "Module8MaxTemperature" | "Module1MinTemperature" | "Module2MinTemperature" | "Module3MinTemperature" | "Module4MinTemperature" | "Module5MinTemperature" | "Module6MinTemperature" | "Module7MinTemperature" | "Module8MinTemperature" | "Module1AvgVoltage" | "Module2AvgVoltage" | "Module3AvgVoltage" | "Module4AvgVoltage" | "Module5AvgVoltage" | "Module6AvgVoltage" | "Module7AvgVoltage" | "Module8AvgVoltage" | "Module1AvgTemperature" | "Module2AvgTemperature" | "Module3AvgTemperature" | "Module4AvgTemperature" | "Module5AvgTemperature" | "Module6AvgTemperature" | "Module7AvgTemperature" | "Module8AvgTemperature"

// Not touched by auto-gen

Expand Down
2 changes: 1 addition & 1 deletion gs/src/lib/util/GrandDataDistributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import type {dataConvFun, Datapoint, NamedDatatype} from "$lib/types";
* let store = gdd.stores.get('BatteryBalanceHigh');
* </script>
* <h1>{$store}</h1>
* ```
*
* @see StateManager
* @version 2.0
Expand Down Expand Up @@ -82,7 +83,6 @@ export class GrandDataDistributor {
*/
protected processData(data: Datapoint[]) {
data.forEach((datapoint) => {
console.log(datapoint)
this.StoreManager.updateStore(datapoint.datatype, datapoint.value);
});
}
Expand Down
Loading

0 comments on commit 32d0c23

Please sign in to comment.