Skip to content

Commit 6cc37db

Browse files
frontend: add relay configuration to vehicle setup
1 parent 7e237f2 commit 6cc37db

File tree

3 files changed

+145
-8
lines changed

3 files changed

+145
-8
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<template>
2+
<v-card class="mt-4 mb-4">
3+
<v-card-text>
4+
<v-row align="center">
5+
<v-col cols="6">
6+
<span class="text-h6">Relay {{ relay_number }}</span>
7+
</v-col>
8+
<v-col cols="6" class="d-flex justify-end">
9+
<v-btn
10+
v-tooltip="'Turn relay off'"
11+
small
12+
@click="setRelay(0)"
13+
>
14+
<v-icon small left>mdi-power-off</v-icon>
15+
Relay Off
16+
</v-btn>
17+
<v-btn
18+
v-tooltip="'Turn relay on'"
19+
small
20+
@click="setRelay(1)"
21+
>
22+
<v-icon small left>mdi-power</v-icon>
23+
Relay On
24+
</v-btn>
25+
</v-col>
26+
</v-row>
27+
28+
<v-row align="center">
29+
30+
<v-col cols="6" class="pa0">
31+
<parameter-switch
32+
v-if="inverted_parameter"
33+
:parameter="inverted_parameter"
34+
:off-value="0"
35+
:on-value="1"
36+
label="Invert Output"
37+
/>
38+
</v-col>
39+
<v-col cols="6" class="pa0">
40+
<parameter-switch
41+
v-if="default_parameter"
42+
:parameter="default_parameter"
43+
:off-value="0"
44+
:on-value="1"
45+
label="Startup State"
46+
/>
47+
</v-col>
48+
</v-row>
49+
</v-card-text>
50+
</v-card>
51+
</template>
52+
53+
<script lang="ts">
54+
import Vue from 'vue'
55+
56+
import mavlink2rest from '@/libs/MAVLink2Rest'
57+
import { MavCmd } from '@/libs/MAVLink2Rest/mavlink2rest-ts/messages/mavlink2rest-enum'
58+
import Parameter from '@/types/autopilot/parameter'
59+
import autopilot_data from '@/store/autopilot';
60+
61+
export default Vue.extend({
62+
name: 'RelaySetup',
63+
props: {
64+
relay_parameter: {
65+
type: Object as () => Parameter,
66+
required: true,
67+
},
68+
},
69+
computed: {
70+
relay_number(): number {
71+
return parseInt(this.relay_parameter.name.match(/RELAY(\d+)_FUNCTION/)?.[1] ?? '0', 10)
72+
},
73+
inverted_parameter(): Parameter | undefined {
74+
return autopilot_data.parameter(`RELAY${this.relay_number}_INVERTED`)
75+
},
76+
default_parameter(): Parameter | undefined {
77+
return autopilot_data.parameter(`RELAY${this.relay_number}_DEFAULT`)
78+
},
79+
},
80+
methods: {
81+
setRelay(setting: number): void {
82+
// MAV_CMD_DO_SET_RELAY: param1 = relay instance (0-indexed), param2 = setting (0=off, 1=on, 2=toggle)
83+
mavlink2rest.sendCommandLong(
84+
MavCmd.MAV_CMD_DO_SET_RELAY,
85+
this.relay_number - 1, // Convert to 0-indexed relay instance
86+
setting,
87+
)
88+
},
89+
},
90+
})
91+
</script>
92+

core/frontend/src/components/parameter-editor/ServoFunctionGpioEditor.vue

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<template>
22
<div class="align-center">
3-
GPIOs can be used for Relays, Leak detection, and other functions not yet supported by this UI.
4-
This servo ({{ servo_number }}) gpio is {{ this_servo_gpio }}.
5-
6-
In use by {{ function_type_using_this_gpio?.name }}
7-
3+
<p>
4+
Some flight controller servo channels are capable of digital (GPIO) functionalities. Available options include relays, leak detection (input-capable pins only), and other functions not yet supported by this UI.
5+
</p>
6+
<p>
7+
This servo's GPIO (<strong>{{ this_servo_gpio }}</strong>) is currently in use by
8+
<strong>{{ function_type_using_this_gpio?.name ?? 'nothing' }}</strong>.
9+
</p>
810
<v-row align="end">
911
<v-col cols="6">
10-
<span style="font-size: 1.0rem;">Change function for this servo's GPIO</span>
12+
<span style="font-size: 1.0rem;">GPIO Function:</span>
1113
</v-col>
1214
<v-col cols="6">
1315
<v-select
@@ -21,6 +23,10 @@
2123
/>
2224
</v-col>
2325
</v-row>
26+
<relay-setup
27+
v-if="function_type_using_this_gpio?.name?.includes('RELAY')"
28+
:relay_parameter="function_type_using_this_gpio"
29+
/>
2430

2531
</div>
2632
</template>

core/frontend/src/components/vehiclesetup/PwmSetup.vue

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
<td v-tooltip="item.name">
137137
{{ convert_servo_name(item.name) }}
138138
</td>
139-
<td>{{ stringToUserFriendlyText(printParam(item)) }}</td>
139+
<td>{{ parameterToUserFriendlyText(item) }}</td>
140140
<td>{{ servo_output[index] }}</td>
141141
</tr>
142142
</tbody>
@@ -173,7 +173,7 @@ import { SERVO_FUNCTION } from '@/types/autopilot/parameter-sub-enums'
173173
import { Dictionary } from '@/types/common'
174174
import { armDisarm, doMotorTest } from '@/utils/ardupilot_mavlink'
175175
import mavlink_store_get from '@/utils/mavlink'
176-
176+
import { fetchCurrentBoard } from '@/components/autopilot/AutopilotManagerUpdater'
177177
import ParameterSwitch from '../common/ParameterSwitch.vue'
178178
179179
interface MotorTestTarget {
@@ -376,6 +376,30 @@ export default Vue.extend({
376376
return output
377377
.map((_, i) => data[`servo${i + 1}_raw`])
378378
},
379+
board_name(): string | undefined {
380+
return autopilot.current_board?.name
381+
},
382+
gpio_to_parameter(): Record<number, Parameter> {
383+
return Object.fromEntries(
384+
autopilot_data.parameterRegex('^.*_PIN$')
385+
.map((param) => [param.value, param])
386+
)
387+
},
388+
servo_to_gpio(): Record<number, number> {
389+
const isNavigator = this.board_name?.includes('Navigator')
390+
return Object.fromEntries(
391+
Array.from({ length: 16 }, (_, i) => {
392+
const servo = i + 1
393+
if (isNavigator) {
394+
return [servo, servo]
395+
}
396+
if (servo <= 8) {
397+
return [servo, servo + 100]
398+
}
399+
return [servo, servo - 9 + 50]
400+
})
401+
)
402+
},
379403
},
380404
watch: {
381405
is_armed() {
@@ -392,6 +416,8 @@ export default Vue.extend({
392416
mounted() {
393417
this.motor_zeroer_interval = setInterval(this.zero_motors, 300)
394418
this.motor_writer_interval = setInterval(this.write_motors, 100)
419+
fetchCurrentBoard()
420+
395421
mavlink.setMessageRefreshRate({ messageName: 'SERVO_OUTPUT_RAW', refreshRate: 10 })
396422
this.desired_armed_state = this.is_armed
397423
this.installListeners()
@@ -455,6 +481,19 @@ export default Vue.extend({
455481
this.selected_param = param
456482
this.edit_param_dialog = true
457483
},
484+
parameterToUserFriendlyText(param: Parameter): string {
485+
if (param.value === -1) { // GPIO
486+
const servo_number = parseInt(/\d+/g.exec(param.name)?.[0] ?? '0', 10)
487+
const gpio = this.servo_to_gpio[servo_number]
488+
const param_using_this_gpio = this.gpio_to_parameter[gpio]
489+
if (param_using_this_gpio) {
490+
const pretty_name = param_using_this_gpio.name.split('_')[0].toLowerCase().toTitle()
491+
return `GPIO [${pretty_name}]`
492+
}
493+
return `Unknown GPIO ${gpio}`
494+
}
495+
return this.stringToUserFriendlyText(printParam(param))
496+
},
458497
stringToUserFriendlyText(text: string) {
459498
return param_value_map?.[this.vehicle_type ?? '']?.[text] ?? text
460499
},

0 commit comments

Comments
 (0)