Skip to content

Commit

Permalink
joystick-pipeline: Add support for multiple function mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaellehmkuhl committed Dec 27, 2023
1 parent c8f1b8f commit 83b5107
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 53 deletions.
98 changes: 50 additions & 48 deletions src/assets/joystick-profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,59 @@ import {
} from '@/types/joystick'

// TODO: Adjust mapping for PS5 controller
export const cockpitStandardToProtocols: JoystickProtocolActionsMapping = {
name: 'Default ROV functions mapping',
axesCorrespondencies: {
[JoystickAxis.A0]: { action: mavlinkManualControlAxes.axis_y, min: -1000, max: +1000 },
[JoystickAxis.A1]: { action: mavlinkManualControlAxes.axis_x, min: +1000, max: -1000 },
[JoystickAxis.A2]: { action: mavlinkManualControlAxes.axis_r, min: -1000, max: +1000 },
[JoystickAxis.A3]: { action: mavlinkManualControlAxes.axis_z, min: +1000, max: 0 },
},
buttonsCorrespondencies: {
[CockpitModifierKeyOption.regular]: {
[JoystickButton.B0]: { action: modifierKeyActions.shift },
[JoystickButton.B1]: { action: availableMavlinkManualControlButtonFunctions['Mode manual'] },
[JoystickButton.B2]: { action: availableMavlinkManualControlButtonFunctions['Mode depth hold'] },
[JoystickButton.B3]: { action: availableMavlinkManualControlButtonFunctions['Mode stabilize'] },
[JoystickButton.B4]: { action: availableCockpitActions.go_to_previous_view },
[JoystickButton.B5]: { action: availableCockpitActions.go_to_next_view },
[JoystickButton.B6]: { action: availableMavlinkManualControlButtonFunctions['Mount tilt down'] },
[JoystickButton.B7]: { action: availableMavlinkManualControlButtonFunctions['Mount tilt up'] },
[JoystickButton.B8]: { action: availableMavlinkManualControlButtonFunctions['Disarm'] },
[JoystickButton.B9]: { action: availableMavlinkManualControlButtonFunctions['Arm'] },
[JoystickButton.B10]: { action: availableMavlinkManualControlButtonFunctions['Mount center'] },
[JoystickButton.B11]: { action: availableMavlinkManualControlButtonFunctions['Input hold set'] },
[JoystickButton.B12]: { action: availableMavlinkManualControlButtonFunctions['Gain inc'] },
[JoystickButton.B13]: { action: availableMavlinkManualControlButtonFunctions['Gain dec'] },
[JoystickButton.B14]: { action: availableMavlinkManualControlButtonFunctions['Lights1 dimmer'] },
[JoystickButton.B15]: { action: availableMavlinkManualControlButtonFunctions['Lights1 brighter'] },
[JoystickButton.B16]: { action: availableCockpitActions.toggle_bottom_bar },
[JoystickButton.B17]: { action: availableMavlinkManualControlButtonFunctions['Roll pitch toggle'] },
export const cockpitStandardToProtocols: JoystickProtocolActionsMapping[] = [
{
name: 'Default ROV functions mapping',
axesCorrespondencies: {
[JoystickAxis.A0]: { action: mavlinkManualControlAxes.axis_y, min: -1000, max: +1000 },
[JoystickAxis.A1]: { action: mavlinkManualControlAxes.axis_x, min: +1000, max: -1000 },
[JoystickAxis.A2]: { action: mavlinkManualControlAxes.axis_r, min: -1000, max: +1000 },
[JoystickAxis.A3]: { action: mavlinkManualControlAxes.axis_z, min: +1000, max: 0 },
},
[CockpitModifierKeyOption.shift]: {
[JoystickButton.B0]: { action: otherAvailableActions.no_function },
[JoystickButton.B1]: { action: otherAvailableActions.no_function },
[JoystickButton.B2]: { action: availableMavlinkManualControlButtonFunctions['Mode poshold'] },
[JoystickButton.B3]: { action: availableMavlinkManualControlButtonFunctions['Mode acro'] },
[JoystickButton.B4]: { action: otherAvailableActions.no_function },
[JoystickButton.B5]: { action: otherAvailableActions.no_function },
[JoystickButton.B6]: { action: availableMavlinkManualControlButtonFunctions['Servo 1 min'] },
[JoystickButton.B7]: { action: availableMavlinkManualControlButtonFunctions['Servo 1 max'] },
[JoystickButton.B8]: { action: otherAvailableActions.no_function },
[JoystickButton.B9]: { action: otherAvailableActions.no_function },
[JoystickButton.B10]: { action: availableMavlinkManualControlButtonFunctions['Relay 1 toggle'] },
[JoystickButton.B11]: { action: otherAvailableActions.no_function },
[JoystickButton.B12]: { action: availableMavlinkManualControlButtonFunctions['Trim pitch inc'] },
[JoystickButton.B13]: { action: availableMavlinkManualControlButtonFunctions['Trim pitch dec'] },
[JoystickButton.B14]: { action: availableMavlinkManualControlButtonFunctions['Trim roll dec'] },
[JoystickButton.B15]: { action: availableMavlinkManualControlButtonFunctions['Trim roll inc'] },
[JoystickButton.B16]: { action: otherAvailableActions.no_function },
[JoystickButton.B17]: { action: otherAvailableActions.no_function },
buttonsCorrespondencies: {
[CockpitModifierKeyOption.regular]: {
[JoystickButton.B0]: { action: modifierKeyActions.shift },
[JoystickButton.B1]: { action: availableMavlinkManualControlButtonFunctions['Mode manual'] },
[JoystickButton.B2]: { action: availableMavlinkManualControlButtonFunctions['Mode depth hold'] },
[JoystickButton.B3]: { action: availableMavlinkManualControlButtonFunctions['Mode stabilize'] },
[JoystickButton.B4]: { action: availableCockpitActions.go_to_previous_view },
[JoystickButton.B5]: { action: availableCockpitActions.go_to_next_view },
[JoystickButton.B6]: { action: availableMavlinkManualControlButtonFunctions['Mount tilt down'] },
[JoystickButton.B7]: { action: availableMavlinkManualControlButtonFunctions['Mount tilt up'] },
[JoystickButton.B8]: { action: availableMavlinkManualControlButtonFunctions['Disarm'] },
[JoystickButton.B9]: { action: availableMavlinkManualControlButtonFunctions['Arm'] },
[JoystickButton.B10]: { action: availableMavlinkManualControlButtonFunctions['Mount center'] },
[JoystickButton.B11]: { action: availableMavlinkManualControlButtonFunctions['Input hold set'] },
[JoystickButton.B12]: { action: availableMavlinkManualControlButtonFunctions['Gain inc'] },
[JoystickButton.B13]: { action: availableMavlinkManualControlButtonFunctions['Gain dec'] },
[JoystickButton.B14]: { action: availableMavlinkManualControlButtonFunctions['Lights1 dimmer'] },
[JoystickButton.B15]: { action: availableMavlinkManualControlButtonFunctions['Lights1 brighter'] },
[JoystickButton.B16]: { action: availableCockpitActions.toggle_bottom_bar },
[JoystickButton.B17]: { action: availableMavlinkManualControlButtonFunctions['Roll pitch toggle'] },
},
[CockpitModifierKeyOption.shift]: {
[JoystickButton.B0]: { action: otherAvailableActions.no_function },
[JoystickButton.B1]: { action: otherAvailableActions.no_function },
[JoystickButton.B2]: { action: availableMavlinkManualControlButtonFunctions['Mode poshold'] },
[JoystickButton.B3]: { action: availableMavlinkManualControlButtonFunctions['Mode acro'] },
[JoystickButton.B4]: { action: otherAvailableActions.no_function },
[JoystickButton.B5]: { action: otherAvailableActions.no_function },
[JoystickButton.B6]: { action: availableMavlinkManualControlButtonFunctions['Servo 1 min'] },
[JoystickButton.B7]: { action: availableMavlinkManualControlButtonFunctions['Servo 1 max'] },
[JoystickButton.B8]: { action: otherAvailableActions.no_function },
[JoystickButton.B9]: { action: otherAvailableActions.no_function },
[JoystickButton.B10]: { action: availableMavlinkManualControlButtonFunctions['Relay 1 toggle'] },
[JoystickButton.B11]: { action: otherAvailableActions.no_function },
[JoystickButton.B12]: { action: availableMavlinkManualControlButtonFunctions['Trim pitch inc'] },
[JoystickButton.B13]: { action: availableMavlinkManualControlButtonFunctions['Trim pitch dec'] },
[JoystickButton.B14]: { action: availableMavlinkManualControlButtonFunctions['Trim roll dec'] },
[JoystickButton.B15]: { action: availableMavlinkManualControlButtonFunctions['Trim roll inc'] },
[JoystickButton.B16]: { action: otherAvailableActions.no_function },
[JoystickButton.B17]: { action: otherAvailableActions.no_function },
},
},
},
}
]

/**
* Follows the standard controller in the Gamepad API: https://www.w3.org/TR/gamepad/#dfn-standard-gamepad
Expand Down
36 changes: 31 additions & 5 deletions src/stores/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useStorage } from '@vueuse/core'
import { saveAs } from 'file-saver'
import { defineStore } from 'pinia'
import Swal from 'sweetalert2'
import { ref } from 'vue'
import { computed, ref } from 'vue'

import { availableGamepadToCockpitMaps, cockpitStandardToProtocols } from '@/assets/joystick-profiles'
import { getKeyDataFromCockpitVehicleStorage, setKeyDataOnCockpitVehicleStorage } from '@/libs/blueos'
Expand All @@ -26,18 +26,42 @@ export type controllerUpdateCallback = (
activeButtonActions: ProtocolAction[]
) => void

const protocolMappingKey = 'cockpit-protocol-mapping-v5'
const protocolMappingsKey = 'cockpit-protocol-mappings-v1'
const protocolMappingIndexKey = 'cockpit-protocol-mapping-index-v1'
const cockpitStdMappingsKey = 'cockpit-standard-mappings-v2'

export const useControllerStore = defineStore('controller', () => {
const joysticks = ref<Map<number, Joystick>>(new Map())
const updateCallbacks = ref<controllerUpdateCallback[]>([])
const protocolMapping = useStorage(protocolMappingKey, cockpitStandardToProtocols)
const protocolMappings = useStorage(protocolMappingsKey, cockpitStandardToProtocols)
const protocolMappingIndex = useStorage(protocolMappingIndexKey, 0)
const cockpitStdMappings = useStorage(cockpitStdMappingsKey, availableGamepadToCockpitMaps)
const availableAxesActions = allAvailableAxes
const availableButtonActions = allAvailableButtons
const enableForwarding = ref(true)

const protocolMapping = computed<JoystickProtocolActionsMapping>({
get() {
return protocolMappings.value[protocolMappingIndex.value]
},
set(newValue) {
protocolMappings.value[protocolMappingIndex.value] = newValue
},
})

/**
* Change current protocol mapping for given one
* @param { JoystickProtocolActionsMapping } mapping - The functions mapping to be loaded
*/
const loadProtocolMapping = (mapping: JoystickProtocolActionsMapping): void => {
const mappingIndex = protocolMappings.value.findIndex((p) => p.name === mapping.name)
if (mappingIndex === -1) {
Swal.fire({ icon: 'error', text: 'Could not find mapping.', timer: 3000 })
return
}
protocolMappingIndex.value = mappingIndex
}

const registerControllerUpdateCallback = (callback: controllerUpdateCallback): void => {
updateCallbacks.value.push(callback)
}
Expand Down Expand Up @@ -222,12 +246,12 @@ export const useControllerStore = defineStore('controller', () => {
vehicleAddress: string,
functionsMapping: JoystickProtocolActionsMapping
): Promise<void> => {
await setKeyDataOnCockpitVehicleStorage(vehicleAddress, protocolMappingKey, functionsMapping)
await setKeyDataOnCockpitVehicleStorage(vehicleAddress, protocolMappingsKey, functionsMapping)
Swal.fire({ icon: 'success', text: 'Joystick functions mapping exported to vehicle.', timer: 3000 })
}

const importFunctionsMappingFromVehicle = async (vehicleAddress: string): Promise<void> => {
const newMapping = await getKeyDataFromCockpitVehicleStorage(vehicleAddress, protocolMappingKey)
const newMapping = await getKeyDataFromCockpitVehicleStorage(vehicleAddress, protocolMappingsKey)
if (
!newMapping ||
!newMapping['name'] ||
Expand All @@ -247,9 +271,11 @@ export const useControllerStore = defineStore('controller', () => {
enableForwarding,
joysticks,
protocolMapping,
protocolMappings,
cockpitStdMappings,
availableAxesActions,
availableButtonActions,
loadProtocolMapping,
exportJoystickMapping,
importJoystickMapping,
exportJoysticksMappingsToVehicle,
Expand Down
11 changes: 11 additions & 0 deletions src/views/ConfigurationJoystickView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@
<p>Could not stablish communication with the vehicle.</p>
<p>Button functions will appear as numbers. If connection is restablished, function names will appear.</p>
</div>
<div v-if="availableModifierKeys" class="flex items-center px-5 py-3 m-5 font-bold border rounded-md">
<Button
v-for="functionMapping in controllerStore.protocolMappings"
:key="functionMapping.name"
class="m-2"
:class="{ 'bg-slate-700': controllerStore.protocolMapping.name === functionMapping.name }"
@click="controllerStore.loadProtocolMapping(functionMapping)"
>
{{ functionMapping.name }}
</Button>
</div>
<div class="flex items-center px-5 py-3 m-5 font-bold border rounded-md">
<Button
v-for="key in availableModifierKeys"
Expand Down

0 comments on commit 83b5107

Please sign in to comment.