Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions core/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"dev": "vite --host",
"build": "NODE_ENV=production vite build",
"serve": "echo 'This is a preview server for testing the built website. Please use `dev` command over `serve`.\nStarting preview server in 5 seconds..\n';sleep 5; vite preview",
"test:parameter-metadata": "esbuild tests/parameter-metadata.spec.ts --bundle --platform=node --format=cjs --outfile=/tmp/blueos-parameter-metadata-test.cjs && node --test /tmp/blueos-parameter-metadata-test.cjs",
"test:mavlink2rest-compat": "esbuild tests/mavlink2rest-compat.spec.ts --bundle --platform=node --format=cjs --outfile=/tmp/blueos-mavlink2rest-compat-test.cjs && node --test /tmp/blueos-mavlink2rest-compat-test.cjs",
"lint": "eslint --max-warnings=0 --ext .js,.vue --ignore-path .gitignore --ignore-pattern src/components/vue-tour src && stylelint 'src/**/*.{vue,css,scss}'",
"lint:css": "stylelint 'src/**/*.{vue,css,scss}'",
"lint:css:fix": "stylelint 'src/**/*.{vue,css,scss}' --fix"
Expand Down
3 changes: 2 additions & 1 deletion core/frontend/src/components/common/StatusTextWatcher.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<script lang="ts">
import mavlink2rest from '@/libs/MAVLink2Rest'
import Listener from '@/libs/MAVLink2Rest/Listener'
import { mavlinkString } from '@/utils/mavlink2rest_compat'

export default {
name: 'StatusTextWatcher',
Expand All @@ -27,7 +28,7 @@ export default {
},
mounted() {
this.listener = mavlink2rest.startListening('STATUSTEXT').setCallback((receivedMessage) => {
const text = receivedMessage.message.text.join('')
const text = mavlinkString(receivedMessage.message.text)
if (this.messages?.last() === text) {
return
}
Expand Down
7 changes: 6 additions & 1 deletion core/frontend/src/components/health/HealthTrayMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ import * as DEFAULT_COLORS from '@/style/colors/default'
import { RaspberryEventType } from '@/types/system-information/platform'
import { Disk } from '@/types/system-information/system'
import mavlink_store_get from '@/utils/mavlink'
import { mavlinkFlagEnabled } from '@/utils/mavlink2rest_compat'

const FETCH_TYPES = [
FetchType.SystemTemperatureType,
Expand Down Expand Up @@ -198,7 +199,11 @@ export default Vue.extend({
}
autopilot_data.setSystemId(message?.header.system_id)
autopilot_data.setAutopilotType(message?.message.autopilot.type)
autopilot_data.setVehicleArmed(Boolean(message?.message.base_mode.bits & MavModeFlag.MAV_MODE_FLAG_SAFETY_ARMED))
autopilot_data.setVehicleArmed(mavlinkFlagEnabled(
message?.message.base_mode,
'MAV_MODE_FLAG_SAFETY_ARMED',
MavModeFlag.MAV_MODE_FLAG_SAFETY_ARMED,
))
autopilot_data.setLastHeartbeatDate(new Date())
}).setFrequency(0))
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ import Fuse from 'fuse.js'
import Vue from 'vue'

import mavlink2rest from '@/libs/MAVLink2Rest'
import autopilot_data from '@/store/autopilot'
import autopilot_data, { refreshParameterMetadata } from '@/store/autopilot'
import autopilot from '@/store/autopilot_manager'
import Parameter, { printParam } from '@/types/autopilot/parameter'
import { Dictionary } from '@/types/common'
Expand Down Expand Up @@ -229,6 +229,9 @@ export default Vue.extend({
}
},
},
async mounted() {
await refreshParameterMetadata()
},
methods: {
setDefaultParamValue(param: Parameter) {
if (param.default === undefined || param.readonly) {
Expand Down
38 changes: 32 additions & 6 deletions core/frontend/src/components/parameter-editor/ParameterLoader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@
</span>
</v-tooltip>
</v-card-title>
<v-card-text v-if="different_param_set_length !== 0" height="80%">
<v-card-text
v-if="different_param_set_length !== 0 && !(write_finished && initial_size > 0)"
height="80%"
>
<v-row class="virtual-table-row">
<v-col class="virtual-table-cell checkbox-cell">
<v-checkbox
Expand Down Expand Up @@ -127,7 +130,10 @@
<v-alert
type="success"
>
Parameters written successfully
Parameter loading complete
<div v-if="skipped_params_length">
{{ skipped_params_length }} rejected parameter values were skipped.
</div>
</v-alert>
</v-card-text>
<v-card-text v-else>
Expand Down Expand Up @@ -186,6 +192,7 @@ export default Vue.extend({
should_open: false,
error: false as boolean | string,
writing: false,
skipped_params: {} as Dictionary<boolean>,
}),
computed: {
progress(): number {
Expand All @@ -209,6 +216,9 @@ export default Vue.extend({
write_finished(): boolean {
return this.user_selected_params_length === 0
},
skipped_params_length(): number {
return Object.keys(this.skipped_params).length
},
},
watch: {
param_checkboxes: {
Expand All @@ -226,11 +236,17 @@ export default Vue.extend({
},
},
},
beforeDestroy() {
clearInterval(this.retry_interval)
},
methods: {
done() {
clearInterval(this.retry_interval)
this.retry_interval = 0
this.$emit('done')
this.error = false
this.retries = 0
this.skipped_params = {}
setTimeout(() => {
// delay this as the dialog is still open when the done event is emitted
// which causes the text to change during the close animation
Expand All @@ -246,21 +262,30 @@ export default Vue.extend({
}
},
writeParams() {
clearInterval(this.retry_interval)
this.retry_interval = 0
this.writing = true
this.error = false
this.retries = 0
this.skipped_params = {}
this.initial_size = this.user_selected_params_length
this.writeSelectedParams()
this.retry_interval = setInterval(() => {
if (this.user_selected_params_length) {
this.retries += 1
if (this.retries > 5) {
clearInterval(this.retry_interval)
this.retry_interval = 0
for (const name of Object.keys(this.user_selected_params)) {
Vue.set(this.skipped_params, name, true)
}
this.retries = 0
this.error = 'Failed to write some parameters. Please restart the vehicle and try again.'
return
}
this.writeSelectedParams()
} else {
clearInterval(this.retry_interval)
this.retry_interval = 0
}
}, 1000)
},
Expand All @@ -273,7 +298,8 @@ export default Vue.extend({
}
},
writeParam(name: string, value: number) {
mavlink2rest.setParam(name, value, autopilot_data.system_id)
const parameter_type = autopilot_data.parameter(name)?.paramType.type
mavlink2rest.setParam(name, value, autopilot_data.system_id, parameter_type)
},
filterParamsByReadOnly(params: Dictionary<number>): Dictionary<number> {
return Object.fromEntries(
Expand All @@ -288,15 +314,15 @@ export default Vue.extend({
Object.entries(params).filter(([name, value]) => {
const param = autopilot_data.parameter(name)
if (!param) {
return true
return false
}
return Math.abs(param.value - value) > 0.0001
}),
)
},
filterParamsBySelection(params: Dictionary<number>): Dictionary<number> {
return Object.fromEntries(
Object.entries(params).filter(([name]) => this.param_checkboxes[name]),
Object.entries(params).filter(([name]) => this.param_checkboxes[name] && !this.skipped_params[name]),
)
},
updateSelectAllStatus() {
Expand Down
19 changes: 16 additions & 3 deletions core/frontend/src/components/vehiclesetup/PwmSetup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ import { SERVO_FUNCTION } from '@/types/autopilot/parameter-sub-enums'
import { Dictionary } from '@/types/common'
import { armDisarm, doMotorTest } from '@/utils/ardupilot_mavlink'
import mavlink_store_get from '@/utils/mavlink'
import { mavlinkFlagEnabled } from '@/utils/mavlink2rest_compat'
import { servoNumberToGpio } from '@/utils/servoGpio'

import ParameterSwitch from '../common/ParameterSwitch.vue'
Expand Down Expand Up @@ -335,7 +336,11 @@ export default Vue.extend({
this.vehicle_id,
1,
) as Message.Heartbeat
return Boolean(heartbeat?.base_mode.bits & MavModeFlag.MAV_MODE_FLAG_SAFETY_ARMED)
return mavlinkFlagEnabled(
heartbeat?.base_mode,
'MAV_MODE_FLAG_SAFETY_ARMED',
MavModeFlag.MAV_MODE_FLAG_SAFETY_ARMED,
)
},
is_manual(): boolean {
const heartbeat = mavlink_store_get(
Expand All @@ -346,8 +351,16 @@ export default Vue.extend({
) as Message.Heartbeat

// Legacy manual mode
if (!(heartbeat?.base_mode.bits & MavModeFlag.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED)) {
return Boolean(heartbeat?.base_mode.bits & MavModeFlag.MAV_MODE_FLAG_MANUAL_INPUT_ENABLED)
if (!mavlinkFlagEnabled(
heartbeat?.base_mode,
'MAV_MODE_FLAG_CUSTOM_MODE_ENABLED',
MavModeFlag.MAV_MODE_FLAG_CUSTOM_MODE_ENABLED,
)) {
return mavlinkFlagEnabled(
heartbeat?.base_mode,
'MAV_MODE_FLAG_MANUAL_INPUT_ENABLED',
MavModeFlag.MAV_MODE_FLAG_MANUAL_INPUT_ENABLED,
)
}

if (this.is_rover) {
Expand Down
7 changes: 1 addition & 6 deletions core/frontend/src/libs/MAVLink2Rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,6 @@ class Mavlink2RestManager {
* @param {string} type Valid mavlink parameter type based on mavlink2rest
*/
setParam(name: string, value: number, sysid: number, type?: string): void {
const param_name = [...name]
while (param_name.length < 16) {
param_name.push('\0')
}

this.sendMessageViaWebsocket({
header: {
system_id: 255,
Expand All @@ -257,7 +252,7 @@ class Mavlink2RestManager {
param_value: value,
target_system: sysid,
target_component: 0,
param_id: param_name,
param_id: name,
param_type: {
type: type ?? 'MAV_PARAM_TYPE_UINT8',
},
Expand Down
5 changes: 5 additions & 0 deletions core/frontend/src/store/autopilot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,9 @@ export { AutopilotStore }

const autopilot_data: AutopilotStore = getModule(AutopilotStore)
parameterFetcher.setStore(autopilot_data)

export async function refreshParameterMetadata(): Promise<void> {
await parameterFetcher.refreshParameterMetadata()
}

export default autopilot_data
12 changes: 8 additions & 4 deletions core/frontend/src/types/autopilot/parameter-fetcher.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import mavlink2rest from '@/libs/MAVLink2Rest'
// eslint-disable-next-line import/no-cycle
import ardupilot_data from '@/store/autopilot'
import { AutopilotStore } from '@/store/autopilot'
import ardupilot_data, { AutopilotStore } from '@/store/autopilot'
import autopilot from '@/store/autopilot_manager'
import { mavlinkString } from '@/utils/mavlink2rest_compat'

import ParametersTable from './parameter-table'
import autopilot from '@/store/autopilot_manager'

export default class ParameterFetcher {
parameter_table = new ParametersTable()
Expand Down Expand Up @@ -56,6 +56,10 @@ export default class ParameterFetcher {
}
}

async refreshParameterMetadata(): Promise<void> {
if (await this.parameter_table.refreshComponentMetadata()) this.updateStore()
}

requestParamsWatchdog(): void {
if (this.total_params_count !== null
&& this.loaded_params_count > 0
Expand Down Expand Up @@ -102,7 +106,7 @@ export default class ParameterFetcher {
this.reset_timestamp = 0
}

const param_name = receivedMessage.message.param_id.join('').replace(/\0/g, '')
const param_name = mavlinkString(receivedMessage.message.param_id)
const { param_index, param_value, param_type } = receivedMessage.message
// We need this due to mismatches between js 64-bit floats and REAL32 in MAVLink
const trimmed_value = Math.round(param_value * 10000) / 10000
Expand Down
Loading