📦 Moves all model loading to model-utilities

This commit is contained in:
Rune Harlyk
2024-08-18 16:26:42 +02:00
parent 296adfee51
commit a86b2fa50e
5 changed files with 70 additions and 62 deletions
+2 -15
View File
@@ -1,10 +1,8 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { BufferGeometry, Line, LineBasicMaterial, Mesh, MeshBasicMaterial, Object3D, SphereGeometry, Vector3, type NormalBufferAttributes, type Object3DEventMap } from 'three';
import uzip from 'uzip';
import { ModesEnum, kinematicData, mode, model, outControllerData, servoAnglesOut, servoAngles, mpu, jointNames } from '$lib/stores';
import { footColor, isEmbeddedApp, throttler, toeWorldPositions } from '$lib/utilities';
import { fileService } from '$lib/services';
import { footColor, isEmbeddedApp, populateModelCache, throttler, toeWorldPositions } from '$lib/utilities';
import SceneBuilder from '$lib/sceneBuilder';
import { lerp, degToRad } from 'three/src/math/MathUtils';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
@@ -76,7 +74,7 @@
}
onMount(async () => {
await cacheModelFiles()
await populateModelCache();
await createScene();
if (!isEmbeddedApp && panel) createPanel();
servoAngles.subscribe(updateAnglesFromStore)
@@ -130,17 +128,6 @@
])
}
const cacheModelFiles = async () => {
let data = await fetch('/stl.zip').then((data) => data.arrayBuffer());
var files = uzip.parse(data);
for (const [path, data] of Object.entries(files) as [path: string, data: Uint8Array][]) {
const url = new URL(path, window.location.href);
fileService.saveFile(url.toString(), data);
}
};
const updateAngles = (name: string, angle: number) => {
modelTargetAngles[$jointNames.indexOf(name)] = angle * (180 / Math.PI);
Throttler.throttle(() => servoAnglesOut.set(modelTargetAngles.map(num => Math.round(num))), 100)
+3
View File
@@ -3,3 +3,6 @@ export * from './logging-store';
export * from './model-store';
export * from './socket';
export * from './fullscreen';
export * from './telemetry';
export * from './analytics';
export * from './user';
+26
View File
@@ -2,9 +2,35 @@ import { Color, LoaderUtils, Vector3 } from 'three';
import URDFLoader, { type URDFRobot } from 'urdf-loader';
import { XacroLoader } from 'xacro-parser';
import { Result } from '$lib/utilities';
import { jointNames, model } from '$lib/stores';
import uzip from 'uzip';
import { fileService } from '$lib/services';
let model_xml: XMLDocument;
export const populateModelCache = async () => {
await cacheModelFiles();
const modelRes = await loadModelAsync('/spot_micro.urdf.xacro');
if (modelRes.isOk()) {
const [urdf, JOINT_NAME] = modelRes.inner;
jointNames.set(JOINT_NAME);
model.set(urdf);
} else {
console.error(modelRes.inner, { exception: modelRes.exception });
}
};
export const cacheModelFiles = async () => {
let data = await fetch('/stl.zip');
var files = uzip.parse(await data.arrayBuffer());
for (const [path, data] of Object.entries(files) as [path: string, data: Uint8Array][]) {
const url = new URL(path, window.location.href);
fileService.saveFile(url.toString(), data);
}
};
export const loadModelAsync = async (
url: string
): Promise<Result<[URDFRobot, string[]], string>> => {
+37 -30
View File
@@ -1,9 +1,5 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { user } from '$lib/stores/user';
import { telemetry } from '$lib/stores/telemetry';
import { analytics } from '$lib/stores/analytics';
import type { userProfile } from '$lib/stores/user';
import { page } from '$app/stores';
import { Modals, closeModal } from 'svelte-modals';
import Toast from '$lib/components/toasts/Toast.svelte';
@@ -13,7 +9,19 @@
import Menu from './menu.svelte';
import Statusbar from './statusbar.svelte';
import Login from './login.svelte';
import { ModesEnum, kinematicData, mode, outControllerData, servoAngles, servoAnglesOut, socket } from '$lib/stores';
import {
telemetry,
analytics,
user,
type userProfile,
ModesEnum,
kinematicData,
mode,
outControllerData,
servoAngles,
servoAnglesOut,
socket
} from '$lib/stores';
import type { Analytics, Battery, DownloadOTA } from '$lib/types/models';
import { api } from '$lib/api';
@@ -21,35 +29,37 @@
if ($user.bearer_token !== '') {
await validateUser($user);
}
const ws_token = $page.data.features.security ? '?access_token=' + $user.bearer_token : '';
const ws_token = $page.data.features.security ? '?access_token=' + $user.bearer_token : '';
socket.init(`ws://${window.location.host}/ws/events${ws_token}`);
addEventListeners();
outControllerData.subscribe((data) => socket.sendEvent("input", {data}));
mode.subscribe((data) => socket.sendEvent("mode", {data}));
servoAnglesOut.subscribe((data) => socket.sendEvent("angles", {data}));
kinematicData.subscribe((data) => socket.sendEvent("position", {data}));
outControllerData.subscribe((data) => socket.sendEvent('input', { data }));
mode.subscribe((data) => socket.sendEvent('mode', { data }));
servoAnglesOut.subscribe((data) => socket.sendEvent('angles', { data }));
kinematicData.subscribe((data) => socket.sendEvent('position', { data }));
});
onDestroy(() => {
removeEventListeners();
});
onDestroy(() => {
removeEventListeners();
});
const addEventListeners = () => {
const addEventListeners = () => {
socket.on('open', handleOpen);
socket.on('close', handleClose);
socket.on('error', handleError);
socket.on('rssi', handleNetworkStatus);
socket.on('mode', (data:ModesEnum) => mode.set(data));
socket.on('angles', (angles:number[]) => { if (angles.length) servoAngles.set(angles)});
socket.on('mode', (data: ModesEnum) => mode.set(data));
socket.on('angles', (angles: number[]) => {
if (angles.length) servoAngles.set(angles);
});
if ($page.data.features.analytics) socket.on('analytics', handleAnalytics);
if ($page.data.features.battery) socket.on('battery', handleBattery);
if ($page.data.features.download_firmware) socket.on('otastatus', handleOAT);
if ($page.data.features.sonar) socket.on('sonar', data => console.log(data))
if ($page.data.features.sonar) socket.on('sonar', (data) => console.log(data));
};
const removeEventListeners = () => {
const removeEventListeners = () => {
socket.off('analytics', handleAnalytics);
socket.off('open', handleOpen);
socket.off('close', handleClose);
@@ -58,12 +68,12 @@
socket.off('otastatus', handleOAT);
};
async function validateUser(userdata: userProfile) {
const result = await api.get('/api/verifyAuthorization')
if (result.isErr()){
user.invalidate();
console.error('Error:', result.inner);
}
async function validateUser(userdata: userProfile) {
const result = await api.get('/api/verifyAuthorization');
if (result.isErr()) {
user.invalidate();
console.error('Error:', result.inner);
}
}
const handleOpen = () => {
@@ -71,7 +81,7 @@
};
const handleClose = () => {
notifications.error('Connection to device lost', 5000);
// notifications.error('Connection to device lost', 5000);
telemetry.setRSSI(0);
};
@@ -86,7 +96,6 @@
const handleOAT = (data: DownloadOTA) => telemetry.setDownloadOTA(data);
let menuOpen = false;
</script>
<svelte:head>
@@ -103,14 +112,12 @@
<Statusbar />
<!-- Main page content here -->
<slot />
<slot />
</div>
<!-- Side Navigation -->
<div class="drawer-side z-30 shadow-lg">
<label for="main-menu" class="drawer-overlay" />
<Menu
on:menuClicked={() => menuOpen = false}
/>
<Menu on:menuClicked={() => (menuOpen = false)} />
</div>
</div>
{/if}
+2 -17
View File
@@ -1,7 +1,4 @@
import { jointNames, model } from '$lib/stores';
import { loadModelAsync } from '$lib/utilities/model-utilities';
export const prerender = true;
export const prerender = false;
export const ssr = false;
const registerFetchIntercept = async () => {
@@ -14,20 +11,8 @@ const registerFetchIntercept = async () => {
};
};
const loadModelFiles = async () => {
const modelRes = await loadModelAsync('/spot_micro.urdf.xacro');
if (modelRes.isOk()) {
const [urdf, JOINT_NAME] = modelRes.inner;
jointNames.set(JOINT_NAME);
model.set(urdf);
} else {
console.error(modelRes.inner, { exception: modelRes.exception });
}
};
export const load = async ({ fetch }) => {
export const load = async () => {
await registerFetchIntercept();
await loadModelFiles();
const result = await fetch('/api/features');
const features = await result.json();
return {