Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaellehmkuhl committed Dec 16, 2024
1 parent fa20d62 commit 5d76384
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 6 deletions.
104 changes: 104 additions & 0 deletions src/components/development/MAVLinkInspector.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<template>
<div class="flex flex-col gap-4">
<div class="flex flex-row gap-4 mb-4">
<div class="flex-1">
<div class="text-lg mb-2">Available Message Types</div>
<div class="mb-2">
<input
v-model="searchQuery"
type="text"
placeholder="Search messages..."
class="w-full px-3 py-2 bg-[#FFFFFF22] rounded-md text-white placeholder-gray-400 outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div class="bg-[#FFFFFF11] rounded-md p-2 max-h-[300px] overflow-y-auto">
<div
v-for="type in filteredMessageTypes"
:key="type"
class="cursor-pointer hover:bg-[#FFFFFF22] p-1 rounded"
:class="{ 'bg-[#FFFFFF33]': trackedMessageTypes.has(type) }"
@click="toggleMessageTracking(type)"
>
{{ type }}
</div>
<div v-if="filteredMessageTypes.length === 0" class="text-gray-400 text-center p-2">No messages found</div>
</div>
</div>
<div class="flex-1">
<div class="text-lg mb-2">Message Values</div>
<div class="bg-[#FFFFFF11] rounded-md p-2 max-h-[340px] overflow-y-auto">
<div v-for="type in trackedMessageTypes" :key="type" class="mb-2">
<div class="font-bold">{{ type }}</div>
<div class="text-xs text-gray-400 mb-1">Incoming Messages:</div>
<pre class="text-sm whitespace-pre-wrap">{{
JSON.stringify(messageValues.get(`in:${type}`), null, 2)
}}</pre>
<div class="text-xs text-gray-400 mt-2 mb-1">Outgoing Messages:</div>
<pre class="text-sm whitespace-pre-wrap">{{
JSON.stringify(messageValues.get(`out:${type}`), null, 2)
}}</pre>
</div>
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue'
import type { Package } from '@/libs/connection/m2r/messages/mavlink2rest'
import { MAVLinkType } from '@/libs/connection/m2r/messages/mavlink2rest-enum'
import { useMainVehicleStore } from '@/stores/mainVehicle'
const mainVehicleStore = useMainVehicleStore()
const searchQuery = ref('')
const availableMessageTypes = computed(() => {
return Object.values(MAVLinkType).filter((type) => typeof type === 'string')
})
const filteredMessageTypes = computed(() => {
const query = searchQuery.value.toLowerCase()
if (!query) return availableMessageTypes.value
return availableMessageTypes.value.filter((type) => type.toLowerCase().includes(query))
})
const trackedMessageTypes = ref<Set<MAVLinkType>>(new Set())
const messageValues = ref<Map<string, unknown>>(new Map())
const toggleMessageTracking = (type: MAVLinkType): void => {
if (trackedMessageTypes.value.has(type)) {
trackedMessageTypes.value.delete(type)
messageValues.value.delete(`in:${type}`)
messageValues.value.delete(`out:${type}`)
} else {
trackedMessageTypes.value.add(type)
setupMessageListeners(type)
}
}
const setupMessageListeners = (type: MAVLinkType): void => {
try {
mainVehicleStore.listenToIncomingMessages(type, (pack: Package) => {
messageValues.value.set(`in:${type}`, pack.message)
})
mainVehicleStore.listenToOutgoingMessages(type, (pack: Package) => {
messageValues.value.set(`out:${type}`, pack.message)
})
} catch (error) {
console.error(`Failed to setup message listeners for type ${type}:`, error)
}
}
// Set up listeners for any already tracked message types
onMounted(() => {
trackedMessageTypes.value.forEach(setupMessageListeners)
})
// Clean up when component is unmounted
onUnmounted(() => {
trackedMessageTypes.value.clear()
messageValues.value.clear()
})
</script>
4 changes: 4 additions & 0 deletions src/libs/connection/connection-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class ConnectionManager {
// Signals
static onMainConnection = new Signal<WeakRef<Connection.Abstract>>()
static onRead = new Signal<Uint8Array>()
static onWrite = new Signal<Uint8Array>()

/**
* Return the connections available
Expand Down Expand Up @@ -69,7 +70,9 @@ export class ConnectionManager {
}

previousConnection?.onRead?.clear()
previousConnection?.onWrite?.clear()
connection.onRead.add((data: Uint8Array) => this.onRead.emit_value(data))
connection.onWrite.add((data: Uint8Array) => this.onWrite.emit_value(data))
ConnectionManager._mainConnection = new WeakRef(connection)
// There is no constructor and updating the register is not expensive in this function
ConnectionManager.onMainConnection.register_caller(
Expand All @@ -96,6 +99,7 @@ export class ConnectionManager {
*/
static write(data: Uint8Array): boolean {
ConnectionManager.mainConnection()?.write(data)
ConnectionManager.onWrite.emit_value(data)
return true
}
}
1 change: 1 addition & 0 deletions src/libs/connection/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export abstract class Abstract {

// Signals
public onRead = new Signal<Uint8Array>()
public onWrite = new Signal<Uint8Array>()

/**
* Return the connection uri
Expand Down
27 changes: 24 additions & 3 deletions src/libs/vehicle/ardupilot/ardupilot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ export abstract class ArduPilotVehicle<Modes> extends Vehicle.AbstractVehicle<Mo

_messages: MAVLinkMessageDictionary = new Map()

onMAVLinkMessage = new SignalTyped()
onIncomingMAVLinkMessage = new SignalTyped()
onOutgoingMAVLinkMessage = new SignalTyped()
_flying = false

protected currentSystemId = 1
Expand Down Expand Up @@ -270,11 +271,31 @@ export abstract class ArduPilotVehicle<Modes> extends Vehicle.AbstractVehicle<Mo
]
}

/**
* Log outgoing messages
* @param {Uint8Array} message
*/
onOutgoingMessage(message: Uint8Array): void {
const textDecoder = new TextDecoder()
let mavlink_message: Package
const text_message = textDecoder.decode(message)
try {
mavlink_message = JSON.parse(text_message) as Package
this.onOutgoingMAVLinkMessage.emit_value(mavlink_message.message.type, mavlink_message)
} catch (error) {
const pattern = /Ok\((\d+)\)/
const match = pattern.exec(text_message)
if (match) return
console.error(`Failed to parse mavlink message: ${text_message}`)
return
}
}

/**
* Decode incoming message
* @param {Uint8Array} message
*/
onMessage(message: Uint8Array): void {
onIncomingMessage(message: Uint8Array): void {
const textDecoder = new TextDecoder()
let mavlink_message: Package
const text_message = textDecoder.decode(message)
Expand Down Expand Up @@ -350,7 +371,7 @@ export abstract class ArduPilotVehicle<Modes> extends Vehicle.AbstractVehicle<Mo

// TODO: Maybe create a signal class to deal with MAVLink only
// Where add will use the template argument type to define the lambda argument type
this.onMAVLinkMessage.emit_value(mavlink_message.message.type, mavlink_message)
this.onIncomingMAVLinkMessage.emit_value(mavlink_message.message.type, mavlink_message)

if (Object.keys(this._usedGenericVariablesdMessagePaths).includes(mavlink_message.message.type)) {
this._usedGenericVariablesdMessagePaths[mavlink_message.message.type].forEach((path) => {
Expand Down
3 changes: 2 additions & 1 deletion src/libs/vehicle/vehicle-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ export class VehicleFactory {
return undefined
}

ConnectionManager.onRead.add((message) => vehicle?.onMessage(message))
ConnectionManager.onRead.add((message) => vehicle?.onIncomingMessage(message))
ConnectionManager.onWrite.add((message) => vehicle?.onOutgoingMessage(message))

VehicleFactory._vehicles.push(new WeakRef(vehicle))
VehicleFactory.onVehicles.register_caller(this.vehicles)
Expand Down
3 changes: 2 additions & 1 deletion src/libs/vehicle/vehicle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ export abstract class AbstractVehicle<Modes> {
}
}

abstract onMessage(message: Uint8Array): void
abstract onIncomingMessage(message: Uint8Array): void
abstract onOutgoingMessage(message: Uint8Array): void

abstract arm(): Promise<void>
abstract altitude(): Altitude
Expand Down
18 changes: 17 additions & 1 deletion src/stores/mainVehicle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ export const useMainVehicleStore = defineStore('main-vehicle', () => {
}
}, 1000)

mainVehicle.value.onMAVLinkMessage.add(MAVLinkType.HEARTBEAT, (pack: Package) => {
mainVehicle.value.onIncomingMAVLinkMessage.add(MAVLinkType.HEARTBEAT, (pack: Package) => {
if (pack.header.component_id != 1) {
return
}
Expand Down Expand Up @@ -533,6 +533,20 @@ export const useMainVehicleStore = defineStore('main-vehicle', () => {
})
})

const listenToIncomingMessages = (messageType: string, callback: (pack: Package) => void): void => {
if (!mainVehicle.value) {
throw new Error('No vehicle available to listen for incoming messages.')
}
mainVehicle.value?.onIncomingMAVLinkMessage.add(messageType, callback)
}

const listenToOutgoingMessages = (messageType: string, callback: (pack: Package) => void): void => {
if (!mainVehicle.value) {
throw new Error('No vehicle available to listen for outgoing messages.')
}
mainVehicle.value?.onOutgoingMAVLinkMessage.add(messageType, callback)
}

// Allow us to set custom commands to be used in the browser
// Expert mode
watch(mainVehicle, async (newVehicle) => {
Expand Down Expand Up @@ -618,5 +632,7 @@ export const useMainVehicleStore = defineStore('main-vehicle', () => {
genericVariables,
availableGenericVariables,
registerUsageOfGenericVariable,
listenToIncomingMessages,
listenToOutgoingMessages,
}
})
7 changes: 7 additions & 0 deletions src/views/ConfigurationDevelopmentView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
thumb-label="hover"
/>
</div>
<ExpansiblePanel :is-expanded="!interfaceStore.isOnPhoneScreen">
<template #title>MAVLink Inspector</template>
<template #content>
<MAVLinkInspector />
</template>
</ExpansiblePanel>
<ExpansiblePanel :is-expanded="!interfaceStore.isOnPhoneScreen">
<template #title>
<div class="flex justify-between">
Expand Down Expand Up @@ -97,6 +103,7 @@ import { saveAs } from 'file-saver'
import { onBeforeMount } from 'vue'
import { ref } from 'vue'
import MAVLinkInspector from '@/components/development/MAVLinkInspector.vue'
import ExpansiblePanel from '@/components/ExpansiblePanel.vue'
import { type SystemLog, cockpitSytemLogsDB } from '@/libs/system-logging'
import { reloadCockpit } from '@/libs/utils'
Expand Down

0 comments on commit 5d76384

Please sign in to comment.