Skip to content

Commit

Permalink
mavlink: Allow also listening to outgoing messages
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaellehmkuhl committed Jan 5, 2025
1 parent 0e9544a commit 8075768
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 6 deletions.
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,
}
})

0 comments on commit 8075768

Please sign in to comment.