Skip to content

Commit

Permalink
Add variance reporting to calibration (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
DTTerastar authored Dec 3, 2023
1 parent d1d4bd0 commit 0af3e7b
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 52 deletions.
1 change: 1 addition & 0 deletions src/Controllers/StateController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public Calibration GetCalibration()
rxM["rssi"] = rx.Rssi;
rxM["err"] = rx.Expected - rx.Distance;
rxM["percent"] = rx.Distance / rx.Expected;
if (rx.Variance is not null) rxM["var"] = rx.Variance.Value;
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/Models/DeviceMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,8 @@ public class DeviceMessage

[JsonProperty("name")]
public string? Name { get; set; }

[JsonProperty("var")]
public double? Variance { get; set; }
}
}
17 changes: 7 additions & 10 deletions src/Models/RxNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class RxNode

public double Distance { get; set; }
public double Rssi { get; set; }
public double RefRssi { get; set; }
public double? Variance { get; set; }

public DateTime? LastHit { get; set; }
public int Hits { get; set; }
Expand All @@ -20,20 +22,15 @@ public class RxNode
public double LastDistance { get; set; }

public bool Current => DateTime.UtcNow - LastHit < TimeSpan.FromSeconds(Tx?.Config?.Timeout ?? 30);
public double RefRssi { get; set; }

public bool ReadMessage(DeviceMessage payload)
{
Distance = payload.Distance;
Variance = payload.Variance;
Rssi = payload.Rssi;
RefRssi = payload.RefRssi;
return NewDistance(payload.Distance);
}

private bool NewDistance(double d)
{
var moved = Math.Abs(LastDistance - d) > 0.25;
if (moved) LastDistance = d;
Distance = d;
var moved = Math.Abs(LastDistance - payload.Distance) > 0.25;
if (moved) LastDistance = payload.Distance;
Distance = payload.Distance;
LastHit = DateTime.UtcNow;
Hits++;
return moved;
Expand Down
6 changes: 3 additions & 3 deletions src/ui/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import '../app.postcss';
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
import { base } from '$app/paths';
import { AppShell, AppRail, AppRailAnchor, Drawer, Toast, Modal, initializeStores, storePopup } from '@skeletonlabs/skeleton';
import { beforeNavigate } from '$app/navigation';
Expand Down Expand Up @@ -32,8 +32,8 @@
</script>

<div class="app h-full">
<Modal />
<Toast />
<Modal />
<Toast />
<AppShell>
<svelte:fragment slot="sidebarLeft">
<AppRail>
Expand Down
81 changes: 42 additions & 39 deletions src/ui/src/routes/calibration/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,32 @@
if (percent == null) {
return '';
}
return (
'background-color: hsl(' + (240 - Math.min(Math.max(percent * 120, 0), 240)) + ', 50%, 50%)'
);
return 'background-color: hsl(' + (240 - Math.min(Math.max(percent * 120, 0), 240)) + ', 50%, 50%)';
}
function value(n1: any, data_point: number) {
if (data_point == 0) {
return Number(Math.round(n1?.percent * 100)) + '%';
} else if (data_point == 1) {
return Number(n1?.err?.toPrecision(3));
} else if (data_point == 2) {
return Number(n1?.absorption?.toPrecision(3));
} else if (data_point == 3) {
return Number(n1?.rx_adj_rssi?.toPrecision(3));
} else if (data_point == 4) {
return Number(n1?.tx_ref_rssi?.toPrecision(3));
if (data_point === 0) {
return n1 ? Number(Math.round(n1.percent * 100)) + '%' : null;
} else if (data_point >= 1 && data_point <= 5) {
let num;
switch (data_point) {
case 1:
num = n1?.err;
break;
case 2:
num = n1?.absorption;
break;
case 3:
num = n1?.rx_adj_rssi;
break;
case 4:
num = n1?.tx_ref_rssi;
break;
case 5:
num = n1?.var;
break;
}
return num !== null && num !== undefined ? Number(num.toPrecision(3)) : 'n/a';
}
}
Expand All @@ -32,8 +42,6 @@
return await response.json();
}
let selected = {};
let cal = {};
calibration().then((data) => {
cal = data;
Expand All @@ -42,12 +50,7 @@
calibration().then((data) => {
cal = data;
});
}, 5000);
let popupSettings: PopupSettings = {
event: 'hover',
target: 'examplePopup'
};
}, 1000);
let rxColumns: Array<string> = [];
$: {
Expand All @@ -68,16 +71,20 @@
<div class="text-column">
<h1 class="h1">Calibration</h1>

<div class="card variant-filled-secondary p-4" data-popup="examplePopup">
{#if selected}
Expected {@html Number(selected?.expected?.toPrecision(3))} - Actual {@html Number(
selected?.actual?.toPrecision(3)
)} = Error {@html Number(selected?.err?.toPrecision(3))}
{:else}
No beacon Received in last 30 seconds
{/if}
<div class="arrow variant-filled-secondary" />
</div>
{#if cal?.matrix}
{#each Object.entries(cal?.matrix) as [id1, n1] (id1)}
{#each rxColumns as id2 (id2)}
<div class="card variant-filled-secondary p-4" data-popup={'popup-' + id1 + '-' + id2}>
{#if n1[id2]}
Expected {@html Number(n1[id2].expected?.toPrecision(3))} - Actual {@html Number(n1[id2]?.actual?.toPrecision(3))} = Error {@html Number(n1[id2]?.err?.toPrecision(3))}
{:else}
No beacon Received in last 30 seconds
{/if}
<div class="arrow variant-filled-secondary" />
</div>
{/each}
{/each}
{/if}

<div class="card m-4">
{#if cal?.matrix}
Expand All @@ -89,6 +96,7 @@
<RadioItem bind:group={data_point} name="justify" value={2}>Absorption</RadioItem>
<RadioItem bind:group={data_point} name="justify" value={3}>Rx Rssi Adj</RadioItem>
<RadioItem bind:group={data_point} name="justify" value={4}>Tx Rssi Ref</RadioItem>
<RadioItem bind:group={data_point} name="justify" value={5}>Variance (m)</RadioItem>
</RadioGroup>
</div>
</header>
Expand All @@ -103,17 +111,12 @@
</tr>
</thead>
<tbody>
{#each Object.entries(cal.matrix) as [id1, n1]}
{#each Object.entries(cal.matrix) as [id1, n1] (id1)}
<tr>
<td>Tx: {@html id1}</td>
{#each rxColumns as id2}
{#each rxColumns as id2 (id2)}
{#if n1[id2]}
<td
use:popup={popupSettings}
on:mouseover={() => (selected = n1[id2])}
on:focus={() => (selected = n1[id2])}
style={coloring(n1[id2]?.percent)}>{@html value(n1[id2], data_point)}</td
>
<td use:popup={{ event: 'hover', target: 'popup-' + id1 + '-' + id2, placement: 'top' }} style={coloring(n1[id2]?.percent)}>{@html value(n1[id2], data_point)}</td>
{:else}
<td />
{/if}
Expand Down

0 comments on commit 0af3e7b

Please sign in to comment.