From 9d8cbea57e462fc4cd703ad83a72292b77e75fe4 Mon Sep 17 00:00:00 2001 From: Medlin Drone Date: Thu, 7 Sep 2023 10:51:37 -0400 Subject: [PATCH] Adding Configurator support for the Camera Angle Reference OSD feature This is an OSD visual reference for current camera angle (open to name changes) intended to be used with a single axis tilt gimbal, like those shown on medlindrone.com For 'Camera Angle Reference' there are five new cli parameters: -osd_car_pos (osd element position) -osd_car_channel (channel controlling the gimbal/car) -osd_car_scale (scale for adjusting vertical scale/sensitivity) -osd_car_width (width for adjusting witdh between dots) -osd_car_dots (number of dots on each side) For 'Camera Angle Reference Sidebar' there are seven new cli parameters: -osd_car_sbar_pos; (osd element position) -osd_car_sbar_scale; (scale for adjusting vertical scale) -osd_car_sbar_low; (angle 1/5) -osd_car_sbar_mid_low; (angle 2/5) -osd_car_sbar_mid; (angle 3/5) -osd_car_sbar_mid_high; (angle 4/5) -osd_car_sbar_high; (angle 5/5) Added UI in OSD tab to changes CLI values, "Camera Angle Reference' section on right side --- locales/en/messages.json | 61 +++++++++++++++++++++++++++++++++- src/css/tabs/osd.less | 24 ++++++++++++++ src/js/VirtualFC.js | 12 +++++++ src/js/tabs/osd.js | 70 +++++++++++++++++++++++++++++++++++++++- src/tabs/osd.html | 8 +++++ 5 files changed, 173 insertions(+), 2 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 0e70dfe512..31229bea79 100755 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -5110,6 +5110,9 @@ "osdSetupAlarmsTitle": { "message": "Alarms" }, + "osdSetupCarTitle": { + "message": "Camera Angle Reference" + }, "osdSetupStatsTitle": { "message": "Post Flight Statistics" }, @@ -5290,6 +5293,20 @@ "osdDescElementHorizonSidebars": { "message": "Sidebars around artificial horizon indicator" }, + "osdTextElementCameraAngleReference": { + "message": "Camera Angle Reference", + "description": "One of the elements of the OSD" + }, + "osdDescElementCameraAngleReference": { + "message": "Camera angle reference for flying with FPV tilt gimbal" + }, + "osdTextElementCameraAngleReferenceSidebar": { + "message": "Camera Angle Reference Sidebar", + "description": "One of the elements of the OSD" + }, + "osdDescElementCameraAngleReferenceSidebar": { + "message": "Sidebar for Camera angle reference" + }, "osdTextElementCurrentDraw": { "message": "Battery current draw", "description": "One of the elements of the OSD" @@ -6164,7 +6181,46 @@ "message": "Altitude", "description": "Text of the altitude alarm" }, - + "osdCarOptionScale": { + "message": "Scale", + "description": "Scale" + }, + "osdCarOptionWidth": { + "message": "Width", + "description": "Width" + }, + "osdCarOptionChannel": { + "message": "Channel", + "description": "Channel" + }, + "osdCarOptionDots": { + "message": "Dots", + "description": "Dots" + }, + "osdCarOptionSbarScale": { + "message": "Sidebar Scale", + "description": "Sidebar Scale" + }, + "osdCarOptionSbarLow": { + "message": "Sidebar Angle 1/5", + "description": "Sidebar Scale" + }, + "osdCarOptionSbarMidLow": { + "message": "Sidebar Angle 2/5", + "description": "Sidebar Scale" + }, + "osdCarOptionSbarMid": { + "message": "Sidebar Angle 3/5", + "description": "Sidebar Scale" + }, + "osdCarOptionSbarMidHigh": { + "message": "Sidebar Angle 4/5", + "description": "Sidebar Scale" + }, + "osdCarOptionSbarHigh": { + "message": "Sidebar Angle 5/5", + "description": "Sidebar Scale" + }, "osdWarningTextArmingDisabled": { "message": "Arming disabled", "description": "One of the warnings that can be selected to be shown in the OSD" @@ -6313,6 +6369,9 @@ "osdSectionHelpAlarms": { "message": "Set the thresholds used for OSD elements with alarm states." }, + "osdSectionHelpCar": { + "message": "Set the Camera Angle Reference parameter values" + }, "osdSectionHelpStats": { "message": "Set the values dispalyed on the post flight statistics screen." }, diff --git a/src/css/tabs/osd.less b/src/css/tabs/osd.less index ad117da697..f810b78d71 100644 --- a/src/css/tabs/osd.less +++ b/src/css/tabs/osd.less @@ -347,6 +347,30 @@ font-weight: normal; } } + .car { + label { + display: block; + width: 100%; + border-bottom: 1px solid var(--subtleAccent); + margin-top: 5px; + padding-bottom: 5px; + &:last-child { + border-bottom: none; + padding-bottom: 0; + } + } + input { + width: 55px; + padding-left: 3px; + height: 18px; + line-height: 20px; + text-align: left; + border-radius: 3px; + margin-right: 11px; + font-size: 11px; + font-weight: normal; + } + } .grid-row { justify-content: flex-start; gap: 7px; diff --git a/src/js/VirtualFC.js b/src/js/VirtualFC.js index ef11818891..205bee2c15 100644 --- a/src/js/VirtualFC.js +++ b/src/js/VirtualFC.js @@ -233,6 +233,18 @@ const VirtualFC = { alt: { display_name: i18n.getMessage('osdTimerAlarmOptionAltitude'), value: 0 }, time: { display_name: 'Minutes', value: 0 }, }; + virtualOSD.data.car = { + scale: { display_name: i18n.getMessage('osdCarOptionScale'), value: 0 }, + width: { display_name: i18n.getMessage('osdCarOptionWidth'), value: 0 }, + channel: { display_name: i18n.getMessage('osdCarOptionChannel'), value: 0 }, + dots: { display_name: i18n.getMessage('osdCarOptionDots'), value: 0 }, + sbar_scale: { display_name: i18n.getMessage('osdCarOptionSbarScale'), value: 0 }, + sbar_low: { display_name: i18n.getMessage('osdCarOptionSbarLow'), value: 0 }, + sbar_mid_low: { display_name: i18n.getMessage('osdCarOptionSbarMidLow'), value: 0 }, + sbar_mid: { display_name: i18n.getMessage('osdCarOptionSbarMid'), value: 0 }, + sbar_mid_high: { display_name: i18n.getMessage('osdCarOptionSbarMidHigh'), value: 0 }, + sbar_high: { display_name: i18n.getMessage('osdCarOptionSbarHigh'), value: 0 }, + }; }, }; diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 67ab4b03bf..8f4391559a 100644 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -309,6 +309,7 @@ OSD.initData = function() { video_system: null, unit_mode: null, alarms: [], + car: [], statItems: [], warnings: [], displayItems: [], @@ -1536,6 +1537,24 @@ OSD.loadDisplayFields = function() { positionable: true, preview: '1:23.456', }, + CAM_ANGLE_REFERENCE: { + name: 'CAM_ANGLE_REFERENCE', + text: 'osdTextElementCameraAngleReference', + desc: 'osdDescElementCameraAngleReference', + defaultPosition: -1, + draw_order: 555, + positionable: true, + preview: '***CAR***', + }, + CAM_ANGLE_REFERENCE_SBAR: { + name: 'CAM_ANGLE_REFERENCE_SBAR', + text: 'osdTextElementCameraAngleReferenceSidebar', + desc: 'osdDescElementCameraAngleReferenceSidebar', + defaultPosition: -1, + draw_order: 560, + positionable: true, + preview: '***SBR***||', + }, }; }; @@ -1970,6 +1989,8 @@ OSD.chooseFields = function() { F.GPS_LAP_TIME_CURRENT, F.GPS_LAP_TIME_PREVIOUS, F.GPS_LAP_TIME_BEST3, + F.CAM_ANGLE_REFERENCE, + F.CAM_ANGLE_REFERENCE_SBAR, ]); } @@ -2188,6 +2209,7 @@ OSD.msp = { result.push16(OSD.data.alarms.cap.value); result.push16(0); // This value is unused by the firmware with configurable timers result.push16(OSD.data.alarms.alt.value); + let warningFlags = 0; for (let i = 0; i < OSD.data.warnings.length; i++) { @@ -2212,6 +2234,19 @@ OSD.msp = { result.push8(OSD.data.parameters.cameraFrameWidth); result.push8(OSD.data.parameters.cameraFrameHeight); } + if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) { + result.push8(OSD.data.car.scale.value); + result.push8(OSD.data.car.width.value); + result.push8(OSD.data.car.channel.value); + result.push8(OSD.data.car.dots.value); + + result.push8(OSD.data.car.sbar_scale.value); + result.push8(OSD.data.car.sbar_low.value); + result.push8(OSD.data.car.sbar_mid_low.value); + result.push8(OSD.data.car.sbar_mid.value); + result.push8(OSD.data.car.sbar_mid_high.value); + result.push8(OSD.data.car.sbar_high.value); + } } return result; }, @@ -2304,7 +2339,7 @@ OSD.msp = { d.alarms['alt'] = { display_name: i18n.getMessage('osdTimerAlarmOptionAltitude'), value: view.readU16() }; } } - + d.state = {}; d.state.haveSomeOsd = (d.flags !== 0); d.state.haveMax7456Configured = bit_check(d.flags, 4); @@ -2424,6 +2459,22 @@ OSD.msp = { d.parameters.cameraFrameHeight = view.readU8(); } + if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_46)) { + d.car = {}; + d.car['scale'] = { display_name: i18n.getMessage('osdCarOptionScale'), value: view.readU8() }; + d.car['width'] = { display_name: i18n.getMessage('osdCarOptionWidth'), value: view.readU8() }; + d.car['channel'] = { display_name: i18n.getMessage('osdCarOptionChannel'), value: view.readU8() }; + d.car['dots'] = { display_name: i18n.getMessage('osdCarOptionDots'), value: view.readU8() }; + + d.car['sbar_scale'] = { display_name: i18n.getMessage('osdCarOptionSbarScale'), value: view.readU8() }; + d.car['sbar_low'] = { display_name: i18n.getMessage('osdCarOptionSbarLow'), value: view.readU8() }; + d.car['sbar_mid_low'] = { display_name: i18n.getMessage('osdCarOptionSbarMidLow'), value: view.readU8() }; + d.car['sbar_mid'] = { display_name: i18n.getMessage('osdCarOptionSbarMid'), value: view.readU8() }; + d.car['sbar_mid_high'] = { display_name: i18n.getMessage('osdCarOptionSbarMidHigh'), value: view.readU8() }; + d.car['sbar_high'] = { display_name: i18n.getMessage('osdCarOptionSbarHigh'), value: view.readU8() }; + + } + this.processOsdElements(d, itemsPositionsRead); OSD.updateDisplaySize(); @@ -2684,6 +2735,7 @@ osd.initialize = function(callback) { $('.units-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpUnits')); $('.timers-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpTimers')); $('.alarms-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpAlarms')); + $('.car-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpCar')); $('.stats-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpStats')); $('.warnings-container div.cf_tip').attr('title', i18n.getMessage('osdSectionHelpWarnings')); @@ -2802,6 +2854,22 @@ osd.initialize = function(callback) { $alarms.append($input); } + // Camera Angle Reference + $('.car-container').show(); + const $car = $('.car').empty(); + for (const k in OSD.data.car) { + const car = OSD.data.car[k]; + const carInput = $(`${car.display_name}`); + carInput.val(car.value); + carInput.focusout(function() { + OSD.data.car[$(this)[0].id].value = $(this)[0].value; + MSP.promise(MSPCodes.MSP_SET_OSD_CONFIG, OSD.msp.encodeOther()) + .then(updateOsdView); + }); + const $input = $('