diff --git a/package.json b/package.json index 467f1e14c..e79eaec71 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@vueuse/math": "^10.1.2", "@zip.js/zip.js": "^2.7.34", "browser-or-node": "^2.0.0", + "cesium": "^1.123.1", "colord": "^2.9.3", "date-fns": "^2.29.3", "file-saver": "^2.0.5", @@ -52,6 +53,7 @@ "leaflet": "1.9.3", "localforage": "^1.10.0", "mathjs": "^13.0.3", + "mavlink-browser": "git+https://github.com/williangalvani/mavlink-browser.git#cockpit_updates", "pinia": "^2.0.13", "roboto-fontface": "*", "semver": "^7.5.4", @@ -59,6 +61,7 @@ "sweetalert2": "^11.7.1", "tailwind-scrollbar-hide": "^1.1.7", "uuid": "^8.3.2", + "vite-plugin-cesium": "^1.2.23", "vue": "^3.4.21", "vue-draggable-plus": "^0.2.0-beta.2", "vue-router": "^4.0.14", diff --git a/public/models/bluerov.glb b/public/models/bluerov.glb new file mode 100755 index 000000000..d64a154c8 Binary files /dev/null and b/public/models/bluerov.glb differ diff --git a/public/models/boat.glb b/public/models/boat.glb new file mode 100755 index 000000000..8a4d43cec Binary files /dev/null and b/public/models/boat.glb differ diff --git a/src/components/EditMenu.vue b/src/components/EditMenu.vue index 63aef0f46..16b1b4b98 100644 --- a/src/components/EditMenu.vue +++ b/src/components/EditMenu.vue @@ -678,6 +678,7 @@ const widgetImages = { IFrame: IFrameImg, ImageView: ImageViewImg, Map: MapImg, + Cesium: MapImg, MiniWidgetsBar: MiniWidgetsBarImg, URLVideoPlayer: URLVideoPlayerImg, VideoPlayer: VideoPlayerImg, diff --git a/src/components/widgets/Cesium.vue b/src/components/widgets/Cesium.vue new file mode 100644 index 000000000..90a338946 --- /dev/null +++ b/src/components/widgets/Cesium.vue @@ -0,0 +1,342 @@ + + + + + \ No newline at end of file diff --git a/src/libs/connection/websocket-connection.ts b/src/libs/connection/websocket-connection.ts index 2a56d1203..5ed8fa5f0 100644 --- a/src/libs/connection/websocket-connection.ts +++ b/src/libs/connection/websocket-connection.ts @@ -1,3 +1,5 @@ +import { MAVLink20Processor } from 'mavlink-browser' + import * as Protocol from '@/libs/vehicle/protocol/protocol' import * as Connection from './connection' @@ -9,7 +11,8 @@ export class WebSocketConnection extends Connection.Abstract { _socket: WebSocket private _textEncoder = new TextEncoder() private _textDecoder = new TextDecoder() - + private mavlinkParser = new MAVLink20Processor(null, 255, 240) + private raw_mavlink_detected = false /** * Websocket constructor * @param {Connection.URI} uri @@ -17,7 +20,11 @@ export class WebSocketConnection extends Connection.Abstract { */ constructor(uri: Connection.URI, vehicleProtocol: Protocol.Type) { super(uri, vehicleProtocol) - + this.mavlinkParser.on('message', (message: any) => { + this.raw_mavlink_detected = true + const data = this._textEncoder.encode(this.mavlink2restfy(message)) + this.onRead.emit_value(data) + }) this._socket = this.createSocket(uri) } @@ -54,7 +61,12 @@ export class WebSocketConnection extends Connection.Abstract { * @returns {boolean} */ write(data: Uint8Array): boolean { - this._socket?.send(this._textDecoder.decode(data)) + if (this.raw_mavlink_detected) { + data = this.mavlinkParser.fromMavlink2RestV1Format(this._textDecoder.decode(data)) + this._socket?.send(data) + } else { + this._socket?.send(this._textDecoder.decode(data)) + } return true } @@ -72,7 +84,13 @@ export class WebSocketConnection extends Connection.Abstract { // We need to have the same abstraction for all onRead socket.onmessage = (message: MessageEvent) => { try { - this.onRead.emit_value(this._textEncoder.encode(message.data)) + if (String.fromCharCode(message.data[0]) == '{') { + this.onRead.emit_value(this._textEncoder.encode(message.data)) + } else { + new Response(message.data).arrayBuffer().then((buffer) => { + this.mavlinkParser.parseBuffer(new Uint8Array(buffer)) + }) + } } catch (error) { console.error('Error reading websocket message: ', error) } @@ -84,4 +102,13 @@ export class WebSocketConnection extends Connection.Abstract { } return socket } + + /** + * + * @param {any} message a "raw" MAVLink message as it comes from Mavlink20Processor + * @returns {string} a MAVLink2Rest-like stringified json object + */ + mavlink2restfy(message): any { + return JSON.stringify(this.mavlinkParser.toMavlink2RestV1Format(message)) + } } diff --git a/src/types/widgets.ts b/src/types/widgets.ts index 23e2f704e..f74c8408a 100644 --- a/src/types/widgets.ts +++ b/src/types/widgets.ts @@ -12,6 +12,7 @@ export enum WidgetType { IFrame = 'IFrame', ImageView = 'ImageView', Map = 'Map', + Cesium = 'Cesium', MiniWidgetsBar = 'MiniWidgetsBar', URLVideoPlayer = 'URLVideoPlayer', VideoPlayer = 'VideoPlayer', diff --git a/vite.config.ts b/vite.config.ts index 72c3d8fea..2c6e72863 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -3,6 +3,7 @@ import { defineConfig } from 'vite' import electron, { startup, treeKillSync } from 'vite-plugin-electron' import { VitePWA } from 'vite-plugin-pwa' import vuetify from 'vite-plugin-vuetify' +import cesium from 'vite-plugin-cesium' const path = require('path') // eslint-disable-line @typescript-eslint/no-var-requires @@ -40,8 +41,12 @@ export default defineConfig({ }, includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'masked-icon.svg'], }), + cesium(), // Add Cesium plugin ].filter(Boolean), - define: { 'process.env': {} }, + define: { + 'process.env': {}, + CESIUM_BASE_URL: JSON.stringify('') + }, resolve: { alias: { '@': path.resolve(__dirname, 'src'), @@ -54,4 +59,4 @@ export default defineConfig({ server: { host: '0.0.0.0', }, -}) +}) \ No newline at end of file