🌍 Split socket service from stores
This commit is contained in:
@@ -8,11 +8,9 @@
|
|||||||
import { ForwardKinematics } from '$lib/kinematic';
|
import { ForwardKinematics } from '$lib/kinematic';
|
||||||
import { location } from '$lib/utilities';
|
import { location } from '$lib/utilities';
|
||||||
import { fileService } from '$lib/services';
|
import { fileService } from '$lib/services';
|
||||||
|
import { servoAngles, mpu } from '$lib/stores';
|
||||||
import SceneBuilder from '$lib/sceneBuilder';
|
import SceneBuilder from '$lib/sceneBuilder';
|
||||||
|
|
||||||
const angles = socketService.angles;
|
|
||||||
const mpu = socketService.mpu;
|
|
||||||
|
|
||||||
let sceneManager: SceneBuilder;
|
let sceneManager: SceneBuilder;
|
||||||
let canvas: HTMLCanvasElement, streamCanvas: HTMLCanvasElement, stream: HTMLImageElement;
|
let canvas: HTMLCanvasElement, streamCanvas: HTMLCanvasElement, stream: HTMLImageElement;
|
||||||
let context: CanvasRenderingContext2D, texture: CanvasTexture;
|
let context: CanvasRenderingContext2D, texture: CanvasTexture;
|
||||||
@@ -142,7 +140,7 @@
|
|||||||
);
|
);
|
||||||
robot.position.y = Math.max(...points.map((coord) => coord[0] / 100)) - 2.7;
|
robot.position.y = Math.max(...points.map((coord) => coord[0] / 100)) - 2.7;
|
||||||
robot.rotation.z = lerp(robot.rotation.z, degToRad($mpu.heading + 90), 0.1);
|
robot.rotation.z = lerp(robot.rotation.z, degToRad($mpu.heading + 90), 0.1);
|
||||||
modelTargetAngles = $angles;
|
modelTargetAngles = $servoAngles;
|
||||||
|
|
||||||
handleVideoStream();
|
handleVideoStream();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export type angles = number[] | Int16Array;
|
||||||
|
|
||||||
|
type AnglesData = {
|
||||||
|
type: 'angles';
|
||||||
|
data: angles;
|
||||||
|
};
|
||||||
|
|
||||||
|
type LogData = {
|
||||||
|
type: 'log';
|
||||||
|
data: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type WebSocketJsonMsg = AnglesData | LogData;
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export { default as fileService } from './file-service';
|
export { default as fileService } from './file-service';
|
||||||
export { default as socketService } from './socket-service';
|
export { default as socketService } from './socket-service';
|
||||||
|
export { default as resultService } from './result-service';
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import { isConnected, socketData } from '$lib/stores';
|
||||||
import { Result, Ok } from '$lib/utilities';
|
import { Result, Ok } from '$lib/utilities';
|
||||||
import { writable, type Writable } from 'svelte/store';
|
import { resultService } from '$lib/services';
|
||||||
|
import { type WebSocketJsonMsg } from '$lib/models';
|
||||||
|
|
||||||
type WebsocketData = string | ArrayBufferLike | Blob | ArrayBufferView;
|
type WebsocketOutData = string | ArrayBufferLike | Blob | ArrayBufferView;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
/**
|
/**
|
||||||
@@ -13,17 +15,6 @@ type WebsocketData = string | ArrayBufferLike | Blob | ArrayBufferView;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class SocketService {
|
class SocketService {
|
||||||
public isConnected = writable(false);
|
|
||||||
public angles = writable(new Int16Array(12).fill(0));
|
|
||||||
public log = writable([] as string[]);
|
|
||||||
public battery = writable({});
|
|
||||||
public mpu = writable({ heading: 0 });
|
|
||||||
public distances = writable({});
|
|
||||||
public settings = writable({});
|
|
||||||
public systemInfo = writable({} as number);
|
|
||||||
public dataBuffer = writable(new Float32Array(13));
|
|
||||||
public servoBuffer: Writable<Int16Array | number[]> = writable(new Int16Array(12));
|
|
||||||
public data = writable();
|
|
||||||
private socket!: WebSocket;
|
private socket!: WebSocket;
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
@@ -33,10 +24,12 @@ class SocketService {
|
|||||||
this.socket.binaryType = 'arraybuffer';
|
this.socket.binaryType = 'arraybuffer';
|
||||||
this.socket.onopen = () => this.handleConnected();
|
this.socket.onopen = () => this.handleConnected();
|
||||||
this.socket.onclose = () => this.handleDisconnected();
|
this.socket.onclose = () => this.handleDisconnected();
|
||||||
this.socket.onmessage = (event: unknown) => this.handleMessage(event);
|
this.socket.onmessage = (event: MessageEvent) =>
|
||||||
|
resultService.handleResult(this.handleMessage(event), 'SocketService');
|
||||||
|
this.socket.onerror = (error: Event) => console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
public send(data: WebsocketData): Result<void, string> {
|
public send(data: WebsocketOutData): Result<void, string> {
|
||||||
if (this.socket.readyState === WebSocket.OPEN) {
|
if (this.socket.readyState === WebSocket.OPEN) {
|
||||||
this.socket.send(data);
|
this.socket.send(data);
|
||||||
return Ok.void();
|
return Ok.void();
|
||||||
@@ -45,56 +38,49 @@ class SocketService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleConnected(): void {
|
private handleConnected(): void {
|
||||||
this.isConnected.set(true);
|
isConnected.set(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleDisconnected(): void {
|
private handleDisconnected(): void {
|
||||||
this.isConnected.set(false);
|
isConnected.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleMessage(event: any): void {
|
private getJsonFromMessage(msg: string): Result<WebSocketJsonMsg, string> {
|
||||||
if (event.data instanceof ArrayBuffer) {
|
try {
|
||||||
let buffer = new Int8Array(event.data);
|
return Result.ok(JSON.parse(msg) as WebSocketJsonMsg);
|
||||||
if (buffer.length === 44) {
|
} catch (error) {
|
||||||
this.dataBuffer.set(new Float32Array(buffer.buffer));
|
return Result.err('Failed to parse socket message', error);
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let data = event.data;
|
|
||||||
try {
|
|
||||||
data = JSON.parse(event.data);
|
|
||||||
} catch (error) {
|
|
||||||
console.warn(error);
|
|
||||||
}
|
|
||||||
switch (data.type) {
|
|
||||||
case 'angles':
|
|
||||||
this.angles.set(data.angles);
|
|
||||||
break;
|
|
||||||
case 'logs':
|
|
||||||
this.log.set(data.logs);
|
|
||||||
break;
|
|
||||||
case 'log':
|
|
||||||
this.log.update((entries) => {
|
|
||||||
entries.push(data.log);
|
|
||||||
return entries;
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'settings':
|
|
||||||
this.settings.set(data.settings);
|
|
||||||
case 'info':
|
|
||||||
this.systemInfo.set(data.info);
|
|
||||||
break;
|
|
||||||
case 'mpu':
|
|
||||||
this.mpu.set(data.mpu);
|
|
||||||
break;
|
|
||||||
case 'distances':
|
|
||||||
this.distances.set(data.distances);
|
|
||||||
break;
|
|
||||||
case 'battery':
|
|
||||||
this.battery.set(data.battery);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleBufferMessage(buffer: ArrayBuffer): Result<void, string> {
|
||||||
|
console.log(buffer);
|
||||||
|
return Ok.void();
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleMessage(event: MessageEvent): Result<void, string> {
|
||||||
|
if (event.data instanceof ArrayBuffer) {
|
||||||
|
return this.handleBufferMessage(event.data);
|
||||||
|
}
|
||||||
|
let msgRes = this.getJsonFromMessage(event.data);
|
||||||
|
if (msgRes.isErr()) {
|
||||||
|
return msgRes;
|
||||||
|
}
|
||||||
|
const msg = msgRes.inner;
|
||||||
|
|
||||||
|
if (msg.type === 'log') {
|
||||||
|
socketData.logs.update((entries) => {
|
||||||
|
entries.push(msg.data);
|
||||||
|
return entries;
|
||||||
|
});
|
||||||
|
return Ok.void();
|
||||||
|
} else if (msg.data && msg.type in socketData) {
|
||||||
|
socketData[msg.type].set(msg.data);
|
||||||
|
return Ok.void();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.err(`Got invalid msg: ${JSON.stringify(msg)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new SocketService();
|
export default new SocketService();
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
|
export * from './socket-store';
|
||||||
export * from './logging-store';
|
export * from './logging-store';
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { writable, type Writable } from 'svelte/store';
|
||||||
|
import { type angles } from '$lib/models';
|
||||||
|
|
||||||
|
export const isConnected = writable(false);
|
||||||
|
export const servoAngles: Writable<angles> = writable(new Int16Array(12).fill(0));
|
||||||
|
export const logs = writable([] as string[]);
|
||||||
|
export const battery = writable({});
|
||||||
|
export const mpu = writable({ heading: 0 });
|
||||||
|
export const distances = writable({});
|
||||||
|
export const settings = writable({});
|
||||||
|
export const systemInfo = writable({} as number);
|
||||||
|
|
||||||
|
export interface socketDataCollection {
|
||||||
|
angles: Writable<angles>;
|
||||||
|
logs: Writable<string[]>;
|
||||||
|
battery: Writable<unknown>;
|
||||||
|
mpu: Writable<unknown>;
|
||||||
|
distances: Writable<unknown>;
|
||||||
|
settings: Writable<unknown>;
|
||||||
|
systemInfo: Writable<unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const socketData = {
|
||||||
|
angles: servoAngles,
|
||||||
|
logs,
|
||||||
|
battery,
|
||||||
|
mpu,
|
||||||
|
distances,
|
||||||
|
settings,
|
||||||
|
systemInfo
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user