diff --git a/OTX_ETX/c800x480/README.md b/OTX_ETX/c800x480/README.md new file mode 100644 index 00000000..8d49ca58 --- /dev/null +++ b/OTX_ETX/c800x480/README.md @@ -0,0 +1,54 @@ +# Yaapu Telemetry Widget - 800x480 EdgeTX + +This is the 800x480 resolution variant of the Yaapu Telemetry Widget for EdgeTX radios with high-resolution color LCDs (e.g., RadioMaster TX16S Mark II, Jumper T18 Pro, etc.). + +## Installation + +Copy the contents of the `SD/` folder to your radio's SD card: + +- `WIDGETS/yaapu/` → Widget files +- `SCRIPTS/TOOLS/` → Configuration and debug tools + +**Important:** You also need the shared map tiles from `color_common/SD/IMAGES/yaapu/maps/` if using map features. + +## Bitmap Assets + +The `images/` folder contains bitmap assets inherited from the 480x272 variant. The following bitmaps should be regenerated at the appropriate size for optimal display on 800x480 screens: + +- `hud.png` and `hud_bg.png` — HUD overlay (should be 400x230px) +- `variogauge_*.png` — Vario gauge +- `graph_bg_120x*.png` — Graph backgrounds (consider 200px width versions) +- `menubar.png` — Menu navigation bar (if using touch) + +Other icon bitmaps (armed, failsafe, GPS status, etc.) can remain at their original size. + +## Layout + +``` +800x480 Screen Layout (default HUD view): +┌──────────────────────────────────────────────────────────────────────────────────┐ +│ Top Bar (18px): Model Name | RSSI/CRSF | TX Voltage | Time │ +├────────────┬──────────────────────────────────────────────────────┬──────────────┤ +│ │ │ │ +│ Left │ HUD / Artificial Horizon │ Right │ +│ Panel │ (400x230px) │ Panel │ +│ (200px) │ Compass | Speed | Altitude │ (200px) │ +│ │ Vario | VSpeed │ │ +├────────────┴──────────────────────────────────────────────────────┴──────────────┤ +│ Info Strip: RPM 1 | RPM 2 | THR% | EFF | PWR | Home Arrow │ +├─────────────────────────────────────────────────────────────────────────────────── │ +│ Custom Sensors (up to 10 slots) │ +├──────────────────────────────────────────────────────────────────────────────────┤ +│ Status Bar: Flight Mode | GPS/HDOP/Sats | Coordinates | Messages | Timer │ +└──────────────────────────────────────────────────────────────────────────────────┘ +``` + +## Changes from 480x272 + +- HUD area expanded from 240x130 to 400x230 pixels +- Left/right panels widened from 120px to 200px +- Custom sensor bar supports up to 10 sensors (was 6) +- Status bar message area supports 6 rows (was 4) +- Plot area expanded to 600px wide +- Map layout uses 7x3 tile grid (was 3x2) +- Menu shows 18 items at once (was 11) diff --git a/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Config.lua b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Config.lua new file mode 100644 index 00000000..5434eebf --- /dev/null +++ b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Config.lua @@ -0,0 +1,645 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +------------------------------------- +-- UNITS Scales from Ardupilot OSD code /ardupilot/libraries/AP_OSD/AP_OSD_Screen.cpp +------------------------------------- +--[[ + static const float scale_metric[UNIT_TYPE_LAST] = { + 1.0, //ALTITUDE m + 3.6, //SPEED km/hr + 1.0, //VSPEED m/s + 1.0, //DISTANCE m + 1.0/1000, //DISTANCE_LONG km + 1.0, //TEMPERATURE C + }; + static const float scale_imperial[UNIT_TYPE_LAST] = { + 3.28084, //ALTITUDE ft + 2.23694, //SPEED mph + 3.28084, //VSPEED ft/s + 3.28084, //DISTANCE ft + 1.0/1609.34, //DISTANCE_LONG miles + 1.8, //TEMPERATURE F + }; + static const float scale_SI[UNIT_TYPE_LAST] = { + 1.0, //ALTITUDE m + 1.0, //SPEED m/s + 1.0, //VSPEED m/s + 1.0, //DISTANCE m + 1.0/1000, //DISTANCE_LONG km + 1.0, //TEMPERATURE C + }; + static const float scale_aviation[UNIT_TYPE_LAST] = { + 3.28084, //ALTITUDE Ft + 1.94384, //SPEED Knots + 196.85, //VSPEED ft/min + 3.28084, //DISTANCE ft + 0.000539957, //DISTANCE_LONG Nm + 1.0, //TEMPERATURE C + }; +--]] +-- +local menuItems = { + {"pause telemetry processing:", "PTP", 2, { "yes", "no" }, { true, false } }, + {"voice language:", "L1", 1, { "english", "italian", "french", "german" } , {"en","it","fr","de"} }, + {"color theme:", "TH", 1, { "default", "ethos" } , { 1, 2} }, + {"batt alert level 1:", "V1", 375, 0,5000,"V",PREC2,5 }, + {"batt alert level 2:", "V2", 350, 0,5000,"V",PREC2,5 }, + {"batt[1] capacity override:", "B1", 0, 0,5000,"Ah",PREC2,10 }, + {"batt[2] capacity override:", "B2", 0, 0,5000,"Ah",PREC2,10 }, + {"batt[1] cell count override:", "CC", 0, 0,16," cells",0,1 }, + {"batt[2] cell count override:", "CC2", 0, 0,16," cells",0,1 }, + {"dual battery config:", "BC", 1, { "parallel", "series", "dual with alert on B1", "dual with alert on B2", "volts on B1, % on B2", "volts on B2, % on B1" }, { 1, 2, 3, 4, 5, 6 } }, + {"enable battery % by voltage:", "BPBV", 1, { "no", "yes" }, { false, true } }, + {"default voltage source:", "VS", 1, { "auto", "FLVSS", "fc" }, { nil, "vs", "fc" } }, + {"disable all sounds:", "S1", 1, { "no", "yes" }, { false, true } }, + {"disable incoming msg beep:", "S2", 1, { "no", "only for INF severity", "always" }, { 1, 2, 3 } }, + {"enable haptic:", "VIBR", 1, { "no", "yes" }, { false, true } }, + {"timer alert every:", "T1", 0, 0,600,"min",PREC1,5 }, + {"min altitude alert:", "A1", 0, 0,500,"m",PREC1,5 }, + {"max altitude alert:", "A2", 0, 0,10000,"m",0,1 }, + {"max distance alert:", "D1", 0, 0,100000,"m",0,10 }, + {"repeat alerts every:", "T2", 10, 5,600,"sec",0,5 }, + {"rangefinder max:", "RM", 0, 0,10000," cm",0,10 }, + {"air/groundspeed unit:", "HSPD", 1, { "m/s", "km/h", "mph", "kn" }, { 1, 3.6, 2.23694, 1.94384} }, + {"vertical speed unit:", "VSPD", 1, { "m/s", "ft/s", "ft/min" }, { 1, 3.28084, 196.85} }, + {"widget layout:", "WL", 1, { "default"}, { 1 } }, + {"main screen center panel:", "CPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"main screen right panel:", "RPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"main screen left panel:", "LPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: center panel:", "CPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: right panel:", "RPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: left panel:", "LPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: center panel:", "CPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: right panel:", "RPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: left panel:", "LPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"enable PX4 flightmodes:", "PX4", 1, { "no", "yes" }, { false, true } }, + {"enable CRSF support:", "CRSF", 1, { "no", "yes" }, { false, true } }, + {"enable RPM support:", "RPM", 1, { "no", "rpm1", "rpm1+rpm2" }, { 1, 2, 3 } }, + {"enable WIND support:", "WIND", 1, { "no", "yes" }, { false, true } }, + {"emulated page channel:", "STC", 0, 0, 32,nil,0,1 }, + {"emulated wheel channel:", "SWC", 0, 0, 32,nil,0,1 }, + {"emulated wheel delay (secs):", "SWCD", 1, 0, 50,"sec",PREC1, 1 }, + {"GPS coordinates format:", "GPS", 1, { "DMS", "decimal" }, { 1, 2 } }, + {"map provider:", "MAPP", 1, { "GMapCatcher", "Google", "QGIS" }, { 1, 2, 3 } }, + {"map type:", "MAPT", 1, { "", "", "", "", "", "" }, { "", "", "", "", "", "" } }, + {"map zoom level def value:", "MAPZ", -2, -2, 17,nil,0,1 }, + {"map zoom level min value:", "MAPmZ", -2, -2, 17,nil,0,1 }, + {"map zoom level max value:", "MAPMZ", 17, -2, 17,nil,0,1 }, + {"map grid lines:", "MAPG", 1, { "yes", "no" }, { true, false } }, + -- allow up to 20 plot sources to be defined by updateMenuItems() + {"plot telemetry source 1:", "PLT1", 1, { "","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" }, { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 } }, + {"plot telemetry source 2:", "PLT2", 1, { "","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" }, { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 } }, +} + +------------------------------- +-- PLOT SOURCE DEFINITIONS +------------------------------- +-- { desc, telemetry, unit, scale, label } +-- unit: 1=alt,2=dist,3=hspeed,4=vspeed,5=none +local plotSources = { + {"None", "nome", 5, 1, }, -- dm + {"Altitude", "homeAlt", 1, 1 }, -- dm + {"Airspeed", "airspeed", 3, 0.1 }, + {"Batt[1] Voltage", "batt1volt", 5, 0.1 }, + {"Batt[1] Current", "batt1current", 5, 0.1 }, + {"Batt[2] Voltage", "batt2volt", 5, 0.1 }, + {"Batt[2] Current", "batt2current", 5, 0.1 }, + {"Groundspeed","hSpeed", 3, 0.1}, -- dm + {"Height Above Terrain", "heightAboveTerrain", 1, 1 }, + {"Home Distance", "homeDist", 2, 1 }, -- m + {"HDOP", "gpsHdopC", 5, 0.1}, + {"Num Sats", "numSats", 5, 1}, + {"Pitch", "pitch", 5, 1 }, + {"Rangefinder", "range", 5, 1 }, + {"Roll", "roll", 5, 1 }, + {"RPM[1]", "rpm1", 5, 1 }, + {"RPM[2]", "rpm2", 5, 1 }, + {"RSSI", "rssi", 5, 1 }, + {"RSSI CRSF", "rssiCRSF", 5, 1 }, + {"Sonar", "range", 5, 1 }, + {"Throttle", "throttle", 5, 1 }, + {"Vertical Speed", "vSpeed", 4, 0.1}, -- dm + {"Wind Speed", "trueWindSpeed", 3, 0.1 }, + {"Wind Direction", "trueWindAngle", 5, 1 }, + {"Yaw", "yaw", 5, 1}, -- deg +} + +-- map from NEW to OLD settings +local mapNewToOldItemCfg = { + ["SWC"] = "ZTC" -- ZTC was replaced by SWC +} + +local utils = {} +local menuItemsByName = {} + +local menu = { + selectedItem = 1, + editSelected = false, + offset = 0, + updated = true, -- if true menu needs a call to updateMenuItems() + wrapOffset = 0, -- changes according to enabled/disabled features and panels +} + +local widgetLayoutFiles = { "layout_def" } + +local centerPanelFiles = {} +local rightPanelFiles = {} +local leftPanelFiles = {} + +--------------------------- +-- LIBRARY LOADING +--------------------------- +local basePath = "/WIDGETS/Yaapu/" +local libBasePath = basePath.."lib/" + +utils.doLibrary = function(filename) + local f = assert(loadScript(libBasePath..filename..".lua")) + return f() +end + +local panels = utils.doLibrary("panels").panels + +------------------------------------------ +-- returns item's VALUE,LABEL,IDX +------------------------------------------ +local function getMenuItemByName(items,name) + local itemIdx = menuItemsByName[name] + local item = items[itemIdx] + if item == nil then + return nil + end + if type(item[4]) == "table" then + -- return item's value, label, index + return item[5][item[3]], item[4][item[3]], itemIdx + else + -- return item's value, label, index + return item[3], name, itemIdx + end +end + +local function plotSourcesToMenuOptions(plotSources) + local labels = {} + local values = {} + + for i=1,#plotSources + do + labels[i] = plotSources[i][1] + values[i] = i + end + return labels, values +end + +local function updateMenuItems() + if menu.updated == true then + local layout, layout_name, layout_idx = getMenuItemByName(menuItems,"WL") + for screen=1,3 + do + local screen_suffix = screen == 1 and "" or tostring(screen) + --------------------- + -- large hud layout + --------------------- + value, name, idx = getMenuItemByName(menuItems,"CPANE"..screen_suffix) + menuItems[idx][4] = panels.default.center.labels + menuItems[idx][5] = panels.default.center.options; + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + value, name, idx = getMenuItemByName(menuItems,"RPANE"..screen_suffix) + menuItems[idx][4] = panels.default.right.labels + menuItems[idx][5] = panels.default.right.options + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + value, name, idx = getMenuItemByName(menuItems,"LPANE"..screen_suffix) + menuItems[idx][4] = panels.default.left.labels + menuItems[idx][5] = panels.default.left.options + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + centerPanelFiles = panels.default.center.files + rightPanelFiles = panels.default.right.files + leftPanelFiles = panels.default.left.files + end + + local value, name, idx = getMenuItemByName(menuItems,"MAPP") + + if value == nil then + return + end + + local value2, name2, idx2 = getMenuItemByName(menuItems,"MAPT") + + if value2 ~= nil then + if value == 1 then --GMapCatcher + menuItems[idx2][4] = { "satellite", "map", "terrain" } + menuItems[idx2][5] = { "sat_tiles", "tiles", "ter_tiles" } + elseif value == 2 then -- Google + menuItems[idx2][4] = { "GoogleSatelliteMap", "GoogleHybridMap", "GoogleMap", "GoogleTerrainMap" } + menuItems[idx2][5] = { "GoogleSatelliteMap", "GoogleHybridMap", "GoogleMap", "GoogleTerrainMap" } + elseif value == 3 then -- QGIS + menuItems[idx2][4] = { "default", "layer1", "layer2", "layer3" } + menuItems[idx2][5] = { "qgis_default", "qgis_layer1", "qgis_layer2", "qgis_layer3" } + end + + if menuItems[idx2][3] > #menuItems[idx2][4] then + menuItems[idx2][3] = 1 + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPmZ") + + local idxzmin = idx2 + + if value2 ~= nil then + if value == 1 then -- GMapCatcher + menuItems[idx2][4] = -2 + menuItems[idx2][5] = 17 + menuItems[idx2][3] = math.max(value2,-2) + elseif value == 2 then -- Google + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 20 + menuItems[idx2][3] = math.max(value2,1) + else + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 25 + menuItems[idx2][3] = math.max(value2,1) + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPMZ") + + local idxzmax = idx2 + + if value2 ~= nil then + if value == 1 then -- GMapCatcher + menuItems[idx2][4] = -2 + menuItems[idx2][5] = 17 + menuItems[idx2][3] = math.min(value2,17) + elseif value == 2 then -- Google + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 20 + menuItems[idx2][3] = math.min(value2,20) + else + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 25 + menuItems[idx2][3] = math.min(value2,25) + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPZ") + + if value2 ~= nil then + menuItems[idx2][4] = menuItems[idxzmin][3] + menuItems[idx2][5] = menuItems[idxzmax][3] + menuItems[idx2][3] = math.min(math.max(value2,menuItems[idxzmin][3]),menuItems[idxzmax][3]) + end + + -- plot sources + value2, name2, idx2 = getMenuItemByName(menuItems,"PLT1") + if value2 ~= nil then + local plotLabels, plotValues= plotSourcesToMenuOptions(plotSources) + menuItems[idx2][4] = plotLabels + menuItems[idx2][5] = plotValues + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"PLT2") + if value2 ~= nil then + local plotLabels, plotValues= plotSourcesToMenuOptions(plotSources) + menuItems[idx2][4] = plotLabels + menuItems[idx2][5] = plotValues + end + + menu.updated = false + end +end + +local function getConfigFilename() + local info = model.getInfo() + return "/WIDGETS/Yaapu/cfg/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..".cfg") +end + +local function getConfigTriggerFilename() + local info = model.getInfo() + return "/WIDGETS/Yaapu/cfg/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..".reload") +end + +local function triggerConfigReload() + local cfg = assert(io.open(getConfigTriggerFilename(),"w")) + if cfg ~= nil then + io.write(cfg, "1") + io.close(cfg) + end + collectgarbage() + collectgarbage() +end + +local function applyConfigValues(conf) + if menu.updated == true then + updateMenuItems() + menu.updated = false + end + conf.pauseTelemetry = getMenuItemByName(menuItems,"PTP") + conf.language = getMenuItemByName(menuItems,"L1") + conf.battAlertLevel1 = getMenuItemByName(menuItems,"V1") + conf.battAlertLevel2 = getMenuItemByName(menuItems,"V2") + conf.battCapOverride1 = getMenuItemByName(menuItems,"B1") + conf.battCapOverride2 = getMenuItemByName(menuItems,"B2") + conf.disableAllSounds = getMenuItemByName(menuItems,"S1") + conf.disableMsgBeep = getMenuItemByName(menuItems,"S2") + conf.enableHaptic = getMenuItemByName(menuItems,"VIBR") + conf.timerAlert = math.floor(getMenuItemByName(menuItems,"T1")*0.1*60) + conf.minAltitudeAlert = getMenuItemByName(menuItems,"A1")*0.1 + conf.maxAltitudeAlert = getMenuItemByName(menuItems,"A2") + conf.maxDistanceAlert = getMenuItemByName(menuItems,"D1") + conf.repeatAlertsPeriod = getMenuItemByName(menuItems,"T2") + conf.battConf = getMenuItemByName(menuItems,"BC") + conf.cell1Count = getMenuItemByName(menuItems,"CC") + conf.cell2Count = getMenuItemByName(menuItems,"CC2") + conf.rangeFinderMax = getMenuItemByName(menuItems,"RM") + conf.horSpeedMultiplier, conf.horSpeedLabel = getMenuItemByName(menuItems,"HSPD") + conf.vertSpeedMultiplier, conf.vertSpeedLabel = getMenuItemByName(menuItems,"VSPD") + -- Layout configuration + conf.widgetLayout = getMenuItemByName(menuItems,"WL") + conf.widgetLayoutFilename = widgetLayoutFiles[conf.widgetLayout] + -- multiple screens setup + for screen=1,3 + do + local screen_suffix = screen == 1 and "" or tostring(screen) + + conf.centerPanel[screen] = getMenuItemByName(menuItems,"CPANE"..screen_suffix) + conf.centerPanelFilename[screen] = centerPanelFiles[conf.centerPanel[screen]] + conf.rightPanel[screen] = getMenuItemByName(menuItems,"RPANE"..screen_suffix) + conf.rightPanelFilename[screen] = rightPanelFiles[conf.rightPanel[screen]] + conf.leftPanel[screen] = getMenuItemByName(menuItems,"LPANE"..screen_suffix) + conf.leftPanelFilename[screen] = leftPanelFiles[conf.leftPanel[screen]] + end + + conf.enablePX4Modes = getMenuItemByName(menuItems,"PX4") + conf.enableCRSF = getMenuItemByName(menuItems,"CRSF") + conf.enableRPM = getMenuItemByName(menuItems,"RPM") + conf.enableWIND = getMenuItemByName(menuItems,"WIND") + + conf.mapZoomLevel = getMenuItemByName(menuItems,"MAPZ") + conf.mapZoomMin = getMenuItemByName(menuItems,"MAPmZ") + conf.mapZoomMax = getMenuItemByName(menuItems,"MAPMZ") + + conf.mapType = getMenuItemByName(menuItems,"MAPT") + + local chInfo = getFieldInfo("ch"..getMenuItemByName(menuItems,"STC")) + conf.screenToggleChannelId = (chInfo == nil and -1 or chInfo['id']) + + chInfo = getFieldInfo("ch"..getMenuItemByName(menuItems,"SWC")) + conf.screenWheelChannelId = (chInfo == nil and -1 or chInfo['id']) + + conf.enableMapGrid = getMenuItemByName(menuItems,"MAPG") + conf.mapProvider = getMenuItemByName(menuItems,"MAPP") + + conf.screenWheelChannelDelay = getMenuItemByName(menuItems,"SWCD") + + -- set default voltage source + if getMenuItemByName(menuItems,"VS") ~= nil then + conf.defaultBattSource = getMenuItemByName(menuItems,"VS") + end + conf.gpsFormat = getMenuItemByName(menuItems,"GPS") + conf.enableBattPercByVoltage = getMenuItemByName(menuItems,"BPBV") + + conf.plotSource1 = getMenuItemByName(menuItems,"PLT1") + conf.plotSource2 = getMenuItemByName(menuItems,"PLT2") + + conf.theme = getMenuItemByName(menuItems,"TH") + + menu.editSelected = false +end + +local function loadConfig(conf) + local cfg_found = false + local cfg_string + local cfg = io.open(getConfigFilename(),"r") + + if cfg ~= nil then + cfg_string = io.read(cfg,500) + io.close(cfg) + if string.len(cfg_string) > 0 then + cfg_found = true + end + end + + for i=1,#menuItems + do + menuItemsByName[tostring(menuItems[i][2])] = i + if cfg_found then + local value = string.match(cfg_string, menuItems[i][2]..":([-%d]+)") + if value == nil then + -- check if it was replaced by an older settings + local oldCfg = mapNewToOldItemCfg[menuItems[i][2]] + if oldCfg ~= nil then + value = string.match(cfg_string, oldCfg..":([-%d]+)") + end + end + if value ~= nil then + menuItems[i][3] = tonumber(value) + -- check if the value read from file is compatible with available options + if type(menuItems[i][4]) == "table" and tonumber(value) > #menuItems[i][4] then + --if not force default + menuItems[i][3] = 1 + end + end + end + end + + -- when run standalone there's nothing to update :-) + if conf ~= nil then + applyConfigValues(conf) + -- menu was loaded apply required changes + menu.updated = true + end +end + +local function saveConfig(conf) + local myConfig = "" + for i=1,#menuItems + do + myConfig = myConfig..menuItems[i][2]..":"..menuItems[i][3] + if i < #menuItems then + myConfig = myConfig.."," + end + end + local cfg = assert(io.open(getConfigFilename(),"w")) + if cfg ~= nil then + io.write(cfg,myConfig) + io.close(cfg) + end + myConfig = nil + -- when run standalone there's nothing to update :-) + if conf ~= nil then + applyConfigValues(conf) + end + triggerConfigReload() +end + +local function drawConfigMenuBars() + local info = model.getInfo() + lcd.setColor(CUSTOM_COLOR,lcd.RGB(16,20,25)) + local itemIdx = string.format("%d/%d",menu.selectedItem,#menuItems) + lcd.drawFilledRectangle(0,0, LCD_W, 35, CUSTOM_COLOR) + lcd.drawRectangle(0, 0, LCD_W, 35, CUSTOM_COLOR) + lcd.drawFilledRectangle(0,LCD_H-35, LCD_W, 35, CUSTOM_COLOR) + lcd.drawRectangle(0, LCD_H-35, LCD_W, 35, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W,9,"Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")",CUSTOM_COLOR+SMLSIZE+RIGHT) + lcd.drawText(0,6,info.name,CUSTOM_COLOR) + lcd.drawText(0,LCD_H-29,getConfigFilename(),CUSTOM_COLOR) + lcd.drawText(LCD_W,LCD_H-29,itemIdx,CUSTOM_COLOR+RIGHT) +end + +local function incMenuItem(idx) + if type(menuItems[idx][4]) == "table" then + menuItems[idx][3] = menuItems[idx][3] + 1 + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + else + menuItems[idx][3] = menuItems[idx][3] + menuItems[idx][8] + if menuItems[idx][3] > menuItems[idx][5] then + menuItems[idx][3] = menuItems[idx][5] + end + end +end + +local function decMenuItem(idx) + if type(menuItems[idx][4]) == "table" then + menuItems[idx][3] = menuItems[idx][3] - 1 + if menuItems[idx][3] < 1 then + menuItems[idx][3] = #menuItems[idx][4] + end + else + menuItems[idx][3] = menuItems[idx][3] - menuItems[idx][8] + if menuItems[idx][3] < menuItems[idx][4] then + menuItems[idx][3] = menuItems[idx][4] + end + end +end + +local function drawItem(idx,flags) + lcd.setColor(CUSTOM_COLOR,WHITE) + if type(menuItems[idx][4]) == "table" then + lcd.drawText(450,42 + (idx-menu.offset-1)*23, menuItems[idx][4][menuItems[idx][3]],flags+CUSTOM_COLOR) + else + if menuItems[idx][3] == 0 and menuItems[idx][4] >= 0 then + lcd.drawText(450,42 + (idx-menu.offset-1)*23, "---",flags+CUSTOM_COLOR) + else + lcd.drawNumber(450,42 + (idx-menu.offset-1)*23, menuItems[idx][3],flags+menuItems[idx][7]+CUSTOM_COLOR) + if menuItems[idx][6] ~= nil then + lcd.drawText(450 + 80,42 + (idx-menu.offset-1)*23, menuItems[idx][6],flags+CUSTOM_COLOR) + end + end + end +end + +local bitmaps = {} + +local function getBitmap(name) + if bitmaps[name] == nil then + bitmaps[name] = Bitmap.open("/WIDGETS/Yaapu/images/"..name..".png") + end + return bitmaps[name],Bitmap.getSize(bitmaps[name]) +end + +local function drawConfigMenu(event) + drawConfigMenuBars() + + updateMenuItems() + if event == EVT_ENTER_BREAK or event == EVT_VIRTUAL_ENTER then + if menu.editSelected == true then + -- confirm modified value + saveConfig() + end + menu.editSelected = not menu.editSelected + menu.updated = true + elseif menu.editSelected and (event == EVT_VIRTUAL_NEXT or event == EVT_PLUS_BREAK or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT) then + incMenuItem(menu.selectedItem) + elseif menu.editSelected and (event == EVT_VIRTUAL_PREV or event == EVT_MINUS_BREAK or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT) then + decMenuItem(menu.selectedItem) + elseif not menu.editSelected and (event == EVT_VIRTUAL_PREV or event == EVT_MINUS_BREAK or event == EVT_ROT_LEFT) then + menu.selectedItem = (menu.selectedItem - 1) + if menu.offset >= menu.selectedItem then + menu.offset = menu.offset - 1 + end + elseif not menu.editSelected and (event == EVT_VIRTUAL_NEXT or event == EVT_PLUS_BREAK or event == EVT_ROT_RIGHT) then + menu.selectedItem = (menu.selectedItem + 1) + if menu.selectedItem - 17 > menu.offset then + menu.offset = menu.offset + 1 + end + end + --wrap + if menu.selectedItem > #menuItems then + menu.selectedItem = 1 + menu.offset = 0 + elseif menu.selectedItem < 1 then + menu.selectedItem = #menuItems + menu.offset = #menuItems - 17 + end + -- + for m=1+menu.offset,math.min(#menuItems,17+menu.offset) do + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(2,42 + (m-menu.offset-1)*23, menuItems[m][1],CUSTOM_COLOR) + if m == menu.selectedItem then + if menu.editSelected then + drawItem(m,INVERS+BLINK) + else + drawItem(m,INVERS) + end + else + drawItem(m,0) + end + end +end + + +-------------------------- +-- RUN +-------------------------- +local function run(event, touchState) + --------------------- + -- CONFIG MENU + --------------------- + lcd.setColor(CUSTOM_COLOR, lcd.RGB(50, 50, 50)) -- hex 0x084c7b -- 073f66 + lcd.clear(CUSTOM_COLOR) + drawConfigMenu(event) + return 0 +end + +local function init() + loadConfig() +end +-------------------------------------------------------------------------------- +-- SCRIPT END +-------------------------------------------------------------------------------- +return {run=run, init=init, loadConfig=loadConfig, compileLayouts=compileLayouts, menuItems=menuItems, plotSources=plotSources} diff --git a/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug CRSF.lua b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug CRSF.lua new file mode 100644 index 00000000..5d0fa088 --- /dev/null +++ b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug CRSF.lua @@ -0,0 +1,195 @@ +local CRSF_FRAME_CUSTOM_TELEM = 0x80 +local CRSF_FRAME_CUSTOM_TELEM_LEGACY = 0x7F +local CRSF_CUSTOM_TELEM_PASSTHROUGH = 0xF0 +local CRSF_CUSTOM_TELEM_STATUS_TEXT = 0xF1 +local CRSF_CUSTOM_TELEM_PASSTHROUGH_ARRAY = 0xF2 + +local packetStats = { + [0x5000] = {count = 0, avg = 0 , tot = 0}, + [0x5001] = {count = 0, avg = 0 , tot = 0}, + [0x5002] = {count = 0, avg = 0 , tot = 0}, + [0x5003] = {count = 0, avg = 0 , tot = 0}, + [0x5004] = {count = 0, avg = 0 , tot = 0}, + [0x5005] = {count = 0, avg = 0 , tot = 0}, + [0x5006] = {count = 0, avg = 0 , tot = 0}, + [0x5007] = {count = 0, avg = 0 , tot = 0}, + [0x5008] = {count = 0, avg = 0 , tot = 0}, + [0x5009] = {count = 0, avg = 0 , tot = 0}, + [0x500A] = {count = 0, avg = 0 , tot = 0}, + [0x500B] = {count = 0, avg = 0 , tot = 0}, + [0x500C] = {count = 0, avg = 0 , tot = 0}, + [0x500D] = {count = 0, avg = 0 , tot = 0}, + link_rate = 0 +} + +local status = {} + +local MAX_MESSAGES = 20 +status.messages = {} +status.messageCount = 0 +status.lastMessageCount = 0 +status.lastMessage = nil + +local logfilename +local logfile +local flushtime = getTime() + +local function drawMessageScreen() + lcd.setColor(CUSTOM_COLOR,WHITE) + for i=0,#status.messages do + lcd.drawText(0,2+13*i, status.messages[(status.messageCount + i) % (#status.messages+1)],SMLSIZE+CUSTOM_COLOR) + end +end + +local function formatMessage(msg) + if status.lastMessageCount > 1 then + return string.format("%02d (x%d) %s", status.messageCount, status.lastMessageCount, msg) + else + return string.format("%02d %s", status.messageCount, msg) + end +end + +local function pushMessage(msg) + if msg == status.lastMessage then + status.lastMessageCount = status.lastMessageCount + 1 + else + status.lastMessageCount = 1 + status.messageCount = status.messageCount + 1 + end + status.messages[(status.messageCount-1) % MAX_MESSAGES] = formatMessage(msg) + status.lastMessage = msg +end + +local function processTelemetry(data_id, value) + if value ~= nil then + if data_id == 0x5006 then -- ROLLPITCH + -- roll [0,1800] ==> [-180,180] + local roll = (math.min(bit32.extract(value,0,11),1800) - 900) * 0.2 + -- pitch [0,900] ==> [-90,90] + local pitch = (math.min(bit32.extract(value,11,10),900) - 450) * 0.2 + -- number encoded on 11 bits: 10 bits for digits + 1 for 10^power + local range = bit32.extract(VALUE,22,10) * (10^bit32.extract(value,21,1)) -- cm + pushMessage(string.format("roll:%d pitch:%d", roll, pitch)) + end + end + if packetStats[data_id] ~= nil then + packetStats[data_id].tot = packetStats[data_id].tot + 1 + packetStats[data_id].count = packetStats[data_id].count + 1 + end + io.write(logfile, getTime(), ";0;", data_id, ";", value, "\r\n") +end + +local function crossfirePop() + local command, data = crossfireTelemetryPop() + -- command is 0x80 CRSF_FRAMETYPE_ARDUPILOT + if (command == CRSF_FRAME_CUSTOM_TELEM or command == CRSF_FRAME_CUSTOM_TELEM_LEGACY) and data ~= nil then + -- actual payload starts at data[2] + if #data >= 7 and data[1] == CRSF_CUSTOM_TELEM_PASSTHROUGH then + local app_id = bit32.lshift(data[3],8) + data[2] + local value = bit32.lshift(data[7],24) + bit32.lshift(data[6],16) + bit32.lshift(data[5],8) + data[4] + return 0x00, 0x10, app_id, value + elseif #data > 4 and data[1] == CRSF_CUSTOM_TELEM_STATUS_TEXT then + return 0x00, 0x10, 0x5000, 0x00000000 + elseif #data >= 8 and data[1] == CRSF_CUSTOM_TELEM_PASSTHROUGH_ARRAY then + -- passthrough array + local app_id, value + for i=0,math.min(data[2]-1, 9) + do + app_id = bit32.lshift(data[4+(6*i)],8) + data[3+(6*i)] + value = bit32.lshift(data[8+(6*i)],24) + bit32.lshift(data[7+(6*i)],16) + bit32.lshift(data[6+(6*i)],8) + data[5+(6*i)] + --pushMessage(7,string.format("CRSF:%d - %04X:%08X",i, app_id, value)) + processTelemetry(app_id, value) + end + end + end + return nil, nil ,nil ,nil +end + +local function getLogFilename() + local datenow = getDateTime() + local info = model.getInfo() + local modelName = string.lower(string.gsub(info.name, "[%c%p%s%z]", "")) + return modelName..string.format("-crsf-%04d%02d%02d_%02d%02d%02d.plog", datenow.year, datenow.mon, datenow.day, datenow.hour, datenow.min, datenow.sec) +end + +local last_refresh = getTime() + +local function background() + for i=1,5 + do + local success, sensor_id, frame_id, data_id, value = pcall(crossfirePop) + if success and frame_id == 0x10 then + processTelemetry(data_id, value) + end + local now = getTime() + if now - last_refresh > 100 then + local aggregate = 0 + for i=0x00,0x0D + do + aggregate = aggregate + packetStats[0x5000+i].count + + if packetStats[0x5000+i].avg == 0 then + packetStats[0x5000+i].avg = packetStats[0x5000+i].count + end + packetStats[0x5000+i].avg = packetStats[0x5000+i].avg * 0.75 + packetStats[0x5000+i].count * 0.25 + packetStats[0x5000+i].count = 0 + end + packetStats.link_rate = packetStats.link_rate * 0.75 + aggregate * 0.25 + last_refresh = now + end + end + + if getTime() - flushtime > 50 then + -- flush + pcall(io.close,logfile) + logfile = io.open("/LOGS/"..logfilename,"a") + + flushtime = getTime() + end +end + +local showMessageScreen = false + +local function run(event) + background() + lcd.setColor(CUSTOM_COLOR, 0x0AB1) + lcd.clear(CUSTOM_COLOR) + + if showMessageScreen == true then + drawMessageScreen() + if event == EVT_EXIT_BREAK or event == 516 then + showMessageScreen = false + end + else + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(1,1,"YAAPU CRSF DEBUG 1.9.5", CUSTOM_COLOR) + + local link_rate = 0 + + for i=0x00,0x0D + do + lcd.setColor(CUSTOM_COLOR, WHITE) + if packetStats[0x5000+i].avg > 0 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(0,255,0)) + end + lcd.drawText(20,22+(i*28),string.format("0x50%02X: rate: %.01fHz, count: %d, ", i, packetStats[0x5000+i].avg, packetStats[0x5000+i].tot),CUSTOM_COLOR) + end + lcd.drawText(LCD_W-10, 1,string.format("link rate: %.01fHz", packetStats.link_rate), CUSTOM_COLOR+RIGHT) + + lcd.drawText(1,LCD_H-35,tostring("/LOGS/"..logfilename),CUSTOM_COLOR) + + if event == 517 then + showMessageScreen = true + end + end + return 0 +end + +local function init() + logfilename = getLogFilename() + logfile = io.open("/LOGS/"..logfilename,"a") + io.write(logfile, "counter;f_time;data_id;value\r\n") + pushMessage("debugger ready!") +end + +return {run=run, init=init} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug FRSKY.lua b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug FRSKY.lua new file mode 100644 index 00000000..1cc0631d --- /dev/null +++ b/OTX_ETX/c800x480/SD/SCRIPTS/TOOLS/Yaapu Debug FRSKY.lua @@ -0,0 +1,108 @@ +local packetStats = { + [0x5000] = {count = 0, avg = 0 , tot = 0}, + [0x5001] = {count = 0, avg = 0 , tot = 0}, + [0x5002] = {count = 0, avg = 0 , tot = 0}, + [0x5003] = {count = 0, avg = 0 , tot = 0}, + [0x5004] = {count = 0, avg = 0 , tot = 0}, + [0x5005] = {count = 0, avg = 0 , tot = 0}, + [0x5006] = {count = 0, avg = 0 , tot = 0}, + [0x5007] = {count = 0, avg = 0 , tot = 0}, + [0x5008] = {count = 0, avg = 0 , tot = 0}, + [0x5009] = {count = 0, avg = 0 , tot = 0}, + [0x500A] = {count = 0, avg = 0 , tot = 0}, + [0x500B] = {count = 0, avg = 0 , tot = 0}, + [0x500C] = {count = 0, avg = 0 , tot = 0}, + [0x500D] = {count = 0, avg = 0 , tot = 0}, + link_rate = 0 +} + +local sensorIds = {} + +local logfilename +local logfile +local flushtime = getTime() + +local function processTelemetry(data_id, value) + if packetStats[data_id] ~= nil then + packetStats[data_id].tot = packetStats[data_id].tot + 1 + packetStats[data_id].count = packetStats[data_id].count + 1 + end + io.write(logfile, getTime(), ";0;", data_id, ";", value, "\r\n") +end + +local function getLogFilename() + local datenow = getDateTime() + local info = model.getInfo() + local modelName = string.lower(string.gsub(info.name, "[%c%p%s%z]", "")) + return modelName..string.format("-frsky-%04d%02d%02d_%02d%02d%02d.plog", datenow.year, datenow.mon, datenow.day, datenow.hour, datenow.min, datenow.sec) +end + +local last_refresh = getTime() + +local function background() + for i=1,5 + do + local success,sensor_id,frame_id,data_id,value = pcall(sportTelemetryPop) + if success and sensor_id ~= nil then + sensorIds[sensor_id] = true + processTelemetry(data_id, value) + end + local now = getTime() + if now - last_refresh > 100 then + local aggregate = 0 + for i=0x00,0x0D + do + aggregate = aggregate + packetStats[0x5000+i].count + + if packetStats[0x5000+i].avg == 0 then + packetStats[0x5000+i].avg = packetStats[0x5000+i].count + end + packetStats[0x5000+i].avg = packetStats[0x5000+i].avg * 0.75 + packetStats[0x5000+i].count * 0.25 + packetStats[0x5000+i].count = 0 + end + packetStats.link_rate = packetStats.link_rate * 0.75 + aggregate * 0.25 + last_refresh = now + end + end + + if getTime() - flushtime > 50 then + -- flush + pcall(io.close,logfile) + logfile = io.open("/LOGS/"..logfilename,"a") + + flushtime = getTime() + end +end + +local function run(event) + background() + lcd.setColor(CUSTOM_COLOR, 0x0AB1) + lcd.clear(CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(1,1,"YAAPU FRSKY DEBUG 1.9.5", CUSTOM_COLOR) + + local link_rate = 0 + for i=0x00,0x0D + do + lcd.setColor(CUSTOM_COLOR, WHITE) + if packetStats[0x5000+i].avg > 0 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(0,255,0)) + end + lcd.drawText(20,22+(i*28),string.format("0x50%02X: rate: %.01fHz, count: %d, ", i, packetStats[0x5000+i].avg, packetStats[0x5000+i].tot),CUSTOM_COLOR) + end + lcd.drawText(LCD_W-10, 1,string.format("link rate: %.01fHz", packetStats.link_rate), CUSTOM_COLOR+RIGHT) + + lcd.drawText(1,LCD_H-35,tostring("/LOGS/"..logfilename),CUSTOM_COLOR) + collectgarbage() + collectgarbage() + return 0 +end + +local function init() + logfilename = getLogFilename() + logfile = io.open("/LOGS/"..logfilename,"a") + io.write(logfile, "counter;f_time;data_id;value\r\n") +end + +return {run=run, init=init} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/flvss_sensors.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/flvss_sensors.lua new file mode 100644 index 00000000..9838e7fe --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/flvss_sensors.lua @@ -0,0 +1,105 @@ +---------------------------------------- +-- custom sensors configuration file +---------------------------------------- +local sensors = { + -- Sensor 1 +[1]= { + "Celm", -- label + "Celm", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 2 +[2]= { + "Celd", -- label + "Celd", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 3 +[3]= { + "Cel4", -- label + "Cel4", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 3.65, -- warning level (nil is do not use feature) + 3.30, -- critical level (nil is do not use feature) + }, + + -- Sensor 4 +[4]= { + "Cel3", -- label + "Cel3", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 3.65, -- warning level (nil is do not use feature) + 3.30, -- critical level (nil is do not use feature) + }, + + -- Sensor 5 +[5]= { + "Cel2", -- label + "Cel2", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 3.65, -- warning level (nil is do not use feature) + 3.30, -- critical level (nil is do not use feature) + }, + + -- Sensor 6 +[6]= { + "Cell", -- label + "Cel1", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 3.65, -- warning level (nil is do not use feature) + 3.30, -- critical level (nil is do not use feature) + }, +} +------------------------------------------------------ +-- the script can optionally look up values here +-- for each sensor and display the corresponding text instead +-- as an example to associate a lookup table to sensor 3 declare it like +-- +--local lookups = { +-- [3] = { +-- [-10] = "ERR", +-- [0] = "OK", +-- [10] = "CRIT", +-- } +-- } +-- this would display the sensor value except when the value corresponds to one +-- of entered above +-- +local lookups = { +} + +collectgarbage() + +return { + sensors=sensors,lookups=lookups +} diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/gsuite_sensors.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/gsuite_sensors.lua new file mode 100644 index 00000000..0886e360 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/gsuite_sensors.lua @@ -0,0 +1,132 @@ +---------------------------------------- +-- custom sensors configuration file +---------------------------------------- +--[[ +GRPc - residual percent +GFlo - flow mL/min +GMFl - max flow mL/min +GAFl - avg flow mL/min +GTp1 - temp 1 C° +GTp2 - temp 2 C° +GRPM - RPM + +--]] +local sensors = { + -- Sensor 1 +[1]= { + "Eng", -- label + "GRPM", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "rpm", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + -- Sensor 2 +[2]= { + "Temp1", -- label + "GTp1", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "C", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 3 +[3]= { + "Temp2", -- label + "GTp2", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "C", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 4 +[4]= { + "Flow", -- label + "GFlo", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "mL", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 5 +[5]= { + "AFlow", -- label + "GAFl", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "mL", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, + + -- Sensor 6 +[6]= { + "Fuel", -- label + "GRpc", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level (nil is do not use feature) + nil, -- critical level (nil is do not use feature) + }, +} +------------------------------------------------------ +-- the script can optionally look up values here +-- for each sensor and display the corresponding text instead +-- as an example to associate a lookup table to sensor 3 declare it like +-- +-- [3] = { +-- [-10] = "ERR", +-- [0] = "OK", +-- [10] = "CRIT", +-- } +-- this would display the sensor value except when the value corresponds to one +-- of entered above +-- +local lookups = { + -- lookup 2 + --[[ + [6] = { + [-30] = "ERROR", + [-20] = "OFF", + [-10] = "COOL", + [-1] = "LOCK", + [0] = "STOP", + [10] = "RUN", + [20] = "REL", + [25] = "GLOW", + [30] = "SPIN", + [40] = "FIRE", + [45] = "IGNT", + [50] = "HEAT", + [60] = "ACCE", + [65] = "CAL", + [70] = "IDLE", + }, + --]] +} + +collectgarbage() + +return { + sensors=sensors,lookups=lookups +} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/kerojet_sensors.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/kerojet_sensors.lua new file mode 100644 index 00000000..7a9422b6 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/examples/kerojet_sensors.lua @@ -0,0 +1,129 @@ +---------------------------------------- +-- custom sensors configuration file +---------------------------------------- +--[[ +S1:Pump,A4,2,V,1,+,1, +S2:Fuel,Fuel,0,ml,1,+,1, +S3:ENG,RPM,0,krpm,100,+,1, +S4:EGT,Tmp1,0,C,1,+,1, +S5:THRO,Thro,0,%,1,+,1, +S6:Status,Tmp2,0,C,1,-,1 +--]] +local sensors = { + -- Sensor 1 + { + "Pump", -- label + "A4", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 1, -- font size 1=small, 2=big + 5, -- warning level (nil is do not use feature) + 10, -- critical level (nil is do not use feature) + }, + + -- Sensor 2 + { + "Fuel", -- label + "Fuel", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "mL", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values + 1, -- font size 1=small, 2=big + 1000, -- warning level + 2000, -- critical level + }, + + -- Sensor 3 + { + "ENG", -- label + "RPM", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "krpm", -- label for unit of measure + 0.001, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 1000, -- warning level + 2000, -- critical value + }, + + -- Sensor 4 + { + "EGT", -- label + "Tmp1", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "C", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 100, -- warning level + 200, -- critical level + }, + + -- Sensor 5 + { + "THRO", -- label + "Thro", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 90, -- warning level + 100, -- critical level + }, + + -- Sensor 6 + { + "Status", -- label + "Tmp2", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 100, -- warning level + 100, -- critical level + }, +} +------------------------------------------------------ +-- the script can optionally look up values here +-- for each sensor and display the corresponding text instead +-- as an example to associate a lookup table to sensor 3 declare it like +-- +-- [3] = { +-- [-10] = "ERR", +-- [0] = "OK", +-- [10] = "CRIT", +-- } +-- this would display the sensor value except when the value corresponds to one +-- of entered above +-- +local lookups = { + -- lookup 2 + [6] = { + [-30] = "ERROR", + [-20] = "OFF", + [-10] = "COOL", + [-1] = "LOCK", + [0] = "STOP", + [10] = "RUN", + [20] = "REL", + [25] = "GLOW", + [30] = "SPIN", + [40] = "FIRE", + [45] = "IGNT", + [50] = "HEAT", + [60] = "ACCE", + [65] = "CAL", + [70] = "IDLE", + }, +} + +collectgarbage() + +return { + sensors=sensors,lookups=lookups +} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname.cfg b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname.cfg new file mode 100644 index 00000000..dc07fc3f --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname.cfg @@ -0,0 +1 @@ +L1:1,V1:375,V2:350,B1:300,B2:0,S1:1,S2:1,S3:1,VS:1,T1:0,A1:0,A2:0,D1:0,T2:10,CC:0,RM:0,SVS:1,HSPD:1,VSPD:1,HDOP:20,CPANE:1,RPANE:2,LPANE:2 \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_batt.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_batt.lua new file mode 100644 index 00000000..b30dc495 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_batt.lua @@ -0,0 +1,37 @@ +-- battery % by voltage +-- you need to enable the relevant option in the widget config menu +-- supported on horus class radios only + +local voltageDrop = 0.15 +local useCellVoltage = false; + +--[[ +local dischargeCurve = { + {3.40, 0}, + {3.46, 10}, + {3.51, 20}, + {3.53, 30}, + {3.56, 40}, + {3.60, 50}, + {3.63, 60}, + {3.70, 70}, + {3.73, 80}, + {3.86, 90}, + {4.00, 99}, + } +--]] +local dischargeCurve = { + {3.40*6, 0}, + {3.46*6, 10}, + {3.51*6, 20}, + {3.53*6, 30}, + {3.56*6, 40}, + {3.60*6, 50}, + {3.63*6, 60}, + {3.70*6, 70}, + {3.73*6, 80}, + {3.86*6, 90}, + {4.00*6, 99}, + } + +return {voltageDrop=voltageDrop,useCellVoltage=useCellVoltage,dischargeCurve=dischargeCurve} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_right_sensors.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_right_sensors.lua new file mode 100644 index 00000000..e22c490c --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_right_sensors.lua @@ -0,0 +1,116 @@ +---------------------------------------- +-- custom sensors configuration file +-- this will be used by the right panel custom sensor layout +-- 5 sensors supported +---------------------------------------- + +local sensors = { + -- Sensor 1 +[1]= { + "Batt", -- label + "VFAS", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 5, -- warning level (nil is do not use feature) + 10, -- critical level (nil is do not use feature) + }, + + -- Sensor 2 +[2]= { + "Curr", -- label + "CURR", -- OpenTX sensor name + 1, -- precision: number of decimals 0,1,2 + "A", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 100, -- warning level + 200, -- critical level + }, + + -- Sensor 3 +[3]= { + "Fuel", -- label + "Fuel", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values + 1, -- font size 1=small, 2=big + 50, -- warning level + 25, -- critical level + true, -- render as gauge + 60, -- gauge width + 20, -- gauge height + 0, -- gauge min value + 100 -- gauge max value + }, + + -- Sensor 4 +[4]= { + "ENG", -- label + "RPM1", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "rpm", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 1, -- font size 1=small, 2=big + 2500, -- warning level + 4000, -- critical value + }, + + -- Sensor 5 +[5]= { + "THR", -- label + "Thr", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 30, -- warning level + 50, -- critical level + }, +} +------------------------------------------------------ +-- the script can optionally look up values here +-- for each sensor and display the corresponding text instead +-- as an example to associate a lookup table to sensor 3 declare it like +-- +-- [3] = { +-- [-10] = "ERR", +-- [0] = "OK", +-- [10] = "CRIT", +-- } +-- this would display the sensor value except when the value corresponds to one +-- of entered above +-- +local lookups = { + -- lookup 2 + [5] = { + [-30] = "ERROR", + [-20] = "OFF", + [-10] = "COOL", + [-1] = "LOCK", + [0] = "STOP", + [10] = "RUN", + [20] = "REL", + [25] = "GLOW", + [30] = "SPIN", + [40] = "FIRE", + [45] = "IGNT", + [50] = "HEAT", + [60] = "ACCE", + [65] = "CAL", + [70] = "IDLE", + }, +} + +collectgarbage() + +return { + sensors=sensors,lookups=lookups +} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_sensors.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_sensors.lua new file mode 100644 index 00000000..8f8bbca1 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/cfg/modelname_sensors.lua @@ -0,0 +1,123 @@ +---------------------------------------- +-- custom sensors configuration file +-- this will be rendered as an horizontal bar above the bottom black status bar +-- 6 sensors supported +---------------------------------------- +local sensors = { + -- Sensor 1 +[1]= { + "Batt", -- label + "VFAS", -- OpenTX sensor name + 2, -- precision: number of decimals 0,1,2 + "V", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 5, -- warning level (nil is do not use feature) + 10, -- critical level (nil is do not use feature) + }, + + -- Sensor 2 +[2]= { + "Curr", -- label + "CURR", -- OpenTX sensor name + 1, -- precision: number of decimals 0,1,2 + "A", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 100, -- warning level + 200, -- critical level + }, + + -- Sensor 3 +[3]= { + "Fuel", -- label + "Fuel", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "-", -- "+" track max values, "-" track min values + 2, -- font size 1=small, 2=big + 50, -- warning level + 25 -- critical level + }, + + -- Sensor 4 +[4]= { + "ENG", -- label + "RPM1", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "rpm", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 1, -- font size 1=small, 2=big + 2500, -- warning level + 4000, -- critical value + }, + + -- Sensor 5 +[5]= { + "THR", -- label + "Thr", -- OpenTX sensor name + 0, -- precision: number of decimals 0,1,2 + "%", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + 30, -- warning level + 50, -- critical level + }, + + -- Sensor 6 +[6]= { + "Spd", -- label + "GSpd", -- OpenTX sensor name + 1, -- precision: number of decimals 0,1,2 + "m/s", -- label for unit of measure + 1, -- multiplier if < 1 than divides + "+", -- "+" track max values, "-" track min values with + 2, -- font size 1=small, 2=big + nil, -- warning level + nil, -- critical level + }, +} +------------------------------------------------------ +-- the script can optionally look up values here +-- for each sensor and display the corresponding text instead +-- as an example to associate a lookup table to sensor 3 declare it like +-- +-- [3] = { +-- [-10] = "ERR", +-- [0] = "OK", +-- [10] = "CRIT", +-- } +-- this would display the sensor value except when the value corresponds to one +-- of entered above +-- +local lookups = { + -- lookup 2 + [6] = { + [-30] = "ERROR", + [-20] = "OFF", + [-10] = "COOL", + [-1] = "LOCK", + [0] = "STOP", + [10] = "RUN", + [20] = "REL", + [25] = "GLOW", + [30] = "SPIN", + [40] = "FIRE", + [45] = "IGNT", + [50] = "HEAT", + [60] = "ACCE", + [65] = "CAL", + [70] = "IDLE", + }, +} + +collectgarbage() + +return { + sensors=sensors,lookups=lookups +} \ No newline at end of file diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/armed.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/armed.png new file mode 100644 index 00000000..8c741ac5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/armed.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battbox_small.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battbox_small.png new file mode 100644 index 00000000..92e14348 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battbox_small.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battfailsafe.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battfailsafe.png new file mode 100644 index 00000000..fb45c896 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/battfailsafe.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange.png new file mode 100644 index 00000000..8f5a3b07 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_86x30.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_86x30.png new file mode 100644 index 00000000..21029321 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_86x30.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink.png new file mode 100644 index 00000000..aec9595c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink_86x30.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink_86x30.png new file mode 100644 index 00000000..25704747 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_blink_86x30.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small.png new file mode 100644 index 00000000..1638e861 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small_blink.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small_blink.png new file mode 100644 index 00000000..c1c062b9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_orange_small_blink.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red.png new file mode 100644 index 00000000..b42f2856 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_86x30.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_86x30.png new file mode 100644 index 00000000..1af846f6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_86x30.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_blink_86x30.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_blink_86x30.png new file mode 100644 index 00000000..98ef4201 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_blink_86x30.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_small.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_small.png new file mode 100644 index 00000000..40020c59 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/cell_red_small.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/disarmed.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/disarmed.png new file mode 100644 index 00000000..0bd36904 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/disarmed.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/downarrow.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/downarrow.png new file mode 100644 index 00000000..f3141344 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/downarrow.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/ekffailsafe.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/ekffailsafe.png new file mode 100644 index 00000000..c478d9be Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/ekffailsafe.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/failsafe.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/failsafe.png new file mode 100644 index 00000000..349e33e8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/failsafe.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_breach.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_breach.png new file mode 100644 index 00000000..06a1153c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_breach.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_ok.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_ok.png new file mode 100644 index 00000000..a4470051 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fence_ok.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fuelgauge_75x75.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fuelgauge_75x75.png new file mode 100644 index 00000000..6ea271be Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/fuelgauge_75x75.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg.png new file mode 100644 index 00000000..10dbc4be Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg_small.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg_small.png new file mode 100644 index 00000000..1e60169c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/gauge_bg_small.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x30.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x30.png new file mode 100644 index 00000000..10552a80 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x30.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x32.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x32.png new file mode 100644 index 00000000..31ced487 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x32.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x40.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x40.png new file mode 100644 index 00000000..c81d608b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x40.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x48.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x48.png new file mode 100644 index 00000000..90eb7416 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/graph_bg_120x48.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/homeorange.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/homeorange.png new file mode 100644 index 00000000..2e1cc13b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/homeorange.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud.png new file mode 100644 index 00000000..bcaf783f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_40x48a.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_40x48a.png new file mode 100644 index 00000000..eb6f7c39 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_40x48a.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_48x48a.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_48x48a.png new file mode 100644 index 00000000..8e4b6b7a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_48x48a.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_bg.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_bg.png new file mode 100644 index 00000000..3b908b01 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/hud_bg.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_100x16.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_100x16.png new file mode 100644 index 00000000..e97a8ec7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_100x16.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_150x16.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_150x16.png new file mode 100644 index 00000000..3c0eb358 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_150x16.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_476x16.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_476x16.png new file mode 100644 index 00000000..0940324c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_476x16.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x16.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x16.png new file mode 100644 index 00000000..65db9fc7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x16.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x22.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x22.png new file mode 100644 index 00000000..3bf99621 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_60x22.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_65x32.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_65x32.png new file mode 100644 index 00000000..6b84a2c1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/maps_box_65x32.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/menubar.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/menubar.png new file mode 100644 index 00000000..17e88a70 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/menubar.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minihomeorange.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minihomeorange.png new file mode 100644 index 00000000..4f7aa666 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minihomeorange.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minmax.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minmax.png new file mode 100644 index 00000000..30ec97c7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/minmax.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nogpsicon.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nogpsicon.png new file mode 100644 index 00000000..c19f2ae6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nogpsicon.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nolockicon.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nolockicon.png new file mode 100644 index 00000000..99072439 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/nolockicon.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/notelemetry.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/notelemetry.png new file mode 100644 index 00000000..79c6d48b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/notelemetry.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_error.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_error.png new file mode 100644 index 00000000..f68caae1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_error.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_ok.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_ok.png new file mode 100644 index 00000000..c7021849 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/terrain_ok.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/uparrow.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/uparrow.png new file mode 100644 index 00000000..c13a14d6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/uparrow.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/variogauge_90.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/variogauge_90.png new file mode 100644 index 00000000..6d9c103a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/variogauge_90.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/varioline.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/varioline.png new file mode 100644 index 00000000..34d41be7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/varioline.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/warn.png b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/warn.png new file mode 100644 index 00000000..48ec752c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/images/warn.png differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/blimp.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/blimp.lua new file mode 100644 index 00000000..c880eba1 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/blimp.lua @@ -0,0 +1,19 @@ + --[[ + // Auto Pilot Modes enumeration + enum control_mode_t { + LAND = 0, // currently just stops moving + MANUAL = 1, // manual control + VELOCITY = 2, // velocity mode + LOITER = 3, // loiter mode (position hold) + }; + --]] + local flightModes = {} + + -- copter flight modes + flightModes[0]="" + flightModes[1]="Land" + flightModes[2]="Manual" + flightModes[3]="Velocity" + flightModes[4]="Loiter" + +return {flightModes=flightModes} diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter.lua new file mode 100644 index 00000000..1cb0dffb --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter.lua @@ -0,0 +1,66 @@ + --[[ + // Auto Pilot Modes enumeration + enum control_mode_t { + STABILIZE = 0, // manual airframe angle with manual throttle + ACRO = 1, // manual body-frame angular rate with manual throttle + ALT_HOLD = 2, // manual airframe angle with automatic throttle + AUTO = 3, // fully automatic waypoint control using mission commands + GUIDED = 4, // fully automatic fly to coordinate or fly at velocity/direction using GCS immediate commands + LOITER = 5, // automatic horizontal acceleration with automatic throttle + RTL = 6, // automatic return to launching point + CIRCLE = 7, // automatic circular flight with automatic throttle + LAND = 9, // automatic landing with horizontal position control + DRIFT = 11, // semi-automous position, yaw and throttle control + SPORT = 13, // manual earth-frame angular rate control with manual throttle + FLIP = 14, // automatically flip the vehicle on the roll axis + AUTOTUNE = 15, // automatically tune the vehicle's roll and pitch gains + POSHOLD = 16, // automatic position hold with manual override, with automatic throttle + BRAKE = 17, // full-brake using inertial/GPS system, no pilot input + THROW = 18, // throw to launch mode using inertial/GPS system, no pilot input + AVOID_ADSB = 19, // automatic avoidance of obstacles in the macro scale - e.g. full-sized aircraft + GUIDED_NOGPS = 20, // guided mode but only accepts attitude and altitude + SMART_RTL = 21, // SMART_RTL returns to home by retracing its steps + FLOWHOLD = 22, // FLOWHOLD holds position with optical flow without rangefinder + FOLLOW = 23, // follow attempts to follow another vehicle or ground station + ZIGZAG = 24, // ZIGZAG mode is able to fly in a zigzag manner with predefined point A and point B + SYSTEMID = 25, // System ID mode produces automated system identification signals in the controllers + AUTOROTATE = 26, // Autonomous autorotation + AUTO_RTL = 27, // Auto RTL, this is not a true mode, AUTO will report as this mode if entered to perform a DO_LAND_START Landing sequence + TURTLE = 28, // Flip over after crash + }; + --]] + local flightModes = {} + + -- copter flight modes + flightModes[0]="" + flightModes[1]="Stabilize" + flightModes[2]="Acro" + flightModes[3]="AltHold" + flightModes[4]="Auto" + flightModes[5]="Guided" + flightModes[6]="Loiter" + flightModes[7]="RTL" + flightModes[8]="Circle" + flightModes[9]="" + flightModes[10]="Land" + flightModes[11]="" + flightModes[12]="Drift" + flightModes[13]="" + flightModes[14]="Sport" + flightModes[15]="Flip" + flightModes[16]="AutoTune" + flightModes[17]="PosHold" + flightModes[18]="Brake" + flightModes[19]="Throw" + flightModes[20]="AvoidADSB" + flightModes[21]="GuidedNOGPS" + flightModes[22]="SmartRTL" + flightModes[23]="FlowHold" + flightModes[24]="Follow" + flightModes[25]="ZigZag" + flightModes[26]="SystemID" + flightModes[27]="Autorotate" + flightModes[28]="AutoRTL" + flightModes[29]="Turtle" + +return {flightModes=flightModes} diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter_px4.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter_px4.lua new file mode 100644 index 00000000..d068aaf9 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/copter_px4.lua @@ -0,0 +1,86 @@ +--[[ + MavToPT 2.63 + + uint8_t PX4FlightModeNum(uint8_t main, uint8_t sub) { + switch(main) { + case 1: + return 0; // MANUAL + case 2: + return 1; // ALTITUDE + case 3: + return 2; // POSCTL + case 4: + switch(sub) { + case 1: + return 12; // AUTO READY + case 2: + return 13; // AUTO TAKEOFF + case 3: + return 14; // AUTO LOITER + case 4: + return 15; // AUTO MISSION + case 5: + return 16; // AUTO RTL + case 6: + return 17; // AUTO LAND + case 7: + return 18; // AUTO RTGS + case 8: + return 19; // AUTO FOLLOW ME + case 9: + return 20; // AUTO PRECLAND + default: + return 31; // AUTO UNKNOWN + } + case 5: + return 3; // ACRO + case 6: + return 4; // OFFBOARD + case 7: + return 5; // STABILIZED + case 8: + return 6; // RATTITUDE + case 9: + return 7; // SIMPLE + default: + return 11; // UNKNOWN + } + } +--]] +local flightModes = {} +-- plane flight modes +flightModes[0] = "Manual" +flightModes[1] = "AltCtl" --px4 specific +flightModes[2] = "PosCtl" --px4 specific +flightModes[3] = "Acro" +flightModes[4] = "OffBoard" --px4 specific +flightModes[5] = "Stabilize" +flightModes[6] = "RAttitude" --px4 specific +flightModes[7] = "Simple" --px4 specific +flightModes[8] = "" +flightModes[9] = "" +flightModes[10] = "" +flightModes[11] = "" +flightModes[12] = "Ready" --px4 specific +flightModes[13] = "Takeoff" --px4 specific +flightModes[14] = "Loiter" +flightModes[15] = "Mission" --px4 specific +flightModes[16] = "RTL" +flightModes[17] = "Land" +flightModes[18] = "" +flightModes[19] = "Follow" +flightModes[20] = "PrecLand" --px4 specific +flightModes[21] = "" +flightModes[22] = "" +flightModes[23] = "" +flightModes[24] = "" +flightModes[25] = "" +flightModes[26] = "" +flightModes[27] = "" +flightModes[28] = "" +flightModes[29] = "" +flightModes[30] = "" +flightModes[31] = "Unknown" + +return {flightModes=flightModes} + diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/drawlib.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/drawlib.lua new file mode 100644 index 00000000..40a3e6ca --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/drawlib.lua @@ -0,0 +1,785 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local drawLib = {} + +local status +local telemetry +local conf +local utils +local libs + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() +local yawRibbonPoints = {"N",nil,"NE",nil,"E",nil,"SE",nil,"S",nil,"SW",nil,"W",nil,"NW",nil} + +if string.find(radio, "x10") and tonumber(maj..minor..rev) < 222 then + drawLib.drawLine = function(x1,y1,x2,y2,flags1,flags2) lcd.drawLine(LCD_W-x1,LCD_H-y1,LCD_W-x2,LCD_H-y2,flags1,flags2) end +else + drawLib.drawLine = function(x1,y1,x2,y2,flags1,flags2) lcd.drawLine(x1,y1,x2,y2,flags1,flags2) end +end + +function drawLib.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function drawLib.drawHArrow(x,y,width,left,right,drawBlinkBitmap) + lcd.drawLine(x, y, x + width,y, SOLID, 0) + if left == true then + lcd.drawLine(x + 1,y - 1,x + 2,y - 2, SOLID, 0) + lcd.drawLine(x + 1,y + 1,x + 2,y + 2, SOLID, 0) + end + if right == true then + lcd.drawLine(x + width - 1,y - 1,x + width - 2,y - 2, SOLID, 0) + lcd.drawLine(x + width - 1,y + 1,x + width - 2,y + 2, SOLID, 0) + end +end +-- +function drawLib.drawVArrow(x,y,top,bottom) + if top == true then + utils.drawBlinkBitmap("uparrow",x,y) + else + utils.drawBlinkBitmap("downarrow",x,y) + end +end + +function drawLib.drawHomeIcon(x,y) + lcd.drawBitmap(utils.getBitmap("minihomeorange"),x,y) +end + +function drawLib.computeOutCode(x,y,xmin,ymin,xmax,ymax) + local code = 0; --initialised as being inside of hud + -- + if x < xmin then --to the left of hud + code = bit32.bor(code,1); + elseif x > xmax then --to the right of hud + code = bit32.bor(code,2); + end + if y < ymin then --below the hud + code = bit32.bor(code,8); + elseif y > ymax then --above the hud + code = bit32.bor(code,4); + end + return code; +end + +local function etxDrawLineWithClipping(x1,y1,x2,y2,style,xmin,xmax,ymin,ymax,color) + lcd.drawLineWithClipping(x1,y1,x2,y2,xmin,xmax,ymin,ymax,style,color) +end + +local function otxDrawLineWithClipping(x1,y1,x2,y2,style,xmin,xmax,ymin,ymax,color) + local x= {} + local y = {} + if not(x1 < xmin and x2 < xmin) and not(x1 > xmax and x2 > xmax) then + if not(y1 < ymin and y2 < ymin) and not(y1 > ymax and y2 > ymax) then + x[1]=x1 + y[1]=y1 + x[2]=x2 + y[2]=y2 + for i=1,2 + do + if x[i] < xmin then + x[i] = xmin + y[i] = ((y2-y1)/(x2-x1))*(xmin-x1)+y1 + elseif x[i] > xmax then + x[i] = xmax + y[i] = ((y2-y1)/(x2-x1))*(xmax-x1)+y1 + end + + if y[i] < ymin then + y[i] = ymin + x[i] = ((x2-x1)/(y2-y1))*(ymin-y1)+x1 + elseif y[i] > ymax then + y[i] = ymax + x[i] = ((x2-x1)/(y2-y1))*(ymax-y1)+x1 + end + end + if not(x[1] < xmin and x[2] < xmin) and not(x[1] > xmax and x[2] > xmax) then + drawLib.drawLine(x[1],y[1],x[2],y[2], style, color) + end + end + end +end + +if lcd.drawLineWithClipping == nil then + drawLib.drawLineWithClippingXY = otxDrawLineWithClipping +else + drawLib.drawLineWithClippingXY = etxDrawLineWithClipping +end + +function drawLib.drawLineByOriginAndAngle(ox,oy,angle,len,style,xmin,xmax,ymin,ymax,color,drawDiameter) + local xx = math.cos(math.rad(angle)) * len * 0.5 + local yy = math.sin(math.rad(angle)) * len * 0.5 + + local x0 = ox - xx + local x1 = ox + xx + local y0 = oy - yy + local y1 = oy + yy + + if drawDiameter == false then + drawLib.drawLineWithClippingXY(ox,oy,x1,y1,style,xmin,xmax,ymin,ymax,color) + else + drawLib.drawLineWithClippingXY(x0,y0,x1,y1,style,xmin,xmax,ymin,ymax,color) + end +end + +function drawLib.drawNumberWithDim(x,y,xDim,yDim,number,dim,flags,dimFlags) + lcd.drawNumber(x, y, number,flags) + lcd.drawText(xDim, yDim, dim, dimFlags) +end + +function drawLib.drawRVehicle(x,y,r,angle,color,half) + local ang = math.rad(angle - 90) + local x1 = x + r * math.cos(ang) + local y1 = y + r * math.sin(ang) + + ang = math.rad(angle - 90 + 150) + local x2 = x + r * math.cos(ang) + local y2 = y + r * math.sin(ang) + + ang = math.rad(angle - 90 - 150) + local x3 = x + r * math.cos(ang) + local y3 = y + r * math.sin(ang) + ang = math.rad(angle - 270) + local x4 = x + r * 0.5 * math.cos(ang) + local y4 = y + r * 0.5 *math.sin(ang) + -- + drawLib.drawLine(x1,y1,x2,y2,SOLID,color) + drawLib.drawLine(x1,y1,x3,y3,SOLID,color) + if half ~= true then + drawLib.drawLine(x2,y2,x4,y4,SOLID,color) + drawLib.drawLine(x3,y3,x4,y4,SOLID,color) + end +end + +function drawLib.drawRArrow(x,y,r1,r2,r3,angle,color) + local ang = math.rad(angle - 90) + local x0 = x - r1 * math.cos(ang) + local y0 = y - r1 * math.sin(ang) + local x1 = x + r1 * math.cos(ang) + local y1 = y + r1 * math.sin(ang) + + ang = math.rad(angle - 90 + r3) + local x2 = x + r2 * math.cos(ang) + local y2 = y + r2 * math.sin(ang) + + ang = math.rad(angle - 90 - r3) + local x3 = x + r2 * math.cos(ang) + local y3 = y + r2 * math.sin(ang) + + drawLib.drawLine(x1,y1,x2,y2,SOLID,color) + drawLib.drawLine(x1,y1,x3,y3,SOLID,color) + drawLib.drawLine(x1,y1,x,y,SOLID,color) + drawLib.drawLine(x,y,x0,y0,SOLID,color) +end + +function drawLib.drawFenceStatus(x,y) + if telemetry.fencePresent == 0 then + return x + end + if telemetry.fenceBreached == 1 then + utils.drawBlinkBitmap("fence_breach",x,y) + return x+21 + end + lcd.drawBitmap(utils.getBitmap("fence_ok"),x,y) + return x+21 +end + +function drawLib.drawTerrainStatus(x,y) + if status.terrainEnabled == 0 then + return x + end + if telemetry.terrainUnhealthy == 1 then + utils.drawBlinkBitmap("terrain_error",x,y) + return x+21 + end + lcd.drawBitmap(utils.getBitmap("terrain_ok"),x,y) + return x+21 +end + + +function drawLib.drawMinMaxBar(x, y, w, h, color, value, min, max, flags) + local perc = math.min(math.max(value,min),max) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawFilledRectangle(x,y,w,h,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,color) + lcd.drawGauge(x, y,w,h,perc-min,max-min,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR, BLACK) + local strperc = string.format("%02d%%",value) + local xOffset = flags==0 and 17 or 28 + local yOffset = flags==0 and 2 or 7 + lcd.drawText(x+w/2-xOffset, y-yOffset, strperc, flags+CUSTOM_COLOR) +end + +-- initialize up to 5 bars +local barMaxValues = {} +local barAvgValues = {} +local barSampleCounts = {} + +function drawLib.initMapTable(mapTable,name) + if mapTable[name] == nil then + mapTable[name] = 0 + end +end + +function drawLib.updateBar(name, value) + -- init + drawLib.initMapTable(barSampleCounts,name) + drawLib.initMapTable(barMaxValues,name) + drawLib.initMapTable(barAvgValues,name) + + -- update metadata + barSampleCounts[name] = barSampleCounts[name]+1 + barMaxValues[name] = math.max(value,barMaxValues[name]) + -- weighted average on 5 samples + barAvgValues[name] = barAvgValues[name]*0.9 + value*0.1 +end + +-- draw an horizontal dynamic bar with an average red pointer of the last 5 samples +function drawLib.drawBar(name, x, y, w, h, color, value, flags) + drawLib.updateBar(name, value) + + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawFilledRectangle(x,y,w,h,CUSTOM_COLOR) + + -- normalize percentage relative to MAX + local perc = 0 + local avgPerc = 0 + if barMaxValues[name] > 0 then + perc = value/barMaxValues[name] + avgPerc = barAvgValues[name]/barMaxValues[name] + end + lcd.setColor(CUSTOM_COLOR, color) + lcd.drawFilledRectangle(math.max(x,x+w-perc*w),y+1,math.min(w,perc*w),h-2,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR, RED) + + lcd.drawLine(x+w-avgPerc*(w-2),y+1,x+w-avgPerc*(w-2),y+h-2,SOLID,CUSTOM_COLOR) + lcd.drawLine(1+x+w-avgPerc*(w-2),y+1,1+x+w-avgPerc*(w-2),y+h-2,SOLID,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR, BLACK) + lcd.drawNumber(x+w-1,y-5,value,CUSTOM_COLOR+flags+RIGHT) + -- border + lcd.setColor(CUSTOM_COLOR, BLACK) + lcd.drawRectangle(x,y,w,h,CUSTOM_COLOR) +end + + +-- max is 20 samples every 1 sec +local graphSampleTime = {} +local graphMaxValues = {} +local graphMinValues = {} +local graphAvgValues = {} +local graphSampleCounts = {} +local graphSamples = {} + +function drawLib.resetGraph(name) + graphSampleTime[name] = 0 + graphMaxValues[name] = 0 + graphMinValues[name] = 0 + graphAvgValues[name] = 0 + graphSampleCounts[name] = 0 + graphSamples[name] = {} +end + +function drawLib.updateGraph(name, value, maxSamples) + local updated = false + if maxSamples == nil then + maxSamples = 20 + end + -- init + drawLib.initMapTable(graphSampleTime,name) + drawLib.initMapTable(graphMaxValues,name) + drawLib.initMapTable(graphMinValues,name) + drawLib.initMapTable(graphAvgValues,name) + drawLib.initMapTable(graphSampleCounts,name) + + if graphSamples[name] == nil then + graphSamples[name] = {} + end + + if getTime() - graphSampleTime[name] > 100 then + graphSampleCounts[name] = graphSampleCounts[name]+1 + graphAvgValues[name] = graphAvgValues[name]*0.9 + value*0.1 + graphSamples[name][graphSampleCounts[name]%maxSamples] = value -- 0->49 + graphSampleTime[name] = getTime() + updated = true + end + + if graphSampleCounts[name] < 2 then + return updated + end + return updated +end + +function drawLib.getGraphMin(name) + return graphMinValues[name] == math.huge and 0 or graphMinValues[name] +end + +function drawLib.getGraphMax(name) + return graphMaxValues[name] == -math.huge and 0 or graphMaxValues[name] +end + +function drawLib.getGraphAvg(name) + return graphAvgValues[name] +end + +function drawLib.drawGraph(name, x ,y ,w , h, color, value, draw_bg, draw_value, unit, maxSamples) + local updateRequired = drawLib.updateGraph(name, value, maxSamples) + + if maxSamples == nil then + maxSamples = 20 + end + + if draw_bg == true then + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawFilledRectangle(x,y,w,h,CUSTOM_COLOR) + end + + lcd.setColor(CUSTOM_COLOR, color) -- graph color + + local height = h - 2 -- available height for the graph + local step = (w-2)/(maxSamples-1) + local maxY = y + height + + -- scale factor based on current min/max difference + local minMaxWindow = graphMaxValues[name]-graphMinValues[name]-- max difference between current window min/max + local scale = minMaxWindow == 0 and 1 or height/minMaxWindow + + -- number of samples we can plot + local tempMin = math.huge + local tempMax = -math.huge + local sampleWindow = math.min(maxSamples-1,graphSampleCounts[name]-1) + local lastY = nil + if sampleWindow >= 2 then + for i=2,sampleWindow + do + -- copy samples to sorting array + local prevSample = graphSamples[name][(i-1+graphSampleCounts[name]-sampleWindow)%maxSamples] + local curSample = graphSamples[name][(i+graphSampleCounts[name]-sampleWindow)%maxSamples] + + local x1 = x + (i-1)*step + local x2 = x + i*step + + local y1 = math.min(maxY,math.max(y,maxY - (prevSample-graphMinValues[name]) * scale)) + local y2 = math.min(math.max(y,maxY - (curSample-graphMinValues[name]) * scale)) + + lastY = y2 + lcd.drawLine(x1,y1,x2,y2,SOLID,CUSTOM_COLOR) + + tempMin = math.min(tempMin, curSample) + tempMax = math.max(tempMax, curSample) + end + graphMinValues[name] = tempMin + graphMaxValues[name] = tempMax + end + + if lastY ~= lastY then --nan + lastY = nil + end + + if lastY ~= nil then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(180,180,180)) + lcd.drawLine(x+2, lastY, x+w-2, lastY ,DOTTED, CUSTOM_COLOR) + end + + if draw_bg == true then + lcd.setColor(CUSTOM_COLOR, BLACK) + lcd.drawRectangle(x,y,w,h,CUSTOM_COLOR) + end + + if draw_value == true and lastY ~= nil then + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(x+2,lastY-6,string.format("%d%s",value,unit),CUSTOM_COLOR+SMLSIZE+INVERS) + end + + return lastY +end + +--[[ + x,y = top,left + image = background image + gx,gy = gauge center point + r1 = gauge radius + r2 = gauge distance from center + perc = value % normalized between min, max + max = angle max +--]] +function drawLib.drawGauge(x, y, image, gx, gy, r1, r2, perc, max, color) + local ang = (360-(max/2))+((perc*0.01)*max) + + if ang > 360 then + ang = ang - 360 + end + + local ra = math.rad(ang-90) + local ra_left = math.rad(ang-90-20) + local ra_right = math.rad(ang-90+20) + + -- tip of the triangle + local x1 = gx + r1 * math.cos(ra) + local y1 = gy + r1 * math.sin(ra) + -- bottom left + local x2 = gx + r2 * math.cos(ra_left) + local y2 = gy + r2 * math.sin(ra_left) + -- bottom right + local x3 = gx + r2 * math.cos(ra_right) + local y3 = gy + r2 * math.sin(ra_right) + + lcd.drawBitmap(utils.getBitmap(image), x, y) + + drawLib.drawLine(x1,y1,x2,y2,SOLID,color) + drawLib.drawLine(x1,y1,x3,y3,SOLID,color) + drawLib.drawLine(x2,y2,x3,y3,SOLID,color) +end + +function drawLib.drawFailsafe(x,y) --150, 45 + if telemetry.ekfFailsafe > 0 then + utils.drawBlinkBitmap("ekffailsafe", x, y) + elseif telemetry.battFailsafe > 0 then + utils.drawBlinkBitmap("battfailsafe", x, y) + elseif telemetry.failsafe > 0 then + utils.drawBlinkBitmap("failsafe", x, y) + end +end + +function drawLib.drawArmStatus(x,y) + -- armstatus + if not utils.failsafeActive(telemetry) and status.timerRunning == 0 then + if telemetry.statusArmed == 1 then + lcd.drawBitmap(utils.getBitmap("armed"), x, y) + else + utils.drawBlinkBitmap("disarmed", x, y) + end + end +end + +function drawLib.drawFilledRectangle(x,y,w,h,flags) + if w > 0 and h > 0 then + lcd.drawFilledRectangle(x,y,w,h,flags) + end +end + +local function fillTriangle(ox, oy, x1, x2, roll, angle,color) + local step = 2 + -- + local y1 = (oy - ox*angle) + x1*angle + local y2 = (oy - ox*angle) + x2*angle + -- + local steps = math.abs(y2-y1) / step + if (0 < roll and roll <= 90) then + for s=0,steps + do + yy = y1 + s*step + xx = (yy - (oy - ox*angle))/angle + lcd.drawRectangle(x1,yy,xx - x1,step,color) + end + elseif (90 < roll and roll <= 180) then + for s=0,steps + do + yy = y2 + s*step + xx = (yy - (oy - ox*angle))/angle + lcd.drawRectangle(x1,yy,xx - x1,step,color) + end + elseif (-90 < roll and roll < 0) then + for s=0,steps + do + yy = y2 + s*step + xx = (yy - (oy - ox*angle))/angle + lcd.drawRectangle(xx,yy,x2-xx+1,step,color) + end + elseif (-180 < roll and roll <= -90) then + for s=0,steps + do + yy = y1 + s*step + xx = (yy - (oy - ox*angle))/angle + lcd.drawRectangle(xx,yy,x2-xx+1,step,color) + end + end +end + +--[[ + based on olliw's improved version over mine :-) + https://github.com/olliw42/otxtelemetry +--]] +function drawLib.drawCompassRibbon(y,myWidget,width,xMin,xMax,stepWidth,bigFont,ribbonFont,ribbonColor) + local minY = y+1 + local heading = telemetry.yaw + local minX = xMin + local maxX = xMax + local midX = (xMax + xMin)/2 + local tickNo = 4 --number of ticks on one side + local stepCount = (maxX - minX -24)/(2*tickNo) + local closestHeading = math.floor(heading/22.5) * 22.5 + local closestHeadingX = midX + (closestHeading - heading)/22.5 * stepCount + local tickIdx = (closestHeading/22.5 - tickNo) % 16 + local tickX = closestHeadingX - tickNo*stepCount + for i = 1,10 do + if tickX >= minX and tickX < maxX then + if yawRibbonPoints[tickIdx+1] == nil then + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawLine(tickX, minY, tickX, y+5, SOLID, CUSTOM_COLOR) + else + lcd.setColor(CUSTOM_COLOR, ribbonColor) + lcd.drawText(tickX, minY-3, yawRibbonPoints[tickIdx+1], CUSTOM_COLOR+CENTER+ribbonFont) + end + end + tickIdx = (tickIdx + 1) % 16 + tickX = tickX + stepCount + end + -- home icon + local homeOffset = 0 + local angle = telemetry.homeAngle - telemetry.yaw + if angle < 0 then angle = angle + 360 end + if angle > 270 or angle < 90 then + homeOffset = (((angle + 90) % 180)/180 * width) - 3 + elseif angle >= 90 and angle < 180 then + homeOffset = width - 13 + end + drawLib.drawHomeIcon(xMin + homeOffset ,minY + (bigFont and 45 or 32),utils) + + -- text box + local w = 100 -- 3 digits width + if heading < 0 then heading = heading + 360 end + if heading < 10 then + w = 33 + elseif heading < 100 then + w = 67 + end + local scale = bigFont and 1 or 0.7 + lcd.setColor(CUSTOM_COLOR, BLACK) + lcd.drawFilledRectangle(midX - (w/2)*scale, minY-1, w*scale, 45*scale, CUSTOM_COLOR+SOLID) + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawNumber(midX, bigFont and minY-6 or minY-2, heading, CUSTOM_COLOR+(bigFont and DBLSIZE or 0)+CENTER) +end + + +-------------------------- +-- CUSTOM SENSORS SUPPORT +-------------------------- + +function drawLib.drawCustomSensors(customSensors, customSensorXY, colorLabel) + if #customSensorXY == 0 then + return + end + if customSensorXY.boxY ~= nil then + lcd.setColor(CUSTOM_COLOR,utils.colors.black) + lcd.drawFilledRectangle(0,customSensorXY.boxY,LCD_W,58,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.grey) + lcd.drawLine(1,customSensorXY.boxY+58,LCD_W-2,customSensorXY.boxY+58,SOLID,CUSTOM_COLOR) + end + + local label,data,prec,mult,flags,sensorConfig + for i=1,#customSensorXY + do + if customSensors.sensors[i] ~= nil then + sensorConfig = customSensors.sensors[i] + + if sensorConfig[4] == "" then + label = string.format("%s",sensorConfig[1]) + else + label = string.format("%s(%s)",sensorConfig[1],sensorConfig[4]) + end + -- draw sensor label + lcd.setColor(CUSTOM_COLOR,customSensorXY[i][5] == nil and colorLabel or customSensorXY[i][5]) + lcd.drawText(customSensorXY[i][1], customSensorXY[i][2],label, SMLSIZE+RIGHT+CUSTOM_COLOR) + + mult = sensorConfig[3] == 0 and 1 or ( sensorConfig[3] == 1 and 10 or 100 ) + prec = mult == 1 and 0 or (mult == 10 and 32 or 48) + + local sensorName = sensorConfig[2]..(status.showMinMaxValues == true and sensorConfig[6] or "") + local sensorValue = getValue(sensorName) + local value = (sensorValue+(mult == 100 and 0.005 or 0))*mult*sensorConfig[5] + + local sign = sensorConfig[6] == "+" and 1 or -1 + flags = sensorConfig[7] == 1 and 0 or MIDSIZE + + if sensorConfig[10] == true then + -- RED lcd.RGB(255,0, 0) + -- GREEN lcd.RGB(0, 255, 0) + -- YELLOW lcd.RGB(255, 204, 0) + local color = lcd.RGB(255,0, 0) + -- min/max tracking + if math.abs(value) ~= 0 then + color = ( sensorValue*sign > sensorConfig[9]*sign and lcd.RGB(255, 0, 0) or (sensorValue*sign > sensorConfig[8]*sign and lcd.RGB(255, 204, 0) or lcd.RGB(0, 255, 0))) + end + drawLib.drawMinMaxBar(customSensorXY[i][3]-sensorConfig[11],customSensorXY[i][4]+5,sensorConfig[11],sensorConfig[12],color,value,sensorConfig[13],sensorConfig[14],flags) + else + -- default font size + local color = utils.colors.white + -- min/max tracking + if math.abs(value) ~= 0 and status.showMinMaxValues == false then + color = ( sensorValue*sign > sensorConfig[9]*sign and lcd.RGB(255,70,0) or (sensorValue*sign > sensorConfig[8]*sign and utils.colors.yellow or utils.colors.white)) + end + lcd.setColor(CUSTOM_COLOR,color) + local voffset = flags==0 and 6 or 0 + -- if a lookup table exists use it! + if customSensors.lookups[i] ~= nil and customSensors.lookups[i][value] ~= nil then + lcd.drawText(customSensorXY[i][3], customSensorXY[i][4]+voffset, customSensors.lookups[i][value] or value, flags+RIGHT+CUSTOM_COLOR) + else + lcd.drawNumber(customSensorXY[i][3], customSensorXY[i][4]+voffset, value, flags+RIGHT+prec+CUSTOM_COLOR) + end + end + end + end +end + +function drawLib.drawWindArrow(x,y,r1,r2,arrow_angle, angle, skew, color) + local a = math.rad(angle - 90) + local ap = math.rad(angle + arrow_angle/2 - 90) + local am = math.rad(angle - arrow_angle/2 - 90) + + local x1 = x + r1 * math.cos(a) * skew + local y1 = y + r1 * math.sin(a) + local x2 = x + r2 * math.cos(ap) * skew + local y2 = y + r2 * math.sin(ap) + local x3 = x + r2 * math.cos(am) * skew + local y3 = y + r2 * math.sin(am) + + lcd.drawLine(x1,y1,x2,y2,SOLID,color) + lcd.drawLine(x1,y1,x3,y3,SOLID,color) +end + +local function otxDrawHudRectangle(pitch, roll, minX, maxX, minY, maxY, color, ox, oy, dx, dy, scale) + local r = -roll + -- angle of the line passing on point(ox,oy) + local angle = math.tan(math.rad(-roll)) + -- prevent divide by zero + if roll == 0 then + libs.drawLib.drawFilledRectangle(minX,math.max(minY,dy+minY+(maxY-minY)/2),maxX-minX,math.max(0,math.min(maxY-minY,(maxY-minY)/2-dy+(math.abs(dy) > 0 and 1 or 0))),CUSTOM_COLOR) + elseif math.abs(roll) >= 180 then + libs.drawLib.drawFilledRectangle(minX,minY,maxX-minX,math.min(maxY-minY,(maxY-minY)/2+dy),CUSTOM_COLOR) + else -- true if flying inverted + local inverted = math.abs(roll) > 90 + -- true if part of the hud can be filled in one pass with a rectangle + local fillNeeded = false + local yRect = inverted and 0 or LCD_H + + local step = 2 + local steps = (maxY - minY)/step - 1 + local yy = 0 + + if 0 < roll and roll < 180 then + for s=0,steps + do + yy = minY + s*step + xx = ox + (yy-oy)/angle + if xx >= minX and xx <= maxX then + lcd.drawFilledRectangle(xx, yy, maxX-xx+1, step,CUSTOM_COLOR) + elseif xx < minX then + yRect = inverted and math.max(yy,yRect)+step or math.min(yy,yRect) + fillNeeded = true + end + end + elseif -180 < roll and roll < 0 then + for s=0,steps + do + yy = minY + s*step + xx = ox + (yy-oy)/angle + if xx >= minX and xx <= maxX then + lcd.drawFilledRectangle(minX, yy, xx-minX, step,CUSTOM_COLOR) + elseif xx > maxX then + yRect = inverted and math.max(yy,yRect)+step or math.min(yy,yRect) + fillNeeded = true + end + end + end + + if fillNeeded then + local yMin = inverted and minY or yRect + local height = inverted and yRect - minY or maxY-yRect + lcd.drawFilledRectangle(minX, yMin, maxX-minX, height ,CUSTOM_COLOR) + end + end +end + +local function etxDrawHudRectangle(pitch, roll, minX, maxX, minY, maxY, color, ox, oy, dx, dy, scale) + lcd.drawHudRectangle(pitch, roll+0.001, minX, maxX, minY, maxY, color) +end + +local drawHudRectangle = etxDrawHudRectangle +if lcd.drawHudRectangle == nil then + drawHudRectangle = otxDrawHudRectangle +end + +function drawLib.drawArtificialHorizon(x, y, w, h, bgBitmapName, colorSky, colorTerrain, lineCount, lineOffset, scale) + local r = -telemetry.roll + local cx,cy,dx,dy + --local scale = 1.85 -- 1.85 + -- no roll ==> segments are vertical, offsets are multiples of R2 + if telemetry.roll == 0 or math.abs(telemetry.roll) == 180 then + dx=0 + dy=telemetry.pitch * scale + cx=0 + cy=lineOffset + else + -- center line offsets + dx = math.cos(math.rad(90 - r)) * -telemetry.pitch + dy = math.sin(math.rad(90 - r)) * telemetry.pitch * scale + -- 1st line offsets + cx = math.cos(math.rad(90 - r)) * lineOffset + cy = math.sin(math.rad(90 - r)) * lineOffset + end + + local rollX = math.floor(x+w/2) -- math.floor(HUD_X + HUD_WIDTH/2) + + local minY = y + local maxY = y + h + + local minX = x + local maxX = x + w + + local ox = x + w/2 + dx + local oy = y + h/2 + dy + local yy = 0 + + if bgBitmapName == nil then + lcd.setColor(CUSTOM_COLOR,colorSky) + lcd.drawFilledRectangle(x,y,w,h,CUSTOM_COLOR) + else + lcd.drawBitmap(utils.getBitmap(bgBitmapName),x, y) + end + + -- HUD drawn using horizontal bars of height 2 + lcd.setColor(CUSTOM_COLOR,colorTerrain) + drawHudRectangle(telemetry.pitch, telemetry.roll, minX, maxX, minY, maxY, CUSTOM_COLOR, ox, oy, dx, dy, scale) + -- parallel lines above and below horizon + lcd.setColor(CUSTOM_COLOR, WHITE) + -- +/- 90 deg + for dist=1,lineCount + do + libs.drawLib.drawLineByOriginAndAngle(rollX + dx - dist*cx, oy + dist*cy, r, (dist%2==0 and 80 or 40), DOTTED, minX+2, maxX-2, minY+2, maxY-2, CUSTOM_COLOR) + libs.drawLib.drawLineByOriginAndAngle(rollX + dx + dist*cx, oy - dist*cy, r, (dist%2==0 and 80 or 40), DOTTED, minX+2, maxX-2, minY+2, maxY-2, CUSTOM_COLOR) + end + + --[[ + -- horizon line + lcd.setColor(CUSTOM_COLOR,lcd.RGB(160,160,160)) + libs.drawLib.drawLineByOriginAndAngle(rollX + dx, oy, r, 200, SOLID, minX+2, maxX-2, minY+2, maxY-2, CUSTOM_COLOR) + --]] +end + +return drawLib diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_def.lua new file mode 100644 index 00000000..3a57ae16 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_def.lua @@ -0,0 +1,221 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget) + + local minY = 32 --HUD_Y + local maxY = 262 --HUD_Y + HUD_HEIGHT (32+230) + local minX = 200 --HUD_X + local maxX = 600 --HUD_X + HUD_WIDTH (200+400) + + libs.drawLib.drawArtificialHorizon(minX, minY, 400, 230, "hud_bg", nil, utils.colors.hudTerrain, 9, 18.5, 1.85) + + -- hashmarks + local startY = minY + 1 + local endY = maxY - 10 + local step = 32 + -- hSpeed + local roundHSpeed = math.floor((telemetry.hSpeed*conf.horSpeedMultiplier*0.1/5)+0.5)*5; + local offset = math.floor((telemetry.hSpeed*conf.horSpeedMultiplier*0.1-roundHSpeed)*0.2*step); + local ii = 0; + local yy = 0 + lcd.setColor(CUSTOM_COLOR,utils.colors.hudDash) + for j=roundHSpeed+20,roundHSpeed-20,-5 + do + yy = startY + (ii*step) + offset - 14 + if yy >= startY and yy < endY then + lcd.drawNumber(303, yy, j, SMLSIZE+CUSTOM_COLOR+RIGHT) + end + ii=ii+1; + end + -- altitude + local roundAlt = math.floor((telemetry.homeAlt*unitScale/5)+0.5)*5; + offset = math.floor((telemetry.homeAlt*unitScale-roundAlt)*0.2*step); + ii = 0; + yy = 0 + for j=roundAlt+20,roundAlt-20,-5 + do + yy = startY + (ii*step) + offset - 14 + if yy >= startY and yy < endY then + lcd.drawNumber(497, yy, j, SMLSIZE+CUSTOM_COLOR) + end + ii=ii+1; + end + lcd.setColor(CUSTOM_COLOR,WHITE) + + ------------------------------------- + -- hud bitmap + ------------------------------------- + lcd.drawBitmap(utils.getBitmap("hud"),200,32) + + ------------------------------------- + -- vario + ------------------------------------- + local varioMax = 5 + local varioSpeed = math.min(math.abs(0.1*telemetry.vSpeed),5) + local varioH = varioSpeed/varioMax*88 + if telemetry.vSpeed > 0 then + varioY = 32 + (88 - varioH) + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + else + varioY = 174 + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + end + lcd.drawFilledRectangle(582, varioY, 18, varioH, CUSTOM_COLOR) + + ------------------------------------- + -- left and right indicators on HUD + ------------------------------------- + -- DATA + -- altitude + local homeAlt = utils.getMaxValue(telemetry.homeAlt,11) * unitScale + local alt = homeAlt + if status.terrainEnabled == 1 then + alt = telemetry.heightAboveTerrain * unitScale + lcd.setColor(CUSTOM_COLOR,BLACK) + lcd.drawRectangle(490, 174, 92, 34, CUSTOM_COLOR) + lcd.drawFilledRectangle(490, 174, 92, 34, CUSTOM_COLOR+SOLID) + end + lcd.setColor(CUSTOM_COLOR, utils.colors.green) --green + + if math.abs(alt) > 999 or alt < -99 then + lcd.drawNumber(490,112,alt,MIDSIZE+CUSTOM_COLOR+RIGHT) + if status.terrainEnabled == 1 then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawNumber(490,163,homeAlt,CUSTOM_COLOR+LEFT+MIDSIZE) + end + elseif math.abs(alt) >= 10 then + lcd.setColor(CUSTOM_COLOR, utils.colors.green) --green + lcd.drawNumber(490,112,alt,DBLSIZE+CUSTOM_COLOR+LEFT) + if status.terrainEnabled == 1 then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawNumber(490,163,homeAlt,CUSTOM_COLOR+LEFT+MIDSIZE) + end + else + lcd.setColor(CUSTOM_COLOR, utils.colors.green) --green + lcd.drawNumber(490,112,alt*10,DBLSIZE+PREC1+CUSTOM_COLOR+LEFT) + if status.terrainEnabled == 1 then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawNumber(490,163,homeAlt*10,PREC1+CUSTOM_COLOR+LEFT+MIDSIZE) + end + end + + -- telemetry.hSpeed and telemetry.airspeed are in dm/s + local hSpeed = utils.getMaxValue(telemetry.hSpeed,14) * 0.1 * conf.horSpeedMultiplier + local speed = hSpeed + + if status.airspeedEnabled == 1 then + speed = telemetry.airspeed * 0.1 * conf.horSpeedMultiplier + lcd.setColor(CUSTOM_COLOR,lcd.RGB(10,20,30)) + lcd.drawRectangle(200, 174, 110, 34, CUSTOM_COLOR) + lcd.drawFilledRectangle(200, 174, 110, 34, CUSTOM_COLOR+SOLID) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(203,172,"G",CUSTOM_COLOR+SMLSIZE+LEFT) + end + if (math.abs(speed) >= 10) then + lcd.setColor(CUSTOM_COLOR,utils.colors.green) --green + lcd.drawNumber(310,112,speed,DBLSIZE+CUSTOM_COLOR+RIGHT) + if status.airspeedEnabled == 1 then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawNumber(310,163,hSpeed,CUSTOM_COLOR+MIDSIZE+RIGHT) + end + else + lcd.setColor(CUSTOM_COLOR,utils.colors.green) --green + lcd.drawNumber(310,112,speed*10,DBLSIZE+CUSTOM_COLOR+PREC1+RIGHT) + if status.airspeedEnabled == 1 then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawNumber(310,163,hSpeed*10,CUSTOM_COLOR+PREC1+MIDSIZE+RIGHT) + end + end + + -- wind + if conf.enableWIND == true then + lcd.setColor(CUSTOM_COLOR,BLACK) + lcd.drawRectangle(200, 227, 110, 37, CUSTOM_COLOR) + lcd.drawFilledRectangle(200, 227, 110, 37, CUSTOM_COLOR+SOLID) + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawText(203,228,"W",CUSTOM_COLOR+SMLSIZE+LEFT) + lcd.drawNumber(310,220,telemetry.trueWindSpeed*conf.horSpeedMultiplier,PREC1+CUSTOM_COLOR+MIDSIZE+RIGHT) + end + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- min/max arrows + if status.showMinMaxValues == true then + libs.drawLib.drawVArrow(280, 129,true,false) + libs.drawLib.drawVArrow(502, 129,true,false) + end + + -- vspeed box + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + + local vSpeed = utils.getMaxValue(telemetry.vSpeed,13) * 0.1 -- m/s + + local xx = math.abs(vSpeed*conf.vertSpeedMultiplier) > 999 and 4 or 3 + xx = xx + (vSpeed*conf.vertSpeedMultiplier < 0 and 1 or 0) + + if math.abs(vSpeed*conf.vertSpeedMultiplier*10) > 99 then -- + lcd.drawNumber(400 + (xx/2)*20, 218, vSpeed*conf.vertSpeedMultiplier, MIDSIZE+CUSTOM_COLOR+RIGHT) + else + lcd.drawNumber(400 + (xx/2)*20, 218, vSpeed*conf.vertSpeedMultiplier*10, MIDSIZE+CUSTOM_COLOR+RIGHT+PREC1) + end + + -- compass ribbon + libs.drawLib.drawCompassRibbon(32,myWidget,367,216,583,42,true,0,utils.colors.compassRibbon) + -- pitch and roll + lcd.setColor(CUSTOM_COLOR, utils.colors.hudFgColor) + local xoffset = math.abs(telemetry.pitch) > 99 and 6 or 0 + lcd.drawNumber(413+xoffset,159,telemetry.pitch,CUSTOM_COLOR+0+RIGHT) + lcd.drawNumber(360,131,telemetry.roll,CUSTOM_COLOR+0+RIGHT) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + + if conf.enableWIND == true then + lcd.setColor(CUSTOM_COLOR, utils.colors.hudFgColor) + libs.drawLib.drawWindArrow(LCD_W/2,152,50,77,77,telemetry.trueWindAngle-telemetry.yaw, 1.5, CUSTOM_COLOR); + libs.drawLib.drawWindArrow(LCD_W/2,152,58,77,77,telemetry.trueWindAngle-telemetry.yaw, 1.5, CUSTOM_COLOR); + end +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_empty.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_empty.lua new file mode 100644 index 00000000..054daf77 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_empty.lua @@ -0,0 +1,52 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget) + +end + +function panel.background(widget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_nav_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_nav_def.lua new file mode 100644 index 00000000..1277b1f7 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_nav_def.lua @@ -0,0 +1,228 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +--------------------------------- +-- Note: Home is absolute origin +--------------------------------- + +-- viewport dimensions +local VP_W = 460 +local VP_H = 230 + +-- home relative vehicle coordinates +local myX = 0 +local myY = 0 + +-- viewport relative vehicle coordinates +local myScreenX = 0 +local myScreenY = 0 + +-- absolute viewport home offset +local originX = (LCD_W-VP_W)/2+VP_W/2 +local originY = 32+VP_H/2 + +-- size of grid in pixel +local tileSize = 50 +-- zoom factor +local zoom = 0.5 +-- last n point circulart buffer +local xPoints = {} +local yPoints = {} + +local sample = 0 +local sampleCount = 0 +local lastSample = getTime() + +local avgDistSamples = {} + +avgDistSamples[0] = 0 + +local avgDist = 0; +local avgDistSum = 0; +local avgDistSample = 0; +local avgDistSampleCount = 0; +local avgDistLastSampleTime = getTime(); + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local function drawVehicle(x,y,r,angle,style,xmin,xmax,ymin,ymax,color) + local x1 = x + r * math.cos(math.rad(angle - 90)) + local y1 = y + r * math.sin(math.rad(angle - 90)) + local x2 = x + r * math.cos(math.rad(angle - 90 + 150)) + local y2 = y + r * math.sin(math.rad(angle - 90 + 150)) + local x3 = x + r * math.cos(math.rad(angle - 90 - 150)) + local y3 = y + r * math.sin(math.rad(angle - 90 - 150)) + local x4 = x + r * 0.5 * math.cos(math.rad(angle - 270)) + local y4 = y + r * 0.5 *math.sin(math.rad(angle - 270)) + -- + libs.drawLib.drawLineWithClipping(x1,y1,x2,y2,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClipping(x1,y1,x3,y3,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClipping(x2,y2,x4,y4,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClipping(x3,y3,x4,y4,style,xmin,xmax,ymin,ymax,color) +end + +local function updateMyPosition(widget) + -- calculate new absolute position + if telemetry.homeAngle >= 0 then + myX = telemetry.homeDist*math.cos(math.rad(telemetry.homeAngle-270)) + myY = telemetry.homeDist*math.sin(math.rad(telemetry.homeAngle-270)) + + myScreenX = zoom*myX + originX; + myScreenY = zoom*myY + originY; + end + + if getTime() - avgDistLastSampleTime > 20 then + avgDistSamples[avgDistSample] = telemetry.homeDist + avgDistSampleCount = avgDistSampleCount+1 + avgDistSample = avgDistSampleCount%10 + avgDistLastSampleTime = getTime() + + avgDistSum = 0 + local samples=math.min(avgDistSampleCount,10)-1 + for s=0,samples + do + avgDistSum = avgDistSum+avgDistSamples[s] + end + avgDist=avgDistSum/(samples+1) + end + -- update last n positioins buffer + if getTime() - lastSample > 50 then + xPoints[sample] = myX + yPoints[sample] = myY + sampleCount = sampleCount+1 + sample = sampleCount%20 + lastSample = getTime() + end +end + +function panel.draw(widget) + + local minY = 32 + local maxY = 32 + VP_H + + local minX = (LCD_W-VP_W)/2 + local maxX = (LCD_W-VP_W)/2 + VP_W + + lcd.setColor(CUSTOM_COLOR,lcd.RGB(0x63, 0x30, 0x00)) + lcd.drawFilledRectangle(minX,minY,VP_W,maxY - minY,CUSTOM_COLOR) + -- angle of the line passing on point(ox,oy) + local angle = math.tan(math.rad(-telemetry.roll)) + -- + updateMyPosition(widget) + + -- draw the tile grids + local myTileSize = tileSize*zoom + + lcd.setColor(CUSTOM_COLOR,utils.colors.grey) + + local myCode = libs.drawLib.computeOutCode(myScreenX, myScreenY, minX+20, minY+20,maxX-20, maxY-20); + + -- center vehicle on screen + if myCode == 1 or myCode == 2 or myCode == 8 or myCode == 4 then + originX = (LCD_W-VP_W)/2+VP_W/2 - zoom*myX; + originY = 32+VP_H/2 - zoom*myY + end + + + -- round minX to closest tileSize multiple + local xStart = (LCD_W-VP_W)/2 + VP_W/2 + 10 - (1+math.floor(VP_W/2/tileSize))*tileSize + local xOffset = xStart + originX%myTileSize + + for v=0,1+VP_W/myTileSize + do + libs.drawLib.drawLineWithClipping(xOffset+v*myTileSize,minY,xOffset+v*myTileSize,maxY,SOLID,minX+1,maxX-1,minY+1,maxY-1,CUSTOM_COLOR) + end + + local yStart = 32 + VP_H/2 + 1.5*10 - (1+math.floor(VP_H/2/tileSize))*tileSize + local yOffset = yStart + originY%myTileSize + for h=0,1+VP_H/myTileSize + do + libs.drawLib.drawLineWithClipping(minX,yOffset+h*myTileSize,maxX,yOffset+h*myTileSize,SOLID,minX+1,maxX-1,minY+1,maxY-1,CUSTOM_COLOR) + end + + local homeCode = libs.drawLib.computeOutCode(originX, originY, minX+10, minY+10,maxX-10, maxY-10); + + local originXclip = originX; + local originYclip = originY; + + if bit32.band(homeCode,1) == 1 then + originXclip = minX+10; + end + if bit32.band(homeCode,2) == 2 then + originXclip = maxX-10; + end + if bit32.band(homeCode,8) == 8 then + originYclip = minY+10; + end + if bit32.band(homeCode,4) == 4 then + originYclip = maxY-10; + end + + if originXclip ~= originX or originYclip ~= originY then + utils.drawBlinkBitmap("minihomeorange",originXclip-10/2,originYclip-10/2) + else + libs.drawLib.drawHomeIcon(originXclip-10/2,originYclip-10/2,utils) + end + + -- last n points + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + for p=0, math.min(sampleCount-1,20-1) + do + local xx = zoom*xPoints[p] + originX; + local yy = zoom*yPoints[p] + originY; + if (xx ~= myScreenX or yy ~= myScreenY) and libs.drawLib.computeOutCode(xx, yy, minX+3, minY+3, maxX-3, maxY-3) == 0 then + lcd.drawFilledRectangle(xx,yy,2,2,CUSTOM_COLOR) + end + end + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + + drawVehicle(myScreenX, myScreenY, 20, telemetry.yaw, SOLID, minX, maxX, minY, maxY, CUSTOM_COLOR) + + lcd.drawNumber((LCD_W-VP_W)/2,32+VP_H+6,avgDist,SMLSIZE+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) +end + +function panel.background(widget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_radar_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_radar_def.lua new file mode 100644 index 00000000..71540d3f --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/hud_radar_def.lua @@ -0,0 +1,199 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +--------------------------------- +-- Note: Home is absolute origin +--------------------------------- + +-- viewport dimensions +local VP_W = 467 +local VP_H = 237 + +-- home relative vehicle coordinates +local myX = 0 +local myY = 0 + +-- viewport relative vehicle coordinates +local myScreenX = 0 +local myScreenY = 0 + +-- absolute viewport home offset +local originX = (LCD_W-VP_W)/2+VP_W/2 +local originY = 32+VP_H/2 + +-- zoom factor +local zoom = 0.5 +-- last n point circulart buffer +local xPoints = {} +local yPoints = {} + +local sample = 0 +local sampleCount = 0 +local lastSample = getTime() + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local function drawVehicle(x,y,r,angle,style,xmin,xmax,ymin,ymax,color) + local x1 = x + r * math.cos(math.rad(angle - 90)) + local y1 = y + r * math.sin(math.rad(angle - 90)) + local x2 = x + r * math.cos(math.rad(angle - 90 + 150)) + local y2 = y + r * math.sin(math.rad(angle - 90 + 150)) + local x3 = x + r * math.cos(math.rad(angle - 90 - 150)) + local y3 = y + r * math.sin(math.rad(angle - 90 - 150)) + local x4 = x + r * 0.5 * math.cos(math.rad(angle - 270)) + local y4 = y + r * 0.5 *math.sin(math.rad(angle - 270)) + -- + libs.drawLib.drawLineWithClippingXY(x1,y1,x2,y2,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClippingXY(x1,y1,x3,y3,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClippingXY(x2,y2,x4,y4,style,xmin,xmax,ymin,ymax,color) + libs.drawLib.drawLineWithClippingXY(x3,y3,x4,y4,style,xmin,xmax,ymin,ymax,color) +end + +local function updateMyPosition(widget) + -- calculate new absolute position + if telemetry.homeAngle >= 0 then + myX = telemetry.homeDist*math.cos(math.rad(telemetry.homeAngle-270)) + myY = telemetry.homeDist*math.sin(math.rad(telemetry.homeAngle-270)) + + myScreenX = zoom*myX + originX; + myScreenY = zoom*myY + originY; + end + + -- update last n positioins buffer + if getTime() - lastSample > 50 then + xPoints[sample] = myX + yPoints[sample] = myY + sampleCount = sampleCount+1 + sample = sampleCount%20 + lastSample = getTime() + end +end + +local function dist(x1,y1,x2,y2) + return math.sqrt((x2-x1)^2 + (y2-y1)^2) +end + +function panel.draw(widget) + local minX = (LCD_W-VP_W)/2 + local minY = 32 + + local maxX = (LCD_W-VP_W)/2 + VP_W + local maxY = 32 + VP_H + + lcd.setColor(CUSTOM_COLOR,lcd.RGB(0x63, 0x30, 0x00)) + lcd.drawFilledRectangle(minX,minY,VP_W,maxY - minY,CUSTOM_COLOR) + + updateMyPosition(widget) + + lcd.setColor(CUSTOM_COLOR,utils.colors.grey) + + -- lets check if vehicle is about to exit viewport + local myCode = libs.drawLib.computeOutCode(myScreenX, myScreenY, minX+20, minY+20,maxX-20, maxY-20); + + if bit32.band(myCode,1) == 1 then + local newOriginX = (LCD_W-VP_W)/2+VP_W/2 - (zoom*myX*0.5); + local homeCode = libs.drawLib.computeOutCode(newOriginX, originY, minX+20, minY+20,maxX-20, maxY-20); + if bit32.band(homeCode,2) == 2 then + zoom = zoom * 0.95 + end + originX = (LCD_W-VP_W)/2+VP_W/2 - (zoom*myX*0.5); + end + + if bit32.band(myCode,2) == 2 then + local newOriginX = (LCD_W-VP_W)/2+VP_W/2 - (zoom*myX*0.5); + local homeCode = libs.drawLib.computeOutCode(newOriginX, originY, minX+20, minY+20,maxX-20, maxY-20); + if bit32.band(homeCode,1) == 1 then + zoom = zoom * 0.95 + end + originX = (LCD_W-VP_W)/2+VP_W/2 - (zoom*myX*0.5); + end + + if bit32.band(myCode,8) == 8 then + local newOriginY = 32+VP_H/2 - (zoom*myY*0.5); + local homeCode = libs.drawLib.computeOutCode(originX, newOriginY, minX+20, minY+20,maxX-20, maxY-20); + if bit32.band(homeCode,4) == 4 then + zoom = zoom * 0.95 + end + originY = 32+VP_H/2 - (zoom*myY*0.5); + end + + if bit32.band(myCode,4) == 4 then + local newOriginY = 32+VP_H/2 - (zoom*myY*0.5); + local homeCode = libs.drawLib.computeOutCode(originX, newOriginY, minX+20, minY+20,maxX-20, maxY-20); + if bit32.band(homeCode,8) == 8 then + zoom = zoom * 0.95 + end + originY = 32+VP_H/2 - (zoom*myY*0.5); + end + + libs.drawLib.drawHomeIcon(originX-33/2,originY-33/2) + + -- last n points + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + for p=0, math.min(sampleCount-1,20-1) + do + local xx = zoom*xPoints[p] + originX; + local yy = zoom*yPoints[p] + originY; + if (xx ~= myScreenX or yy ~= myScreenY) and libs.drawLib.computeOutCode(xx, yy, minX+3, minY+3, maxX-3, maxY-3) == 0 then + lcd.drawFilledRectangle(xx,yy,2,2,CUSTOM_COLOR) + end + end + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + + drawVehicle(myScreenX, myScreenY, 33, telemetry.yaw, SOLID, minX, maxX, minY, maxY, CUSTOM_COLOR) + + lcd.drawText((LCD_W-VP_W)/2,32,string.format("zoom:%.02f",zoom),SMLSIZE+CUSTOM_COLOR) + lcd.drawText((LCD_W-VP_W)/2,32+15,string.format("dist:%d",telemetry.homeDist),SMLSIZE+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + + if dist(myScreenX, myScreenY, originX, originY) < VP_H/2 then + if zoom < 0.5 then + zoom = math.min(zoom * 1.1, 0.5) + end + end +end + +function panel.background(widget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_def.lua new file mode 100644 index 00000000..ae5144db --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_def.lua @@ -0,0 +1,137 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local layout = {} + +local conf +local telemetry +local status +local utils +local libs + +function layout.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local customSensorXY = { + { 80, 346, 80, 356}, + { 160, 346, 160, 356}, + { 240, 346, 240, 356}, + { 320, 346, 320, 356}, + { 400, 346, 400, 356}, + { 480, 346, 480, 356}, + { 560, 346, 560, 356}, + { 640, 346, 640, 356}, + { 720, 346, 720, 356}, + { 800, 346, 800, 356}, + boxY = 346 +} + +function layout.draw(widget, customSensors, leftPanel, centerPanel, rightPanel) + local colorLabel = lcd.RGB(140, 140, 140) + -- reset visibility, panels can override this + status.hidePower = 0 + status.hideEfficiency = 0 + -- center panel + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + centerPanel[status.currentScreen].draw(widget) + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + -- home directory arrow + libs.drawLib.drawRVehicle(400,306,32,math.floor(telemetry.homeAngle - telemetry.yaw),CUSTOM_COLOR) + local battIdForPower = 1 + -- with dual battery default is to show aggregate view + if status.batt2sources.fc or status.batt2sources.vs then + if status.showDualBattery == false then + -- dual battery: aggregate view + rightPanel[status.currentScreen].draw(widget, 600, 32, 0) + -- left pane info + leftPanel[status.currentScreen].draw(widget, 0, 32, 0) + battIdForPower = 0 + else + -- dual battery:battery 1 right pane + rightPanel[status.currentScreen].draw(widget, 600, 32, 1) + -- dual battery:battery 2 left pane + rightPanel[status.currentScreen].draw(widget, 600, 32, 2) + end + else + -- battery 1 right pane in single battery mode + rightPanel[status.currentScreen].draw(widget, 600, 32, 1) + -- left pane info in single battery mode + leftPanel[status.currentScreen].draw(widget, 0, 32, 0) + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + -- RPM 1 + if conf.enableRPM == 2 or conf.enableRPM == 3 then + lcd.drawText(10, 266, "RPM 1", SMLSIZE+CUSTOM_COLOR) + libs.drawLib.drawBar("rpm1", 10, 266+28, 150, 43, utils.colors.darkyellow, math.abs(telemetry.rpm1), MIDSIZE) + end + -- RPM 2 + lcd.setColor(CUSTOM_COLOR,colorLabel) + if conf.enableRPM == 3 then + lcd.drawText(192, 266, "RPM 2", SMLSIZE+CUSTOM_COLOR+0) + libs.drawLib.drawBar("rpm2", 192, 266+28, 150, 43, utils.colors.darkyellow, math.abs(telemetry.rpm2), MIDSIZE) + end + -- throttle % + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(525, 266, "THR %", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawNumber(525,294,telemetry.throttle,MIDSIZE+RIGHT+CUSTOM_COLOR) + -- efficiency (check if hidden by another panel) + if status.hideEfficiency == 0 then + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(658, 266, "EFF mAh", SMLSIZE+CUSTOM_COLOR+RIGHT) + local speed = utils.getMaxValue(telemetry.hSpeed,14) + -- efficiency for indipendent batteries makes sense only for battery 1 + local eff = speed > 2 and status.battery[7+battIdForPower]*1000/(speed*conf.horSpeedMultiplier) or 0 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawNumber(658,294+(eff > 9999 and 7 or 0),eff,(eff > 9999 and 0 or MIDSIZE)+RIGHT+CUSTOM_COLOR) + end + -- power (check if hidden by another panel) + if status.hidePower == 0 then + lcd.setColor(CUSTOM_COLOR,colorLabel) + local power = status.battery[4+battIdForPower]*status.battery[7+battIdForPower]*0.01 + local powerUnit = (power > 999) and "kW" or "W" + local flags = (power > 999) and PREC2 or 0 + lcd.drawText(797, 266, string.format("PWR %s",powerUnit), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawNumber(797,294,power*(power > 999 and 0.1 or 1),MIDSIZE+RIGHT+CUSTOM_COLOR+flags) + end + libs.layoutLib.drawTopBar() + local msgRows = 4 + if customSensors ~= nil then + msgRows = 1 + -- draw custom sensors + libs.drawLib.drawCustomSensors(customSensors, customSensorXY, utils.colors.lightgrey) + end + libs.layoutLib.drawStatusBar(msgRows) + local nextX = libs.drawLib.drawTerrainStatus(205, 34) + libs.drawLib.drawFenceStatus(nextX,34) + lcd.setColor(CUSTOM_COLOR,WHITE) +end + +return layout diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_map.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_map.lua new file mode 100644 index 00000000..9ce4dd8f --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_map.lua @@ -0,0 +1,151 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +local layout = {} + +local conf +local telemetry +local status +local utils +local libs + +function layout.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local function drawMiniHud(x,y) + libs.drawLib.drawArtificialHorizon(x, y, 48, 36, nil, lcd.RGB(0x7B, 0x9D, 0xFF), lcd.RGB(0x63, 0x30, 0x00), 6, 6.5, 1.3) + lcd.drawBitmap(utils.getBitmap("hud_48x48a"), 3-1, 22-10) +end + +local flipFlop = true + +local function drawTelemetryBar(widget) + local colorLabel = lcd.RGB(140,140,140) + -- CELL + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 34, string.upper(status.battsource).." V", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + if status.battery[1] * 0.01 < 10 then + lcd.drawNumber(LCD_W-2, 34+16, status.battery[1] + 0.5, PREC2+MIDSIZE+CUSTOM_COLOR+RIGHT) + else + lcd.drawNumber(LCD_W-2, 34+16, (status.battery[1] + 0.5)*0.1, PREC1+MIDSIZE+CUSTOM_COLOR+RIGHT) + end + -- aggregate batt % + local strperc = string.format("%2d", status.battery[16]) + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, 74, "BATT %", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, 74+16, strperc, MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- alt + local alt = telemetry.homeAlt * unitScale + local altLabel = "ALT" + if status.terrainEnabled == 1 then + alt = telemetry.heightAboveTerrain * unitScale + altLabel = "HAT" + end + lcd.drawBitmap(utils.getBitmap("graph_bg_120x48"),598, 287) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(598+118,287-2,altLabel.." "..unitLabel,SMLSIZE+CUSTOM_COLOR+RIGHT) + local lastY = libs.drawLib.drawGraph("map_alt", 598-4, 287, 120, 48, utils.colors.darkyellow, alt, false, false, nil, nil) + local altMin = libs.drawLib.getGraphMin("map_alt") + local altMax = libs.drawLib.getGraphMax("map_alt") + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(598,287+9,string.format("%d",alt),MIDSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR, lcd.RGB(190,190,190)) + lcd.drawText(598,287+32,string.format("%d",altMin),SMLSIZE+CUSTOM_COLOR) + lcd.drawText(598,287,string.format("%d",altMax),SMLSIZE+CUSTOM_COLOR) + + -- speed + local speed = telemetry.hSpeed * 0.1 * conf.horSpeedMultiplier + local speedLabel = "GSPD" + if status.airspeedEnabled == 1 then + speed = telemetry.airspeed * 0.1 * conf.horSpeedMultiplier + speedLabel = "ASPD" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 114, string.format("%s %s", speedLabel, conf.horSpeedLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-2, 114+16, string.format("%.01f",speed), MIDSIZE+CUSTOM_COLOR+RIGHT) + -- home distance + local label = unitLabel + local dist = telemetry.homeDist + local flags = 0 + if dist*unitScale > 999 then + flags = flags + PREC2 + dist = dist*unitLongScale*100 + label = unitLongLabel + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 154, string.format("HOME %s", label), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawNumber(LCD_W-2, 154+16, dist, MIDSIZE+flags+CUSTOM_COLOR+RIGHT) + + -- home angle + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + libs.drawLib.drawRVehicle(770,208,18,math.floor(telemetry.homeAngle - telemetry.yaw),CUSTOM_COLOR) +end + +function layout.draw(widget) + libs.mapLib.drawMap(widget, 0, 32, 800, 339, status.mapZoomLevel, 7, 3) + if status.wpEnabledMode == 1 and status.wpEnabled == 1 and telemetry.wpNumber > 0 then + -- wp number and distance + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawBitmap(utils.getBitmap("maps_box_60x22"),660-58,35-1) + lcd.drawBitmap(utils.getBitmap("maps_box_60x22"),660-58,35+23) + + lcd.drawText(660, 35, string.format("#%d", telemetry.wpNumber),CUSTOM_COLOR+RIGHT) + lcd.drawText(660, 35+22, string.format("%d%s", telemetry.wpDistance * unitScale,unitLabel),CUSTOM_COLOR+RIGHT) + end + drawTelemetryBar(widget) + drawMiniHud(3, 36) + libs.layoutLib.drawTopBar() + libs.layoutLib.drawStatusBar(2) + -- wind + if conf.enableWIND == true then + lcd.setColor(CUSTOM_COLOR, utils.colors.white) + lcd.drawBitmap(utils.getBitmap("maps_box_60x22"),60,36) + lcd.drawBitmap(utils.getBitmap("maps_box_60x22"),60+60,36) + lcd.drawText(60+30, 36, string.format("%.01f %s", telemetry.trueWindSpeed*conf.horSpeedMultiplier*0.1,conf.horSpeedLabel),CUSTOM_COLOR) + libs.drawLib.drawRArrow(60+15,36+11,8,5,45,telemetry.trueWindAngle-180,CUSTOM_COLOR) + end + + local nextX = libs.drawLib.drawTerrainStatus(4, 74) + libs.drawLib.drawFenceStatus(nextX, 74) + --]] +end + +function layout.background(widget) + libs.drawLib.updateGraph("map_alt", telemetry.homeAlt) +end + +return layout diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_plot.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_plot.lua new file mode 100644 index 00000000..cd4fd444 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_plot.lua @@ -0,0 +1,212 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +local lastProcessCycle = getTime() +local processCycle = 0 + +local layout = {} + +local conf +local telemetry +local status +local utils +local libs + +function layout.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local val1Max = -math.huge +local val1Min = math.huge +local val2Max = -math.huge +local val2Min = math.huge +local initialized = false + +local function drawMiniHud(x,y) + libs.drawLib.drawArtificialHorizon(x, y, 48, 36, nil, lcd.RGB(0x7B, 0x9D, 0xFF), lcd.RGB(0x63, 0x30, 0x00), 6, 6.5, 1.3) + lcd.drawBitmap(utils.getBitmap("hud_48x48a"), x-1, y-10) +end + +local function setup(widget) + if not initialized then + val1Max = -math.huge + val1Min = math.huge + val2Max = -math.huge + val2Min = math.huge + libs.drawLib.resetGraph("plot1") + libs.drawLib.resetGraph("plot2") + initialized = true + end +end + +local function drawTelemetryBar() + local colorLabel = lcd.RGB(140,140,140) + -- CELL + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 34-3, string.upper(status.battsource).." V", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + if status.battery[1] * 0.01 < 10 then + lcd.drawNumber(LCD_W-2, 34+7, status.battery[1] + 0.5, PREC2+MIDSIZE+CUSTOM_COLOR+RIGHT) + else + lcd.drawNumber(LCD_W-2, 34+7, (status.battery[1] + 0.5)*0.1, PREC1+MIDSIZE+CUSTOM_COLOR+RIGHT) + end + -- aggregate batt % + local strperc = string.format("%2d", status.battery[16]) + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, 74-3, "BATT %", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, 74+7, strperc, MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- speed + local speed = telemetry.hSpeed * 0.1 * conf.horSpeedMultiplier + local speedLabel = "GSPD" + if status.airspeedEnabled == 1 then + speed = telemetry.airspeed * 0.1 * conf.horSpeedMultiplier + speedLabel = "ASPD" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 154-3, string.format("%s %s", speedLabel, conf.horSpeedLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-2, 154+7, string.format("%.01f",speed), MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- home distance + local label = unitLabel + local dist = telemetry.homeDist + local flags = 0 + if dist*unitScale > 999 then + flags = flags + PREC2 + dist = dist*unitLongScale*100 + label = unitLongLabel + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 194-3, string.format("HOME %s", label), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawNumber(LCD_W-2, 194+7, dist, MIDSIZE+flags+CUSTOM_COLOR+RIGHT) + + + -- alt + local alt = telemetry.homeAlt * unitScale + local altLabel = "ALT" + if status.terrainEnabled == 1 then + alt = telemetry.heightAboveTerrain * unitScale + altLabel = "HAT" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, 114-3, string.format("%s %s", altLabel, unitLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, 114+7, string.format("%.0f",alt), MIDSIZE+CUSTOM_COLOR+RIGHT) + -- home angle + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + libs.drawLib.drawRVehicle(770,430,18,math.floor(telemetry.homeAngle - telemetry.yaw),CUSTOM_COLOR) +end + + +function layout.draw(widget, customSensors, leftPanel, centerPanel, rightPanel) + setup(widget) + + drawTelemetryBar(widget) + + -- plot area + local PLOT_X = 80 + local PLOT1_Y = 36 + local PLOT2_Y = 214 + local PLOT_W = 600 + local PLOT_H = 165 + + if conf.plotSource1 <= 1 and conf.plotSource2 <= 1 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(80,80,80)) + lcd.drawFilledRectangle(PLOT_X,PLOT1_Y,PLOT_W,PLOT_H,SOLID+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR, lcd.RGB(80,80,80)) + lcd.drawFilledRectangle(PLOT_X,PLOT2_Y,PLOT_W,PLOT_H,SOLID+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT1_Y+PLOT_H/2-8,"no source for graph 1",CUSTOM_COLOR+MIDSIZE+CENTER) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT2_Y+PLOT_H/2-8,"no source for graph 2",CUSTOM_COLOR+MIDSIZE+CENTER) + else + local y1,y2,val1,val2 + if conf.plotSource1 <= 1 or conf.plotSource2 <= 1 then + PLOT1_Y = 34 + PLOT2_Y = 34 + PLOT_H = 341 + end + -- val1 + if conf.plotSource1 > 1 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(80,80,80)) + lcd.drawFilledRectangle(PLOT_X,PLOT1_Y,PLOT_W,PLOT_H,SOLID+CUSTOM_COLOR) + val1 = telemetry[status.plotSources[conf.plotSource1][2]] * status.plotSources[conf.plotSource1][4] * status.unitConversion[status.plotSources[conf.plotSource1][3]] + val1Min = libs.drawLib.getGraphMin("plot1") + val1Max = libs.drawLib.getGraphMax("plot1") + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT1_Y-2,status.plotSources[conf.plotSource1][1],CUSTOM_COLOR+SMLSIZE+CENTER) + lcd.drawText(PLOT_X,PLOT1_Y,string.format("%d", val1Max),CUSTOM_COLOR+SMLSIZE) + lcd.drawText(PLOT_X,PLOT1_Y+PLOT_H-15,string.format("%d", val1Min),CUSTOM_COLOR+SMLSIZE) + y1 = libs.drawLib.drawGraph("plot1", PLOT_X, PLOT1_Y+4, PLOT_W, PLOT_H-8, utils.colors.darkyellow, val1, false, false, nil, 30) + if y1 ~= nil then + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT1_Y+PLOT_H/2-8,string.format("%d", val1),CUSTOM_COLOR+DBLSIZE+CENTER) + end + end + -- val2 + if conf.plotSource2 > 1 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(80,80,80)) + lcd.drawFilledRectangle(PLOT_X,PLOT2_Y,PLOT_W,PLOT_H,SOLID+CUSTOM_COLOR) + val2 = telemetry[status.plotSources[conf.plotSource2][2]] * status.plotSources[conf.plotSource2][4] * status.unitConversion[status.plotSources[conf.plotSource2][3]] + val2Min = libs.drawLib.getGraphMin("plot2") + val2Max = libs.drawLib.getGraphMax("plot2") + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT2_Y-2,status.plotSources[conf.plotSource2][1],CUSTOM_COLOR+SMLSIZE+CENTER) + lcd.drawText(PLOT_X,PLOT2_Y,string.format("%d", val2Max),CUSTOM_COLOR+SMLSIZE) + lcd.drawText(PLOT_X,PLOT2_Y+PLOT_H-15,string.format("%d", val2Min),CUSTOM_COLOR+SMLSIZE) + y2 = libs.drawLib.drawGraph("plot2", PLOT_X, PLOT2_Y+4, PLOT_W, PLOT_H-8, utils.colors.white, val2, false, false, nil, 30) + if y2 ~= nil then + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawText(PLOT_X+PLOT_W/2,PLOT2_Y+PLOT_H/2-8,string.format("%d", val2),CUSTOM_COLOR+DBLSIZE+CENTER) + end + end + end + libs.layoutLib.drawTopBar() + libs.layoutLib.drawStatusBar(2) + local nextX = libs.drawLib.drawTerrainStatus(6,36) + libs.drawLib.drawFenceStatus(nextX,36) +end + +function layout.background(widget) + if status.unitConversion ~= nil then + if conf.plotSource1 > 1 then + libs.drawLib.updateGraph("plot1", telemetry[status.plotSources[conf.plotSource1][2]] * status.plotSources[conf.plotSource1][4] * status.unitConversion[status.plotSources[conf.plotSource1][3]], 50) + end + if conf.plotSource2 > 1 then + libs.drawLib.updateGraph("plot2", telemetry[status.plotSources[conf.plotSource2][2]] * status.plotSources[conf.plotSource2][4] * status.unitConversion[status.plotSources[conf.plotSource2][3]], 50) + end + end +end + +return layout diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_stats.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_stats.lua new file mode 100644 index 00000000..52a0c853 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layout_stats.lua @@ -0,0 +1,129 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local ver, radio, maj, minor, rev = getVersion() + +local lastProcessCycle = getTime() +local processCycle = 0 + +local layout = {} + +local conf +local telemetry +local status +local utils +local libs + +function layout.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local initialized = false + +local function setup(widget) + if not initialized then + initialized = true + end +end + +local function drawRightBar(widget) + local yCell = 34 + local yPERC = 74 + local yALT = 114 + local ySPD = 154 + + local yDIST = 74 + local yHOME = 344 + + local colorLabel = lcd.RGB(140,140,140) + -- CELL + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, yCell-3, string.upper(status.battsource).." V", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + if status.battery[1] * 0.01 < 10 then + lcd.drawNumber(LCD_W-2, yCell+7, status.battery[1] + 0.5, PREC2+TXT_ALIGN+MIDSIZE+CUSTOM_COLOR+RIGHT) + else + lcd.drawNumber(LCD_W-2, yCell+7, (status.battery[1] + 0.5)*0.1, PREC1+TXT_ALIGN+MIDSIZE+CUSTOM_COLOR+RIGHT) + end + --]] + -- aggregate batt % + local strperc = string.format("%2d", status.battery[16]) + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, yPERC-3, "BATT %", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, yPERC+7, strperc, MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- alt + local alt = telemetry.homeAlt * unitScale + local altLabel = "ALT" + if status.terrainEnabled == 1 then + alt = telemetry.heightAboveTerrain * unitScale + altLabel = "HAT" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, yALT-3, string.format("%s %s", altLabel, unitLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-2, yALT+7, string.format("%.0f",alt), MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- speed + local speed = telemetry.hSpeed * 0.1 * conf.horSpeedMultiplier + local speedLabel = "GSPD" + if status.airspeedEnabled == 1 then + speed = telemetry.airspeed * 0.1 * conf.horSpeedMultiplier + speedLabel = "ASPD" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, ySPD-3, string.format("%s %s", speedLabel, conf.horSpeedLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-2, ySPD+7, string.format("%.01f",speed), MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- home distance + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(6, yDIST-3, string.format("HOME %s", unitLabel), SMLSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(6, yDIST+7, string.format("%.0f",telemetry.homeDist*unitScale), MIDSIZE+CUSTOM_COLOR) + + -- home angle + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + libs.drawLib.drawRVehicle(770,430,18,math.floor(telemetry.homeAngle - telemetry.yaw),CUSTOM_COLOR) +end + +function layout.draw(widget, customSensors, leftPanel, centerPanel, rightPanel) + setup(widget) + drawRightBar(widget) + + libs.layoutLib.drawTopBar() + libs.layoutLib.drawStatusBar(2) + local nextX = libs.drawLib.drawTerrainStatus(6,36) + libs.drawLib.drawFenceStatus(nextX,36) +end + +function layout.background(widget) +end + +return layout diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layoutlib.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layoutlib.lua new file mode 100644 index 00000000..437d5bdd --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/layoutlib.lua @@ -0,0 +1,162 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local layoutLib = {} + +local status +local telemetry +local conf +local utils +local libs + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +function layoutLib.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function layoutLib.drawTopBar() + lcd.setColor(CUSTOM_COLOR, utils.colors.bars) + -- black bar + lcd.drawFilledRectangle(0,0, LCD_W, 32, CUSTOM_COLOR) + -- frametype and model name + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + if status.modelString ~= nil then + local modelString = status.currentScreen == 1 and status.modelString or string.format("[%d] %s",status.currentScreen, status.modelString) + lcd.drawText(2, 6, modelString, CUSTOM_COLOR) + end + -- flight time + local time = getDateTime() + local strtime = string.format("%02d:%02d:%02d",time.hour,time.min,time.sec) + lcd.drawText(LCD_W, 10, strtime, SMLSIZE+RIGHT+CUSTOM_COLOR) + -- RSSI + if utils.telemetryEnabled() == false then + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + lcd.drawText(500, 6, "NO TELEM", 0+CUSTOM_COLOR) + else + utils.drawRssi() + end + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- tx voltage + local vtx = string.format("%.1fv",getValue(getFieldInfo("tx-voltage").id)) + lcd.drawText(652,10, vtx, 0+CUSTOM_COLOR+SMLSIZE) +end + +function layoutLib.drawNoTelemetryData(telemetryEnabled) + -- no telemetry data + if (not utils.telemetryEnabled()) then + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawFilledRectangle(147,131, 506, 148, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + lcd.drawFilledRectangle(149,133, 502, 144, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(400, 150, "no telemetry data", DBLSIZE+CUSTOM_COLOR+CENTER) + lcd.drawText(400, 221, "Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")", SMLSIZE+CUSTOM_COLOR+CENTER) + libs.layoutLib.drawTopBar() + local info = model.getInfo() + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(0,6,info.name,CUSTOM_COLOR) + end +end + +function layoutLib.drawWidgetPaused() + if conf.pauseTelemetry == true then + lcd.setColor(CUSTOM_COLOR,BLACK) + lcd.drawFilledRectangle(147,131, 506, 148, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + lcd.drawFilledRectangle(149,133, 502, 144, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,BLACK) + lcd.drawText(400, 150, "WIDGET PAUSED", DBLSIZE+CUSTOM_COLOR+CENTER) + lcd.drawText(400, 221, "Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")", SMLSIZE+CUSTOM_COLOR+CENTER) + end +end + +function layoutLib.drawStatusBar(maxRows) + local yDelta = (maxRows-1)*21 + + lcd.setColor(CUSTOM_COLOR,utils.colors.bars) + lcd.drawFilledRectangle(0,400-yDelta,800,LCD_H-(400-yDelta),CUSTOM_COLOR) + -- flight time + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawTimer(LCD_W, 390-yDelta, model.getTimer(2).value, DBLSIZE+CUSTOM_COLOR+RIGHT) + -- flight mode + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + if status.strFlightMode ~= nil then + lcd.drawText(1,401-yDelta,status.strFlightMode,MIDSIZE+CUSTOM_COLOR) + end + -- gps status, draw coordinates if good at least once + if telemetry.lon ~= nil and telemetry.lat ~= nil then + lcd.drawText(625, 396-yDelta, telemetry.strLat, SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.drawText(625, 422-yDelta, telemetry.strLon, SMLSIZE+CUSTOM_COLOR+RIGHT) + end + -- gps status + local hdop = telemetry.gpsHdopC + local strStatus = utils.gpsStatuses[telemetry.gpsStatus] + local flags = BLINK + local mult = 1 + + if telemetry.gpsStatus > 2 then + if telemetry.homeAngle ~= -1 then + flags = PREC1 + end + if hdop > 999 then + hdop = 999 + flags = 0 + mult=0.1 + elseif hdop > 99 then + flags = 0 + mult=0.1 + end + lcd.drawNumber(407,394-yDelta, hdop*mult,DBLSIZE+flags+CUSTOM_COLOR) + -- SATS + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(343,401-yDelta, utils.gpsStatuses[telemetry.gpsStatus][1], SMLSIZE+CUSTOM_COLOR) + lcd.drawText(343,420-yDelta, utils.gpsStatuses[telemetry.gpsStatus][2], SMLSIZE+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + if telemetry.numSats == 15 then + lcd.drawNumber(330,394-yDelta, telemetry.numSats, DBLSIZE+CUSTOM_COLOR+RIGHT) + lcd.drawText(330,409-yDelta, "+", SMLSIZE+CUSTOM_COLOR) + else + lcd.drawNumber(330,394-yDelta,telemetry.numSats, DBLSIZE+CUSTOM_COLOR+RIGHT) + end + elseif telemetry.gpsStatus == 0 then + utils.drawBlinkBitmap("nogpsicon",250,396-yDelta) + else + utils.drawBlinkBitmap("nolockicon",250,396-yDelta) + end + + local offset = math.min(maxRows,#status.messages+1) + for i=0,offset-1 do + lcd.setColor(CUSTOM_COLOR,utils.mavSeverity[status.messages[(status.messageCount + i - offset) % (#status.messages+1)][2]][2]) + lcd.drawText(1,(450-yDelta)+(21*i), status.messages[(status.messageCount + i - offset) % (#status.messages+1)][1],SMLSIZE+CUSTOM_COLOR) + end +end + +return layoutLib diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_def.lua new file mode 100644 index 00000000..89753f95 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_def.lua @@ -0,0 +1,124 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + local colorLabel = lcd.RGB(140, 140, 140) + --[[ + lcd.setColor(CUSTOM_COLOR,lcd.RGB(5,52,85)) + lcd.drawRectangle(x, 18, 120, 43, CUSTOM_COLOR) + lcd.drawRectangle(x, 61, 120, 43, CUSTOM_COLOR) + lcd.drawRectangle(x, 104, 120, 44, CUSTOM_COLOR) + --]] + lcd.setColor(CUSTOM_COLOR,colorLabel) + --lcd.drawBitmap(utils.getBitmap("left_def"),x,18) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + if conf.rangeFinderMax > 0 then + flags = 0 + local rng = telemetry.range + rng = utils.getMaxValue(rng,16) + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + if rng > conf.rangeFinderMax and status.showMinMaxValues == false then + lcd.drawFilledRectangle(x+13, y+16+7,170,48, CUSTOM_COLOR) + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+0, string.format("RANGE %s",unitLabel), SMLSIZE+CUSTOM_COLOR) + --lcd.drawText(100, 9+10, unitLabel, SMLSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(x+17, y+16, string.format("%.1f",rng*0.01*unitScale), DBLSIZE+CUSTOM_COLOR) + else + flags = BLINK + -- always display gps altitude even without 3d lock + local alt = telemetry.gpsAlt/10 + if telemetry.gpsStatus > 2 then + flags = 0 + -- update max only with 3d or better lock + alt = utils.getMaxValue(alt,12) + end + if status.showMinMaxValues == true then + flags = 0 + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+0, string.format("GALT %s",unitLabel), SMLSIZE+CUSTOM_COLOR) + local stralt = string.format("%d",alt*unitScale) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(x+17, y+16, stralt, DBLSIZE+flags+CUSTOM_COLOR) + end + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- home distance + flags = 0 + if telemetry.homeAngle == -1 then + flags = BLINK + end + local dist = utils.getMaxValue(telemetry.homeDist,15) + if status.showMinMaxValues == true then + flags = 0 + end + local label = unitLabel + if dist*unitScale > 999 then + flags = flags + PREC2 + dist = dist*unitLongScale*100 + label = unitLongLabel + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+74, string.format("HOME %s",label), SMLSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawNumber(x+17, y+90, dist, DBLSIZE+flags+CUSTOM_COLOR) + + -- total distance + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+152, string.format("TRAVEL %s",unitLongLabel), SMLSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local mult = telemetry.totalDist*unitLongScale > 99 and 10 or 100 + local prec = telemetry.totalDist*unitLongScale > 99 and PREC1 or PREC2 + lcd.drawNumber(x+17, y+168, telemetry.totalDist*unitLongScale*mult, prec+DBLSIZE+CUSTOM_COLOR) + + if status.showMinMaxValues == true then + libs.drawLib.drawVArrow(x+7, y+16 + 7,true,false) + libs.drawLib.drawVArrow(x+7, y+90 + 7 ,true,false) + end +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_dualcurr_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_dualcurr_def.lua new file mode 100644 index 00000000..e74574a9 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_dualcurr_def.lua @@ -0,0 +1,157 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140, 140, 140)) + lcd.drawText(x+2,y+-4,"B1",0+CUSTOM_COLOR+SMLSIZE) + lcd.drawText(x+2,y+111,"B2",0+CUSTOM_COLOR+SMLSIZE) + + local perc1 = status.battery[16+1] + local perc2 = status.battery[16+2] + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- battery 1 current + local flagUseDecimals = status.battery[7+1]*0.1 < 10 + libs.drawLib.drawNumberWithDim(x+167,y+-7,x+167,y+11,status.battery[7+1]*(flagUseDecimals and 1 or 0.1),"A",MIDSIZE+RIGHT+CUSTOM_COLOR+(flagUseDecimals and PREC1 or 0),SMLSIZE+CUSTOM_COLOR) + -- battery 2 current + flagUseDecimals = status.battery[7+2]*0.1 < 10 + libs.drawLib.drawNumberWithDim(x+167,y+108,x+167,y+126,status.battery[7+2]*(flagUseDecimals and 1 or 0.1),"A",MIDSIZE+RIGHT+CUSTOM_COLOR+(flagUseDecimals and PREC1 or 0),SMLSIZE+CUSTOM_COLOR) + -- battery 1 capacity bar % + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawFilledRectangle(x+17, y+44,167,32,CUSTOM_COLOR) + if perc1 > 50 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(0,255,0)) + elseif perc1 <= 50 and perc1 > 25 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 204, 0)) -- yellow + else + lcd.setColor(CUSTOM_COLOR, utils.colors.red) + end + lcd.drawGauge(x+17, y+44,167,32,perc1,100,CUSTOM_COLOR) + -- battery 2 capacity bar % + lcd.setColor(CUSTOM_COLOR, WHITE) + lcd.drawFilledRectangle(x+17, y+159,167,32,CUSTOM_COLOR) + if perc2 > 50 then + lcd.setColor(CUSTOM_COLOR, lcd.RGB(0,255,0)) + elseif perc2 <= 50 and perc2 > 25 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 204, 0)) -- yellow + else + lcd.setColor(CUSTOM_COLOR, RED) + end + lcd.drawGauge(x+17, y+159,167,32,perc2,100,CUSTOM_COLOR) + -- battery 1 percentage + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + local strperc = string.format("%02d%%",perc1) + lcd.drawText(x+87, y+42, strperc, 0+CUSTOM_COLOR) + -- battery 2 percentage + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + strperc = string.format("%02d%%",perc2) + lcd.drawText(x+87, y+157, strperc, 0+CUSTOM_COLOR) + -- battery 1 mah + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local strmah = string.format("%.02f/%.01fAh",status.battery[10+1]/1000,status.battery[13+1]/1000) + lcd.drawText(x+183, y+78, strmah, SMLSIZE+RIGHT+CUSTOM_COLOR) + -- label + -- battery 2 mah + strmah = string.format("%.02f/%.01fAh",status.battery[10+2]/1000,status.battery[13+2]/1000) + lcd.drawText(x+183, y+193, strmah, SMLSIZE+RIGHT+CUSTOM_COLOR) + + -- GPS Altitude uses either RPM1 panel or overrides Efficiency panel + local gpsAltX = x+153 + if conf.enableRPM == 2 or conf.enableRPM == 3 then + status.hideEfficiency = 1 + gpsAltX = x+658 + end + -- use power panel if RPM2 is enabled + local homeDistX = x+320 + if conf.enableRPM == 3 then + status.hidePower = 1 + homeDistX = x+797 + end + -- home distance + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140,140,140)) + lcd.drawText(homeDistX, y+230, "HOME("..unitLabel..")", SMLSIZE+RIGHT+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local flags = 0 + if telemetry.homeAngle == -1 then + flags = BLINK + end + local dist = utils.getMaxValue(telemetry.homeDist,15) + if status.showMinMaxValues == true then + flags = 0 + end + local strdist = string.format("%d",dist*unitScale) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(homeDistX, y+257, strdist, MIDSIZE+flags+RIGHT+CUSTOM_COLOR) + -- GPS Altitude and rangefinder + if conf.rangeFinderMax > 0 then + flags = 0 + local rng = telemetry.range + rng = utils.getMaxValue(rng,16) + lcd.setColor(CUSTOM_COLOR,utils.colors.lightgrey) + lcd.drawText(gpsAltX, y+230, "RNG("..unitLabel..")", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + if rng > conf.rangeFinderMax and status.showMinMaxValues == false then + lcd.drawFilledRectangle(gpsAltX-108, y+264,108,37,CUSTOM_COLOR) + end + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(gpsAltX, y+257, string.format("%.1f",rng*0.01*unitScale), MIDSIZE+RIGHT+CUSTOM_COLOR) + else + flags = BLINK + -- always display gps altitude even without 3d lock + local alt = telemetry.gpsAlt/10 + if telemetry.gpsStatus > 2 then + flags = 0 + -- update max only with 3d or better lock + alt = utils.getMaxValue(alt,12) + end + if status.showMinMaxValues == true then + flags = 0 + end + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140,140,140)) + lcd.drawText(gpsAltX, y+230, "GALT("..unitLabel..")", SMLSIZE+CUSTOM_COLOR+RIGHT) + local stralt = string.format("%d",alt*unitScale) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(gpsAltX, y+257, stralt, MIDSIZE+flags+RIGHT+CUSTOM_COLOR) + end +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_wp_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_wp_def.lua new file mode 100644 index 00000000..b3cf0fbf --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/left_wp_def.lua @@ -0,0 +1,140 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +--# include "includes/layout_def_inc.lua" +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + local colorLabel = lcd.RGB(140, 140, 140) + local flags = 0 + if conf.rangeFinderMax > 0 then + local rng = telemetry.range + rng = utils.getMaxValue(rng,16) + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+-7, "RNG "..unitLabel, SMLSIZE+CUSTOM_COLOR) + if rng > conf.rangeFinderMax and status.showMinMaxValues == false then + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + lcd.drawFilledRectangle(x+17-108, y+9+7,108,37,CUSTOM_COLOR) + end + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(x+17, y+9, string.format("%.1f",rng*0.01*unitScale), MIDSIZE+flags+CUSTOM_COLOR) + else + flags = BLINK + -- always display gps altitude even without 3d lock + local alt = telemetry.gpsAlt/10 + if telemetry.gpsStatus > 2 then + flags = 0 + -- update max only with 3d or better lock + alt = utils.getMaxValue(alt,12) + end + if status.showMinMaxValues == true then + flags = 0 + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+-7, "GALT "..unitLabel, SMLSIZE+CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawNumber(x+17, y+9, alt*unitScale, MIDSIZE+flags+CUSTOM_COLOR) + end + -- LABELS + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(x+17, y+55, "HOME-TRAVEL", SMLSIZE+CUSTOM_COLOR) + lcd.drawText(x+17, y+143, "WP "..unitLabel, SMLSIZE+CUSTOM_COLOR) + -- VALUES + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- home distance + flags = 0 + if telemetry.homeAngle == -1 then + flags = BLINK + end + local dist = utils.getMaxValue(telemetry.homeDist,15) + if status.showMinMaxValues == true then + flags = 0 + end + local strdist = string.format("%d%s",dist*unitScale,unitLabel) + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + if dist < 999 then + lcd.drawText(x+17, y+71, strdist, MIDSIZE+flags+CUSTOM_COLOR) + else + lcd.drawText(x+17, y+71, string.format("%0.2f%s", dist*unitLongScale, unitLongLabel), MIDSIZE+flags+CUSTOM_COLOR) + end + -- total distance + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(x+17, y+110, string.format("%0.2f%s", telemetry.totalDist*unitLongScale, unitLongLabel), SMLSIZE+CUSTOM_COLOR+PREC2) + -- draw WP info only for supported flight modes + -- AUTO, GUIDED, LOITER, RTL, QRTL, QLOITER, QLAND, FOLLOW, ZIGZAG + if status.wpEnabledMode == 1 then + -- wp number + lcd.drawText(x+17, y+198, string.format("#%d",telemetry.wpNumber),SMLSIZE+CUSTOM_COLOR) + -- wp distance + lcd.drawNumber(x+17, y+161, telemetry.wpDistance * unitScale,MIDSIZE+CUSTOM_COLOR) + -- LINES + lcd.setColor(CUSTOM_COLOR,utils.colors.white) --yellow + -- wp bearing + libs.drawLib.drawRVehicle(x+167,y+198,22,telemetry.wpOffsetFromCog,CUSTOM_COLOR) + else + -- wp number + lcd.drawText(x+17, y+198, "# ---",SMLSIZE+CUSTOM_COLOR) + -- wp distance + lcd.drawText(x+17, y+161, "---",MIDSIZE+CUSTOM_COLOR) + -- LINES + lcd.setColor(CUSTOM_COLOR,utils.colors.white) --yellow + -- wp bearing + libs.drawLib.drawRVehicle(x+167, y+198, 22, 0, CUSTOM_COLOR) + end + + if status.showMinMaxValues == true then + libs.drawLib.drawVArrow(x+5, y+9+7,true,false) + libs.drawLib.drawVArrow(x+5, y+71+7 ,true,false) + end +end + +function panel.background(myWidget) + -- RC CHANNELS + --[[ + if conf.enableRCChannels == true then + for i=1,#telemetry.rcchannels do + setTelemetryValue(Thr_ID, Thr_SUBID, Thr_INSTANCE + i, telemetry.rcchannels[i], 13 , Thr_PRECISION , "RC"..i) + end + end + --]] + + -- WP + setTelemetryValue(0x050F, 0, 10, telemetry.wpNumber, 0 , 0 , "WPN") + setTelemetryValue(0x082F, 0, 10, telemetry.wpDistance, 9 , 0 , "WPD") +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/maplib.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/maplib.lua new file mode 100644 index 00000000..611bc9e1 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/maplib.lua @@ -0,0 +1,478 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local mapLib = {} + +local status +local telemetry +local conf +local utils +local libs + +local MAP_X = (LCD_W-800)/2 +local MAP_Y = 32 +local TILES_X = 7 +local TILES_Y = 3 + +--[[ + for info see https://github.com/heldersepu/GMapCatcher + + Notes: + - tiles need to be resized down to 100x100 from original size of 256x256 + - at max zoom level (-2) 1 tile = 100px = 76.5m +]] + +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() + +-- map support +local posUpdated = false +local myScreenX, myScreenY +local homeScreenX, homeScreenY +local estimatedHomeScreenX, estimatedHomeScreenY +local wpScreenX,wpScreenY +local tile_x,tile_y,offset_x,offset_y +local home_tile_x,home_tile_y,home_offset_x,home_offset_y +local tiles = {} +local tilesXYByPath = {} +local tiles_path_to_idx = {} -- path to idx cache +local mapBitmapByPath = {} +local nomap = nil +local world_tiles +local tiles_per_radian +local tile_dim +local scaleLen +local scaleLabel +local posHistory = {} +local homeNeedsRefresh = true +local sample = 0 +local sampleCount = 0 +local lastPosUpdate = getTime() +local lastPosSample = getTime() +local lastHomePosUpdate = getTime() +local lastZoomLevel = -99 +local estimatedHomeGps = { + lat = nil, + lon = nil +} + +local drawCycle = 0 +local avgDistSamples = {} +local avgDist = 0; +local avgDistSum = 0; +local avgDistSample = 0; +local avgDistSampleCount = 0; +local avgDistLastSampleTime = getTime(); +avgDistSamples[0] = 0 + +local coord_to_tiles = nil +local tiles_to_path = nil +local MinLatitude = -85.05112878; +local MaxLatitude = 85.05112878; +local MinLongitude = -180; +local MaxLongitude = 180; + +function mapLib.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +local function clip(n, min, max) + return math.min(math.max(n, min), max) +end + +local function tiles_on_level(conf,level) + if conf.mapProvider == 1 then + return bit32.lshift(1,17 - level) + else + return 2^level + end +end + +--[[ + total tiles on the web mercator projection = 2^zoom*2^zoom +--]] +local function get_tile_matrix_size_pixel(level) + local size = 2^level * 100 + return size, size +end + +--[[ + https://developers.google.com/maps/documentation/javascript/coordinates + https://github.com/judero01col/GMap.NET + + Questa funzione ritorna il pixel (assoluto) associato alle coordinate. + La proiezione di mercatore è una matrice di pixel, tanto più grande quanto è elevato il valore dello zoom. + zoom 1 = 1x1 tiles + zoom 2 = 2x2 tiles + zoom 3 = 4x4 tiles + ... + in cui ogni tile è di 256x256 px. + in generale la matrice ha dimensioni 2^(zoom-1)*2^(zoom-1) + Per risalire al singolo tile si divide per 256 (largezza del tile): + + tile_x = math.floor(x_coord/256) + tile_y = math.floor(y_coord/256) + + Le coordinate relative all'interno del tile si calcolano con l'operatore modulo a partire dall'angolo in alto a sx + + x_offset = x_coord%256 + y_offset = y_coord%256 + + Su filesystem il percorso è /tile_y/tile_x.png +--]] +local function google_coord_to_tiles(lat, lng, level) + lat = clip(lat, MinLatitude, MaxLatitude) + lng = clip(lng, MinLongitude, MaxLongitude) + + local x = (lng + 180) / 360 + local sinLatitude = math.sin(lat * math.pi / 180) + local y = 0.5 - math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * math.pi) + + local mapSizeX, mapSizeY = get_tile_matrix_size_pixel(level) + + -- absolute pixel coordinates on the mercator projection at this zoom level + local rx = clip(x * mapSizeX + 0.5, 0, mapSizeX - 1) + local ry = clip(y * mapSizeY + 0.5, 0, mapSizeY - 1) + -- return tile_x, tile_y, offset_x, offset_y + return math.floor(rx/100), math.floor(ry/100), math.floor(rx%100), math.floor(ry%100) +end + +local function qgis_coord_to_tiles(lat, lng, level) + lat = clip(lat, MinLatitude, MaxLatitude) + lng = clip(lng, MinLongitude, MaxLongitude) + + local x = (lng + 180) / 360 + local sinLatitude = math.sin(lat * math.pi / 180) + local y = 0.5 - math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * math.pi) + + local mapSizeX, mapSizeY = get_tile_matrix_size_pixel(level) + + -- absolute pixel coordinates on the mercator projection at this zoom level + local rx = clip(x * mapSizeX + 0.5, 0, mapSizeX - 1) + local ry = clip(y * mapSizeY + 0.5, 0, mapSizeY - 1) + -- return tile_x, tile_y, offset_x, offset_y + return math.floor(rx/100), math.floor(ry/100), math.floor(rx%100), math.floor(ry%100) +end + +local function gmapcacther_coord_to_tiles(lat, lon, level) + local x = world_tiles / 360 * (lon + 180) + local e = math.sin(lat * (1/180 * math.pi)) + local y = world_tiles / 2 + 0.5 * math.log((1+e)/(1-e)) * -1 * tiles_per_radian + -- return tile_x, tile_y, offset_x, offset_y + return math.floor(x % world_tiles), math.floor(y % world_tiles), math.floor((x - math.floor(x)) * 100), math.floor((y - math.floor(y)) * 100) +end + +local function google_tiles_to_path(tile_x, tile_y, level) + return string.format("/%d/%d/s_%d.jpg", level, tile_y, tile_x) +end + +local function gmapcatcher_tiles_to_path(tile_x, tile_y, level) + return string.format("/%d/%d/%d/%d/s_%d.png", level, tile_x/1024, tile_x%1024, tile_y/1024, tile_y%1024) +end + +local function qgis_tiles_to_path(tile_x, tile_y, level) + return string.format("/%d/%d/%d.jpg", level, tile_x, tile_y) +end + +local function getTileBitmap(tilePath) + local fullPath = "/IMAGES/yaapu/maps/"..conf.mapType..tilePath + -- check cache + if mapBitmapByPath[tilePath] ~= nil then + return mapBitmapByPath[tilePath] + end + + local bmp = Bitmap.open(fullPath) + local w,h = Bitmap.getSize(bmp) + + if w > 0 then + mapBitmapByPath[tilePath] = bmp + return bmp + else + if nomap == nil then + nomap = Bitmap.open("/IMAGES/Yaapu/maps/nomap.png") + end + mapBitmapByPath[tilePath] = nomap + return nomap + end +end + +local function loadAndCenterTiles(tile_x,tile_y,offset_x,offset_y,width,level) + -- determine if upper or lower center tile + local yy = 2 + if offset_y > 100/2 then + yy = 1 + end + for x=1,TILES_X + do + for y=1,TILES_Y + do + local tile_path = tiles_to_path(tile_x+x-2, tile_y+y-yy, level) + local idx = width*(y-1)+x + + if tiles[idx] == nil then + tiles[idx] = tile_path + tiles_path_to_idx[tile_path] = { idx, x, y } + else + if tiles[idx] ~= tile_path then + tiles[idx] = tile_path + tiles_path_to_idx[tile_path] = { idx, x, y } + end + end + tilesXYByPath[tile_path] = {x,y} + end + end + -- release unused cached images + for path, bmp in pairs(mapBitmapByPath) do + local remove = true + for i=1,#tiles + do + if tiles[i] == path then + remove = false + end + end + if remove then + mapBitmapByPath[path]=nil + tiles_path_to_idx[path]=nil + tilesXYByPath[path] = nil + end + end + -- force a call to destroyBitmap() + collectgarbage() + collectgarbage() +end + +local function drawTiles(width,xmin,xmax,ymin,ymax,color,level) + for x=1,TILES_X + do + for y=1,TILES_Y + do + local idx = width*(y-1)+x + if tiles[idx] ~= nil then + lcd.drawBitmap(getTileBitmap(tiles[idx]), xmin+(x-1)*100, ymin+(y-1)*100) + end + end + end + if conf.enableMapGrid then + -- draw grid + for x=1,TILES_X-1 + do + lcd.drawLine(xmin+x*100,ymin,xmin+x*100,ymax,DOTTED,color) + end + + for y=1,TILES_Y-1 + do + lcd.drawLine(xmin,ymin+y*100,xmax,ymin+y*100,DOTTED,color) + end + end + -- draw 50m or 150ft line at max zoom + lcd.drawBitmap(utils.getBitmap("maps_box_150x16"),xmin+3,ymax-19) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawLine(xmin+5,ymax-6,xmin+5+scaleLen,ymax-6,SOLID,CUSTOM_COLOR) + lcd.drawText(xmin+5,ymax-20,string.format("%s (%d)", scaleLabel, level),SMLSIZE+CUSTOM_COLOR) +end + +local function getScreenCoordinates(minX,minY,tile_x,tile_y,offset_x,offset_y,level) + -- is this tile on screen ? + local tile_path = tiles_to_path(tile_x, tile_y, level) + local tcache = tiles_path_to_idx[tile_path] + if tcache ~= nil then + if tiles[tcache[1]] ~= nil then + -- ok it's on screen + return minX + (tcache[2]-1)*100 + offset_x, minY + (tcache[3]-1)*100 + offset_y + end + end + -- force offscreen up + return LCD_W/2, -10 +end + +local function setupMaps(x, y, level, tiles_x, tiles_y) + if level == nil or tiles_x == nil or tiles_y == nil or x == nil or y == nil then + return + end + + MAP_X = x + MAP_Y = y + + TILES_X = tiles_x + TILES_Y = tiles_y + + if level ~= lastZoomLevel then + utils.clearTable(tiles) + utils.clearTable(mapBitmapByPath) + utils.clearTable(posHistory) + + sample = 0 + sampleCount = 0 + + world_tiles = tiles_on_level(conf,level) + tiles_per_radian = world_tiles / (2 * math.pi) + + if conf.mapProvider == 1 then + coord_to_tiles = gmapcacther_coord_to_tiles + tiles_to_path = gmapcatcher_tiles_to_path + tile_dim = (40075017/world_tiles) * unitScale -- m or ft + scaleLabel = tostring((unitScale==1 and 1 or 3)*50*2^(level+2))..unitLabel + scaleLen = ((unitScale==1 and 1 or 3)*50*2^(level+2)/tile_dim)*100 + elseif conf.mapProvider == 2 then + coord_to_tiles = google_coord_to_tiles + tiles_to_path = google_tiles_to_path + tile_dim = (40075017/world_tiles) * unitScale -- m or ft + scaleLabel = tostring((unitScale==1 and 1 or 3)*50*2^(20-level))..unitLabel + scaleLen = ((unitScale==1 and 1 or 3)*50*2^(20-level)/tile_dim)*100 + elseif conf.mapProvider == 3 then + coord_to_tiles = qgis_coord_to_tiles + tiles_to_path = qgis_tiles_to_path + tile_dim = (40075017/world_tiles) * unitScale -- m or ft + scaleLabel = tostring((unitScale==1 and 1 or 3)*50*2^(20-level))..unitLabel + scaleLen = ((unitScale==1 and 1 or 3)*50*2^(20-level)/tile_dim)*100 + end + + lastZoomLevel = level + end + drawCycle = (drawCycle+1) % 2 +end + +function mapLib.drawMap(widget, x, y, w, h, level, tiles_x, tiles_y) + setupMaps(x, y, level, tiles_x, tiles_y) + + if tiles_to_path == nil or coord_to_tiles == nil then + return + end + + local minX = math.max(0,MAP_X) + local maxX = math.min(LCD_W, math.min(minX+w, minX+TILES_X*100)) + + local minY = math.max(0,MAP_Y) + local maxY = math.min(LCD_H, math.min(minY+h, minY+TILES_Y*100)) + + if telemetry.lat ~= nil and telemetry.lon ~= nil then + -- position update on even cycles + if getTime() - lastPosUpdate > 50 and drawCycle%2==0 then + posUpdated = true + lastPosUpdate = getTime() + -- current vehicle tile coordinates + tile_x,tile_y,offset_x,offset_y = coord_to_tiles(telemetry.lat,telemetry.lon,level) + -- viewport relative coordinates + myScreenX,myScreenY = getScreenCoordinates(minX,minY,tile_x,tile_y,offset_x,offset_y,level) + -- check if offscreen + local myCode = libs.drawLib.computeOutCode(myScreenX, myScreenY, minX+17, minY+17, maxX-17, maxY-17); + + -- center vehicle on screen + if myCode > 0 then + loadAndCenterTiles(tile_x, tile_y, offset_x, offset_y, TILES_X, level) + -- after centering screen position needs to be computed again + tile_x,tile_y,offset_x,offset_y = coord_to_tiles(telemetry.lat,telemetry.lon,level) + myScreenX,myScreenY = getScreenCoordinates(minX,minY,tile_x,tile_y,offset_x,offset_y,level) + end + end + + -- home position update on odd cycles + if getTime() - lastHomePosUpdate > 50 and posUpdated and drawCycle%2==0 then + lastHomePosUpdate = getTime() + if homeNeedsRefresh then + -- update home, schedule estimated home update + homeNeedsRefresh = false + if telemetry.homeLat ~= nil then + -- current vehicle tile coordinates + home_tile_x,home_tile_y,home_offset_x,home_offset_y = coord_to_tiles(telemetry.homeLat,telemetry.homeLon,level) + -- viewport relative coordinates + homeScreenX,homeScreenY = getScreenCoordinates(minX,minY,home_tile_x,home_tile_y,home_offset_x,home_offset_y,level) + end + else + homeNeedsRefresh = true + end + end + + -- position history sampling + if getTime() - lastPosSample > 25 and posUpdated then + lastPosSample = getTime() + posUpdated = false + -- points history + local path = tiles_to_path(tile_x, tile_y, level) + posHistory[sample] = { path, offset_x, offset_y } + sampleCount = sampleCount+1 + sample = sampleCount%10 + end + + -- draw map tiles + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + drawTiles(TILES_X,minX,maxX,minY,maxY,CUSTOM_COLOR,level) + -- draw home on odd + if telemetry.homeLat ~= nil and telemetry.homeLon ~= nil and homeScreenX ~= nil then + local homeCode = libs.drawLib.computeOutCode(homeScreenX, homeScreenY, minX+11, minY+10, maxX-11, maxY-10); + if homeCode == 0 then + lcd.drawBitmap(utils.getBitmap("homeorange"),homeScreenX-11,homeScreenY-10) + end + end + + -- draw vehicle + if myScreenX ~= nil then + lcd.setColor(CUSTOM_COLOR,WHITE) + libs.drawLib.drawRVehicle(myScreenX,myScreenY,17-5,telemetry.yaw,CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,BLACK) + libs.drawLib.drawRVehicle(myScreenX,myScreenY,17,telemetry.yaw,CUSTOM_COLOR) + -- WP drawing enabled only for selected flight modes + -- AUTO, GUIDED, LOITER, RTL, QRTL, QLOITER, QLAND, FOLLOW, ZIGZAG + if status.wpEnabledMode == 1 and status.wpEnabled == 1 and telemetry.wpNumber > 0 then + -- draw current waypoint info in white + -- calc new position on odd cycles + if drawCycle%2==1 and status.wpLat ~= nil and status.wpLon ~= nil then + tile_x,tile_y,offset_x,offset_y = coord_to_tiles(status.wpLat, status.wpLon, level) + wpScreenX,wpScreenY = getScreenCoordinates(minX,minY,tile_x,tile_y,offset_x,offset_y,level) + end + if wpScreenX ~= nil then + local myCode = libs.drawLib.computeOutCode(wpScreenX, wpScreenY, minX+4, minY+4, maxX-4, maxY-4); + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + if myCode == 0 then + lcd.drawLine(myScreenX,myScreenY,wpScreenX,wpScreenY,DOTTED,CUSTOM_COLOR) + lcd.drawRectangle(wpScreenX-2,wpScreenY-2,4,4,CUSTOM_COLOR) + lcd.drawText(wpScreenX,wpScreenY,telemetry.wpNumber,SMLSIZE+CUSTOM_COLOR) + else + libs.drawLib.drawLineByOriginAndAngle(myScreenX, myScreenY, telemetry.wpBearing-90, 2*800, DOTTED, minX, maxX, minY, maxY, CUSTOM_COLOR, false) + end + end + end + end + -- draw gps trace + lcd.setColor(CUSTOM_COLOR,utils.colors.yellow) + for p=0, math.min(sampleCount-1,10-1) + do + if p ~= (sampleCount-1)%10 then + -- check if on screen + if tilesXYByPath[posHistory[p][1]] ~= nil then + local x = tilesXYByPath[posHistory[p][1]][1] + local y = tilesXYByPath[posHistory[p][1]][2] + lcd.drawFilledRectangle(minX + (x-1)*100 + posHistory[p][2]-1, minY + (y-1)*100 + posHistory[p][3]-1,3,3,CUSTOM_COLOR) + end + end + end + end + lcd.setColor(CUSTOM_COLOR,utils.colors.white) +end + +return mapLib diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/panels.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/panels.lua new file mode 100644 index 00000000..664d7966 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/panels.lua @@ -0,0 +1,71 @@ +local panels = { + default = { + center = { + labels = { + "default", +--[[ + "navigation", + "radar" +--]] + }, + files = { + "hud_def", +--[[ + "hud_nav_def", + "hud_radar_def" +--]] + }, + options = { + 1, +--[[ + 2, + 3, +--]] + } + }, + left = { + labels = { + "default", + "waypoint info", + "dual current", + }, + files = { + "left_def", + "left_wp_def", + "left_dualcurr_def" + }, + options = { + 1, + 2, + 3, + } + }, + right = { + labels = { + "default", + "batt % by voltage", + "tether", + "hybrid", + "user selected sensors", + "no cell voltage", + }, + files = { + "right_def", + "right_battperc_def", + "right_tether_def", + "right_hybrid_def", + "right_custom_def", + "right_nocellv_def", + }, + options = { + 1, + 2, + 3, + 4, + 5, + 6, + } + } + } +} +return { panels=panels } diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane.lua new file mode 100644 index 00000000..5a337088 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane.lua @@ -0,0 +1,113 @@ +--[[ +enum FlightMode { + MANUAL = 0, + CIRCLE = 1, + STABILIZE = 2, + TRAINING = 3, + ACRO = 4, + FLY_BY_WIRE_A = 5, + FLY_BY_WIRE_B = 6, + CRUISE = 7, + AUTOTUNE = 8, + AUTO = 10, + RTL = 11, + LOITER = 12, + TAKEOFF = 13, + AVOID_ADSB = 14, + GUIDED = 15, + INITIALISING = 16, + QSTABILIZE = 17, + QHOVER = 18, + QLOITER = 19, + QLAND = 20, + QRTL = 21, + QAUTOTUNE = 22, + QACRO = 23, + THERMAL = 24, +}; +--]] +local flightModes = {} +--[[ +flightModes["MANU"]=1 +flightModes["CIRC"]=2 +flightModes["STAB"]=3 +flightModes["TRAN"]=4 +flightModes["ACRO"]=5 +flightModes["FBWA"]=6 +flightModes["FBWB"]=7 +flightModes["CRUS"]=8 +flightModes["ATUN"]=9 +flightModes["AUTO"]=11 +flightModes["RTL"]=12 +flightModes["LOIT"]=13 +flightModes["TKOF"]=14 +flightModes["AVOI"]=15 +flightModes["GUID"]=16 +flightModes["INIT"]=17 +flightModes["QSTB"]=18 +flightModes["QHOV"]=19 +flightModes["QLOT"]=20 +flightModes["QLND"]=21 +flightModes["QRTL"]=22 +flightModes["QATN"]=23 +flightModes["QACR"]=24 +flightModes["THML"]=25 + +-- plane flight modes +flightModes[0]={"",""} +flightModes[1]={"Manual","MANU"} +flightModes[2]={"Circle","CIRC"} +flightModes[3]={"Stabilize","STAB"} +flightModes[4]={"Training","TRAN"} +flightModes[5]={"Acro","ACRO"} +flightModes[6]={"FlyByWireA","FBWA"} +flightModes[7]={"FlyByWireB","FBWB"} +flightModes[8]={"Cruise","CRUS"} +flightModes[9]={"Autotune","ATUN"} +flightModes[10]={"",""} +flightModes[11]={"Auto","AUTO"} +flightModes[12]={"RTL","RTL"} +flightModes[13]={"Loiter","LOIT"} +flightModes[14]={"Takeoff","TKOF"} +flightModes[15]={"AvoidADSB","AVOI"} +flightModes[16]={"Guided","GUID"} +flightModes[17]={"Initializing","INIT"} +flightModes[18]={"QStabilize","SSTB"} +flightModes[19]={"QHover","QHOV"} +flightModes[20]={"QLoiter","QLOT"} +flightModes[21]={"Qland","QLND"} +flightModes[22]={"QRTL","QRTL"} +flightModes[23]={"QAutotune","QATN"} +flightModes[24]={"QAcro","QACR"} +flightModes[25]={"Thermal","THML"} +--]] + +flightModes[0]="" +flightModes[1]="Manual" +flightModes[2]="Circle" +flightModes[3]="Stabilize" +flightModes[4]="Training" +flightModes[5]="Acro" +flightModes[6]="FlyByWireA" +flightModes[7]="FlyByWireB" +flightModes[8]="Cruise" +flightModes[9]="Autotune" +flightModes[10]="" +flightModes[11]="Auto" +flightModes[12]="RTL" +flightModes[13]="Loiter" +flightModes[14]="Takeoff" +flightModes[15]="AvoidADSB" +flightModes[16]="Guided" +flightModes[17]="Initializing" +flightModes[18]="QStabilize" +flightModes[19]="QHover" +flightModes[20]="QLoiter" +flightModes[21]="Qland" +flightModes[22]="QRTL" +flightModes[23]="QAutotune" +flightModes[24]="QAcro" +flightModes[25]="Thermal" +-- +return {flightModes=flightModes} + diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane_px4.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane_px4.lua new file mode 100644 index 00000000..d068aaf9 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/plane_px4.lua @@ -0,0 +1,86 @@ +--[[ + MavToPT 2.63 + + uint8_t PX4FlightModeNum(uint8_t main, uint8_t sub) { + switch(main) { + case 1: + return 0; // MANUAL + case 2: + return 1; // ALTITUDE + case 3: + return 2; // POSCTL + case 4: + switch(sub) { + case 1: + return 12; // AUTO READY + case 2: + return 13; // AUTO TAKEOFF + case 3: + return 14; // AUTO LOITER + case 4: + return 15; // AUTO MISSION + case 5: + return 16; // AUTO RTL + case 6: + return 17; // AUTO LAND + case 7: + return 18; // AUTO RTGS + case 8: + return 19; // AUTO FOLLOW ME + case 9: + return 20; // AUTO PRECLAND + default: + return 31; // AUTO UNKNOWN + } + case 5: + return 3; // ACRO + case 6: + return 4; // OFFBOARD + case 7: + return 5; // STABILIZED + case 8: + return 6; // RATTITUDE + case 9: + return 7; // SIMPLE + default: + return 11; // UNKNOWN + } + } +--]] +local flightModes = {} +-- plane flight modes +flightModes[0] = "Manual" +flightModes[1] = "AltCtl" --px4 specific +flightModes[2] = "PosCtl" --px4 specific +flightModes[3] = "Acro" +flightModes[4] = "OffBoard" --px4 specific +flightModes[5] = "Stabilize" +flightModes[6] = "RAttitude" --px4 specific +flightModes[7] = "Simple" --px4 specific +flightModes[8] = "" +flightModes[9] = "" +flightModes[10] = "" +flightModes[11] = "" +flightModes[12] = "Ready" --px4 specific +flightModes[13] = "Takeoff" --px4 specific +flightModes[14] = "Loiter" +flightModes[15] = "Mission" --px4 specific +flightModes[16] = "RTL" +flightModes[17] = "Land" +flightModes[18] = "" +flightModes[19] = "Follow" +flightModes[20] = "PrecLand" --px4 specific +flightModes[21] = "" +flightModes[22] = "" +flightModes[23] = "" +flightModes[24] = "" +flightModes[25] = "" +flightModes[26] = "" +flightModes[27] = "" +flightModes[28] = "" +flightModes[29] = "" +flightModes[30] = "" +flightModes[31] = "Unknown" + +return {flightModes=flightModes} + diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/prefix_hashes.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/prefix_hashes.lua new file mode 100644 index 00000000..778fd735 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/prefix_hashes.lua @@ -0,0 +1,115 @@ +local prefixHashes = { + --[[ + max prefix length: + hashes longer than maxLength will not be searched in the hash map + longer hashes have precedence over shorter hashes, i.e. a prefix hash is + looked up in the map up until maxLength overwriting status.shortHash + --]] + maxLength = 16 +} + +--[[ + OPTIONS + true|false, -- match pattern + prefix, -- extra soundfile prefix, used in conjuction with extraGroup and paramGroup + regex, -- define max 3 groups + paramGroup=x -- index of the param group [1|2|3], will be played as number and also appended to [prefix] and played as soundfile + suffixGroup=y -- index of the suffix sound file [1|2|3] will be played as soundfile + extraGroup=z -- index of the group used for the lookup in the extraMap table, if found the matching value is appended to prefix and played as soundfile +--]] +--[[ +-- FNV32 hashes +-- size 5 +--shortHashes[158533322] = { true, "trk_", "^.* (%d+) (%a+) %((.*)%).*", paramGroup=1, suffixGroup=2, extraGroup=3 } -- prefixLength size=5, Trick prefixLength +prefixHashes[158533322] = { true, "trk_", "^.* (%d+) (selected) %((.*)%).*", paramGroup=1, suffixGroup=2, extraGroup=3 } -- prefixLength size=5, Trick prefixLength +-- size 12 +prefixHashes[121896728] = { false } -- prefixLength size=12, trick aborted +-- size 16 +prefixHashes[3351294456] = { false } -- prefixLength size=16, Soaring: Outside MAX RADIUS, RTL +prefixHashes[3538212740] = { false } -- prefixLength size=16, Soaring: restoring previous mode +prefixHashes[142400872] = { false } -- prefixLength size=16, Soaring: Climb below VERTICAL SPEED +prefixHashes[1746499976] = { false } -- prefixLength size=16, Soaring: Exit via RC switch +prefixHashes[981284144] = { false } -- prefixLength size=16, Soaring: Thermal detected +prefixHashes[883458048] = { false } -- prefixLength size=16, Soaring: Enabled +prefixHashes[2561543032] = { false } -- prefixLength size=16, Soaring: Disabled +prefixHashes[4091124880] = { true, nil, "^.* #(%d+).*", paramGroup=1} -- prefixLength size=16, reached command: +prefixHashes[3311875476] = { true, nil, "^.* #(%d+).*", paramGroup=1} -- prefixLength size=16, reached waypoint: +prefixHashes[1997782032] = { true, nil, "^.* #(%d+).*", paramGroup=1} -- prefixLength size=16, Passed waypoint: +prefixHashes[554623408] = { false } -- prefixLength size=16, Takeoff complete +prefixHashes[3025044912] = { false } -- prefixLength size=16, Smart RTL deactivated +prefixHashes[3956583920] = { false } -- prefixLength size=16, GPS home acquired +prefixHashes[1309405592] = { false } -- prefixLength size=16, GPS home acquired +--]] + +-- fletcher24 hashes +-- size 5 +prefixHashes[6128125] = { true, "trk_", "^.* (%d+) (selected) %((.*)%).*", paramGroup=1, suffixGroup=2, extraGroup=3 } -- prefixLength size=5, Trick prefixLength +-- size 12 +prefixHashes[13841562] = { false } -- prefix size=12, trick aborted +-- size 16 +prefixHashes[3020298] = { false } -- prefix size=16, Soaring: Outside MAX RADIUS, RTL +prefixHashes[2053593] = { false } -- prefix size=16, Soaring: restoring previous mode +prefixHashes[1475990] = { false } -- prefix size=16, Soaring: Climb below VERTICAL SPEED +prefixHashes[1865158] = { false } -- prefix size=16, Soaring: Exit via RC switch +prefixHashes[2573818] = { false } -- prefix size=16, Soaring: Thermal detected +prefixHashes[1934808] = { false } -- prefix size=16, Soaring: Enabled +prefixHashes[2074081] = { false } -- prefix size=16, Soaring: Disabled +prefixHashes[2262475] = { true, nil, "^.* #(%d+).*", paramGroup=1 } -- prefix size=16, reached command: +prefixHashes[3466823] = { true, nil, "^.* #(%d+).*", paramGroup=1 } -- prefix size=16, reached waypoint: +prefixHashes[4597275] = { true, nil, "^.* #(%d+).*", paramGroup=1 } -- prefix size=16, Passed waypoint: +prefixHashes[3843641] = { false } -- prefix size=16, Takeoff complete +prefixHashes[1865209] = { false } -- prefix size=16, Smart RTL deactivated +prefixHashes[4170928] = { false } -- prefix size=16, GPS home acquired +prefixHashes[4224177] = { false } -- prefix size=16, GPS home acquired + +prefixHashes.extraMap = { + -- plane aerobatics + ["Figure Eight"] = "fig8", + ["Loop"] = "loop", + ["Horizontal Rectangle"] = "horrec", + ["Climbing Circle"] = "clicir", + ["Vertical Box"] = "verbox", + ["Immelmann Fast"] = "immfas", + ["Axial Roll"] = "axirol", + ["Rolling Circle"] = "rolcir", + ["Half Cuban Eight"] = "hcu8", + ["Half Reverse Cuban Eight"] = "hrvcu8", + ["Cuban Eight"] = "cu8", + ["Humpty Bump"] = "hubu", + ["Straight Flight"] = "strfli", + ["Scale Figure Eight"] = "scfig8", + ["Immelmann Turn"] = "immtrn", + ["Split-S"] = "splts", + ["Upline-45"] = "up45", + ["Downline-45"] = "dw45", + ["Stall Turn"] = "statrn", + ["Procedure Turn"] = "prctrn", + ["Half Climbing Circle"] = "hfclci", + ["Laydown Humpty"] = "layhu", + ["Barrel Roll"] = "barrol", + ["Straight Hold"] = "strhol", + ["Partial Circle"] = "parcir", + ["Multi Point Roll"] = "mproll", + ["Side Step"] = "sstep", + -- schedules + ["SuperAirShow"] = "sashow", + ["F3AF23"] = "f34f23", + ["F3AF25"] = "f3af25", + ["F3AP23"] = "f3ap23", + ["F3AP25"] = "f3ap25", + ["F4CScaleExampleSchedule"] = "f4css", + ["NZClubmanSchedule"] = "nzclub", + ["Sport_Plane_AirShow"] = "spshow", + ["StallTurnTest"] = "sttest", + -- rate based + ["Roll(s)"] = "roll", + ["Loop(s)/Turnaround"] = "lotrn", + ["Rolling Circle"] = "rolcir", + ["Knife-Edge"] = "kniedg", + ["Pause"] = "pause", + ["Knife Edge Circle"] = "kniedc", + ["4pt Roll"] = "4ptrol", + ["Split-S"] = "splits", +} + +return prefixHashes diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_battperc_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_battperc_def.lua new file mode 100644 index 00000000..b464e89e --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_battperc_def.lua @@ -0,0 +1,114 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + status.hidePower = 1 + status.hideEfficiency = 1 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local perc = status.battery[16+battId] + -- battery min cell + local flags = 0 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + + -- display capacity bar % + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,255, 255)) + lcd.drawFilledRectangle(x+17, y+101,167,49,CUSTOM_COLOR) + if perc > 50 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(0, 255, 0)) + elseif perc <= 50 and perc > 25 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 204, 0)) -- yellow + else + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,0, 0)) + end + lcd.drawGauge(x+17, y+101,167,49,perc,100,CUSTOM_COLOR) + -- battery percentage + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + + local strperc = string.format("%02d%%",perc) + lcd.drawText(x+67, y+94, strperc, DBLSIZE+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+50,y+25) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+50,y+25) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+50,y+25) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+50,y+25) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + flags = CUSTOM_COLOR + --PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+battId] * 0.01 < 10 then + lcd.drawNumber(x+168+2, y+18, status.battery[1+battId] + 0.5, PREC2+DBLSIZE+RIGHT+flags) + else + lcd.drawNumber(x+168+2, y+18, (status.battery[1+battId] + 0.5)*0.1, PREC1+DBLSIZE+RIGHT+flags) + end + + local lx = x+172 + lcd.drawText(lx, y+44, "V", flags) + -- labels + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140, 140, 140)) + lcd.drawText(x+2,y+-4,battId == 0 and "B1+B2" or (battId == 1 and "B1" or "B2"),SMLSIZE+CUSTOM_COLOR) + lcd.drawText(x+183, y+157, "IMU TEMP", SMLSIZE+RIGHT+CUSTOM_COLOR) + + -- IMU Temperature + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(x+183, y+173, string.format("%d%s",telemetry.imuTemp, conf.degSymbol), DBLSIZE+RIGHT+CUSTOM_COLOR) + + if status.showMinMaxValues == true then + drawLib.drawVArrow(x+168+19, y+18 + 8,false,true) + end + + lcd.setColor(CUSTOM_COLOR, lcd.RGB(140, 140, 140)) + lcd.drawText(x+183, y+-4, string.format("%s CELL",string.upper(status.battsource)), SMLSIZE+RIGHT+CUSTOM_COLOR) + +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_custom_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_custom_def.lua new file mode 100644 index 00000000..00c226b4 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_custom_def.lua @@ -0,0 +1,63 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local customSensors = nil + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + status.hidePower = 0 + status.hideEfficiency = 0 + + local customSensorXY = { + { x+197, y+0, x+197, y+25, lcd.RGB(140,140,140)}, + { x+197, y+74, x+197, y+99, lcd.RGB(140,140,140)}, + { x+197, y+152, x+197, y+177, lcd.RGB(140,140,140)}, + } + + if customSensors ~= nil then + libs.drawLib.drawCustomSensors(customSensors, customSensorXY, lcd.RGB(140, 140, 140)) + else + customSensors = utils.loadCustomSensors("right") + end +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_def.lua new file mode 100644 index 00000000..229f5772 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_def.lua @@ -0,0 +1,130 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + --[[ + lcd.setColor(CUSTOM_COLOR,lcd.RGB(5,52,85)) + lcd.drawRectangle(x, 18, 200, 97, CUSTOM_COLOR) + lcd.drawRectangle(x, 115, 200, 133, CUSTOM_COLOR) + --]] + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local perc = status.battery[16+battId] + -- battery min cell + local flags = 0 + -- + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+52,y+25) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+52,y+25) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+52,y+25) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+52,y+25) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + flags = CUSTOM_COLOR + --PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+battId] * 0.01 < 10 then + lcd.drawNumber(x+177+3, y+18, status.battery[1+battId] + 0.5, PREC2+DBLSIZE+RIGHT+flags) + else + lcd.drawNumber(x+177+3, y+18, (status.battery[1+battId] + 0.5)*0.1, PREC1+DBLSIZE+RIGHT+flags) + end + + local lx = x+180 + lcd.drawText(lx, y+48, "V", flags+SMLSIZE) + --lcd.drawText(lx, 12, status.battsource, flags) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + -- battery voltage + libs.drawLib.drawNumberWithDim(x+70,y+120,x+70, y+131, status.battery[4+battId],"V",RIGHT+PREC1+CUSTOM_COLOR,SMLSIZE+CUSTOM_COLOR) + -- battery current + local lowAmp = status.battery[7+battId]*0.1 < 10 + libs.drawLib.drawNumberWithDim(x+180,y+97,x+180,y+131,status.battery[7+battId]*(lowAmp and 1 or 0.1),"A",DBLSIZE+RIGHT+CUSTOM_COLOR+(lowAmp and PREC1 or 0),SMLSIZE+CUSTOM_COLOR) + -- display capacity bar % + local color = lcd.RGB(255,0, 0) + if perc > 50 then + color = lcd.RGB(0, 255, 0) -- red + elseif perc <= 50 and perc > 25 then + color = lcd.RGB(255, 204, 0) -- yellow + end + libs.drawLib.drawMinMaxBar(x+8, y+159,183,37,color,perc,0,100,MIDSIZE) + -- battery mah + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local strmah = string.format("%.02f/%.01fAh",status.battery[10+battId]/1000,status.battery[13+battId]/1000) + --lcd.drawText(x+183, 198+2, "Ah", SMLSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+183, y+198, strmah, 0+RIGHT+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140, 140, 140)) + local battLabel = "B1B2" + if battId == 0 then + if conf.battConf == 3 then + -- alarms are based on battery 1 + battLabel = "B1" + elseif conf.battConf == 4 then + -- alarms are based on battery 2 + battLabel = "B2" + end + else + battLabel = (battId == 1 and "B1" or "B2") + end + + lcd.drawText(x+2, y+-4, battLabel, SMLSIZE+CUSTOM_COLOR) + + if status.showMinMaxValues == true then + libs.drawLib.drawVArrow(x+177+18, y+18 + 8,false,true) + libs.drawLib.drawVArrow(x+70+18, y+120 + 3, false,true) + libs.drawLib.drawVArrow(x+180+18, y+97 + 10,true,false) + end + --]] + lcd.setColor(CUSTOM_COLOR, lcd.RGB(140, 140, 140)) + lcd.drawText(x+183, y+-4, string.format("%s CELL",string.upper(status.battsource)), SMLSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+183, y+81, "CURR", SMLSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+77, y+81, "BATT", SMLSIZE+RIGHT+CUSTOM_COLOR) +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_dualbatt_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_dualbatt_def.lua new file mode 100644 index 00000000..cf8fe980 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_dualbatt_def.lua @@ -0,0 +1,125 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + status.hidePower = 1 + status.hideEfficiency = 1 + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local perc = status.battery[16+1] + local perc2 = status.battery[16+2] + -- battery 1 cell voltage (no alerts on battery 1) + local flags = 0 + lcd.setColor(CUSTOM_COLOR,WHITE) -- white + flags = CUSTOM_COLOR + --PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+1] * 0.01 < 10 then + lcd.drawNumber(x+168+2, y+-7, status.battery[1+1] + 0.5, PREC2+MIDSIZE+RIGHT+flags) + else + lcd.drawNumber(x+168+2, y+-7, (status.battery[1+1] + 0.5)*0.1, PREC1+MIDSIZE+RIGHT+flags) + end + local lx = x+168 + lcd.drawText(lx, y+28, "V", flags) + lcd.drawText(lx, y+-4, status.battsource, flags) + -- battery 2 cell voltage + flags = 0 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+53,y+97) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+53,y+97) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+53,y+97) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+53,y+97) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + flags = CUSTOM_COLOR + -- PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+2] * 0.01 < 10 then + lcd.drawNumber(x+168+2, y+90, status.battery[1+2] + 0.5, PREC2+MIDSIZE+RIGHT+flags) + else + lcd.drawNumber(x+168+2, y+90, (status.battery[1+2] + 0.5)*0.1, PREC1+MIDSIZE+RIGHT+flags) + end + + lx = x+168 + lcd.drawText(lx, y+119, "V", flags) + lcd.drawText(lx, y+90, status.battsource, flags) + lcd.setColor(CUSTOM_COLOR, lcd.RGB(140, 140, 140)) + lcd.drawText(x, y+-4, "B1", flags) + lcd.drawText(x, y+90, "B2", flags) + + -- batt2 capacity bar % + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,255, 255)) + lcd.drawFilledRectangle(x+17, y+191,167,35,CUSTOM_COLOR) + if perc2 > 50 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(0, 255, 0)) + elseif perc2 <= 50 and perc2 > 25 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 204, 0)) -- yellow + else + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,0, 0)) + end + lcd.drawGauge(x+17, y+191,167,35,perc2,100,CUSTOM_COLOR) + -- battery 2 percentage + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + local strperc2 = string.format("%02d%%",perc2) + lcd.drawText(x+83, y+184, strperc2, MIDSIZE+CUSTOM_COLOR) + + -- POWER -- + -- power 1 + lcd.setColor(CUSTOM_COLOR,WHITE) -- white + local power1 = status.battery[4+1]*status.battery[7+1]*0.01 + lcd.drawNumber(x+158,y+42,power1,MIDSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+162,y+55,"W",CUSTOM_COLOR) + -- power 2 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local power2 = status.battery[4+2]*status.battery[7+2]*0.01 + lcd.drawNumber(x+158,y+145,power2,MIDSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+162,y+157,"W",CUSTOM_COLOR) +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_empty.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_empty.lua new file mode 100644 index 00000000..c7395e22 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_empty.lua @@ -0,0 +1,46 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) +end + +function panel.background(widget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_hybrid_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_hybrid_def.lua new file mode 100644 index 00000000..a7010a28 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_hybrid_def.lua @@ -0,0 +1,96 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +------------------------------------------------------------------------------------ +-- On hybrid vehicle we have voltage and current from battery 1, mah from battery 2 +------------------------------------------------------------------------------------ +function panel.draw(widget, x, y, battId) + status.hidePower = 1 + status.hideEfficiency = 1 + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- battery min cell + local flags = 0 + -- + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+28,y+0) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+28,y+0) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+28,y+0) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+28,y+0) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + flags = CUSTOM_COLOR + -- PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+1] * 0.01 < 10 then + lcd.drawNumber(x+142+2, y+-7, status.battery[1+1] + 0.5, PREC2+DBLSIZE+RIGHT+flags) + else + lcd.drawNumber(x+142+2, y+-7, (status.battery[1+1] + 0.5)*0.1, PREC1+DBLSIZE+RIGHT+flags) + end + + local lx = x+143 + lcd.drawText(lx, y+21, "V", flags) + lcd.drawText(lx, y+-4, status.battsource, flags) + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + -- battery current + local lowAmp = status.battery[7+1]*0.1 < 10 + libs.drawLib.drawNumberWithDim(x+142,y+237,x+143,y+264,status.battery[7+1]*(lowAmp and 1 or 0.1),"A",DBLSIZE+RIGHT+CUSTOM_COLOR+(lowAmp and PREC1 or 0),0+CUSTOM_COLOR) + -- battery mah is from battery 2 + -- we display remaining liters vs used liters as usual + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local strmah = string.format("%.01f/%.01fL",(status.battery[13+2]-status.battery[10+2])/1000,status.battery[13+2]/1000) + lcd.drawText(x+170, y+200, strmah, 0+RIGHT+CUSTOM_COLOR) + -- fuel gauge from battery 2 + lcd.setColor(CUSTOM_COLOR,utils.colors.red) + libs.drawLib.drawGauge(x+33,y+60,"fuelgauge_75x75", 673, 120, 25, 8, status.battery[16+2], 125, CUSTOM_COLOR) +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_nocellv_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_nocellv_def.lua new file mode 100644 index 00000000..02631695 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_nocellv_def.lua @@ -0,0 +1,114 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local perc = status.battery[16+battId] + -- battery min cell + local flags = 0 + -- + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+52,y+21) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+52,y+21) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+52,y+21) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+52,y+21) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + -- battery voltage + flags = CUSTOM_COLOR + libs.drawLib.drawNumberWithDim(x+177,y+14,x+180, y+48, status.battery[4+battId],"V",RIGHT+PREC1+DBLSIZE+CUSTOM_COLOR,SMLSIZE+CUSTOM_COLOR) + local lx = x+180 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + -- battery current + local lowAmp = status.battery[7+battId]*0.1 < 10 + libs.drawLib.drawNumberWithDim(x+180,y+94,x+180,y+127,status.battery[7+battId]*(lowAmp and 1 or 0.1),"A",DBLSIZE+RIGHT+CUSTOM_COLOR+(lowAmp and PREC1 or 0),SMLSIZE+CUSTOM_COLOR) + -- display capacity bar % + local color = lcd.RGB(255,0, 0) + if perc > 50 then + color = lcd.RGB(0, 255, 0) -- red + elseif perc <= 50 and perc > 25 then + color = lcd.RGB(255, 204, 0) -- yellow + end + libs.drawLib.drawMinMaxBar(x+8, y+156,183,37,color,perc,0,100,MIDSIZE) + -- battery mah + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local strmah = string.format("%.02f/%.01fAh",status.battery[10+battId]/1000,status.battery[13+battId]/1000) + lcd.drawText(x+183, y+195, strmah, 0+RIGHT+CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,lcd.RGB(140, 140, 140)) + local battLabel = "B1B2" + if battId == 0 then + if conf.battConf == 3 then + -- alarms are based on battery 1 + battLabel = "B1" + elseif conf.battConf == 4 then + -- alarms are based on battery 2 + battLabel = "B2" + end + else + battLabel = (battId == 1 and "B1" or "B2") + end + + lcd.drawText(x+2, y+-7, battLabel, SMLSIZE+CUSTOM_COLOR) + + if status.showMinMaxValues == true then + libs.drawLib.drawVArrow(x+177+18, y+14 + 8,false,true) + libs.drawLib.drawVArrow(x+177+18,y+14 + 3, false,true) + libs.drawLib.drawVArrow(x+180+18,y+94 + 10,true,false) + end + + lcd.setColor(CUSTOM_COLOR, lcd.RGB(140, 140, 140)) + lcd.drawText(x+183, y+-7, string.format("%s BATT",string.upper(status.battsource)), SMLSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+183, y+78, "CURR", SMLSIZE+RIGHT+CUSTOM_COLOR) +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_tether_def.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_tether_def.lua new file mode 100644 index 00000000..94938e12 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/right_tether_def.lua @@ -0,0 +1,125 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +local panel = {} + +local conf +local telemetry +local status +local utils +local libs + +function panel.init(param_status, param_telemetry, param_conf, param_utils, param_libs) + status = param_status + telemetry = param_telemetry + conf = param_conf + utils = param_utils + libs = param_libs +end + +function panel.draw(widget, x, y, battId) + status.hidePower = 1 + status.hideEfficiency = 1 + + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local perc = status.battery[16+1] + local perc2 = status.battery[16+2] + -- battery 1 cell voltage (no alerts on battery 1) + local flags = 0 + lcd.setColor(CUSTOM_COLOR,WHITE) -- white + flags = CUSTOM_COLOR + --PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+1] * 0.01 < 10 then + lcd.drawNumber(x+168+2, y+-7, status.battery[1+1] + 0.5, PREC2+DBLSIZE+RIGHT+flags) + else + lcd.drawNumber(x+168+2, y+-7, (status.battery[1+1] + 0.5)*0.1, PREC1+DBLSIZE+RIGHT+flags) + end + local lx = x+168 + lcd.drawText(lx, y+28, "V", flags) + lcd.drawText(lx, y+-4, status.battsource, flags) + -- battery 2 cell voltage + flags = 0 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) -- white + if status.showMinMaxValues == false then + if status.battLevel2 == false and status.alarms[8][2] > 0 then + utils.drawBlinkBitmap("cell_red_blink_86x30",x+53,y+97) + utils.lcdBacklightOn() + elseif status.battLevel2 == true then + lcd.drawBitmap(utils.getBitmap("cell_red_86x30"),x+53,y+97) + elseif status.battLevel1 == false and status.alarms[7][2] > 0 then + --lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + utils.drawBlinkBitmap("cell_orange_blink_86x30",x+53,y+97) + utils.lcdBacklightOn() + elseif status.battLevel1 == true then + lcd.drawBitmap(utils.getBitmap("cell_orange_86x30"),x+53,y+97) + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + end + end + flags = CUSTOM_COLOR + -- PREC2 forces a math.floor() whereas a math.round() is required, math.round(f) = math.floor(f+0.5) + if status.battery[1+2] * 0.01 < 10 then + lcd.drawNumber(x+168+2, y+90, status.battery[1+2] + 0.5, PREC2+DBLSIZE+RIGHT+flags) + else + lcd.drawNumber(x+168+2, y+90, (status.battery[1+2] + 0.5)*0.1, PREC1+DBLSIZE+RIGHT+flags) + end + + lx = x+168 + lcd.drawText(lx, y+119, "V", flags) + lcd.drawText(lx, y+90, status.battsource, flags) + lcd.setColor(CUSTOM_COLOR, lcd.RGB(140, 140, 140)) + lcd.drawText(x, y+-4, "B1", flags) + lcd.drawText(x, y+90, "B2", flags) + + -- batt2 capacity bar % + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,255, 255)) + lcd.drawFilledRectangle(x+17, y+191,167,35,CUSTOM_COLOR) + if perc2 > 50 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(0, 255, 0)) + elseif perc2 <= 50 and perc2 > 25 then + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 204, 0)) -- yellow + else + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255,0, 0)) + end + lcd.drawGauge(x+17, y+191,167,35,perc2,100,CUSTOM_COLOR) + -- battery 2 percentage + lcd.setColor(CUSTOM_COLOR,utils.colors.black) -- black + local strperc2 = string.format("%02d%%",perc2) + lcd.drawText(x+83, y+184, strperc2, MIDSIZE+CUSTOM_COLOR) + + -- POWER -- + -- power 1 + lcd.setColor(CUSTOM_COLOR,WHITE) -- white + local power1 = status.battery[4+1]*status.battery[7+1]*0.01 + lcd.drawNumber(x+158,y+42,power1,MIDSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+162,y+55,"W",CUSTOM_COLOR) + -- power 2 + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + local power2 = status.battery[4+2]*status.battery[7+2]*0.01 + lcd.drawNumber(x+158,y+145,power2,MIDSIZE+RIGHT+CUSTOM_COLOR) + lcd.drawText(x+162,y+157,"W",CUSTOM_COLOR) +end + +function panel.background(myWidget) +end + +return panel diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/rover.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/rover.lua new file mode 100644 index 00000000..aee6cd0f --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/lib/rover.lua @@ -0,0 +1,48 @@ +--[[ + // Auto Pilot modes + // ---------------- + enum Number { + MANUAL = 0, + ACRO = 1, + STEERING = 3, + HOLD = 4, + LOITER = 5, + FOLLOW = 6, + SIMPLE = 7, + AUTO = 10, + RTL = 11, + SMART_RTL = 12, + GUIDED = 15, + INITIALISING = 16 + }; +--]] + +local flightModes = {} + +-- rover modes +flightModes[0]="" +flightModes[1]="Manual" +flightModes[2]="Acro" +flightModes[3]="" +flightModes[4]="Steering" +flightModes[5]="Hold" +flightModes[6]="Loiter" +flightModes[7]="Follow" +flightModes[8]="Simple" +flightModes[9]="" +flightModes[10]="" +flightModes[11]="Auto" +flightModes[12]="RTL" +flightModes[13]="SmartRTL" +flightModes[14]="" +flightModes[15]="" +flightModes[16]="Guided" +flightModes[17]="Initializing" +flightModes[18]="" +flightModes[19]="" +flightModes[20]="" +flightModes[21]="" +flightModes[22]="" +-- +return {flightModes=flightModes} + diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/main.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/main.lua new file mode 100644 index 00000000..33265e40 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/main.lua @@ -0,0 +1,2888 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + +----------- +-- CONFIG +----------- +local conf = { + language = "en", + defaultBattSource = "na", -- auto + battAlertLevel1 = 0, + battAlertLevel2 = 0, + battCapOverride1 = 0, + battCapOverride2 = 0, + disableAllSounds = false, + disableMsgBeep = 1, + enableHaptic = false, + timerAlert = 0, + repeatAlertsPeriod = 10, + minAltitudeAlert = 0, + maxAltitudeAlert = 0, + maxDistanceAlert = 0, + battConf = 1, -- 1=parallel,2=other + cell1Count = 0, + cell2Count = 0, + enableBattPercByVoltage = false, + rangeFinderMax=0, + enableSynthVSpeed=false, + horSpeedMultiplier=1, + vertSpeedMultiplier=1, + horSpeedLabel = "m/s", + vertSpeedLabel = "m/s", + maxHdopAlert = 2, + enablePX4Modes = false, + enableCRSF = false, + -- layout and multiple screens support + widgetLayout = 1, + widgetLayoutFilename = "layout_def", + centerPanel = {1,1,1}, + rightPanel = {1,1,1}, + leftPanel = {1,1,1}, + centerPanelFilename = {"hud_def","hud_def","hud_def"}, + rightPanelFilename = {"right_def","right_def","right_def"}, + leftPanelFilename = {"left_def","left_def","left_def"}, + -- map support + mapType = "sat_tiles", -- applies to gmapcacther only + mapZoomLevel = 2, + mapZoomMax = 17, + mapZoomMin = -2, + enableMapGrid = true, + screenToggleChannelId = 0, + screenWheelChannelId = 0, + screenWheelChannelDelay = 20, + gpsFormat = 1, -- DMS + mapProvider = 1, -- 1 GMapCatcher, 2 Google + enableRPM = 0, + enableWIND = 0, + plotSource1 = 1, + plotSource2 = 1, + degSymbol = "@", + theme = 1, + pauseTelemetry = false, +} + +------------------------------ +-- TELEMETRY DATA +------------------------------ +local telemetry = { + -- STATUS + flightMode = 0, + simpleMode = 0, + landComplete = 0, + statusArmed = 0, + battFailsafe = 0, + ekfFailsafe = 0, + failsafe = 0, + imuTemp = 0, + fencePresent = 0, + fenceBreached = 0, + -- GPS + numSats = 0, + gpsStatus = 0, + gpsHdopC = 100, + gpsAlt = 0, + -- BATT 1 + batt1volt = 0, + batt1current = 0, + batt1mah = 0, + -- BATT 2 + batt2volt = 0, + batt2current = 0, + batt2mah = 0, + -- HOME + homeDist = 0, + homeAlt = 0, + homeAngle = -1, + -- VELANDYAW + vSpeed = 0, + hSpeed = 0, + yaw = 0, + -- ROLLPITCH + roll = 0, + pitch = 0, + range = 0, + -- PARAMS + frameType = -1, + batt1Capacity = 0, + batt2Capacity = 0, + -- GPS + lat = nil, + lon = nil, + homeLat = nil, + homeLon = nil, + strLat = "N/A", + strLon = "N/A", + -- WP + wpNumber = 0, + wpDistance = 0, + wpXTError = 0, + wpBearing = 0, + wpCommands = 0, + wpOffsetFromCog = 0, + -- RC channels + rcchannels = {}, + -- VFR + airspeed = 0, + throttle = 0, + baroAlt = 0, + -- Total distance + totalDist = 0, + -- RPM + rpm1 = 0, + rpm2 = 0, + -- TERRAIN + heightAboveTerrain = 0, + terrainUnhealthy = 0, + -- WIND + trueWindSpeed = 0, + trueWindAngle = 0, + apparentWindSpeed = 0, + apparentWindAngle = 0, + -- RSSI + rssi = 0, + rssiCRSF = 0, + -- PARAMS + paramId = nil, + paramValue = nil, +} + +-------------------------------- +-- STATUS DATA +-------------------------------- +local status = {} +status.frameNames = {} +-- copter +status.frameNames[0] = "GEN" +status.frameNames[2] = "QUAD" +status.frameNames[3] = "COAX" +status.frameNames[4] = "HELI" +status.frameNames[7] = "BLIMP" +status.frameNames[13] = "HEX" +status.frameNames[14] = "OCTO" +status.frameNames[15] = "TRI" +status.frameNames[29] = "DODE" +-- plane +status.frameNames[1] = "WING" +status.frameNames[16] = "FLAP" +status.frameNames[19] = "VTOL2" +status.frameNames[20] = "VTOL4" +status.frameNames[20] = "VTOL4" +status.frameNames[21] = "VTOLT" +status.frameNames[22] = "VTOL" +status.frameNames[23] = "VTOL" +status.frameNames[24] = "VTOL" +status.frameNames[25] = "VTOL" +status.frameNames[28] = "FOIL" +-- rover +status.frameNames[10] = "ROV" +-- boat +status.frameNames[11] = "BOAT" + +--[[ + MAV_TYPE_GENERIC=0, /* Generic micro air vehicle. | */ + MAV_TYPE_FIXED_WING=1, /* Fixed wing aircraft. | */ + MAV_TYPE_QUADROTOR=2, /* Quadrotor | */ + MAV_TYPE_COAXIAL=3, /* Coaxial helicopter | */ + MAV_TYPE_HELICOPTER=4, /* Normal helicopter with tail rotor. | */ + MAV_TYPE_ANTENNA_TRACKER=5, /* Ground installation | */ + MAV_TYPE_GCS=6, /* Operator control unit / ground control station | */ + MAV_TYPE_AIRSHIP=7, /* Airship, controlled | */ + MAV_TYPE_FREE_BALLOON=8, /* Free balloon, uncontrolled | */ + MAV_TYPE_ROCKET=9, /* Rocket | */ + MAV_TYPE_GROUND_ROVER=10, /* Ground rover | */ + MAV_TYPE_SURFACE_BOAT=11, /* Surface vessel, boat, ship | */ + MAV_TYPE_SUBMARINE=12, /* Submarine | */ + MAV_TYPE_HEXAROTOR=13, /* Hexarotor | */ + MAV_TYPE_OCTOROTOR=14, /* Octorotor | */ + MAV_TYPE_TRICOPTER=15, /* Tricopter | */ + MAV_TYPE_FLAPPING_WING=16, /* Flapping wing | */ + MAV_TYPE_KITE=17, /* Kite | */ + MAV_TYPE_ONBOARD_CONTROLLER=18, /* Onboard companion controller | */ + MAV_TYPE_VTOL_DUOROTOR=19, /* Two-rotor VTOL using control surfaces in vertical operation in addition. Tailsitter. | */ + MAV_TYPE_VTOL_QUADROTOR=20, /* Quad-rotor VTOL using a V-shaped quad config in vertical operation. Tailsitter. | */ + MAV_TYPE_VTOL_TILTROTOR=21, /* Tiltrotor VTOL | */ + MAV_TYPE_VTOL_RESERVED2=22, /* VTOL reserved 2 | */ + MAV_TYPE_VTOL_RESERVED3=23, /* VTOL reserved 3 | */ + MAV_TYPE_VTOL_RESERVED4=24, /* VTOL reserved 4 | */ + MAV_TYPE_VTOL_RESERVED5=25, /* VTOL reserved 5 | */ + MAV_TYPE_GIMBAL=26, /* Onboard gimbal | */ + MAV_TYPE_ADSB=27, /* Onboard ADSB peripheral | */ + MAV_TYPE_PARAFOIL=28, /* Steerable, nonrigid airfoil | */ + MAV_TYPE_DODECAROTOR=29, /* Dodecarotor | */ +]] + +status.frameTypes = {} +-- copter +status.frameTypes[0] = "c" +status.frameTypes[2] = "c" +status.frameTypes[3] = "c" +status.frameTypes[4] = "c" +status.frameTypes[7] = "a" +status.frameTypes[13] = "c" +status.frameTypes[14] = "c" +status.frameTypes[15] = "c" +status.frameTypes[29] = "c" +-- plane +status.frameTypes[1] = "p" +status.frameTypes[16] = "p" +status.frameTypes[19] = "p" +status.frameTypes[20] = "p" +status.frameTypes[21] = "p" +status.frameTypes[22] = "p" +status.frameTypes[23] = "p" +status.frameTypes[24] = "p" +status.frameTypes[25] = "p" +status.frameTypes[28] = "p" +-- rover +status.frameTypes[10] = "r" +-- boat +status.frameTypes[11] = "b" + + +status.currentFrameType = {} +-- travel +status.lastUpdateTotDist = getTime() +status.lastSpeed = 0 +-- FLVSS 1 +status.cell1min = 0 +status.cell1sum = 0 +-- FLVSS 2 +status.cell2min = 0 +status.cell2sum = 0 +-- FC 1 +status.cell1sumFC = 0 +status.cell1maxFC = 0 +-- FC 2 +status.cell2sumFC = 0 +status.cell2maxFC = 0 +-------------------------------- +status.cell1count = 0 +status.cell2count = 0 + +status.battsource = "na" + +status.batt1sources = { + vs = false, + fc = false +} +status.batt2sources = { + vs = false, + fc = false +} +-- FLIGHT TIME +status.lastTimerStart = 0 +status.timerRunning = 0 +status.flightTime = 0 +-- EVENTS +status.lastStatusArmed = 0 +status.lastGpsStatus = 0 +status.lastFlightMode = 0 +status.lastSimpleMode = 0 +-- battery levels +status.batLevel = 99 +status.battLevel1 = false +status.battLevel2 = false +status.lastBattLevel = 14 +-- MESSAGES +status.messages = {} +status.msgBuffer = "" +status.lastMsgValue = 0 +status.lastMsgTime = 0 +status.lastMessage = nil +status.lastMessageSeverity = 0 +status.lastMessageCount = 1 +status.messageRow = 0 +status.messageCount = 0 +status.messageOffset = 0 +status.messageAutoScroll = true +-- LINK STATUS +status.noTelemetryData = 1 +status.hideNoTelemetry = false +status.showDualBattery = false +status.showMinMaxValues = false +-- MAP +status.screenTogglePage = 1 +status.mapZoomLevel = 1 +-- FLIGHTMODE +status.strFlightMode = nil +status.modelString = nil +-- TERRAIN +status.terrainEnabled = 0 +status.terrainLastData = getTime() +-- AIRSPEED +status.airspeedEnabled = 0 +-- PLOT data +status.plotSources = nil +-- UNIT CONVERSION +status.unitConversion = {} +-- WAYPOINTS +status.cog = nil +status.lastLat = nil +status.lastLon = nil +status.wpEnabled = 0 +status.wpEnabledMode = 0 +-- MULTIPLE SCREEN SUPPORT +status.currentScreen = 1 +-- dynamic layout elemnt hiding +status.hidePower = 0 +status.hideEfficiency = 0 +status.currentModel = nil +status.pauseTelemetry = false +--------------------------- +-- BATTERY TABLE +--------------------------- +status.battery = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + +--------------------------------- +-- ALARMS +--------------------------------- +--[[ + ALARM_TYPE_MIN needs arming (min has to be reached first), value below level for grace, once armed is periodic, reset on landing + ALARM_TYPE_MAX no arming, value above level for grace, once armed is periodic, reset on landing + ALARM_TYPE_TIMER no arming, fired periodically, spoken time, reset on landing + ALARM_TYPE_BATT needs arming (min has to be reached first), value below level for grace, no reset on landing +{ + 1 = notified, + 2 = alarm start, + 3 = armed, + 4 = type(0=min,1=max,2=timer,3=batt), + 5 = grace duration + 6 = ready + 7 = last alarm +} +--]] +status.alarms = { + --{ notified, alarm_start, armed, type(0=min,1=max,2=timer,3=batt), grace, ready, last_alarm} + { false, 0 , false, 0, 0, false, 0}, --MIN_ALT + { false, 0 , false, 1, 0, false, 0 }, --MAX_ALT + { false, 0 , false, 1, 0, false, 0 }, --15 + { false, 0 , true, 1, 0, false, 0 }, --FS_EKF + { false, 0 , true, 1, 0, false, 0 }, --FS_BAT + { false, 0 , true, 2, 0, false, 0 }, --FLIGTH_TIME + { false, 0 , false, 3, 4, false, 0 }, --BATT L1 + { false, 0 , false, 4, 4, false, 0 }, --BATT L2 + { false, 0 , true, 1, 0, false, 0 }, --FS + { false, 0 , true, 1, 0, false, 0 }, --FENCE + { false, 0 , true, 1, 0, false, 0 }, --TERRAIN +} + +--------------------------------- +-- TRANSITIONS +--------------------------------- +status.transitions = { + --{ last_value, last_changed, transition_done, delay } + { 0, 0, false, 30 }, +} + +status.batLevels = {0,5,10,15,20,25,30,40,50,60,70,80,90} +status.minmaxValues = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + +--------------------------------- +-- MSG HASHING +--------------------------------- +status.prefixHash = nil +status.parsePrefixHash = false +status.hashByteIndex = 0 +status.hash = 0 +status.hash_a = 0 +status.hash_b = 0 +status.hashSoundfile = nil + +local utils = {} + +-- GPS fix types +utils.gpsStatuses = {} +utils.gpsStatuses[0]={"No","GPS"} +utils.gpsStatuses[1]={"No","Lock"} +utils.gpsStatuses[2]={"2D",""} +utils.gpsStatuses[3]={"3D",""} +utils.gpsStatuses[4]={"DGPS",""} +utils.gpsStatuses[5]={"RTK","Flt"} +utils.gpsStatuses[6]={"RTK","Fxd"} + +utils.colors = {} +utils.mavSeverity = {} + +utils.wpEnabledModeList = { + ['AUTO'] = 1, + ['GUIDED'] = 1, + ['LOITER'] = 1, + ['RTL'] = 1, + ['QRTL'] = 1, + ['QLOITER'] = 1, + ['QLAND'] = 1, + ['FOLLOW'] = 1, + ['ZIGZAG'] = 1, +} + +local libs = { + drawLib = {}, + mapLib = {}, + layoutLib = {}, +} + +-- paths and files +local soundFileBasePath = "/WIDGETS/Yaapu/sounds" +local basePath = "/WIDGETS/Yaapu/" +local libBasePath = basePath.."lib/" +-- telemetry loops +local telemetryPopLoops = 15 +-- layouts +local layout = nil +local centerPanel = {nil, nil, nil} +local rightPanel = {nil, nil, nil} +local leftPanel = {nil, nil, nil} +local mapLayout = nil +local plotLayout = nil +-- user selected sensors +local customSensors = nil +-- reset +local resetPhase = 0 +local resetPending = false +local loadConfigPending = false +local modelChangePending = false +local resetLayoutPhase = 0 +local resetLayoutPending = false +local currentPage = 0 +-- blinking support +local bitmaps = {} +local blinktime = getTime() +local blinkon = false +-- model and opentx version +local ver, radio, maj, minor, rev = getVersion() +local opentx = tonumber(maj..minor..rev) +-- battery % by voltage +local battPercByVoltage = {} + + +-- for better performance we cache lcd.RGB() +utils.initColors = function() + -- check if we have lcd.RGB() at init time + local color = lcd.RGB(0,0,0) + if color == nil then + utils.colors.black = BLACK + utils.colors.darkgrey = 0x18C3 + utils.colors.white = WHITE + utils.colors.green = 0x1FEA + utils.colors.blue = BLUE + utils.colors.darkblue = 0x2A2B + utils.colors.darkyellow = 0xFE60 + utils.colors.yellow = 0xFFE0 + utils.colors.orange = 0xFB60 + utils.colors.red = 0xF800 + utils.colors.lightgrey = 0x8C71 + utils.colors.grey = 0x7BCF + --utils.colors.darkgrey = 0x5AEB + utils.colors.lightred = 0xF9A0 + utils.colors.bars2 = 0x10A3 + utils.colors.bg = conf.theme == 1 and utils.colors.darkblue or 0x3186 + utils.colors.hudTerrain = conf.theme == 1 and 0x6225 or 0x65CB + utils.colors.hudFgColor = conf.theme == 1 and utils.colors.darkyellow or utils.colors.black + utils.colors.hudDash = conf.theme == 1 and utils.colors.white or 0x3186 + utils.colors.compassRibbon = conf.theme == 1 and 0x3186 or utils.colors.white + --utils.colors.bars = conf.theme == 1 and utils.colors.darkgrey or utils.colors.black + utils.colors.bars = utils.colors.black + else + -- EdgeTX + utils.colors.black = BLACK + utils.colors.darkgrey = lcd.RGB(27,27,27) + utils.colors.white = WHITE + utils.colors.green = lcd.RGB(00, 0xED, 0x32) + utils.colors.blue = BLUE + --utils.colors.darkblue = lcd.RGB(8,84,136) + utils.colors.darkblue = lcd.RGB(43,70,90) + utils.colors.darkyellow = lcd.RGB(255,206,0) + utils.colors.yellow = lcd.RGB(255, 0xCE, 0) + utils.colors.orange = lcd.RGB(248,109,0) + utils.colors.red = RED + utils.colors.lightgrey = lcd.RGB(138,138,138) + utils.colors.grey = lcd.RGB(120,120,120) + --utils.colors.darkgrey = lcd.RGB(90,90,90) + utils.colors.lightred = lcd.RGB(255,53,0) + utils.colors.bars2 = lcd.RGB(16,20,25) + utils.colors.bg = conf.theme == 1 and utils.colors.darkblue or lcd.RGB(50, 50, 50) + utils.colors.hudSky = lcd.RGB(123,157,255) + utils.colors.hudTerrain = conf.theme == 1 and lcd.RGB(102, 71, 42) or lcd.RGB(100,185,95) + utils.colors.hudFgColor = conf.theme == 1 and utils.colors.darkyellow or utils.colors.black + utils.colors.hudDash = conf.theme == 1 and utils.colors.white or lcd.RGB(100, 100, 100) + utils.colors.compassRibbon = conf.theme == 1 and lcd.RGB(50, 50, 50) or utils.colors.white + --utils.colors.bars = conf.theme == 1 and utils.colors.darkgrey or utils.colors.black + utils.colors.bars = utils.colors.black + end + + --[[ + 0 MAV_SEVERITY_EMERGENCY System is unusable. This is a "panic" condition. + 1 MAV_SEVERITY_ALERT Action should be taken immediately. Indicates error in non-critical systems. + 2 MAV_SEVERITY_CRITICAL Action must be taken immediately. Indicates failure in a primary system. + 3 MAV_SEVERITY_ERROR Indicates an error in secondary/redundant systems. + 4 MAV_SEVERITY_WARNING Indicates about a possible future error if this is not resolved within a given timeframe. Example would be a low battery warning. + 5 MAV_SEVERITY_NOTICE An unusual event has occured, though not an error condition. This should be investigated for the root cause. + 6 MAV_SEVERITY_INFO Normal operational messages. Useful for logging. No action is required for these messages. + 7 MAV_SEVERITY_DEBUG Useful non-operational messages that can assist in debugging. These should not occur during normal operation. + --]] + utils.mavSeverity[0] = {"EMR", utils.colors.orange} + utils.mavSeverity[1] = {"ALR", utils.colors.orange} + utils.mavSeverity[2] = {"CRT", utils.colors.orange} + utils.mavSeverity[3] = {"ERR", utils.colors.orange} + utils.mavSeverity[4] = {"WRN", utils.colors.orange} + utils.mavSeverity[5] = {"NTC", utils.colors.green} + utils.mavSeverity[6] = {"INF", WHITE} + utils.mavSeverity[7] = {"DBG", WHITE} +end + +local function triggerReset() + resetPending = true + modelChangePending = true +end + +local function getConfigTriggerFilename() + local info = model.getInfo() + return "/WIDGETS/Yaapu/cfg/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..".reload") +end + +local function triggerConfigReload() + local cfg = assert(io.open(getConfigTriggerFilename(),"w")) + if cfg ~= nil then + io.write(cfg, "1") + io.close(cfg) + end + collectgarbage() + collectgarbage() +end + +utils.failsafeActive = function(telemetry) + if telemetry.ekfFailsafe == 0 and telemetry.battFailsafe == 0 and telemetry.failsafe == 0 then + return false + end + return true +end + +local function calcCellCount() + -- cellcount override from menu + local c1 = 0 + local c2 = 0 + + if conf.cell1Count ~= nil and conf.cell1Count > 0 then + c1 = conf.cell1Count + elseif status.batt1sources.vs == true and status.cell1count > 1 then + c1 = status.cell1count + else + c1 = math.floor( ((status.cell1maxFC*0.1) / 4.35) + 1) + end + + if conf.cell2Count ~= nil and conf.cell2Count > 0 then + c2 = conf.cell2Count + elseif status.batt2sources.vs == true and status.cell2count > 1 then + c2 = status.cell2count + else + c2 = math.floor(((status.cell2maxFC*0.1)/4.35) + 1) + end + + return c1,c2 +end + +utils.getBattPercByCell = function(voltage) + if battPercByVoltage.dischargeCurve == nil then + return 99 + end + -- when disarmed apply voltage drop to use an "under load" curve + if telemetry.statusArmed == 0 then + voltage = voltage - battPercByVoltage.voltageDrop + end + + if battPercByVoltage.useCellVoltage == false then + voltage = voltage*calcCellCount() + end + if voltage == 0 then + return 99 + end + if voltage >= battPercByVoltage.dischargeCurve[#battPercByVoltage.dischargeCurve][1] then + return 99 + end + if voltage <= battPercByVoltage.dischargeCurve[1][1] then + return 0 + end + for i=2,#battPercByVoltage.dischargeCurve do + if voltage <= battPercByVoltage.dischargeCurve[i][1] then + -- + local v0 = battPercByVoltage.dischargeCurve[i-1][1] + local fv0 = battPercByVoltage.dischargeCurve[i-1][2] + -- + local v1 = battPercByVoltage.dischargeCurve[i][1] + local fv1 = battPercByVoltage.dischargeCurve[i][2] + -- interpolation polinomial + return fv0 + ((fv1 - fv0)/(v1-v0))*(voltage - v0) + end + end --for +end + +local loadCycle = 0 + +utils.doLibrary = function(filename) + local l = assert(loadScript(libBasePath..filename..".lua")) + local lib = l() + if lib.init ~= nil then + lib.init(status, telemetry, conf, utils, libs) + end + return lib +end +----------------------------- +-- clears the loaded table +-- and recovers memory +----------------------------- +utils.clearTable = function(t) + if type(t)=="table" then + for i,v in pairs(t) do + if type(v) == "table" then + utils.clearTable(v) + end + t[i] = nil + end + end + t = nil + collectgarbage() + collectgarbage() +end + +local function resetLayouts() + if resetLayoutPending == true then + utils.initColors() + if resetLayoutPhase == -1 then + -- empty step + resetLayoutPhase = 0 + elseif resetLayoutPhase == 0 then + utils.clearTable(layout) + layout = nil + resetLayoutPhase = 1 + elseif resetLayoutPhase == 1 then + for screen=1,3 + do + utils.clearTable(centerPanel[screen]) + end + centerPanel = {nil, nil, nil} + resetLayoutPhase = 2 + elseif resetLayoutPhase == 2 then + for screen=1,3 + do + utils.clearTable(rightPanel[screen]) + end + rightPanel = {nil, nil, nil} + resetLayoutPhase = 3 + elseif resetLayoutPhase == 3 then + for screen=1,3 + do + utils.clearTable(leftPanel[screen]) + end + leftPanel = {nil, nil, nil} + resetLayoutPhase = 4 + elseif resetLayoutPhase == 4 then + utils.clearTable(mapLayout) + mapLayout = nil + utils.clearTable(plotLayout) + plotLayout = nil + resetLayoutPhase = 0 + resetLayoutPending = false + end + end +end + +utils.getBitmap = function(name) + if bitmaps[name] == nil then + bitmaps[name] = Bitmap.open("/WIDGETS/Yaapu/images/"..name..".png") + end + return bitmaps[name],Bitmap.getSize(bitmaps[name]) +end + +utils.unloadBitmap = function(name) + if bitmaps[name] ~= nil then + bitmaps[name] = nil + -- force call to luaDestroyBitmap() + collectgarbage() + collectgarbage() + end +end + +utils.lcdBacklightOn = function() + lcd.resetBacklightTimeout() +end + +utils.playSound = function(soundFile,skipHaptic) + if conf.enableHaptic and skipHaptic == nil then + playHaptic(15,0) + end + if conf.disableAllSounds then + return + end + utils.lcdBacklightOn() + playFile(soundFileBasePath .."/"..conf.language.."/".. soundFile..".wav") +end + +utils.playSoundByFlightMode = function(flightMode) + if conf.enableHaptic then + playHaptic(15,0) + end + if conf.disableAllSounds then + return + end + if status.currentFrameType.flightModes then + if status.currentFrameType.flightModes[flightMode] ~= nil then + utils.lcdBacklightOn() + -- rover sound files differ because they lack "flight" word + playFile(soundFileBasePath.."/"..conf.language.."/".. status.currentFrameType.flightModes[flightMode] .. ((status.frameTypes[telemetry.frameType]=="r" or status.frameTypes[telemetry.frameType]=="b") and "_r.wav" or ".wav")) + end + end +end + +local function updateHash(c) + if status.hashByteIndex >= utils.prefixHashes.maxLength and status.prefixHash ~= nil then + return + end + + status.hash_a = ( status.hash_a + c ) % 4095 + status.hash_b = ( status.hash_a + status.hash_b ) % 4095 + status.hash = status.hash_b * 4096 + status.hash_a + + status.hashByteIndex = status.hashByteIndex+1 + -- check if we need to process this prefix and if so + -- check if we have a prefix hash + if utils.prefixHashes[status.hash] ~= nil then + status.prefixHash = status.hash + status.parsePrefixHash = utils.prefixHashes[status.prefixHash][1] + end +end + +local function resetHash() + -- reset hash for next string + status.parsePrefixHash = false + status.prefixHash = nil + + status.hash = 0 + status.hash_a = 0 + status.hash_b = 0 + + status.hashByteIndex = 0 +end + +local function playHash() + -- Note: we try to play hash sound files without checking for existence + if status.prefixHash == nil then + -- play full hash and return + utils.playSound(status.hash, true) + return + end + -- A prefixHash has been detected, 2 options: + -- 1) prefixHash does not have a regex, play the prefixHash regardless + -- 2) prefixHash has a regex, play the prefixHash only if we get a match + if status.parsePrefixHash == false then + -- 1) no regex defined + utils.playSound(status.prefixHash, true) + return + end + -- 2) regex defined, check if we get a match + local groups = { nil,nil,nil } + groups[1], groups[2], groups[3] = string.match(status.msgBuffer, utils.prefixHashes[status.prefixHash][3]) + if groups[1] == nil then + -- no match so nothing left to do + return + end + local param = groups[utils.prefixHashes[status.prefixHash].paramGroup] + local suffix = groups[utils.prefixHashes[status.prefixHash].suffixGroup] + local extra = groups[utils.prefixHashes[status.prefixHash].extraGroup] + + local prefix = utils.prefixHashes[status.prefixHash][2] + local extraFileToPlay = prefix + + utils.playSound(status.prefixHash, true) + if param ~= nil then + playNumber(tonumber(param),0) + if extraFileToPlay ~= nil then + extraFileToPlay = extraFileToPlay..param + end + end + if suffix ~= nil then + utils.playSound(suffix, false) + end + -- check if we need to play an extra file + if extraFileToPlay ~= nil then + utils.playSound(extraFileToPlay, false) + end + -- play an additional file only if a prefix is defined and [extra] is mapped to a file in the extraMap table + if extra ~= nil and prefix ~= nil and utils.prefixHashes.extraMap[extra] ~= nil then + utils.playSound(prefix..utils.prefixHashes.extraMap[extra],false) + end +end + +local function formatMessage(severity,msg) + if status.lastMessageCount > 1 then + return string.format("%02d:%02d %s (x%d) %s", status.flightTime/60, status.flightTime%60, utils.mavSeverity[severity][1], status.lastMessageCount, msg) + else + return string.format("%02d:%02d %s %s", status.flightTime/60, status.flightTime%60, utils.mavSeverity[severity][1], msg) + end +end + +local lastMsgTime = getTime() + +utils.pushMessage = function(severity, msg) + if conf.enableHaptic then + playHaptic(15,0) + end + local now = getTime() + if now - lastMsgTime > 50 then + local silence = conf.disableMsgBeep == 3 or (severity >=5 and conf.disableMsgBeep == 2) + if silence == false then + utils.playSound("../"..utils.mavSeverity[severity][1],true) + end + lastMsgTime = now + end + + if msg == status.lastMessage then + status.lastMessageCount = status.lastMessageCount + 1 + else + status.lastMessageCount = 1 + status.messageCount = status.messageCount + 1 + status.messageRow = status.messageRow + 1 + end + + local longMsg = formatMessage(severity,msg) + + if #longMsg > 65 then + -- search for the first blank before max length + local splitPos = #longMsg - string.find(string.reverse(longMsg)," ",#longMsg-65) + if splitPos == nil then + splitPos = 65 + end + if msg == status.lastMessage then + status.messageRow = status.messageRow - 1 + end + if status.messages[(status.messageRow-1) % 200] == nil then + status.messages[(status.messageRow-1) % 200] = {} + end + status.messages[(status.messageRow-1) % 200][1] = string.sub(longMsg, 1, splitPos) + status.messages[(status.messageRow-1) % 200][2] = severity + status.messageRow = status.messageRow + 1 + if status.messages[(status.messageRow-1) % 200] == nil then + status.messages[(status.messageRow-1) % 200] = {} + end + status.messages[(status.messageRow-1) % 200][1] = " "..string.sub(longMsg, splitPos+1, 60) + status.messages[(status.messageRow-1) % 200][2] = severity + else + if status.messages[(status.messageRow-1) % 200] == nil then + status.messages[(status.messageRow-1) % 200] = {} + end + status.messages[(status.messageRow-1) % 200][1] = longMsg + status.messages[(status.messageRow-1) % 200][2] = severity + end + status.lastMessage = msg + status.lastMessageSeverity = severity + msg = nil +end + +utils.haversine = function(lat1, lon1, lat2, lon2) + lat1 = lat1 * math.pi / 180 + lon1 = lon1 * math.pi / 180 + lat2 = lat2 * math.pi / 180 + lon2 = lon2 * math.pi / 180 + + lat_dist = lat2-lat1 + lon_dist = lon2-lon1 + lat_hsin = math.pow(math.sin(lat_dist/2),2) + lon_hsin = math.pow(math.sin(lon_dist/2),2) + + a = lat_hsin + math.cos(lat1) * math.cos(lat2) * lon_hsin + return 2 * 6372.8 * math.asin(math.sqrt(a)) * 1000 +end + +utils.getAngleFromLatLon = function(lat1, lon1, lat2, lon2) + local la1 = math.rad(lat1) + local lo1 = math.rad(lon1) + local la2 = math.rad(lat2) + local lo2 = math.rad(lon2) + + local y = math.sin(lo2-lo1) * math.cos(la2); + local x = math.cos(la1)*math.sin(la2) - math.sin(la1)*math.cos(la2)*math.cos(lo2-lo1); + local a = math.atan2(y, x); + + return (a*180/math.pi + 360) % 360 -- in degrees +end + +utils.getLatLonFromAngleAndDistance = function(telemetry, angle, distance) + --[[ + la1,lo1 coordinates of first point + d be distance (m), + R as radius of Earth (m), + Ad be the angular distance i.e d/R and + θ be the bearing in deg + + la2 = asin(sin la1 * cos Ad + cos la1 * sin Ad * cos θ), and + lo2 = lo1 + atan2(sin θ * sin Ad * cos la1 , cos Ad – sin la1 * sin la2) + --]] + if telemetry.lat == nil or telemetry.lon == nil then + return nil,nil + end + local lat1 = math.rad(telemetry.lat) + local lon1 = math.rad(telemetry.lon) + local Ad = distance/(6371000) --meters + local lat2 = math.asin( math.sin(lat1) * math.cos(Ad) + math.cos(lat1) * math.sin(Ad) * math.cos( math.rad(angle)) ) + local lon2 = lon1 + math.atan2( math.sin( math.rad(angle) ) * math.sin(Ad) * math.cos(lat1) , math.cos(Ad) - math.sin(lat1) * math.sin(lat2)) + return math.deg(lat2), math.deg(lon2) +end + + +utils.decToDMS = function(dec,lat) + local D = math.floor(math.abs(dec)) + local M = (math.abs(dec) - D)*60 + local S = (math.abs((math.abs(dec) - D)*60) - M)*60 + return D .. string.format("%s%04.2f", conf.degSymbol, M) .. (lat and (dec >= 0 and "E" or "W") or (dec >= 0 and "N" or "S")) +end + +utils.decToDMSFull = function(dec,lat) + local D = math.floor(math.abs(dec)) + local M = math.floor((math.abs(dec) - D)*60) + local S = (math.abs((math.abs(dec) - D)*60) - M)*60 + return D .. string.format("%s%d'%04.1f", conf.degSymbol, M, S) .. (lat and (dec >= 0 and "E" or "W") or (dec >= 0 and "N" or "S")) +end + +--[[ +--]] + +status.travelLat = nil +status.travelLon = nil +status.lastTravelLatLonSampleTime = nil + +utils.updateTotalDist = function() + local now = getTime() + if telemetry.armingStatus == 0 then + status.lastUpdateTotDist = now + return + end + if telemetry.lat ~= nil and telemetry.lon ~= nil then + if status.travelLat == nil or status.travelLon == nil then + status.travelLat = telemetry.lat + status.travelLon = telemetry.lon + status.lastTravelLatLonSampleTime = now + end + + if now - status.lastTravelLatLonSampleTime > 50 then + local travelDist = utils.haversine(telemetry.lat, telemetry.lon, status.travelLat, status.travelLon) + -- discard sampling errors + if travelDist < 10000 then + telemetry.totalDist = telemetry.totalDist + travelDist + end + status.travelLat = telemetry.lat + status.travelLon = telemetry.lon + status.lastTravelLatLonSampleTime = now + end + end +end + +utils.drawBlinkBitmap = function(bitmap,x,y) + if blinkon == true then + lcd.drawBitmap(utils.getBitmap(bitmap),x,y) + end +end + +local function getSensorsConfigFilename(panel) + local info = model.getInfo() + local strPanel = panel == nil and "" or "_"..panel + local cfg = "/WIDGETS/YAAPU/CFG/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..strPanel.."_sensors.lua") + local file = io.open(cfg,"r") + + if file == nil then + cfg = "/WIDGETS/YAAPU/CFG/default_sensors.lua" + else + io.close(file) + end + + return cfg +end + +local function getBattConfigFilename() + local info = model.getInfo() + return "/WIDGETS/YAAPU/CFG/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "").."_batt.lua") +end + +-------------------------- +-- CUSTOM SENSORS SUPPORT +-------------------------- + +utils.loadCustomSensors = function(panel) + local success, sensorScript = pcall(loadScript,getSensorsConfigFilename(panel)) + if success then + if sensorScript == nil then + return nil + end + local sensors = sensorScript() + -- handle nil values for warning and critical levels + for i=1,6 + do + if sensors.sensors[i] ~= nil then + local sign = sensors.sensors[i][6] == "+" and 1 or -1 + if sensors.sensors[i][9] == nil then + sensors.sensors[i][9] = math.huge*sign + end + if sensors.sensors[i][8] == nil then + sensors.sensors[i][8] = math.huge*sign + end + end + end + return sensors + else + return nil + end +end + +------------------------------------------- +-- Battery Percentage By Voltage +------------------------------------------- +utils.loadBatteryConfigFile = function() + local success, battConfig = pcall(loadScript,getBattConfigFilename()) + if success then + if battConfig == nil then + battPercByVoltage = {} + return + end + battPercByVoltage = battConfig() + --utils.pushMessage(6,"battery curve loaded") + else + battPercByVoltage = {} + end +end + +local function startTimer() + status.lastTimerStart = getTime()/100 + model.setTimer(2,{mode=1}) +end + +local function stopTimer() + model.setTimer(2,{mode=0}) + status.lastTimerStart = 0 +end + + +----------------------------------------------------------------- +-- TELEMETRY +----------------------------------------------------------------- +local function wrap360(angle) + local res = angle % 360 + if res < 0 then + res = res + 360 + end + return res +end + +local function processTelemetry(appId,value,now) + if appId == 0x5006 then -- ROLLPITCH + -- roll [0,1800] ==> [-180,180] + telemetry.roll = (math.min(bit32.extract(value,0,11),1800) - 900) * 0.2 + -- pitch [0,900] ==> [-90,90] + telemetry.pitch = (math.min(bit32.extract(value,11,10),900) - 450) * 0.2 + -- number encoded on 11 bits: 10 bits for digits + 1 for 10^power + telemetry.range = bit32.extract(value,22,10) * (10^bit32.extract(value,21,1)) -- cm + elseif appId == 0x5005 then -- VELANDYAW + telemetry.vSpeed = bit32.extract(value,1,7) * (10^bit32.extract(value,0,1)) * (bit32.extract(value,8,1) == 1 and -1 or 1)-- dm/s + telemetry.yaw = bit32.extract(value,17,11) * 0.2 + -- once detected it's sticky + if bit32.extract(value,28,1) == 1 then + telemetry.airspeed = bit32.extract(value,10,7) * (10^bit32.extract(value,9,1)) -- dm/s + else + telemetry.hSpeed = bit32.extract(value,10,7) * (10^bit32.extract(value,9,1)) -- dm/s + end + if status.airspeedEnabled == 0 then + status.airspeedEnabled = bit32.extract(value,28,1) + end + elseif appId == 0x5001 then -- AP STATUS + telemetry.flightMode = bit32.extract(value,0,5) + telemetry.simpleMode = bit32.extract(value,5,2) + telemetry.landComplete = bit32.extract(value,7,1) + telemetry.statusArmed = bit32.extract(value,8,1) + telemetry.battFailsafe = bit32.extract(value,9,1) + telemetry.ekfFailsafe = bit32.extract(value,10,2) + telemetry.failsafe = bit32.extract(value,12,1) + telemetry.fencePresent = bit32.extract(value,13,1) + telemetry.fenceBreached = telemetry.fencePresent == 1 and bit32.extract(value,14,1) or 0 -- ignore if fence is disabled + telemetry.throttle = math.floor(0.5 + (bit32.extract(value,19,6) * (bit32.extract(value,25,1) == 1 and -1 or 1) * 1.58)) -- signed throttle [-63,63] -> [-100,100] + -- IMU temperature: 0 means temp =< 19°, 63 means temp => 82° + telemetry.imuTemp = bit32.extract(value,26,6) + 19 -- C° + elseif appId == 0x5002 then -- GPS STATUS + telemetry.numSats = bit32.extract(value,0,4) + -- offset 4: NO_GPS = 0, NO_FIX = 1, GPS_OK_FIX_2D = 2, GPS_OK_FIX_3D or GPS_OK_FIX_3D_DGPS or GPS_OK_FIX_3D_RTK_FLOAT or GPS_OK_FIX_3D_RTK_FIXED = 3 + -- offset 14: 0: no advanced fix, 1: GPS_OK_FIX_3D_DGPS, 2: GPS_OK_FIX_3D_RTK_FLOAT, 3: GPS_OK_FIX_3D_RTK_FIXED + telemetry.gpsStatus = bit32.extract(value,4,2) + bit32.extract(value,14,2) + telemetry.gpsHdopC = bit32.extract(value,7,7) * (10^bit32.extract(value,6,1)) -- dm + telemetry.gpsAlt = bit32.extract(value,24,7) * (10^bit32.extract(value,22,2)) * (bit32.extract(value,31,1) == 1 and -1 or 1)-- dm + elseif appId == 0x5003 then -- BATT + telemetry.batt1volt = bit32.extract(value,0,9) + -- telemetry max is 51.1V, 51.2 is reported as 0.0, 52.3 is 0.1...60 is 88 + -- if >= 12S and V > 51.1 ==> Vreal = 51.2 + telemetry.batt1volt + if conf.cell1Count >= 12 and telemetry.batt1volt < conf.cell1Count*20 then + -- assume a 2V as minimum acceptable "real" voltage + telemetry.batt1volt = 512 + telemetry.batt1volt + end + telemetry.batt1current = bit32.extract(value,10,7) * (10^bit32.extract(value,9,1)) + telemetry.batt1mah = bit32.extract(value,17,15) + elseif appId == 0x5008 then -- BATT2 + telemetry.batt2volt = bit32.extract(value,0,9) + -- telemetry max is 51.1V, 51.2 is reported as 0.0, 52.3 is 0.1...60 is 88 + -- if >= 12S and V > 51.1 ==> Vreal = 51.2 + telemetry.batt1volt + if conf.cell2Count >= 12 and telemetry.batt2volt < conf.cell2Count*20 then + -- assume a 2V as minimum acceptable "real" voltage + telemetry.batt2volt = 512 + telemetry.batt2volt + end + telemetry.batt2current = bit32.extract(value,10,7) * (10^bit32.extract(value,9,1)) + telemetry.batt2mah = bit32.extract(value,17,15) + elseif appId == 0x5004 then -- HOME + telemetry.homeDist = bit32.extract(value,2,10) * (10^bit32.extract(value,0,2)) + telemetry.homeAlt = bit32.extract(value,14,10) * (10^bit32.extract(value,12,2)) * 0.1 * (bit32.extract(value,24,1) == 1 and -1 or 1) + telemetry.homeAngle = bit32.extract(value, 25, 7) * 3 + elseif appId == 0x5000 then -- MESSAGES + if value ~= status.lastMsgValue then + status.lastMsgValue = value + local c + local msgEnd = false + local chunk = {} + for i=3,0,-1 + do + c = bit32.extract(value,i*8,7) + if c ~= 0 then + --status.msgBuffer = status.msgBuffer .. string.char(c) + chunk[4-i] = string.char(c) + updateHash(c) + else + msgEnd = true + break + end + end + status.msgBuffer = status.msgBuffer..table.concat(chunk) + if msgEnd then + local severity = (bit32.extract(value,7,1) * 1) + (bit32.extract(value,15,1) * 2) + (bit32.extract(value,23,1) * 4) + utils.pushMessage( severity, status.msgBuffer) + playHash() + resetHash() + status.msgBuffer = nil + status.msgBuffer = "" + end + end + elseif appId == 0x5007 then -- PARAMS + telemetry.paramId = bit32.extract(value,24,4) + telemetry.paramValue = bit32.extract(value,0,24) + if telemetry.paramId == 1 then + telemetry.frameType = telemetry.paramValue + elseif telemetry.paramId == 4 then + telemetry.batt1Capacity = telemetry.paramValue + elseif telemetry.paramId == 5 then + telemetry.batt2Capacity = telemetry.paramValue + elseif telemetry.paramId == 6 then + telemetry.wpCommands = telemetry.paramValue + end + elseif appId == 0x5009 then -- WAYPOINTS @1Hz + telemetry.wpNumber = bit32.extract(value,0,10) -- wp index + telemetry.wpDistance = bit32.extract(value,12,10) * (10^bit32.extract(value,10,2)) -- meters + telemetry.wpXTError = bit32.extract(value,23,4) * (10^bit32.extract(value,22,1)) * (bit32.extract(value,27,1) == 1 and -1 or 1)-- meters + telemetry.wpOffsetFromCog = bit32.extract(value,29,3) -- offset from cog with 45° resolution + elseif appId == 0x500A then -- RPM 1 and 2 + -- rpm1 and rpm2 are int16_t + local rpm1 = bit32.extract(value,0,16) + local rpm2 = bit32.extract(value,16,16) + telemetry.rpm1 = 10*(bit32.extract(value,15,1) == 0 and rpm1 or -1*(1+bit32.band(0x0000FFFF,bit32.bnot(rpm1)))) -- 2 complement if negative + telemetry.rpm2 = 10*(bit32.extract(value,31,1) == 0 and rpm2 or -1*(1+bit32.band(0x0000FFFF,bit32.bnot(rpm2)))) -- 2 complement if negative + elseif appId == 0x500B then -- TERRAIN + telemetry.heightAboveTerrain = bit32.extract(value,2,10) * (10^bit32.extract(value,0,2)) * 0.1 * (bit32.extract(value,12,1) == 1 and -1 or 1) -- dm to meters + telemetry.terrainUnhealthy = bit32.extract(value,13,1) + status.terrainLastData = now + status.terrainEnabled = 1 + elseif appId == 0x500C then -- WIND + telemetry.trueWindSpeed = bit32.extract(value,8,7) * (10^bit32.extract(value,7,1)) -- dm/s + telemetry.trueWindAngle = bit32.extract(value, 0, 7) * 3 -- degrees + telemetry.apparentWindSpeed = bit32.extract(value,23,7) * (10^bit32.extract(value,22,1)) -- dm/s + telemetry.apparentWindAngle = bit32.extract(value, 16, 6) * (bit32.extract(value,15,1) == 1 and -1 or 1) * 3 -- degrees + elseif appId == 0x500D then -- WAYPOINTS @1Hz + telemetry.wpNumber = bit32.extract(value,0,11) -- wp index + telemetry.wpDistance = bit32.extract(value,13,10) * (10^bit32.extract(value,11,2)) -- meters + telemetry.wpBearing = bit32.extract(value, 23, 7) * 3 + if status.cog ~= nil then + telemetry.wpOffsetFromCog = wrap360(telemetry.wpBearing - status.cog) + end + status.wpEnabled = 1 + --[[ + elseif appId == 0x50F1 then -- RC CHANNELS + -- channels 1 - 32 + local offset = bit32.extract(value,0,4) * 4 + rcchannels[1 + offset] = 100 * (bit32.extract(value,4,6)/63) * (bit32.extract(value,10,1) == 1 and -1 or 1) + rcchannels[2 + offset] = 100 * (bit32.extract(value,11,6)/63) * (bit32.extract(value,17,1) == 1 and -1 or 1) + rcchannels[3 + offset] = 100 * (bit32.extract(value,18,6)/63) * (bit32.extract(value,24,1) == 1 and -1 or 1) + rcchannels[4 + offset] = 100 * (bit32.extract(value,25,6)/63) * (bit32.extract(value,31,1) == 1 and -1 or 1) + --]] + elseif appId == 0x50F2 then -- VFR + telemetry.airspeed = bit32.extract(value,1,7) * (10^bit32.extract(value,0,1)) -- dm/s + telemetry.throttle = bit32.extract(value,8,7) -- unsigned throttle + telemetry.baroAlt = bit32.extract(value,17,10) * (10^bit32.extract(value,15,2)) * 0.1 * (bit32.extract(value,27,1) == 1 and -1 or 1) + status.airspeedEnabled = 1 + end +end + + +function utils.telemetryEnabled() + if getRSSI() == 0 then + status.noTelemetryData = 1 + end + return status.noTelemetryData == 0 +end + +utils.getMaxValue = function(value,idx) + status.minmaxValues[idx] = math.max(value,status.minmaxValues[idx]) + return status.showMinMaxValues == true and status.minmaxValues[idx] or value +end + +local function calcMinValue(value,min) + return min == 0 and value or math.min(value,min) +end + +-- returns the actual minimun only if both are > 0 +local function getNonZeroMin(v1,v2) + return v1 == 0 and v2 or ( v2 == 0 and v1 or math.min(v1,v2)) +end + +local function getBatt1Capacity() + return conf.battCapOverride1 > 0 and conf.battCapOverride1*10 or telemetry.batt1Capacity +end + +local function getBatt2Capacity() + -- this is a fix for passthrough telemetry reporting batt2 capacity > 0 even if BATT2_MONITOR = 0 + return conf.battCapOverride2 > 0 and conf.battCapOverride2*10 or ( status.batt2sources.fc and telemetry.batt2Capacity or 0 ) +end + +-- gets the voltage based on source and min value, battId = [1|2] +local function getMinVoltageBySource(source, cell, cellFC, battId) + -- offset 0 for cell voltage, 2 for pack voltage + local offset = 0 + -- + if cell > 4.35*2 or cellFC > 4.35*2 then + offset = 2 + end + -- + if source == "vs" then + return status.showMinMaxValues == true and status.minmaxValues[2+offset+battId] or cell + elseif source == "fc" then + -- FC only tracks batt1 and batt2 no cell voltage tracking + local minmax = (offset == 2 and status.minmaxValues[battId] or status.minmaxValues[battId]/calcCellCount()) + return status.showMinMaxValues == true and minmax or cellFC + end + -- + return 0 +end + +local function calcFLVSSBatt(battIdx) + local cellMin,cellSum,cellCount + local battSources = battIdx == 1 and status.batt1sources or status.batt2sources + + local cellResult = battIdx == 1 and getValue("Cels") or getValue("Cel2") + + if type(cellResult) == "table" then + cellMin = 4.35 + cellSum = 0 + -- cellcount is global and shared + cellCount = #cellResult + for i, v in pairs(cellResult) do + cellSum = cellSum + v + if cellMin > v then + cellMin = v + end + end + -- if connected after scritp started + if battSources.vs == false then + status.battsource = "na" + end + if status.battsource == "na" then + status.battsource = "vs" + end + battSources.vs = true + else + battSources.vs = false + cellMin = 0 + cellSum = 0 + end + return cellMin,cellSum,cellCount +end + +local function calcBattery() + status.cell1min, status.cell1sum, status.cell1count = calcFLVSSBatt(1) --1 = Cels + status.cell2min, status.cell2sum, status.cell2count = calcFLVSSBatt(2) --2 = Cel2 + + -------------------------------- + -- flight controller battery 1 + -------------------------------- + if telemetry.batt1volt > 0 then + status.cell1sumFC = telemetry.batt1volt*0.1 + status.cell1maxFC = math.max(telemetry.batt1volt,status.cell1maxFC) + if status.battsource == "na" then + status.battsource = "fc" + end + status.batt1sources.fc = true + else + status.batt1sources.fc = false + status.cell1sumFC = 0 + end + -------------------------------- + -- flight controller battery 2 + -------------------------------- + if telemetry.batt2volt > 0 then + status.cell2sumFC = telemetry.batt2volt*0.1 + status.cell2maxFC = math.max(telemetry.batt2volt,status.cell2maxFC) + if status.battsource == "na" then + status.battsource = "fc" + end + status.batt2sources.fc = true + else + status.batt2sources.fc = false + status.cell2sumFC = 0 + end + -- batt fc + status.minmaxValues[1] = calcMinValue(status.cell1sumFC,status.minmaxValues[1]) + status.minmaxValues[2] = calcMinValue(status.cell2sumFC,status.minmaxValues[2]) + -- cell flvss + status.minmaxValues[3] = calcMinValue(status.cell1min,status.minmaxValues[3]) + status.minmaxValues[4] = calcMinValue(status.cell2min,status.minmaxValues[4]) + -- batt flvss + status.minmaxValues[5] = calcMinValue(status.cell1sum,status.minmaxValues[5]) + status.minmaxValues[6] = calcMinValue(status.cell2sum,status.minmaxValues[6]) + -- + ------------------------------------------ + -- table to pass battery info to panes + -- offsets are: 1 celm, 4 batt, 7 curr, 10 mah, 13 cap, indexing starts at 1 + -- value = offset + [0 aggregate|1 for batt 1| 2 for batt2] + -- batt2 = 4 + 2 = 6 + ------------------------------------------ + + -- 1 1 + -- 4 4 + -- 7 7 + -- 10 10 + -- 13 13 + -- 16 16 + -- possible battery configs + -- 1, 2, 3, 4, 5, 6 + + -- Note: these can be calculated. not necessary to track them as min/max + -- cell1minFC = cell1sumFC/calcCellCount() + -- cell2minFC = cell2sumFC/calcCellCount() + -- cell1minA2 = cell1sumA2/calcCellCount() + -- + local count1,count2 = calcCellCount() + + status.battery[1+1] = getMinVoltageBySource(status.battsource, status.cell1min, status.cell1sumFC/count1, 1)*100 --cel1m + status.battery[1+2] = getMinVoltageBySource(status.battsource, status.cell2min, status.cell2sumFC/count2, 2)*100 --cel2m + + status.battery[4+1] = getMinVoltageBySource(status.battsource, status.cell1sum, status.cell1sumFC, 1)*10 --batt1 + status.battery[4+2] = getMinVoltageBySource(status.battsource, status.cell2sum, status.cell2sumFC, 2)*10 --batt2 + + status.battery[7+1] = telemetry.batt1current --curr1 + status.battery[7+2] = telemetry.batt2current --curr2 + + status.battery[10+1] = telemetry.batt1mah --mah1 + status.battery[10+2] = telemetry.batt2mah --mah2 + + status.battery[13+1] = getBatt1Capacity() --cap1 + status.battery[13+2] = getBatt2Capacity() --cap2 + + if (conf.battConf == 1) then + status.battery[1] = getNonZeroMin(status.battery[2], status.battery[3]) + status.battery[4] = getNonZeroMin(status.battery[5],status.battery[6]) + status.battery[7] = telemetry.batt1current + telemetry.batt2current + status.battery[10] = telemetry.batt1mah + telemetry.batt2mah + status.battery[13] = getBatt2Capacity() + getBatt1Capacity() + elseif (conf.battConf == 2) then + status.battery[1] = getNonZeroMin(status.battery[2], status.battery[3]) + status.battery[4] = status.battery[5] + status.battery[6] + status.battery[7] = telemetry.batt1current + status.battery[10] = telemetry.batt1mah + status.battery[13] = getBatt1Capacity() + elseif (conf.battConf == 3) then + -- independent batteries, alerts and capacity % on battery 1 + status.battery[1] = status.battery[2] + status.battery[4] = status.battery[5] + status.battery[7] = telemetry.batt1current + status.battery[10] = telemetry.batt1mah + status.battery[13] = getBatt1Capacity() + elseif (conf.battConf == 4) then + -- independent batteries, alerts and capacity % on battery 2 + status.battery[1] = status.battery[3] + status.battery[4] = status.battery[6] + status.battery[7] = telemetry.batt2current + status.battery[10] = telemetry.batt2mah + status.battery[13] = getBatt2Capacity() + elseif (conf.battConf == 5) then + -- independent batteries, voltage alerts on battery 1, capacity % on battery 2 + status.battery[1] = status.battery[2] + status.battery[4] = status.battery[5] + status.battery[7] = telemetry.batt2current + status.battery[10] = telemetry.batt2mah + status.battery[13] = getBatt2Capacity() + elseif (conf.battConf == 6) then + -- independent batteries, voltage alerts on battery 2, capacity % on battery 1 + status.battery[1] = status.battery[3] + status.battery[4] = status.battery[6] + status.battery[7] = telemetry.batt1current + status.battery[10] = telemetry.batt1mah + status.battery[13] = getBatt1Capacity() + end + + --[[ + discharge curve is based on battery under load, when motors are disarmed + cellvoltage needs to be corrected by subtracting the "under load" voltage drop + --]] + if conf.enableBattPercByVoltage == true then + for battId=0,2 + do + status.battery[16+battId] = utils.getBattPercByCell(0.01*status.battery[1+battId]) + end + else + for battId=0,2 + do + if (status.battery[13+battId] > 0) then + status.battery[16+battId] = (1 - (status.battery[10+battId]/status.battery[13+battId]))*100 + if status.battery[16+battId] > 99 then + status.battery[16+battId] = 99 + elseif status.battery[16+battId] < 0 then + status.battery[16+battId] = 0 + end + else + status.battery[16+battId] = 99 + end + end + end + + if status.showDualBattery == true and conf.battConf == 1 then + -- dual parallel battery: do I have also dual current monitor? + if status.battery[7+1] > 0 and status.battery[7+2] == 0 then + -- special case: assume 1 power brick is monitoring batt1+batt2 in parallel + status.battery[7+1] = status.battery[7+1]/2 --curr1 + status.battery[7+2] = status.battery[7+1] --curr2 + -- + status.battery[10+1] = status.battery[10+1]/2 --mah1 + status.battery[10+2] = status.battery[10+1] --mah2 + -- + status.battery[13+1] = status.battery[13+1]/2 --cap1 + status.battery[13+2] = status.battery[13+1] --cap2 + -- + status.battery[16+1] = status.battery[16+1]/2 --perc1 + status.battery[16+2] = status.battery[16+1] --perc2 + end + end + + -- aggregate value + status.minmaxValues[7] = math.max(status.battery[7], status.minmaxValues[7]) + -- indipendent values + status.minmaxValues[8] = math.max(telemetry.batt1current,status.minmaxValues[8]) + status.minmaxValues[9] = math.max(telemetry.batt2current,status.minmaxValues[9]) +end + +local function checkLandingStatus() + if status.timerRunning == 0 and telemetry.landComplete == 1 and status.lastTimerStart == 0 then + startTimer() + end + if status.timerRunning == 1 and telemetry.landComplete == 0 and status.lastTimerStart ~= 0 then + stopTimer() + -- play landing complete anly if motorts are armed + if telemetry.statusArmed == 1 then + utils.playSound("landing") + end + end + status.timerRunning = telemetry.landComplete +end + +local function drainTelemetryQueues() + if conf.enableCRSF == false then + -- SPORT + local i = 0 + -- empty sport queue + local a,b,c,d = sportTelemetryPop() + while a ~= null and i < 50 do + a,b,c,d = sportTelemetryPop() + i = i + 1 + end + else + -- CRSF + local i = 0 + -- empty sport queue + local a,b = crossfireTelemetryPop() + while a ~= null and i < 50 do + a,b = crossfireTelemetryPop() + i = i + 1 + end + end +end + +local function drawRssi() + -- RSSI + lcd.drawText(543, 6, "RS:", 0+CUSTOM_COLOR) + lcd.drawText(543 + 30,6, getRSSI(), 0+CUSTOM_COLOR) +end + +local function drawRssiCRSF() + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + -- RSSI + lcd.drawText(543 - 148, 6, "RTP:", 0+CUSTOM_COLOR+SMLSIZE) + lcd.drawText(543, 6, "RS:", 0+CUSTOM_COLOR+SMLSIZE) + lcd.drawText(543 - 148 + 30, 6, string.format("%d/%d/%d",getValue("RQly"),getValue("TQly"),getValue("TPWR")), 0+CUSTOM_COLOR+SMLSIZE) + lcd.drawText(543 + 22, 6, string.format("%d/%d", telemetry.rssiCRSF, getValue("RFMD")), 0+CUSTOM_COLOR+SMLSIZE) +end + +local function resetTelemetry() + ----------------------------- + -- TELEMETRY + ----------------------------- + -- AP STATUS + telemetry.flightMode = 0 + telemetry.simpleMode = 0 + telemetry.landComplete = 0 + telemetry.statusArmed = 0 + telemetry.battFailsafe = 0 + telemetry.ekfFailsafe = 0 + telemetry.imuTemp = 0 + -- GPS + telemetry.numSats = 0 + telemetry.gpsStatus = 0 + telemetry.gpsHdopC = 100 + telemetry.gpsAlt = 0 + -- BATT 1 + telemetry.batt1volt = 0 + telemetry.batt1current = 0 + telemetry.batt1mah = 0 + -- BATT 2 + telemetry.batt2volt = 0 + telemetry.batt2current = 0 + telemetry.batt2mah = 0 + -- HOME + telemetry.homeDist = 0 + telemetry.homeAlt = 0 + telemetry.homeAngle = -1 + -- VELANDYAW + telemetry.vSpeed = 0 + telemetry.hSpeed = 0 + telemetry.yaw = 0 + -- ROLLPITCH + telemetry.roll = 0 + telemetry.pitch = 0 + telemetry.range = 0 + -- PARAMS + telemetry.frameType = -1 + telemetry.batt1Capacity = 0 + telemetry.batt2Capacity = 0 + -- GPS + telemetry.lat = nil + telemetry.lon = nil + telemetry.homeLat = nil + telemetry.homeLon = nil + -- WP + telemetry.wpNumber = 0 + telemetry.wpDistance = 0 + telemetry.wpXTError = 0 + telemetry.wpBearing = 0 + telemetry.wpOffsetFromCog = 0 + telemetry.wpCommands = 0 + telemetry.wpLat = 0 + telemetry.wpLon = 0 + -- RC channels + telemetry.rcchannels = {} + -- VFR + telemetry.airspeed = 0 + telemetry.throttle = 0 + telemetry.baroAlt = 0 + -- Total distance + telemetry.totalDist = 0 + -- RPM + telemetry.rpm1 = 0 + telemetry.rpm2 = 0 + -- TERRAIN + telemetry.heightAboveTerrain = 0 + telemetry.terrainUnhealthy = 0 + -- WIND + telemetry.trueWindSpeed = 0 + telemetry.trueWindAngle = 0 + telemetry.apparentWindSpeed = 0 + telemetry.apparentWindAngle = 0 + -- RSSI + telemetry.rssi = 0 + telemetry.rssiCRSF = 0 +end + +local function resetStatus() + ----------------------------- + -- SCRIPT STATUS + ----------------------------- + -- FLVSS 1 + status.cell1min = 0 + status.cell1sum = 0 + -- FLVSS 2 + status.cell2min = 0 + status.cell2sum = 0 + -- FC 1 + status.cell1sumFC = 0 + status.cell1maxFC = 0 + -- FC 2 + status.cell2sumFC = 0 + status.cell2maxFC = 0 + -- BATT + status.cell1count = 0 + status.cell2count = 0 + + status.battsource = "na" + -- BATT 1 + status.batt1sources = { + vs = false, + fc = false + } + -- BATT 2 + status.batt2sources = { + vs = false, + fc = false + } + -- TELEMETRY + status.noTelemetryData = 1 + -- MESSAGES + status.msgBuffer = "" + status.lastMsgValue = 0 + status.lastMsgTime = 0 + -- FLIGHT TIME + status.lastTimerStart = 0 + status.timerRunning = 0 + status.flightTime = 0 + -- EVENTS + status.lastStatusArmed = 0 + status.lastGpsStatus = 0 + status.lastFlightMode = 0 + status.lastSimpleMode = 0 + -- battery levels + status.batLevel = 99 + status.battLevel1 = false + status.battLevel2 = false + status.lastBattLevel = 14 + ------------------------- + -- BATTERY ARRAY + ------------------------- + battery = {0,0,0,0,0,0,0,0,0,0,0,0} +end + +local function resetMessages() + -- MESSAGES + utils.clearTable(status.messages) + + status.msgBuffer = "" + status.lastMsgValue = 0 + status.lastMsgTime = 0 + status.lastMessage = nil + status.lastMessageSeverity = 0 + status.lastMessageCount = 1 + status.messageCount = 0 + status.messageRow = 0 + status.messages = {} +end + +local function resetAlarms() + -- reset alarms + status.alarms[1] = { false, 0 , false, 0, 0, false, 0} --MIN_ALT + status.alarms[2] = { false, 0 , true, 1, 0, false, 0 } --MAX_ALT + status.alarms[3] = { false, 0 , true, 1, 0, false, 0 } --15 + status.alarms[4] = { false, 0 , true, 1, 0, false, 0 } --FS_EKF + status.alarms[5] = { false, 0 , true, 1, 0, false, 0 } --FS_BAT + status.alarms[6] = { false, 0 , true, 2, 0, false, 0 } --FLIGTH_TIME + status.alarms[7] = { false, 0 , false, 3, 4, false, 0 } --BATT L1 + status.alarms[8] = { false, 0 , false, 4, 4, false, 0 } --BATT L2 + status.alarms[9] = { false, 0 , true, 1, 0, false, 0 } --FS + status.alarms[10] = { false, 0 , true, 1, 0, false, 0 } --FENCE + status.alarms[11] = { false, 0 , true, 1, 0, false, 0 } --TERRAIN +end + +local function resetTimers() + -- stop and reset timer + model.setTimer(2,{mode=0}) + model.setTimer(2,{value=0}) +end + +local function reset() + if resetPending then + if resetPhase == 0 then + -- reset frame + utils.clearTable(status.currentFrameType.frameTypes) + drainTelemetryQueues() + resetPhase = 1 + elseif resetPhase == 1 then + resetTelemetry() + resetPhase = 2 + elseif resetPhase == 2 then + resetStatus() + resetPhase = 3 + elseif resetPhase == 3 then + resetAlarms() + resetPhase = 4 + elseif resetPhase == 4 then + resetTimers() + resetMessages() + resetPhase = 5 + elseif resetPhase == 5 then + currentPage = 0 + status.minmaxValues = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} + status.showMinMaxValues = false + status.showDualBattery = false + status.strFlightMode = nil + status.modelString = nil + status.currentFrameType= {} + libs.drawLib.resetGraph("plot1") + libs.drawLib.resetGraph("plot2") + resetPhase = 6 + elseif resetPhase == 6 then + -- custom sensors + utils.clearTable(customSensors) + customSensors = utils.loadCustomSensors() + -- done + resetPhase = 7 + elseif resetPhase == 7 then + utils.pushMessage(7,"Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")") + utils.playSound("yaapu") + -- on model change reload config! + if modelChangePending == true then + -- force load model config + loadConfigPending = true + triggerConfigReload() + end + resetPhase = 0 + resetPending = false + end + end +end + +local function calcFlightTime() + -- update local variable with timer 3 value + if model.getTimer(2).value < status.flightTime and telemetry.statusArmed == 0 then + triggerReset() + end + if model.getTimer(2).value < status.flightTime and telemetry.statusArmed == 1 then + model.setTimer(2,{value=status.flightTime}) + utils.pushMessage(4,"Reset ignored while armed") + end + status.flightTime = model.getTimer(2).value +end + +local function setSensorValues() + if not utils.telemetryEnabled() then + return + end + if conf.enableCRSF then + -- CRSF + setTelemetryValue(0x07, 0, 0, telemetry.vSpeed, 5 , 2 , "VSpd") + + if conf.enableRPM == 2 or conf.enableRPM == 3 then + setTelemetryValue(0, 0, 1, telemetry.rpm1, 18 , 0 , "RPM1") + end + if conf.enableRPM == 3 then + setTelemetryValue(0, 0, 2, telemetry.rpm2, 18 , 0 , "RPM2") + end + if status.airspeedEnabled == 1 then + setTelemetryValue(0, 0, 3, telemetry.airspeed*0.1, 4 , 0 , "ASPD") + end + else + -- FRSKY + setTelemetryValue(0x060F, 0, 0, status.battery[16], 13 , 0 , "Fuel") + setTelemetryValue(0x020F, 0, 0, status.battery[7], 2 , 1 , "CURR") + setTelemetryValue(0x084F, 0, 0, math.floor(telemetry.yaw), 20 , 0 , "Hdg") + setTelemetryValue(0x010F, 0, 0, telemetry.homeAlt*10, 9 , 1 , "Alt") + setTelemetryValue(0x083F, 0, 0, telemetry.hSpeed*0.1, 5 , 0 , "GSpd") + setTelemetryValue(0x021F, 0, 0, status.battery[4]*10, 1 , 2 , "VFAS") + setTelemetryValue(0x011F, 0, 0, telemetry.vSpeed, 5 , 1 , "VSpd") + setTelemetryValue(0x082F, 0, 0, math.floor(telemetry.gpsAlt*0.1), 9 , 0 , "GAlt") + setTelemetryValue(0x041F, 0, 0, telemetry.imuTemp, 11 , 0 , "IMUt") + setTelemetryValue(0x060F, 0, 1, telemetry.statusArmed*100, 0 , 0 , "ARM") + setTelemetryValue(0x050D, 0, 0, telemetry.throttle, 13 , 0 , "Thr") + + if conf.enableRPM == 2 or conf.enableRPM == 3 then + setTelemetryValue(0x050E, 0, 0, telemetry.rpm1, 18 , 0 , "RPM1") + end + if conf.enableRPM == 3 then + setTelemetryValue(0x050F, 0, 0, telemetry.rpm2, 18 , 0 , "RPM2") + end + if status.airspeedEnabled == 1 then + setTelemetryValue(0x0AF, 0, 0, telemetry.airspeed*0.1, 4 , 0 , "ASpd") + end + --setTelemetryValue(0x070F, 0, 0, telemetry.roll, 20 , 0 , "ROLL") + --setTelemetryValue(0x071F, 0, 0, telemetry.pitch, 20 , 0 , "PTCH") + end +end + +local function drawMessagesTelemetryBar() + local colorLabel = lcd.RGB(140,140,140) + -- CELL + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 34, string.upper(status.battsource).." V", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + if status.battery[1] * 0.01 < 10 then + lcd.drawNumber(LCD_W-2, 34+16, status.battery[1] + 0.5, PREC2+MIDSIZE+CUSTOM_COLOR+RIGHT) + else + lcd.drawNumber(LCD_W-2, 34+16, (status.battery[1] + 0.5)*0.1, PREC1+MIDSIZE+CUSTOM_COLOR+RIGHT) + end + -- aggregate batt % + local strperc = string.format("%2d", status.battery[16]) + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, 74, "BATT %", SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, 74+16, strperc, MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- speed + local speed = telemetry.hSpeed * 0.1 * conf.horSpeedMultiplier + local speedLabel = "GSPD" + if status.airspeedEnabled == 1 then + speed = telemetry.airspeed * 0.1 * conf.horSpeedMultiplier + speedLabel = "ASPD" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 154, string.format("%s %s", speedLabel, conf.horSpeedLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-2, 154+16, string.format("%.01f",speed), MIDSIZE+CUSTOM_COLOR+RIGHT) + + -- home distance + local label = unitLabel + local dist = telemetry.homeDist + local flags = 0 + if dist*unitScale > 999 then + flags = flags + PREC2 + dist = dist*unitLongScale*100 + label = unitLongLabel + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-2, 194, string.format("HOME %s", label), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawNumber(LCD_W-2, 194+16, dist, MIDSIZE+flags+CUSTOM_COLOR+RIGHT) + + -- alt + local alt = telemetry.homeAlt * unitScale + local altLabel = "ALT" + if status.terrainEnabled == 1 then + alt = telemetry.heightAboveTerrain * unitScale + altLabel = "HAT" + end + lcd.setColor(CUSTOM_COLOR,colorLabel) + lcd.drawText(LCD_W-4, 114, string.format("%s %s", altLabel, unitLabel), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W-4, 114+16, string.format("%.0f",alt), MIDSIZE+CUSTOM_COLOR+RIGHT) + -- home angle + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + libs.drawLib.drawRVehicle(736,290,18,math.floor(telemetry.homeAngle - telemetry.yaw),CUSTOM_COLOR) +end + +local function drawMessageScreen() + libs.layoutLib.drawTopBar() + -- each new message scrolls all messages to the end (offset is absolute) + if status.messageAutoScroll == true then + status.messageOffset = math.max(0, status.messageCount - 23) + end + + local row = 0 + local offsetStart = status.messageOffset + local offsetEnd = math.min(status.messageCount-1, status.messageOffset + 23 - 1) + + for i=offsetStart,offsetEnd do + lcd.setColor(CUSTOM_COLOR,utils.mavSeverity[status.messages[i % 200][2]][2]) + lcd.drawText(0,34+18*row, status.messages[i % 200][1],SMLSIZE+CUSTOM_COLOR) + row = row+1 + end + lcd.setColor(CUSTOM_COLOR,utils.colors.bg) + lcd.drawFilledRectangle(672,32,128,448,CUSTOM_COLOR) + + drawMessagesTelemetryBar() + -- AUTOSCROLL + if status.messageAutoScroll == true then + lcd.setColor(CUSTOM_COLOR,WHITE) + else + lcd.setColor(CUSTOM_COLOR,utils.colors.darkyellow) + end + + local maxPages = tonumber(math.ceil((#status.messages+1)/23)) + local currentPage = 1+tonumber(maxPages - (status.messageCount - status.messageOffset)/23) + + lcd.drawText(LCD_W-2, LCD_H-16, string.format("%d/%d",currentPage,maxPages), SMLSIZE+CUSTOM_COLOR+RIGHT) + lcd.setColor(CUSTOM_COLOR,utils.colors.grey) + lcd.drawLine(0,LCD_H-20,672,LCD_H-20,SOLID,CUSTOM_COLOR) + + lcd.setColor(CUSTOM_COLOR,WHITE) + if status.strFlightMode ~= nil then + lcd.drawText(0,LCD_H-20,status.strFlightMode,CUSTOM_COLOR) + end + lcd.drawTimer(670, LCD_H-20, model.getTimer(2).value, CUSTOM_COLOR+RIGHT) +end + +--------------------------------- +-- This function checks alarm condition and as long as the condition persists it plays +-- a warning sound. +--------------------------------- +utils.checkAlarm = function(level,value,idx,sign,sound,delay) + if delay == 0 then + return + end + -- once landed reset all alarms except battery alerts + if status.timerRunning == 0 then + if status.alarms[idx][4] == 0 then + status.alarms[idx] = { false, 0, false, 0, 0, false, 0} + elseif status.alarms[idx][4] == 1 then + status.alarms[idx] = { false, 0, true, 1, 0, false, 0} + elseif status.alarms[idx][4] == 2 then + status.alarms[idx] = { false, 0, true, 2, 0, false, 0} + elseif status.alarms[idx][4] == 3 then + status.alarms[idx] = { false, 0 , false, 3, 4, false, 0} + elseif status.alarms[idx][4] == 4 then + status.alarms[idx] = { false, 0 , false, 4, 4, false, 0} + end + -- reset done + return + end + -- if needed arm the alarm only after value has reached level + if status.alarms[idx][3] == false and level > 0 and -1 * sign*value > -1 * sign*level then + status.alarms[idx][3] = true + end + + if status.alarms[idx][4] == 2 then + if status.flightTime > 0 and math.floor(status.flightTime) % delay == 0 then + if status.alarms[idx][1] == false then + status.alarms[idx][1] = true + utils.playSound(sound) + playDuration(status.flightTime,(status.flightTime > 3600 and 1 or 0)) -- minutes,seconds + end + else + status.alarms[idx][1] = false + end + else + if status.alarms[idx][3] == true then + if level > 0 and sign*value > sign*level then + -- value is outside level + if status.alarms[idx][2] == 0 then + -- first time outside level after last reset + status.alarms[idx][2] = status.flightTime + -- status: START + end + else + -- value back to normal ==> reset + status.alarms[idx][2] = 0 + status.alarms[idx][1] = false + status.alarms[idx][6] = false + -- status: RESET + end + if status.alarms[idx][2] > 0 and (status.flightTime ~= status.alarms[idx][2]) and (status.flightTime - status.alarms[idx][2]) >= status.alarms[idx][5] then + -- enough time has passed after START + status.alarms[idx][6] = true + -- status: READY + end + + if status.alarms[idx][6] == true and status.alarms[idx][1] == false then + utils.playSound(sound) + status.alarms[idx][1] = true + status.alarms[idx][7] = status.flightTime + -- status: BEEP + end + -- all but battery alarms + if status.alarms[idx][4] ~= 3 then + if status.alarms[idx][6] == true and status.flightTime ~= status.alarms[idx][7] and (status.flightTime - status.alarms[idx][7]) % delay == 0 then + status.alarms[idx][1] = false + -- status: REPEAT + end + end + end + end +end + +local function loadFlightModes() + if status.currentFrameType.flightModes then + return + end + if telemetry.frameType ~= -1 then + if status.frameTypes[telemetry.frameType] == "c" then + status.currentFrameType= utils.doLibrary(conf.enablePX4Modes and "copter_px4" or "copter") + elseif status.frameTypes[telemetry.frameType] == "p" then + status.currentFrameType= utils.doLibrary(conf.enablePX4Modes and "plane_px4" or "plane") + elseif status.frameTypes[telemetry.frameType] == "r" or status.frameTypes[telemetry.frameType] == "b" then + status.currentFrameType= utils.doLibrary("rover") + elseif status.frameTypes[telemetry.frameType] == "a" then + status.currentFrameType= utils.doLibrary("blimp") + end + end +end + +--------------------------------- +-- This function checks state transitions and only returns true if a specific delay has passed +-- new transitions reset the delay timer +--------------------------------- +local function checkTransition(idx,value) + if value ~= status.transitions[idx][1] then + -- value has changed + status.transitions[idx][1] = value + status.transitions[idx][2] = getTime() + status.transitions[idx][3] = false + -- status: RESET + return false + end + if status.transitions[idx][3] == false and (getTime() - status.transitions[idx][2]) > status.transitions[idx][4] then + -- enough time has passed after RESET + status.transitions[idx][3] = true + -- status: FIRE + return true + end +end + +local function checkEvents() + loadFlightModes() + + -- silence alarms when showing min/max values + if status.showMinMaxValues == false then + local alt = status.terrainEnabled == 1 and telemetry.heightAboveTerrain or telemetry.homeAlt + utils.checkAlarm(conf.minAltitudeAlert,alt,1,-1,"minalt",conf.repeatAlertsPeriod) + utils.checkAlarm(conf.maxAltitudeAlert,alt,2,1,"maxalt",conf.repeatAlertsPeriod) + utils.checkAlarm(conf.maxDistanceAlert,telemetry.homeDist,3,1,"maxdist",conf.repeatAlertsPeriod) + utils.checkAlarm(1,2*telemetry.ekfFailsafe,4,1,"ekf",conf.repeatAlertsPeriod) + utils.checkAlarm(1,2*telemetry.battFailsafe,5,1,"lowbat",conf.repeatAlertsPeriod) + utils.checkAlarm(1,2*telemetry.failsafe,9,1,"failsafe",conf.repeatAlertsPeriod) + utils.checkAlarm(1,2*telemetry.fenceBreached,10,1,"fencebreach",conf.repeatAlertsPeriod) + utils.checkAlarm(1,2*telemetry.terrainUnhealthy,11,1,"terrainko",conf.repeatAlertsPeriod) + utils.checkAlarm(conf.timerAlert,status.flightTime,6,1,"timealert",conf.timerAlert) + end + + if conf.enableBattPercByVoltage == true then + status.batLevel = utils.getBattPercByCell(status.battery[1]*0.01) + else + if (status.battery[13] > 0) then + status.batLevel = (1 - (status.battery[10]/status.battery[13]))*100 + else + status.batLevel = 99 + end + end + + for l=1,13 do + -- trigger alarm as as soon as it falls below level + 1 (i.e 91%,81%,71%,...) + if status.batLevel <= status.batLevels[l] + 1 and l < status.lastBattLevel then + status.lastBattLevel = l + utils.playSound("bat"..status.batLevels[l]) + break + end + end + + if telemetry.statusArmed == 1 and status.lastStatusArmed == 0 then + status.lastStatusArmed = telemetry.statusArmed + utils.playSound("armed") + if telemetry.fencePresent == 1 then + utils.playSound("fence") + end + -- reset home on arming + telemetry.homeLat = nil + telemetry.homeLon = nil + elseif telemetry.statusArmed == 0 and status.lastStatusArmed == 1 then + status.lastStatusArmed = telemetry.statusArmed + utils.playSound("disarmed") + end + + if telemetry.gpsStatus > 2 and status.lastGpsStatus <= 2 then + status.lastGpsStatus = telemetry.gpsStatus + utils.playSound("gpsfix") + elseif telemetry.gpsStatus <= 2 and status.lastGpsStatus > 2 then + status.lastGpsStatus = telemetry.gpsStatus + utils.playSound("gpsnofix") + end + + -- home detecting code + if telemetry.homeLat == nil then + if telemetry.gpsStatus > 2 and telemetry.homeAngle ~= -1 then + telemetry.homeLat, telemetry.homeLon = utils.getLatLonFromAngleAndDistance(telemetry, telemetry.homeAngle, telemetry.homeDist) + end + end + + -- flightmode transitions have a grace period to prevent unwanted flightmode call out + -- on quick radio mode switches + if telemetry.frameType ~= -1 and checkTransition(1,telemetry.flightMode) then + utils.playSoundByFlightMode(telemetry.flightMode) + -- check if we should enable waypoint plotting for this flight mode + -- supported modes are AUTO, GUIDED, LOITER, RTL, QRTL, QLOITER, QLAND, FOLLOW, ZIGZAG + -- see /MAVProxy/modules/mavproxy_map/__init__.py + if utils.wpEnabledModeList[string.upper(status.currentFrameType.flightModes[telemetry.flightMode])] == 1 then + status.wpEnabledMode = 1 + else + status.wpEnabledMode = 0 + end + end + + if telemetry.simpleMode ~= status.lastSimpleMode then + if telemetry.simpleMode == 0 then + utils.playSound( status.lastSimpleMode == 1 and "simpleoff" or "ssimpleoff" ) + else + utils.playSound( telemetry.simpleMode == 1 and "simpleon" or "ssimpleon" ) + end + status.lastSimpleMode = telemetry.simpleMode + end +end + +local function checkCellVoltage() + if status.battery[1] <= 0 then + return + end + -- check alarms + utils.checkAlarm(conf.battAlertLevel1,status.battery[1],7,-1,"batalert1",conf.repeatAlertsPeriod) + utils.checkAlarm(conf.battAlertLevel2,status.battery[1],8,-1,"batalert2",conf.repeatAlertsPeriod) + -- cell bgcolor is sticky but gets triggered with alarms + if status.battLevel1 == false then status.battLevel1 = status.alarms[7][1] end + if status.battLevel2 == false then status.battLevel2 = status.alarms[8][1] end +end +-------------------------------------------------------------------------------- +-- MAIN LOOP +-------------------------------------------------------------------------------- +-- + + + +-- telemetry pop function, either SPort or CRSF +local telemetryPop = nil + +local function crossfirePop() + local now = getTime() + local command, data = crossfireTelemetryPop() + if (command == 0x80 or command == 0x7F) and data ~= nil then + -- actual payload starts at data[2] + if #data >= 7 and data[1] == 0xF0 then + local app_id = bit32.lshift(data[3],8) + data[2] + local value = bit32.lshift(data[7],24) + bit32.lshift(data[6],16) + bit32.lshift(data[5],8) + data[4] + return 0x00, 0x10, app_id, value + elseif #data > 4 and data[1] == 0xF1 then + local msg = {} + local severity = data[2] + -- copy the terminator as well + for i=3,#data + do + -- avoid string concatenation which is slow! + msg[i-2] = string.char(data[i]) + -- hash support + updateHash(data[i]) + end + status.msgBuffer = table.concat(msg) + utils.pushMessage(severity, status.msgBuffer) + -- hash audio support + playHash() + -- hash reset + resetHash() + status.msgBuffer = nil + status.msgBuffer = "" + elseif #data >= 8 and data[1] == 0xF2 then + -- passthrough array + local app_id, value + for i=0,math.min(data[2]-1, 9) + do + app_id = bit32.lshift(data[4+(6*i)],8) + data[3+(6*i)] + value = bit32.lshift(data[8+(6*i)],24) + bit32.lshift(data[7+(6*i)],16) + bit32.lshift(data[6+(6*i)],8) + data[5+(6*i)] + --utils.pushMessage(7,string.format("CRSF:%d - %04X:%08X",i, app_id, value), true) + processTelemetry(app_id, value, now) + end + status.noTelemetryData = 0 + status.hideNoTelemetry = true + end + end + return nil, nil ,nil ,nil +end + +local function loadConfig(init) + -- load menu library + local menuLib = utils.doLibrary("../menu") + menuLib.loadConfig(conf) + -- get a reference to the plotSources table + status.plotSources = menuLib.plotSources + -- ok configuration loaded + status.battsource = conf.defaultBattSource + -- CRSF or SPORT? + telemetryPop = sportTelemetryPop + utils.drawRssi = drawRssi + if conf.enableCRSF then + telemetryPop = crossfirePop + utils.drawRssi = drawRssiCRSF + -- we need a lower value here to prevent CPU Kill + -- when decoding multiple packet frames + telemetryPopLoops = 8 + end + -- do not reset layout on boot + if init == nil then + resetLayoutPending = true + resetLayoutPhase = -1 + end + status.mapZoomLevel = conf.mapProvider == 1 and conf.mapZoomMin or conf.mapZoomMax + + loadConfigPending = false +end + +local function checkConfig() + local cfg = io.open(getConfigTriggerFilename(),"r") + if cfg ~= nil then + local str = io.read(cfg,1) + io.close(cfg) + + if str == "1" then + cfg = io.open(getConfigTriggerFilename(),"w") + if cfg ~= nil then + io.write(cfg, "0") + io.close(cfg) + end + loadConfig() + end + end + collectgarbage() + collectgarbage() +end + +local timerPage = getTime() +local timerWheel = getTime() +local updateCog = 0 + +local function task5HzA(widget, now) + -- handle page emulation + if now - timerPage > 50 then + local chValue = getValue(conf.screenWheelChannelId) + status.mapZoomLevel = utils.getMapZoomLevel(widget, conf, status, chValue) + status.messageOffset = utils.getMessageOffset(widget, conf, status, chValue) + status.screenTogglePage = utils.getScreenTogglePage(widget,conf,status) + timerPage = now + end + utils.updateTotalDist() + telemetry.rssi = getRSSI() +end + +local function task2HzA(widget, now) + if conf.enableCRSF then + -- apply same algo used by ardupilot to estimate a 0-100 rssi value + -- rssi = roundf((1.0f - (rssi_dbm - 50.0f) / 70.0f) * 255.0f); + local rssi_dbm = math.abs(getValue("1RSS")) + if getValue("ANT") ~= 0 then + rssi_dbm = math.abs(getValue("2RSS")) + end + telemetry.rssiCRSF = math.min(100, math.floor(0.5 + ((1-(rssi_dbm - 50)/70)*100))) + + if getValue("RFMD") == 1 then + -- GPS + telemetry.numSats = getValue("Sats") + -- BATT 1 + telemetry.batt1volt = getValue("RxBt") * 10 -- V to dV + telemetry.batt1current = getValue("Curr") * 10 -- A to dA + telemetry.batt1mah = getValue("Capa") -- mAh + -- VELANDYAW + telemetry.hSpeed = getValue("GSpd") * 2.777 -- km/h to dm/s + -- ROLLPITCH + telemetry.roll = math.deg(getValue("Roll")) -- rad to deg + telemetry.pitch = math.deg(getValue("Ptch")) -- rad to deg + telemetry.yaw = math.deg(getValue("Yaw")) -- rad to deg + -- VFR + telemetry.homeAlt = getValue("Alt") -- m + end + end + checkEvents() + checkLandingStatus() + checkCellVoltage() +end + +local function task2HzB(widget, now) + if telemetry.lat ~= nil and telemetry.lon ~= nil then + if updateCog == 1 then + -- update COG + if status.lastLat ~= nil and status.lastLon ~= nil and status.lastLat ~= telemetry.lat and status.lastLon ~= telemetry.lon then + local cog = utils.getAngleFromLatLon(status.lastLat, status.lastLon, telemetry.lat, telemetry.lon) + status.cog = cog ~= nil and cog or status.cog + end + updateCog = 0 + else + -- update last GPS coords + status.lastLat = telemetry.lat + status.lastLon = telemetry.lon + -- process wpLat and wpLon updates + if status.wpEnabled == 1 then + status.wpLat, status.wpLon = utils.getLatLonFromAngleAndDistance(telemetry, telemetry.wpBearing, telemetry.wpDistance) + end + updateCog = 1 + end + end + setSensorValues() + calcFlightTime() + -- update gps telemetry data + local gpsData = getValue("GPS") + if type(gpsData) == "table" and gpsData.lat ~= nil and gpsData.lon ~= nil then + telemetry.lat = gpsData.lat + telemetry.lon = gpsData.lon + end +end + +local function task2HzC(widget, now) + calcBattery() + -- flight mode + if status.currentFrameType.flightModes then + status.strFlightMode = status.currentFrameType.flightModes[telemetry.flightMode] + if status.strFlightMode ~= nil and telemetry.simpleMode > 0 then + local strSimpleMode = telemetry.simpleMode == 1 and "(S)" or "(SS)" + status.strFlightMode = string.format("%s%s",status.strFlightMode,strSimpleMode) + end + end + + if telemetry.lat ~= nil and telemetry.lon ~= nil then + if conf.gpsFormat == 1 then + -- DMS + telemetry.strLat = utils.decToDMSFull(telemetry.lat) + telemetry.strLon = utils.decToDMSFull(telemetry.lon, telemetry.lat) + else + -- decimal + telemetry.strLat = string.format("%.06f", telemetry.lat) + telemetry.strLon = string.format("%.06f", telemetry.lon) + end + end +end + +local function task1HzA(widget, now) + -- top bar model frame and name + if status.modelString == nil then + -- frametype and model name + local info = model.getInfo() + local fn = status.frameNames[telemetry.frameType] + local strmodel = info.name + if fn ~= nil then + status.modelString = fn..": "..info.name + end + end + + -- map background function + if status.screenTogglePage ~= 5 then + if mapLayout ~= nil then + mapLayout.background(widget,conf,telemetry,status,utils,libs.drawLib) + end + end +end + +local function task05HzA(widget, now) + -- reload config + checkConfig() + + -- if we do not see terrain data for more than 5 sec we assume TERRAIN_ENABLE = 0 + if status.terrainEnabled == 1 and now - status.terrainLastData > 500 then + status.terrainEnabled = 0 + telemetry.terrainUnhealthy = 0 + end +end + + +local bgTasks = { + {0, 35, task5HzA}, -- 3.0Hz + {0, 50, task2HzA}, -- 2.0Hz + {0, 50, task2HzB}, -- 2.0Hz + {0, 50, task2HzC}, -- 2.0Hz + {0, 100, task1HzA}, -- 1.0Hz + {0, 200, task05HzA}, -- 0.5Hz +} + +local function checkTaskTimeConstraints(now, tasks, task_id) + return (now - tasks[task_id][1]) >= tasks[task_id][2] +end + +utils.runScheduler = function(widget, tasks) + local now = getTime() + local maxDelayTaskId = -1 + local maxDelay = 0 + local delay = 0 + + for taskId=1,#tasks + do + delay = (now - (tasks[taskId][1]))/tasks[taskId][2] + if (delay >= maxDelay and checkTaskTimeConstraints(now, tasks, taskId)) then + maxDelay = delay + maxDelayTaskId = taskId + end + end + if maxDelayTaskId < 0 then + return maxDelayTaskId + end + tasks[maxDelayTaskId][1] = now; + tasks[maxDelayTaskId][3](widget, getTime()) +end + +local function backgroundTasks(widget,telemetryLoops) + local now = getTime() + -- don't process telemetry while resetting to prevent CPU kill + if conf.pauseTelemetry == false and resetPending == false and resetLayoutPending == false and loadConfigPending == false then + for i=1,telemetryLoops + do + local success, sensor_id,frame_id,data_id,value = pcall(telemetryPop) + + if success and frame_id == 0x10 then + status.noTelemetryData = 0 + -- no telemetry dialog only shown once + status.hideNoTelemetry = true + processTelemetry(data_id,value,now) + end + end + end + + for i=1,3 + do + utils.runScheduler(widget, bgTasks) + end + + -- blinking support + if now - blinktime > 65 then + blinkon = not blinkon + blinktime = now + end + return 0 +end + +local function init() + + -- initialize flight timer + model.setTimer(2,{mode=0}) + model.setTimer(2,{value=0}) + -- load configuration at boot and only refresh if GV(8,8) = 1 + loadConfig(true) + -- color init + utils.initColors() + -- ok configuration loaded + status.mapZoomLevel = conf.mapZoomLevel + + status.battsource = conf.defaultBattSource + -- load draw library + libs.drawLib = utils.doLibrary("drawlib") + libs.mapLib = utils.doLibrary("maplib") + libs.layoutLib = utils.doLibrary("layoutlib") + utils.prefixHashes = utils.doLibrary("prefix_hashes") + status.currentModel = model.getInfo().name + -- load custom sensors + customSensors = utils.loadCustomSensors() + -- load battery config + utils.loadBatteryConfigFile() + -- ok done + utils.pushMessage(7,"Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")") + + utils.playSound("yaapu") + -- fix for generalsettings lazy loading... + unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 + unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" + unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 + unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" + -- unit conversion helper + status.unitConversion[1] = unitScale + status.unitConversion[2] = unitScale + status.unitConversion[3] = conf.horSpeedMultiplier + status.unitConversion[4] = conf.vertSpeedMultiplier + status.unitConversion[5] = 1 + + -- check if EdgeTx >= 2.8 + local ver, radio, maj, minor, rev, osname = getVersion() + if osname == 'EdgeTX' and maj >= 2 and minor >= 8 then + conf.degSymbol = '°' + end +end + +-------------------------------------------------------------------------------- +-- page 1 single battery view +-- page 2 message history +-- page 3 min max +-- page 4 dual battery view +-- page 5 map view +-- page 6 plot view +-- check if EdgeTx >= 2.8 +local ver, radio, maj, minor, rev, osname = getVersion() +local options = { + { "Screen Type", VALUE, 1, 1, 8}, +} +-- shared init flag +local initDone = 0 +-- This function is runned once at the creation of the widget +local function create(zone, options) + -- this vars are widget scoped, each instance has its own set + local vars = { + } + -- all local vars are shared between widget instances + -- init() needs to be called only once! + if initDone == 0 then + init(zone) + initDone = 1 + end + -- + return { zone=zone, options=options, vars=vars } +end +-- This function allow updates when you change widgets settings +local function update(widget, options) + widget.options = options + -- reload menu settings + loadConfig() +end + +utils.getScreenTogglePage = function(widget,conf,status) + local screenChValue = getValue(conf.screenToggleChannelId) + if conf.screenToggleChannelId > -1 then + if screenChValue < -600 then + -- message history + return 2 + end + + if screenChValue > 600 then + -- map view + return 5 + end + end + return widget.options["Screen Type"] +end + + +local zoomDelayStart = getTime() + +utils.getMessageOffset = function(widget,conf,status,chValue) + if currentPage ~= 2 and status.screenTogglePage ~= 2 then + return status.messageOffset + end + + local now = getTime() + if now - zoomDelayStart < conf.screenWheelChannelDelay*10 then + return status.messageOffset + end + + zoomDelayStart = now + + if conf.screenWheelChannelId > -1 then + -- SW up + if chValue < -600 then + local offset = math.min(status.messageOffset + 19, math.max(0,status.messageCount - 19)) + if offset >= (status.messageCount - 19) then + status.messageAutoScroll = true + else + status.messageAutoScroll = false + end + return offset + end + -- SW down + if chValue > 600 then + status.messageAutoScroll = false + return math.max(0,math.max(status.messageCount - 200,status.messageOffset - 19)) + end + -- switch is idle, force timer expire + zoomDelayStart = now - conf.screenWheelChannelDelay*10 + end + return status.messageOffset +end + +utils.getMapZoomLevel = function(widget,conf,status,chValue) + if currentPage ~= 5 and status.screenTogglePage ~= 5 then + return status.mapZoomLevel + end + + local now = getTime() + + if now - zoomDelayStart < conf.screenWheelChannelDelay*10 then + return status.mapZoomLevel + end + + zoomDelayStart = now + + if conf.screenWheelChannelId > -1 then + -- SW up (increase zoom level) + if chValue < -600 then + if conf.mapProvider == 1 then + return status.mapZoomLevel > conf.mapZoomMin and status.mapZoomLevel - 1 or status.mapZoomLevel + end + return status.mapZoomLevel < conf.mapZoomMax and status.mapZoomLevel + 1 or status.mapZoomLevel + end + -- SW down (decrease zoom level) + if chValue > 600 then + if conf.mapProvider == 1 then + return status.mapZoomLevel < conf.mapZoomMax and status.mapZoomLevel + 1 or status.mapZoomLevel + end + return status.mapZoomLevel > conf.mapZoomMin and status.mapZoomLevel - 1 or status.mapZoomLevel + end + -- switch is idle, force timer expire + zoomDelayStart = now - conf.screenWheelChannelDelay*10 + end + -- SW mid + return status.mapZoomLevel +end + +-- called when widget instance page changes +local function onChangePage(widget) + if widget.options["Screen Type"] == 3 then + -- when page 3 goes to foreground show minmax values + status.showMinMaxValues = true + elseif widget.options["Screen Type"] == 4 then + -- when page 4 goes to foreground show dual battery view + status.showDualBattery = true + end + -- reset HUD counters + widget.vars.hudcounter = 0 +end + +-- Called when script is hidden @20Hz +local function background(widget) + -- when page 1 goes to background run bg tasks + if widget.options["Screen Type"] == 1 then + -- run bg tasks + backgroundTasks(widget,telemetryPopLoops) + -- call custom panel background functions + if leftPanel[1] ~= nil then + leftPanel[1].background(widget) + end + if centerPanel[1] ~= nil then + centerPanel[1].background(widget) + end + if rightPanel[1] ~= nil then + rightPanel[1].background(widget) + end + return + end + -- when page 3 goes to background hide minmax values + if widget.options["Screen Type"] == 3 then + status.showMinMaxValues = false + return + end + -- when page 4 goes to background hide dual battery view + if widget.options["Screen Type"] == 4 then + status.showDualBattery = false + return + end + -- when page 5 goes to background + if widget.options["Screen Type"] == 5 then + if mapLayout ~= nil then + mapLayout.background(widget) + end + return + end + -- when page 6 goes to background + if widget.options["Screen Type"] == 6 then + if plotLayout ~= nil then + plotLayout.background(widget) + end + return + end +end + +local slowTimer = getTime() +local fastTimer = getTime() + +local function fullScreenRequired(widget) + lcd.setColor(CUSTOM_COLOR,lcd.RGB(255, 0, 0)) + lcd.drawText(widget.zone.x,widget.zone.y,"full screen",SMLSIZE+CUSTOM_COLOR) + lcd.drawText(widget.zone.x,widget.zone.y+16,"required",SMLSIZE+CUSTOM_COLOR) +end + + +local function drawMsgDialog(msg) + lcd.clear(CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawFilledRectangle(147,131, 506, 148, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.bars2) + lcd.drawFilledRectangle(147+2,131+2, 506-4, 148-4, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,utils.colors.white) + lcd.drawText(math.floor(LCD_W/2), 131+44, msg, DBLSIZE+CUSTOM_COLOR+CENTER) +end + +local function loadLayout() + -- Layout start + if leftPanel[status.currentScreen] == nil and loadCycle == 1 then + leftPanel[status.currentScreen] = utils.doLibrary(conf.leftPanelFilename[status.currentScreen]) + end + + if centerPanel[status.currentScreen] == nil and loadCycle == 2 then + centerPanel[status.currentScreen] = utils.doLibrary(conf.centerPanelFilename[status.currentScreen]) + end + + if rightPanel[status.currentScreen] == nil and loadCycle == 4 then + rightPanel[status.currentScreen] = utils.doLibrary(conf.rightPanelFilename[status.currentScreen]) + end + + if layout == nil and loadCycle == 6 and leftPanel[status.currentScreen] ~= nil and centerPanel[status.currentScreen] ~= nil and rightPanel[status.currentScreen] ~= nil then + layout = utils.doLibrary(conf.widgetLayoutFilename) + end + + drawMsgDialog("loading layout...") + --[[ + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawFilledRectangle(88,74, 304, 84, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,COLOR_BARS_2) + lcd.drawFilledRectangle(90,76, 300, 80, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,COLOR_TEXT) + lcd.drawText(120, 95, "loading layout...", DBLSIZE+CUSTOM_COLOR) + --]] +end + +local function loadMapLayout() + -- Layout start + if loadCycle == 3 then + mapLayout = utils.doLibrary("layout_map") + end +end + +local function loadPlotLayout() + -- Layout start + if loadCycle == 3 then + plotLayout = utils.doLibrary("layout_plot") + end +end + +local function loadStatsLayout() + -- Layout start + if loadCycle == 3 then + plotLayout = utils.doLibrary("layout_stats") + end +end + + +local fgclock = 0 + +local screenByPageMapping = {1,1,1,1,1,1,2,3} + +local function taskResetLayout(widget, now) + -- reset phase 2 if reset pending + if resetLayoutPending == true then + resetLayouts() + elseif resetPending == true then + reset() + end +end + +local function taskScreenChange(widget, now) + if currentPage ~= widget.options["Screen Type"] then + currentPage = widget.options["Screen Type"] + onChangePage(widget) + end +end + +local function taskModelChange(widget, now) + -- frametype and model name + local info = model.getInfo() + -- model change event + if status.currentModel ~= info.name then + status.currentModel = info.name + -- trigger reset + triggerReset() + end +end + +local fgTasks = { + {0, 100, taskModelChange}, -- 1.0Hz + {0, 50, taskScreenChange}, -- 2.0Hz + {0, 50, taskResetLayout}, -- 2.0Hz +} + +-- Called when script is visible +local function drawFullScreen(widget) + -- when page 1 goes to foreground run bg tasks + if math.max(1,widget.options["Screen Type"]) == 1 then + -- run bg tasks only if we are not resetting, this prevent cpu limit kill + if not (resetPending or resetLayoutPending) then + backgroundTasks(widget,15) + end + end + -- map pages to multiple screens + status.currentScreen = screenByPageMapping[math.max(1,widget.options["Screen Type"])] + lcd.setColor(CUSTOM_COLOR, utils.colors.bg) + + if not (resetPending or resetLayoutPending or loadConfigPending) then + local drawStatus = true + if widget.options["Screen Type"] == 2 or status.screenTogglePage == 2 then + ------------------------------------ + -- Widget Page 2: MESSAGES + ------------------------------------ + lcd.setColor(CUSTOM_COLOR, BLACK) + lcd.clear(CUSTOM_COLOR) + + drawMessageScreen() + elseif widget.options["Screen Type"] == 5 or status.screenTogglePage == 5 then + ------------------------------------ + -- Widget Page 5: MAP + ------------------------------------ + lcd.setColor(CUSTOM_COLOR, utils.colors.bg) + lcd.clear(CUSTOM_COLOR) + + if mapLayout ~= nil then + mapLayout.draw(widget) + else + loadMapLayout() + drawStatus = false + end + elseif widget.options["Screen Type"] == 6 then + ------------------------------------ + -- Widget Page 6: Plotting screen + ------------------------------------ + lcd.clear(CUSTOM_COLOR) + + if plotLayout ~= nil then + plotLayout.draw(widget, customSensors, leftPanel, centerPanel, rightPanel) + else + loadPlotLayout() + drawStatus = false + end + else + ------------------------------------ + -- Widget Page 1: HUD + ------------------------------------ + lcd.clear(CUSTOM_COLOR) + if layout ~= nil and leftPanel[status.currentScreen] ~= nil and centerPanel[status.currentScreen] ~= nil and rightPanel[status.currentScreen] ~= nil then + layout.draw(widget, customSensors, leftPanel, centerPanel, rightPanel) + else + loadLayout(); + drawStatus = false + end + end + if drawStatus then + libs.drawLib.drawFailsafe(310, 108) + libs.drawLib.drawArmStatus(310, 108 + 40) + end + else + -- not ready to draw yet + drawMsgDialog("initializing...") + end + + utils.runScheduler(widget, fgTasks) + + if conf.pauseTelemetry == true then + libs.layoutLib.drawWidgetPaused() + else + -- no telemetry/minmax outer box + if utils.telemetryEnabled() == false then + -- no telemetry inner box + if status.hideNoTelemetry == false then + libs.layoutLib.drawNoTelemetryData(telemetryEnabled) + end + utils.drawBlinkBitmap("warn",0,0) + else + if status.showMinMaxValues == true then + utils.drawBlinkBitmap("minmax",0,0) + end + end + end + + loadCycle=(loadCycle+1)%8 +end + +-- are we full screen? if +local function drawScreen(widget, event, touchState) + if widget.zone.h < 440 then + fullScreenRequired(widget) + return + end + drawFullScreen(widget) +end + +function refresh(widget) + drawScreen(widget) +end + +return { name="Yaapu", options=options, create=create, update=update, background=background, refresh=refresh } diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/menu.lua b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/menu.lua new file mode 100644 index 00000000..f7fbbdaf --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/menu.lua @@ -0,0 +1,664 @@ +-- +-- A FRSKY SPort/FPort/FPort2 and TBS CRSF telemetry widget for the Horus class radios +-- based on ArduPilot's passthrough telemetry protocol +-- +-- Author: Alessandro Apostoli, https://github.com/yaapu +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY, without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, see . +-- +local unitScale = getGeneralSettings().imperial == 0 and 1 or 3.28084 +local unitLabel = getGeneralSettings().imperial == 0 and "m" or "ft" +local unitLongScale = getGeneralSettings().imperial == 0 and 1/1000 or 1/1609.34 +local unitLongLabel = getGeneralSettings().imperial == 0 and "km" or "mi" +------------------------------------- +-- UNITS Scales from Ardupilot OSD code /ardupilot/libraries/AP_OSD/AP_OSD_Screen.cpp +------------------------------------- +--[[ + static const float scale_metric[UNIT_TYPE_LAST] = { + 1.0, //ALTITUDE m + 3.6, //SPEED km/hr + 1.0, //VSPEED m/s + 1.0, //DISTANCE m + 1.0/1000, //DISTANCE_LONG km + 1.0, //TEMPERATURE C + }; + static const float scale_imperial[UNIT_TYPE_LAST] = { + 3.28084, //ALTITUDE ft + 2.23694, //SPEED mph + 3.28084, //VSPEED ft/s + 3.28084, //DISTANCE ft + 1.0/1609.34, //DISTANCE_LONG miles + 1.8, //TEMPERATURE F + }; + static const float scale_SI[UNIT_TYPE_LAST] = { + 1.0, //ALTITUDE m + 1.0, //SPEED m/s + 1.0, //VSPEED m/s + 1.0, //DISTANCE m + 1.0/1000, //DISTANCE_LONG km + 1.0, //TEMPERATURE C + }; + static const float scale_aviation[UNIT_TYPE_LAST] = { + 3.28084, //ALTITUDE Ft + 1.94384, //SPEED Knots + 196.85, //VSPEED ft/min + 3.28084, //DISTANCE ft + 0.000539957, //DISTANCE_LONG Nm + 1.0, //TEMPERATURE C + }; +--]] +-- +local menuItems = { + {"pause telemetry processing:", "PTP", 2, { "yes", "no" }, { true, false } }, + {"voice language:", "L1", 1, { "english", "italian", "french", "german" } , {"en","it","fr","de"} }, + {"color theme:", "TH", 1, { "default", "ethos" } , { 1, 2} }, + {"batt alert level 1:", "V1", 375, 0,5000,"V",PREC2,5 }, + {"batt alert level 2:", "V2", 350, 0,5000,"V",PREC2,5 }, + {"batt[1] capacity override:", "B1", 0, 0,5000,"Ah",PREC2,10 }, + {"batt[2] capacity override:", "B2", 0, 0,5000,"Ah",PREC2,10 }, + {"batt[1] cell count override:", "CC", 0, 0,16," cells",0,1 }, + {"batt[2] cell count override:", "CC2", 0, 0,16," cells",0,1 }, + {"dual battery config:", "BC", 1, { "parallel", "series", "dual with alert on B1", "dual with alert on B2", "volts on B1, % on B2", "volts on B2, % on B1" }, { 1, 2, 3, 4, 5, 6 } }, + {"enable battery % by voltage:", "BPBV", 1, { "no", "yes" }, { false, true } }, + {"default voltage source:", "VS", 1, { "auto", "FLVSS", "fc" }, { nil, "vs", "fc" } }, + {"disable all sounds:", "S1", 1, { "no", "yes" }, { false, true } }, + {"disable incoming msg beep:", "S2", 1, { "no", "only for INF severity", "always" }, { 1, 2, 3 } }, + {"enable haptic:", "VIBR", 1, { "no", "yes" }, { false, true } }, + {"timer alert every:", "T1", 0, 0,600,"min",PREC1,5 }, + {"min altitude alert:", "A1", 0, 0,500,"m",PREC1,5 }, + {"max altitude alert:", "A2", 0, 0,10000,"m",0,1 }, + {"max distance alert:", "D1", 0, 0,100000,"m",0,10 }, + {"repeat alerts every:", "T2", 10, 5,600,"sec",0,5 }, + {"rangefinder max:", "RM", 0, 0,10000," cm",0,10 }, + {"air/groundspeed unit:", "HSPD", 1, { "m/s", "km/h", "mph", "kn" }, { 1, 3.6, 2.23694, 1.94384} }, + {"vertical speed unit:", "VSPD", 1, { "m/s", "ft/s", "ft/min" }, { 1, 3.28084, 196.85} }, + {"widget layout:", "WL", 1, { "default"}, { 1 } }, + {"main screen center panel:", "CPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"main screen right panel:", "RPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"main screen left panel:", "LPANE", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: center panel:", "CPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: right panel:", "RPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [2]: left panel:", "LPANE2", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: center panel:", "CPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: right panel:", "RPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"screen [3]: left panel:", "LPANE3", 1, { "","","","","","","","","","" }, { 1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10 } }, + {"enable PX4 flightmodes:", "PX4", 1, { "no", "yes" }, { false, true } }, + {"enable CRSF support:", "CRSF", 1, { "no", "yes" }, { false, true } }, + {"enable RPM support:", "RPM", 1, { "no", "rpm1", "rpm1+rpm2" }, { 1, 2, 3 } }, + {"enable WIND support:", "WIND", 1, { "no", "yes" }, { false, true } }, + {"emulated page channel:", "STC", 0, 0, 32,nil,0,1 }, + {"emulated wheel channel:", "SWC", 0, 0, 32,nil,0,1 }, + {"emulated wheel delay (secs):", "SWCD", 1, 0, 50,"sec",PREC1, 1 }, + {"GPS coordinates format:", "GPS", 1, { "DMS", "decimal" }, { 1, 2 } }, + {"map provider:", "MAPP", 1, { "GMapCatcher", "Google", "QGIS" }, { 1, 2, 3 } }, + {"map type:", "MAPT", 1, { "", "", "", "", "", "" }, { "", "", "", "", "", "" } }, + {"map zoom level def value:", "MAPZ", -2, -2, 17,nil,0,1 }, + {"map zoom level min value:", "MAPmZ", -2, -2, 17,nil,0,1 }, + {"map zoom level max value:", "MAPMZ", 17, -2, 17,nil,0,1 }, + {"map grid lines:", "MAPG", 1, { "yes", "no" }, { true, false } }, + -- allow up to 20 plot sources to be defined by updateMenuItems() + {"plot telemetry source 1:", "PLT1", 1, { "","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" }, { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 } }, + {"plot telemetry source 2:", "PLT2", 1, { "","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" }, { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 } }, +} + +------------------------------- +-- PLOT SOURCE DEFINITIONS +------------------------------- +-- { desc, telemetry, unit, scale, label } +-- unit: 1=alt,2=dist,3=hspeed,4=vspeed,5=none +local plotSources = { + {"None", "nome", 5, 1, }, -- dm + {"Altitude", "homeAlt", 1, 1 }, -- dm + {"Airspeed", "airspeed", 3, 0.1 }, + {"Batt[1] Voltage", "batt1volt", 5, 0.1 }, + {"Batt[1] Current", "batt1current", 5, 0.1 }, + {"Batt[2] Voltage", "batt2volt", 5, 0.1 }, + {"Batt[2] Current", "batt2current", 5, 0.1 }, + {"Groundspeed","hSpeed", 3, 0.1}, -- dm + {"Height Above Terrain", "heightAboveTerrain", 1, 1 }, + {"Home Distance", "homeDist", 2, 1 }, -- m + {"HDOP", "gpsHdopC", 5, 0.1}, + {"Num Sats", "numSats", 5, 1}, + {"Pitch", "pitch", 5, 1 }, + {"Rangefinder", "range", 5, 1 }, + {"Roll", "roll", 5, 1 }, + {"RPM[1]", "rpm1", 5, 1 }, + {"RPM[2]", "rpm2", 5, 1 }, + {"RSSI", "rssi", 5, 1 }, + {"RSSI CRSF", "rssiCRSF", 5, 1 }, + {"Sonar", "range", 5, 1 }, + {"Throttle", "throttle", 5, 1 }, + {"Vertical Speed", "vSpeed", 4, 0.1}, -- dm + {"Wind Speed", "trueWindSpeed", 3, 0.1 }, + {"Wind Direction", "trueWindAngle", 5, 1 }, + {"Yaw", "yaw", 5, 1}, -- deg +} + +-- map from NEW to OLD settings +local mapNewToOldItemCfg = { + ["SWC"] = "ZTC" -- ZTC was replaced by SWC +} + +local utils = {} +local menuItemsByName = {} + +local menu = { + selectedItem = 1, + editSelected = false, + offset = 0, + updated = true, -- if true menu needs a call to updateMenuItems() + wrapOffset = 0, -- changes according to enabled/disabled features and panels +} + +local widgetLayoutFiles = { "layout_def" } + +local centerPanelFiles = {} +local rightPanelFiles = {} +local leftPanelFiles = {} + +--------------------------- +-- LIBRARY LOADING +--------------------------- +local basePath = "/WIDGETS/Yaapu/" +local libBasePath = basePath.."lib/" + +utils.doLibrary = function(filename) + local f = assert(loadScript(libBasePath..filename..".lua")) + return f() +end + +local panels = utils.doLibrary("panels").panels + +------------------------------------------ +-- returns item's VALUE,LABEL,IDX +------------------------------------------ +local function getMenuItemByName(items,name) + local itemIdx = menuItemsByName[name] + local item = items[itemIdx] + if item == nil then + return nil + end + if type(item[4]) == "table" then + -- return item's value, label, index + return item[5][item[3]], item[4][item[3]], itemIdx + else + -- return item's value, label, index + return item[3], name, itemIdx + end +end + +local function plotSourcesToMenuOptions(plotSources) + local labels = {} + local values = {} + + for i=1,#plotSources + do + labels[i] = plotSources[i][1] + values[i] = i + end + return labels, values +end + +local function updateMenuItems() + if menu.updated == true then + local layout, layout_name, layout_idx = getMenuItemByName(menuItems,"WL") + for screen=1,3 + do + local screen_suffix = screen == 1 and "" or tostring(screen) + --------------------- + -- large hud layout + --------------------- + value, name, idx = getMenuItemByName(menuItems,"CPANE"..screen_suffix) + menuItems[idx][4] = panels.default.center.labels + menuItems[idx][5] = panels.default.center.options; + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + value, name, idx = getMenuItemByName(menuItems,"RPANE"..screen_suffix) + menuItems[idx][4] = panels.default.right.labels + menuItems[idx][5] = panels.default.right.options + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + value, name, idx = getMenuItemByName(menuItems,"LPANE"..screen_suffix) + menuItems[idx][4] = panels.default.left.labels + menuItems[idx][5] = panels.default.left.options + + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + + centerPanelFiles = panels.default.center.files + rightPanelFiles = panels.default.right.files + leftPanelFiles = panels.default.left.files + end + + local value, name, idx = getMenuItemByName(menuItems,"MAPP") + + if value == nil then + return + end + + local value2, name2, idx2 = getMenuItemByName(menuItems,"MAPT") + + if value2 ~= nil then + if value == 1 then --GMapCatcher + menuItems[idx2][4] = { "satellite", "map", "terrain" } + menuItems[idx2][5] = { "sat_tiles", "tiles", "ter_tiles" } + elseif value == 2 then -- Google + menuItems[idx2][4] = { "GoogleSatelliteMap", "GoogleHybridMap", "GoogleMap", "GoogleTerrainMap" } + menuItems[idx2][5] = { "GoogleSatelliteMap", "GoogleHybridMap", "GoogleMap", "GoogleTerrainMap" } + elseif value == 3 then -- QGIS + menuItems[idx2][4] = { "default", "layer1", "layer2", "layer3" } + menuItems[idx2][5] = { "qgis_default", "qgis_layer1", "qgis_layer2", "qgis_layer3" } + end + + if menuItems[idx2][3] > #menuItems[idx2][4] then + menuItems[idx2][3] = 1 + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPmZ") + + local idxzmin = idx2 + + if value2 ~= nil then + if value == 1 then -- GMapCatcher + menuItems[idx2][4] = -2 + menuItems[idx2][5] = 17 + menuItems[idx2][3] = math.max(value2,-2) + elseif value == 2 then -- Google + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 20 + menuItems[idx2][3] = math.max(value2,1) + else + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 25 + menuItems[idx2][3] = math.max(value2,1) + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPMZ") + + local idxzmax = idx2 + + if value2 ~= nil then + if value == 1 then -- GMapCatcher + menuItems[idx2][4] = -2 + menuItems[idx2][5] = 17 + menuItems[idx2][3] = math.min(value2,17) + elseif value == 2 then -- Google + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 20 + menuItems[idx2][3] = math.min(value2,20) + else + menuItems[idx2][4] = 1 + menuItems[idx2][5] = 25 + menuItems[idx2][3] = math.min(value2,25) + end + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"MAPZ") + + if value2 ~= nil then + menuItems[idx2][4] = menuItems[idxzmin][3] + menuItems[idx2][5] = menuItems[idxzmax][3] + menuItems[idx2][3] = math.min(math.max(value2,menuItems[idxzmin][3]),menuItems[idxzmax][3]) + end + + -- plot sources + value2, name2, idx2 = getMenuItemByName(menuItems,"PLT1") + if value2 ~= nil then + local plotLabels, plotValues= plotSourcesToMenuOptions(plotSources) + menuItems[idx2][4] = plotLabels + menuItems[idx2][5] = plotValues + end + + value2, name2, idx2 = getMenuItemByName(menuItems,"PLT2") + if value2 ~= nil then + local plotLabels, plotValues= plotSourcesToMenuOptions(plotSources) + menuItems[idx2][4] = plotLabels + menuItems[idx2][5] = plotValues + end + + menu.updated = false + end +end + +local function getConfigFilename() + local info = model.getInfo() + return "/WIDGETS/Yaapu/cfg/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..".cfg") +end + +local function getConfigTriggerFilename() + local info = model.getInfo() + return "/WIDGETS/Yaapu/cfg/" .. string.lower(string.gsub(info.name, "[%c%p%s%z]", "")..".reload") +end + +local function triggerConfigReload() + local cfg = assert(io.open(getConfigTriggerFilename(),"w")) + if cfg ~= nil then + io.write(cfg, "1") + io.close(cfg) + end + collectgarbage() + collectgarbage() +end + +local function applyConfigValues(conf) + if menu.updated == true then + updateMenuItems() + menu.updated = false + end + conf.pauseTelemetry = getMenuItemByName(menuItems,"PTP") + conf.language = getMenuItemByName(menuItems,"L1") + conf.battAlertLevel1 = getMenuItemByName(menuItems,"V1") + conf.battAlertLevel2 = getMenuItemByName(menuItems,"V2") + conf.battCapOverride1 = getMenuItemByName(menuItems,"B1") + conf.battCapOverride2 = getMenuItemByName(menuItems,"B2") + conf.disableAllSounds = getMenuItemByName(menuItems,"S1") + conf.disableMsgBeep = getMenuItemByName(menuItems,"S2") + conf.enableHaptic = getMenuItemByName(menuItems,"VIBR") + conf.timerAlert = math.floor(getMenuItemByName(menuItems,"T1")*0.1*60) + conf.minAltitudeAlert = getMenuItemByName(menuItems,"A1")*0.1 + conf.maxAltitudeAlert = getMenuItemByName(menuItems,"A2") + conf.maxDistanceAlert = getMenuItemByName(menuItems,"D1") + conf.repeatAlertsPeriod = getMenuItemByName(menuItems,"T2") + conf.battConf = getMenuItemByName(menuItems,"BC") + conf.cell1Count = getMenuItemByName(menuItems,"CC") + conf.cell2Count = getMenuItemByName(menuItems,"CC2") + conf.rangeFinderMax = getMenuItemByName(menuItems,"RM") + conf.horSpeedMultiplier, conf.horSpeedLabel = getMenuItemByName(menuItems,"HSPD") + conf.vertSpeedMultiplier, conf.vertSpeedLabel = getMenuItemByName(menuItems,"VSPD") + -- Layout configuration + conf.widgetLayout = getMenuItemByName(menuItems,"WL") + conf.widgetLayoutFilename = widgetLayoutFiles[conf.widgetLayout] + -- multiple screens setup + for screen=1,3 + do + local screen_suffix = screen == 1 and "" or tostring(screen) + + conf.centerPanel[screen] = getMenuItemByName(menuItems,"CPANE"..screen_suffix) + conf.centerPanelFilename[screen] = centerPanelFiles[conf.centerPanel[screen]] + conf.rightPanel[screen] = getMenuItemByName(menuItems,"RPANE"..screen_suffix) + conf.rightPanelFilename[screen] = rightPanelFiles[conf.rightPanel[screen]] + conf.leftPanel[screen] = getMenuItemByName(menuItems,"LPANE"..screen_suffix) + conf.leftPanelFilename[screen] = leftPanelFiles[conf.leftPanel[screen]] + end + + conf.enablePX4Modes = getMenuItemByName(menuItems,"PX4") + conf.enableCRSF = getMenuItemByName(menuItems,"CRSF") + conf.enableRPM = getMenuItemByName(menuItems,"RPM") + conf.enableWIND = getMenuItemByName(menuItems,"WIND") + + conf.mapZoomLevel = getMenuItemByName(menuItems,"MAPZ") + conf.mapZoomMin = getMenuItemByName(menuItems,"MAPmZ") + conf.mapZoomMax = getMenuItemByName(menuItems,"MAPMZ") + + conf.mapType = getMenuItemByName(menuItems,"MAPT") + + local chInfo = getFieldInfo("ch"..getMenuItemByName(menuItems,"STC")) + conf.screenToggleChannelId = (chInfo == nil and -1 or chInfo['id']) + + chInfo = getFieldInfo("ch"..getMenuItemByName(menuItems,"SWC")) + conf.screenWheelChannelId = (chInfo == nil and -1 or chInfo['id']) + + conf.enableMapGrid = getMenuItemByName(menuItems,"MAPG") + conf.mapProvider = getMenuItemByName(menuItems,"MAPP") + + conf.screenWheelChannelDelay = getMenuItemByName(menuItems,"SWCD") + + -- set default voltage source + if getMenuItemByName(menuItems,"VS") ~= nil then + conf.defaultBattSource = getMenuItemByName(menuItems,"VS") + end + conf.gpsFormat = getMenuItemByName(menuItems,"GPS") + conf.enableBattPercByVoltage = getMenuItemByName(menuItems,"BPBV") + + conf.plotSource1 = getMenuItemByName(menuItems,"PLT1") + conf.plotSource2 = getMenuItemByName(menuItems,"PLT2") + + conf.theme = getMenuItemByName(menuItems,"TH") + + menu.editSelected = false +end + +local function loadConfig(conf) + local cfg_found = false + local cfg_string + local cfg = io.open(getConfigFilename(),"r") + + if cfg ~= nil then + cfg_string = io.read(cfg,500) + io.close(cfg) + if string.len(cfg_string) > 0 then + cfg_found = true + end + end + + for i=1,#menuItems + do + menuItemsByName[tostring(menuItems[i][2])] = i + if cfg_found then + local value = string.match(cfg_string, menuItems[i][2]..":([-%d]+)") + if value == nil then + -- check if it was replaced by an older settings + local oldCfg = mapNewToOldItemCfg[menuItems[i][2]] + if oldCfg ~= nil then + value = string.match(cfg_string, oldCfg..":([-%d]+)") + end + end + if value ~= nil then + menuItems[i][3] = tonumber(value) + -- check if the value read from file is compatible with available options + if type(menuItems[i][4]) == "table" and tonumber(value) > #menuItems[i][4] then + --if not force default + menuItems[i][3] = 1 + end + end + end + end + + -- when run standalone there's nothing to update :-) + if conf ~= nil then + applyConfigValues(conf) + -- menu was loaded apply required changes + menu.updated = true + end +end + +local function saveConfig(conf) + local myConfig = "" + for i=1,#menuItems + do + myConfig = myConfig..menuItems[i][2]..":"..menuItems[i][3] + if i < #menuItems then + myConfig = myConfig.."," + end + end + local cfg = assert(io.open(getConfigFilename(),"w")) + if cfg ~= nil then + io.write(cfg,myConfig) + io.close(cfg) + end + myConfig = nil + -- when run standalone there's nothing to update :-) + if conf ~= nil then + applyConfigValues(conf) + end + triggerConfigReload() +end + +local function drawConfigMenuBars() + local info = model.getInfo() + lcd.setColor(CUSTOM_COLOR,lcd.RGB(16,20,25)) + local itemIdx = string.format("%d/%d",menu.selectedItem,#menuItems) + lcd.drawFilledRectangle(0,0, LCD_W, 20, CUSTOM_COLOR) + lcd.drawRectangle(0, 0, LCD_W, 20, CUSTOM_COLOR) + lcd.drawFilledRectangle(0,LCD_H-20, LCD_W, 20, CUSTOM_COLOR) + lcd.drawRectangle(0, LCD_H-20, LCD_W, 20, CUSTOM_COLOR) + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(LCD_W,3,"Yaapu Telemetry Widget 2.1.x dev".." ("..'7a17b47'..")",CUSTOM_COLOR+SMLSIZE+RIGHT) + lcd.drawText(0,0,info.name,CUSTOM_COLOR) + lcd.drawText(0,LCD_H-20+1,getConfigFilename(),CUSTOM_COLOR) + lcd.drawText(LCD_W,LCD_H-20+1,itemIdx,CUSTOM_COLOR+RIGHT) +end + +local function incMenuItem(idx) + if type(menuItems[idx][4]) == "table" then + menuItems[idx][3] = menuItems[idx][3] + 1 + if menuItems[idx][3] > #menuItems[idx][4] then + menuItems[idx][3] = 1 + end + else + menuItems[idx][3] = menuItems[idx][3] + menuItems[idx][8] + if menuItems[idx][3] > menuItems[idx][5] then + menuItems[idx][3] = menuItems[idx][5] + end + end +end + +local function decMenuItem(idx) + if type(menuItems[idx][4]) == "table" then + menuItems[idx][3] = menuItems[idx][3] - 1 + if menuItems[idx][3] < 1 then + menuItems[idx][3] = #menuItems[idx][4] + end + else + menuItems[idx][3] = menuItems[idx][3] - menuItems[idx][8] + if menuItems[idx][3] < menuItems[idx][4] then + menuItems[idx][3] = menuItems[idx][4] + end + end +end + +local function drawItem(idx,flags) + lcd.setColor(CUSTOM_COLOR,WHITE) + if type(menuItems[idx][4]) == "table" then + lcd.drawText(450,25 + (idx-menu.offset-1)*20, menuItems[idx][4][menuItems[idx][3]],flags+CUSTOM_COLOR) + else + if menuItems[idx][3] == 0 and menuItems[idx][4] >= 0 then + lcd.drawText(450,25 + (idx-menu.offset-1)*20, "---",flags+CUSTOM_COLOR) + else + lcd.drawNumber(450,25 + (idx-menu.offset-1)*20, menuItems[idx][3],flags+menuItems[idx][7]+CUSTOM_COLOR) + if menuItems[idx][6] ~= nil then + lcd.drawText(450 + 50,25 + (idx-menu.offset-1)*20, menuItems[idx][6],flags+CUSTOM_COLOR) + end + end + end +end + +local bitmaps = {} + +local function getBitmap(name) + if bitmaps[name] == nil then + bitmaps[name] = Bitmap.open("/WIDGETS/Yaapu/images/"..name..".png") + end + return bitmaps[name],Bitmap.getSize(bitmaps[name]) +end + +local function drawConfigMenu(event) + lcd.drawBitmap(getBitmap("menubar"),0,LCD_H-46-18) + drawConfigMenuBars() + + updateMenuItems() + if event == EVT_ENTER_BREAK or event == EVT_VIRTUAL_ENTER then + if menu.editSelected == true then + -- confirm modified value + saveConfig() + end + menu.editSelected = not menu.editSelected + menu.updated = true + elseif menu.editSelected and (event == EVT_VIRTUAL_NEXT or event == EVT_PLUS_BREAK or event == EVT_ROT_RIGHT or event == EVT_PLUS_REPT) then + incMenuItem(menu.selectedItem) + elseif menu.editSelected and (event == EVT_VIRTUAL_PREV or event == EVT_MINUS_BREAK or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT) then + decMenuItem(menu.selectedItem) + elseif not menu.editSelected and (event == EVT_VIRTUAL_PREV or event == EVT_MINUS_BREAK or event == EVT_ROT_LEFT) then + menu.selectedItem = (menu.selectedItem - 1) + if menu.offset >= menu.selectedItem then + menu.offset = menu.offset - 1 + end + elseif not menu.editSelected and (event == EVT_VIRTUAL_NEXT or event == EVT_PLUS_BREAK or event == EVT_ROT_RIGHT) then + menu.selectedItem = (menu.selectedItem + 1) + if menu.selectedItem - 18 > menu.offset then + menu.offset = menu.offset + 1 + end + end + --wrap + if menu.selectedItem > #menuItems then + menu.selectedItem = 1 + menu.offset = 0 + elseif menu.selectedItem < 1 then + menu.selectedItem = #menuItems + menu.offset = #menuItems - 18 + end + -- + for m=1+menu.offset,math.min(#menuItems,18+menu.offset) do + lcd.setColor(CUSTOM_COLOR,WHITE) + lcd.drawText(2,25 + (m-menu.offset-1)*20, menuItems[m][1],CUSTOM_COLOR) + if m == menu.selectedItem then + if menu.editSelected then + drawItem(m,INVERS+BLINK) + else + drawItem(m,INVERS) + end + else + drawItem(m,0) + end + end +end + + +-------------------------- +-- RUN +-------------------------- +local function run(event, touchState) + if event ~= 0 and touchState then -- Do we have an event? + if event == EVT_TOUCH_TAP then + if touchState.y > (LCD_H-64) and touchState.y < (LCD_H-18) then + -- A short tap gives TAP instead of BREAK + -- touchState.tapCount shows number of taps + if touchState.x > 3 and touchState.x < 70 then + event = EVT_VIRTUAL_EXIT + return 1 + elseif touchState.x > 90 and touchState.x < 158 then + event = EVT_VIRTUAL_PREV + elseif touchState.x > 162 and touchState.x < 230 then + event = EVT_VIRTUAL_NEXT + elseif touchState.x > 250 and touchState.x < 315 then + event = EVT_VIRTUAL_ENTER + end + end + end + end + --------------------- + -- CONFIG MENU + --------------------- + lcd.setColor(CUSTOM_COLOR, lcd.RGB(50, 50, 50)) -- hex 0x084c7b -- 073f66 + lcd.clear(CUSTOM_COLOR) + drawConfigMenu(event) + return 0 +end + +local function init() + loadConfig() +end +-------------------------------------------------------------------------------- +-- SCRIPT END +-------------------------------------------------------------------------------- +return {run=run, init=init, loadConfig=loadConfig, compileLayouts=compileLayouts, menuItems=menuItems, plotSources=plotSources} diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/alr.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/alr.wav new file mode 100644 index 00000000..c09e1b57 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/alr.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/crt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/crt.wav new file mode 100644 index 00000000..c09e1b57 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/crt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/dbg.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/dbg.wav new file mode 100644 index 00000000..28ace3cf Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/dbg.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1050361.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1050361.wav new file mode 100644 index 00000000..d6555058 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1050361.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1061733.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1061733.wav new file mode 100644 index 00000000..2835568b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1061733.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13077757.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13077757.wav new file mode 100644 index 00000000..af750317 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13077757.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13236108.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13236108.wav new file mode 100644 index 00000000..b94384b4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13236108.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13841562.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13841562.wav new file mode 100644 index 00000000..e83b25f1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/13841562.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14444224.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14444224.wav new file mode 100644 index 00000000..47613061 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14444224.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14472699.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14472699.wav new file mode 100644 index 00000000..d78607fe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14472699.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14608272.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14608272.wav new file mode 100644 index 00000000..1dc34d52 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/14608272.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1475990.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1475990.wav new file mode 100644 index 00000000..01359c43 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1475990.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1541806.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1541806.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1541806.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/16455510.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/16455510.wav new file mode 100644 index 00000000..cec6dca5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/16455510.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865158.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865158.wav new file mode 100644 index 00000000..29bee961 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865158.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865209.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865209.wav new file mode 100644 index 00000000..b0b457dd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1865209.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1934808.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1934808.wav new file mode 100644 index 00000000..e2395e46 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/1934808.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2053593.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2053593.wav new file mode 100644 index 00000000..22d56a32 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2053593.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2074081.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2074081.wav new file mode 100644 index 00000000..35cc7653 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2074081.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2131412.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2131412.wav new file mode 100644 index 00000000..4e96f5bb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2131412.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2262475.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2262475.wav new file mode 100644 index 00000000..85307073 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2262475.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2573818.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2573818.wav new file mode 100644 index 00000000..76995200 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/2573818.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3466823.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3466823.wav new file mode 100644 index 00000000..73ae612b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3466823.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3843641.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3843641.wav new file mode 100644 index 00000000..aaffd0e3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/3843641.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4170928.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4170928.wav new file mode 100644 index 00000000..40b1c287 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4170928.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4224177.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4224177.wav new file mode 100644 index 00000000..92415f02 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4224177.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4597275.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4597275.wav new file mode 100644 index 00000000..f76ea52d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/4597275.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6128125.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6128125.wav new file mode 100644 index 00000000..c0c4d645 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6128125.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6634944.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6634944.wav new file mode 100644 index 00000000..e83fddd7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6634944.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6908206.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6908206.wav new file mode 100644 index 00000000..7585e093 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/6908206.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7210780.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7210780.wav new file mode 100644 index 00000000..168c3060 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7210780.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7211373.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7211373.wav new file mode 100644 index 00000000..169b1f1d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/7211373.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/8828501.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/8828501.wav new file mode 100644 index 00000000..bf9fb04f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/8828501.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9430632.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9430632.wav new file mode 100644 index 00000000..de8d9611 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9430632.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9713.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9713.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9713.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9811007.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9811007.wav new file mode 100644 index 00000000..51192563 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/9811007.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro.wav new file mode 100644 index 00000000..ebb2aa2f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro_r.wav new file mode 100644 index 00000000..bac56b1d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/acro_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/altctl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/altctl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/althold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/althold.wav new file mode 100644 index 00000000..68db44da Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/althold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/armed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/armed.wav new file mode 100644 index 00000000..8867e083 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/armed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto.wav new file mode 100644 index 00000000..43098c5b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto_r.wav new file mode 100644 index 00000000..5c39a92f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/auto_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autorotate.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autorotate.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autortl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autortl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autotune.wav new file mode 100644 index 00000000..f1691028 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/autotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/avoidadsb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/avoidadsb.wav new file mode 100644 index 00000000..dbcfb2d7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/avoidadsb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat10.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat10.wav new file mode 100644 index 00000000..85285fbb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat10.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat15.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat15.wav new file mode 100644 index 00000000..f66c08af Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat15.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat20.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat20.wav new file mode 100644 index 00000000..b2b58223 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat20.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat25.wav new file mode 100644 index 00000000..8db5e7d4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat30.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat30.wav new file mode 100644 index 00000000..5ea72afe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat30.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat40.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat40.wav new file mode 100644 index 00000000..99b44850 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat40.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat5.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat5.wav new file mode 100644 index 00000000..de5b2ec6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat5.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat50.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat50.wav new file mode 100644 index 00000000..b9e66812 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat50.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat60.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat60.wav new file mode 100644 index 00000000..9867ef63 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat60.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat70.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat70.wav new file mode 100644 index 00000000..6457ee16 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat70.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat80.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat80.wav new file mode 100644 index 00000000..e479035b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat80.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat90.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat90.wav new file mode 100644 index 00000000..25e62832 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/bat90.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert.wav new file mode 100644 index 00000000..0e4b315b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert1.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert1.wav new file mode 100644 index 00000000..7f276ea1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert1.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert2.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert2.wav new file mode 100644 index 00000000..2d0570da Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/batalert2.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/brake.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/brake.wav new file mode 100644 index 00000000..290c5c7a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/brake.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/circle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/circle.wav new file mode 100644 index 00000000..481ff10d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/circle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/cruise.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/cruise.wav new file mode 100644 index 00000000..175543e1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/cruise.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/disarmed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/disarmed.wav new file mode 100644 index 00000000..9a1e2b4f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/disarmed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/drift.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/drift.wav new file mode 100644 index 00000000..b06407d3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/drift.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ekf.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ekf.wav new file mode 100644 index 00000000..24f3c332 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ekf.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/failsafe.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/failsafe.wav new file mode 100644 index 00000000..bbe20edc Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/failsafe.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fence.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fence.wav new file mode 100644 index 00000000..df8a09b5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fence.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fencebreach.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fencebreach.wav new file mode 100644 index 00000000..5c86f1ac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/fencebreach.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flip.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flip.wav new file mode 100644 index 00000000..b7185863 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flip.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flowhold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flowhold.wav new file mode 100644 index 00000000..4c3ec61c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flowhold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywirea.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywirea.wav new file mode 100644 index 00000000..aa4bde0a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywirea.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywireb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywireb.wav new file mode 100644 index 00000000..6db61075 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/flybywireb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/follow.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/follow.wav new file mode 100644 index 00000000..80d2ae74 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/follow.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/follow_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/follow_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsfix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsfix.wav new file mode 100644 index 00000000..c1d9e8c2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsfix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsnofix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsnofix.wav new file mode 100644 index 00000000..6180912f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/gpsnofix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided.wav new file mode 100644 index 00000000..c73154d3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided_r.wav new file mode 100644 index 00000000..53dc5c51 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guided_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guidednogps.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guidednogps.wav new file mode 100644 index 00000000..7ecae613 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/guidednogps.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/hold_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/hold_r.wav new file mode 100644 index 00000000..559fbe8a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/hold_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/initializing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/initializing.wav new file mode 100644 index 00000000..8421aac7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/initializing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/initializing_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/initializing_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/land.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/land.wav new file mode 100644 index 00000000..d9952011 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/land.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/landing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/landing.wav new file mode 100644 index 00000000..fab79365 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/landing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/loiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/loiter.wav new file mode 100644 index 00000000..17c479b6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/loiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/loiter_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/loiter_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/lowbat.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/lowbat.wav new file mode 100644 index 00000000..b240244d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/lowbat.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual.wav new file mode 100644 index 00000000..79ce9346 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual_r.wav new file mode 100644 index 00000000..2f48752b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/manual_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxalt.wav new file mode 100644 index 00000000..a1d1421e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxdist.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxdist.wav new file mode 100644 index 00000000..ab6e0d47 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/maxdist.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/minalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/minalt.wav new file mode 100644 index 00000000..f6f9f857 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/minalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/mission.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/mission.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/offboard.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/offboard.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/posctl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/posctl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/poshold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/poshold.wav new file mode 100644 index 00000000..da431806 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/poshold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/precland.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/precland.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qacro.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qacro.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qautotune.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qautotune.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qhover.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qhover.wav new file mode 100644 index 00000000..b1497fce Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qhover.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qland.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qland.wav new file mode 100644 index 00000000..0256617e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qland.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qloiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qloiter.wav new file mode 100644 index 00000000..90567f81 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qloiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qrtl.wav new file mode 100644 index 00000000..6af3d349 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qstabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qstabilize.wav new file mode 100644 index 00000000..1a00a662 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/qstabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rattitude.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rattitude.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ready.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ready.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtgs.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtgs.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl.wav new file mode 100644 index 00000000..5cf52af3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl_r.wav new file mode 100644 index 00000000..aa7581b2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/rtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simple.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simple.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simple_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simple_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleoff.wav new file mode 100644 index 00000000..674db011 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleon.wav new file mode 100644 index 00000000..8acbb76a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/simpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl.wav new file mode 100644 index 00000000..3be9db5f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl_r.wav new file mode 100644 index 00000000..76981133 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/smartrtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/sport.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/sport.wav new file mode 100644 index 00000000..40602cef Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/sport.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ssimpleoff.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ssimpleoff.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ssimpleon.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/ssimpleon.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/stabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/stabilize.wav new file mode 100644 index 00000000..2475c115 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/stabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/steering_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/steering_r.wav new file mode 100644 index 00000000..fa14e23b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/steering_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/systemid.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/systemid.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/takeoff.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/takeoff.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/terrainko.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/terrainko.wav new file mode 100644 index 00000000..b7f309ec Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/terrainko.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/thermal.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/thermal.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/throw.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/throw.wav new file mode 100644 index 00000000..ce43aa64 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/throw.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/timealert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/timealert.wav new file mode 100644 index 00000000..06040425 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/timealert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/training.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/training.wav new file mode 100644 index 00000000..1cb87ffd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/training.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/turtle.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/turtle.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/velocity.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/velocity.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/yaapu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/yaapu.wav new file mode 100644 index 00000000..45ed896b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/yaapu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/zigzag.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/de/zigzag.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/emr.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/emr.wav new file mode 100644 index 00000000..c09e1b57 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/emr.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1050361.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1050361.wav new file mode 100644 index 00000000..d6555058 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1050361.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1061733.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1061733.wav new file mode 100644 index 00000000..2835568b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1061733.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13077757.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13077757.wav new file mode 100644 index 00000000..af750317 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13077757.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13236108.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13236108.wav new file mode 100644 index 00000000..b94384b4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13236108.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13841562.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13841562.wav new file mode 100644 index 00000000..e83b25f1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/13841562.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14444224.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14444224.wav new file mode 100644 index 00000000..47613061 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14444224.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14472699.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14472699.wav new file mode 100644 index 00000000..d78607fe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14472699.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14608272.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14608272.wav new file mode 100644 index 00000000..1dc34d52 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/14608272.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1475990.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1475990.wav new file mode 100644 index 00000000..01359c43 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1475990.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1541806.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1541806.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1541806.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/16455510.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/16455510.wav new file mode 100644 index 00000000..cec6dca5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/16455510.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865158.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865158.wav new file mode 100644 index 00000000..29bee961 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865158.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865209.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865209.wav new file mode 100644 index 00000000..b0b457dd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1865209.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1934808.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1934808.wav new file mode 100644 index 00000000..e2395e46 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/1934808.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2053593.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2053593.wav new file mode 100644 index 00000000..22d56a32 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2053593.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2074081.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2074081.wav new file mode 100644 index 00000000..35cc7653 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2074081.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2131412.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2131412.wav new file mode 100644 index 00000000..4e96f5bb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2131412.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2262475.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2262475.wav new file mode 100644 index 00000000..85307073 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2262475.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2573818.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2573818.wav new file mode 100644 index 00000000..76995200 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/2573818.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3466823.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3466823.wav new file mode 100644 index 00000000..73ae612b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3466823.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3843641.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3843641.wav new file mode 100644 index 00000000..aaffd0e3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/3843641.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4170928.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4170928.wav new file mode 100644 index 00000000..40b1c287 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4170928.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4224177.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4224177.wav new file mode 100644 index 00000000..92415f02 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4224177.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4597275.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4597275.wav new file mode 100644 index 00000000..f76ea52d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/4597275.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6128125.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6128125.wav new file mode 100644 index 00000000..c0c4d645 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6128125.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6634944.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6634944.wav new file mode 100644 index 00000000..e83fddd7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6634944.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6908206.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6908206.wav new file mode 100644 index 00000000..7585e093 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/6908206.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7210780.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7210780.wav new file mode 100644 index 00000000..168c3060 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7210780.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7211373.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7211373.wav new file mode 100644 index 00000000..169b1f1d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/7211373.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/8828501.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/8828501.wav new file mode 100644 index 00000000..bf9fb04f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/8828501.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9430632.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9430632.wav new file mode 100644 index 00000000..de8d9611 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9430632.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9713.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9713.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9713.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9811007.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9811007.wav new file mode 100644 index 00000000..51192563 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/9811007.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro.wav new file mode 100644 index 00000000..20fecbde Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro_r.wav new file mode 100644 index 00000000..51992d24 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/acro_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/althold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/althold.wav new file mode 100644 index 00000000..c07fc5cf Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/althold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/armed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/armed.wav new file mode 100644 index 00000000..928986bc Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/armed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto.wav new file mode 100644 index 00000000..7913cd16 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto_r.wav new file mode 100644 index 00000000..1c3bd1e9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/auto_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autorotate.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autorotate.wav new file mode 100644 index 00000000..c78ab6df Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autorotate.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autortl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autortl.wav new file mode 100644 index 00000000..f260be33 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autortl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autotune.wav new file mode 100644 index 00000000..775da3be Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/autotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/avoidadsb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/avoidadsb.wav new file mode 100644 index 00000000..97ec5bb5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/avoidadsb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat10.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat10.wav new file mode 100644 index 00000000..dec74ef8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat10.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat15.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat15.wav new file mode 100644 index 00000000..ced2fc58 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat15.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat20.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat20.wav new file mode 100644 index 00000000..17dc7c4c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat20.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat25.wav new file mode 100644 index 00000000..8899fa05 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat30.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat30.wav new file mode 100644 index 00000000..e1c2176f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat30.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat40.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat40.wav new file mode 100644 index 00000000..2b588e9f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat40.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat50.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat50.wav new file mode 100644 index 00000000..40ca4361 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat50.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat60.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat60.wav new file mode 100644 index 00000000..5d317f1d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat60.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat70.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat70.wav new file mode 100644 index 00000000..f37b15fa Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat70.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat80.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat80.wav new file mode 100644 index 00000000..bb2b1059 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat80.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat90.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat90.wav new file mode 100644 index 00000000..ddebd8b3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/bat90.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert.wav new file mode 100644 index 00000000..ba014b29 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert1.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert1.wav new file mode 100644 index 00000000..0bb0c711 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert1.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert2.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert2.wav new file mode 100644 index 00000000..10dbfffe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/batalert2.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/brake.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/brake.wav new file mode 100644 index 00000000..3bd38a52 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/brake.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/circle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/circle.wav new file mode 100644 index 00000000..76aa06a0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/circle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/cruise.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/cruise.wav new file mode 100644 index 00000000..84cc844a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/cruise.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/disarmed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/disarmed.wav new file mode 100644 index 00000000..be81b86d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/disarmed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/drift.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/drift.wav new file mode 100644 index 00000000..1238d003 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/drift.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ekf.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ekf.wav new file mode 100644 index 00000000..03ccdb6e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ekf.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/failsafe.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/failsafe.wav new file mode 100644 index 00000000..f4071ee5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/failsafe.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fence.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fence.wav new file mode 100644 index 00000000..c7a95fdc Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fence.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fencebreach.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fencebreach.wav new file mode 100644 index 00000000..d133ff4c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/fencebreach.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flip.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flip.wav new file mode 100644 index 00000000..ca5a22d3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flip.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flowhold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flowhold.wav new file mode 100644 index 00000000..e99eaf28 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flowhold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywirea.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywirea.wav new file mode 100644 index 00000000..ba691d4b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywirea.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywireb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywireb.wav new file mode 100644 index 00000000..4fbe0368 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/flybywireb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow.wav new file mode 100644 index 00000000..f58984d0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow_r.wav new file mode 100644 index 00000000..45c68216 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/follow_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsfix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsfix.wav new file mode 100644 index 00000000..00fe50a3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsfix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsnofix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsnofix.wav new file mode 100644 index 00000000..afcf21ed Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/gpsnofix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided.wav new file mode 100644 index 00000000..ccc884b7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided_r.wav new file mode 100644 index 00000000..4a2bc389 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guided_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guidednogps.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guidednogps.wav new file mode 100644 index 00000000..28c7da64 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/guidednogps.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/hold_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/hold_r.wav new file mode 100644 index 00000000..18ca7e1f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/hold_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing.wav new file mode 100644 index 00000000..e1711c27 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing_r.wav new file mode 100644 index 00000000..218c78fb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/initializing_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/land.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/land.wav new file mode 100644 index 00000000..5e736d15 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/land.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/landing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/landing.wav new file mode 100644 index 00000000..759f02f4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/landing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter.wav new file mode 100644 index 00000000..5eb5e0d2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter_r.wav new file mode 100644 index 00000000..f17f2bfa Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/loiter_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/lowbat.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/lowbat.wav new file mode 100644 index 00000000..f7912313 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/lowbat.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual.wav new file mode 100644 index 00000000..cd3e3162 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual_r.wav new file mode 100644 index 00000000..9e24da73 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/manual_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxalt.wav new file mode 100644 index 00000000..bceaedb3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxdist.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxdist.wav new file mode 100644 index 00000000..26d7b395 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/maxdist.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/minalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/minalt.wav new file mode 100644 index 00000000..d6eaf9af Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/minalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/poshold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/poshold.wav new file mode 100644 index 00000000..4a1e6b0b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/poshold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qacro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qacro.wav new file mode 100644 index 00000000..85f72da8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qacro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qautotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qautotune.wav new file mode 100644 index 00000000..6f2813c3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qautotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qhover.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qhover.wav new file mode 100644 index 00000000..55dc9b8b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qhover.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qland.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qland.wav new file mode 100644 index 00000000..c3f8434d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qland.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qloiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qloiter.wav new file mode 100644 index 00000000..e6132394 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qloiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qrtl.wav new file mode 100644 index 00000000..19551371 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qstabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qstabilize.wav new file mode 100644 index 00000000..60c9d357 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/qstabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl.wav new file mode 100644 index 00000000..9ac801b1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl_r.wav new file mode 100644 index 00000000..034713ac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/rtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/selected.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/selected.wav new file mode 100644 index 00000000..10c74157 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/selected.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simple_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simple_r.wav new file mode 100644 index 00000000..a6b85420 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simple_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleoff.wav new file mode 100644 index 00000000..84550c68 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleon.wav new file mode 100644 index 00000000..da9ae7a7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/simpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl.wav new file mode 100644 index 00000000..3c3654f0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl_r.wav new file mode 100644 index 00000000..3a87df7b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/smartrtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/sport.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/sport.wav new file mode 100644 index 00000000..44731df5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/sport.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleoff.wav new file mode 100644 index 00000000..10cf2fac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleon.wav new file mode 100644 index 00000000..25994581 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/ssimpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/stabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/stabilize.wav new file mode 100644 index 00000000..84c4d369 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/stabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/started.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/started.wav new file mode 100644 index 00000000..078fcb7c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/started.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/steering_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/steering_r.wav new file mode 100644 index 00000000..00fdb363 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/steering_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/systemid.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/systemid.wav new file mode 100644 index 00000000..9198e795 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/systemid.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/takeoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/takeoff.wav new file mode 100644 index 00000000..9ba895d5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/takeoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/terrainko.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/terrainko.wav new file mode 100644 index 00000000..34e32cf0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/terrainko.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/thermal.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/thermal.wav new file mode 100644 index 00000000..335e1762 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/thermal.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/throw.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/throw.wav new file mode 100644 index 00000000..5ef6fa27 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/throw.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/timealert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/timealert.wav new file mode 100644 index 00000000..708a9575 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/timealert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/training.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/training.wav new file mode 100644 index 00000000..f4bda123 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/training.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_4ptrol.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_4ptrol.wav new file mode 100644 index 00000000..d747dd79 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_4ptrol.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_axirol.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_axirol.wav new file mode 100644 index 00000000..407d341a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_axirol.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_barrol.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_barrol.wav new file mode 100644 index 00000000..971f0fe3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_barrol.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_clicir.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_clicir.wav new file mode 100644 index 00000000..d1a31b2a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_clicir.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_cu8.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_cu8.wav new file mode 100644 index 00000000..306ed3c3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_cu8.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_dw45.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_dw45.wav new file mode 100644 index 00000000..825fcdf2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_dw45.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f34f23.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f34f23.wav new file mode 100644 index 00000000..f5f16f0d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f34f23.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3af25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3af25.wav new file mode 100644 index 00000000..01567811 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3af25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap23.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap23.wav new file mode 100644 index 00000000..e44a3418 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap23.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap25.wav new file mode 100644 index 00000000..cbbfb27e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f3ap25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f4css.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f4css.wav new file mode 100644 index 00000000..5c7f7190 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_f4css.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_fig8.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_fig8.wav new file mode 100644 index 00000000..cfcf57a0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_fig8.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hcu8.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hcu8.wav new file mode 100644 index 00000000..5658ce6d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hcu8.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hfclci.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hfclci.wav new file mode 100644 index 00000000..38da69ba Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hfclci.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_horrec.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_horrec.wav new file mode 100644 index 00000000..5bc9f466 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_horrec.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hrvcu8.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hrvcu8.wav new file mode 100644 index 00000000..de875cab Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hrvcu8.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hubu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hubu.wav new file mode 100644 index 00000000..569a241e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_hubu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immfas.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immfas.wav new file mode 100644 index 00000000..1617d0fb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immfas.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immtrn.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immtrn.wav new file mode 100644 index 00000000..6acd465f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_immtrn.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedc.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedc.wav new file mode 100644 index 00000000..b8fee24f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedc.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedg.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedg.wav new file mode 100644 index 00000000..d9199386 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_kniedg.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_layhu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_layhu.wav new file mode 100644 index 00000000..9bc411f4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_layhu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_loop.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_loop.wav new file mode 100644 index 00000000..51498efe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_loop.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_lotrn.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_lotrn.wav new file mode 100644 index 00000000..5d63a611 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_lotrn.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_mproll.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_mproll.wav new file mode 100644 index 00000000..69cf987c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_mproll.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_nzclub.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_nzclub.wav new file mode 100644 index 00000000..7dbf5c8a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_nzclub.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_parcir.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_parcir.wav new file mode 100644 index 00000000..5b640f6c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_parcir.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_pause.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_pause.wav new file mode 100644 index 00000000..e5c9868e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_pause.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_prctrn.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_prctrn.wav new file mode 100644 index 00000000..52fd85b4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_prctrn.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_rolcir.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_rolcir.wav new file mode 100644 index 00000000..f092e52d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_rolcir.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_roll.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_roll.wav new file mode 100644 index 00000000..2fc685ea Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_roll.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sashow.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sashow.wav new file mode 100644 index 00000000..a43cf766 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sashow.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_scfig8.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_scfig8.wav new file mode 100644 index 00000000..dd1152b6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_scfig8.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_splits.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_splits.wav new file mode 100644 index 00000000..b64b614e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_splits.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_spshow.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_spshow.wav new file mode 100644 index 00000000..baa429f4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_spshow.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sstep.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sstep.wav new file mode 100644 index 00000000..b122270f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sstep.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_statrn.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_statrn.wav new file mode 100644 index 00000000..afb51034 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_statrn.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strfli.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strfli.wav new file mode 100644 index 00000000..2cc8f704 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strfli.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strhol.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strhol.wav new file mode 100644 index 00000000..ba9faa6a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_strhol.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sttest.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sttest.wav new file mode 100644 index 00000000..0888e961 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_sttest.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_up45.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_up45.wav new file mode 100644 index 00000000..00a9e2b9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_up45.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_verbox.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_verbox.wav new file mode 100644 index 00000000..2668716e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/trk_verbox.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/turtle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/turtle.wav new file mode 100644 index 00000000..20da7366 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/turtle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/velocity.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/velocity.wav new file mode 100644 index 00000000..d80ccc8e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/velocity.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/yaapu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/yaapu.wav new file mode 100644 index 00000000..b628494b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/yaapu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/zigzag.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/zigzag.wav new file mode 100644 index 00000000..84259563 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/en/zigzag.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english.psv b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english.psv new file mode 100644 index 00000000..63250b75 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english.psv @@ -0,0 +1,90 @@ +WIDGETS/Yaapu/sounds/en|acro|Acro flight mode +WIDGETS/Yaapu/sounds/en|acro_r|Acro mode +WIDGETS/Yaapu/sounds/en|althold|Altitude hold flight mode +WIDGETS/Yaapu/sounds/en|armed|Motors armed +WIDGETS/Yaapu/sounds/en|auto|Auto flight mode +WIDGETS/Yaapu/sounds/en|auto_r|Auto mode +WIDGETS/Yaapu/sounds/en|autorotate|autorotate flight mode +WIDGETS/Yaapu/sounds/en|autortl|Auto RTL flight mode +WIDGETS/Yaapu/sounds/en|autotune|Autotune enabled +WIDGETS/Yaapu/sounds/en|avoidadsb|Avoid A D S B flight mode +WIDGETS/Yaapu/sounds/en|bat10|Battery at 10 percent +WIDGETS/Yaapu/sounds/en|bat15|Battery at 15 percent +WIDGETS/Yaapu/sounds/en|bat20|Battery at 20 percent +WIDGETS/Yaapu/sounds/en|bat25|Battery at 25 percent +WIDGETS/Yaapu/sounds/en|bat30|Battery at 30 percent +WIDGETS/Yaapu/sounds/en|bat40|Battery at 40 percent +WIDGETS/Yaapu/sounds/en|bat50|Battery at 50 percent +WIDGETS/Yaapu/sounds/en|bat60|Battery at 60 percent +WIDGETS/Yaapu/sounds/en|bat70|Battery at 70 percent +WIDGETS/Yaapu/sounds/en|bat80|Battery at 80 percent +WIDGETS/Yaapu/sounds/en|bat90|Battery at 90 percent +WIDGETS/Yaapu/sounds/en|batalert|Battery alert +WIDGETS/Yaapu/sounds/en|batalert1|Battery level 1 alert +WIDGETS/Yaapu/sounds/en|batalert2|Battery level 2 alert +WIDGETS/Yaapu/sounds/en|brake|Brake flight mode +WIDGETS/Yaapu/sounds/en|circle|Circle flight mode +WIDGETS/Yaapu/sounds/en|cruise|Cruise flight mode +WIDGETS/Yaapu/sounds/en|disarmed|Motors disarmed +WIDGETS/Yaapu/sounds/en|drift|Drift flight mode +WIDGETS/Yaapu/sounds/en|ekf|E K F failsafe +WIDGETS/Yaapu/sounds/en|failsafe|failsafe +WIDGETS/Yaapu/sounds/en|fence|fence enabled +WIDGETS/Yaapu/sounds/en|fencebreach|fence breach +WIDGETS/Yaapu/sounds/en|flip|Flip flight mode +WIDGETS/Yaapu/sounds/en|flowhold|flow position hold flight mode +WIDGETS/Yaapu/sounds/en|flybywirea|Fly by wire a flight mode +WIDGETS/Yaapu/sounds/en|flybywireb|Fly by wire b flight mode +WIDGETS/Yaapu/sounds/en|follow|follow flight mode +WIDGETS/Yaapu/sounds/en|follow_r|follow mode +WIDGETS/Yaapu/sounds/en|gpsfix|GPS 3D fix lock +WIDGETS/Yaapu/sounds/en|gpsnofix|No gps +WIDGETS/Yaapu/sounds/en|guided|Guided flight mode +WIDGETS/Yaapu/sounds/en|guided_r|Guided mode +WIDGETS/Yaapu/sounds/en|guidednogps|Guided no gps flight mode +WIDGETS/Yaapu/sounds/en|hold_r|Hold mode +WIDGETS/Yaapu/sounds/en|initializing|Initializing +WIDGETS/Yaapu/sounds/en|initializing_r|Initializing +WIDGETS/Yaapu/sounds/en|land|Land flight mode +WIDGETS/Yaapu/sounds/en|landing|Landing complete +WIDGETS/Yaapu/sounds/en|loiter|Loiter flight mode +WIDGETS/Yaapu/sounds/en|loiter_r|Loiter mode +WIDGETS/Yaapu/sounds/en|lowbat|Low battery +WIDGETS/Yaapu/sounds/en|manual|Manual flight mode +WIDGETS/Yaapu/sounds/en|manual_r|Manual mode +WIDGETS/Yaapu/sounds/en|maxalt|Max altitude alert +WIDGETS/Yaapu/sounds/en|maxdist|Max distance alert +WIDGETS/Yaapu/sounds/en|minalt|Low altitude alert +WIDGETS/Yaapu/sounds/en|poshold|Position hold flight mode +WIDGETS/Yaapu/sounds/en|qacro|Q acro flight mode +WIDGETS/Yaapu/sounds/en|qautotune|Q autotune flight mode +WIDGETS/Yaapu/sounds/en|qhover|Q hover flight mode +WIDGETS/Yaapu/sounds/en|qland|Q land flight mode +WIDGETS/Yaapu/sounds/en|qloiter|Q loiter flight mode +WIDGETS/Yaapu/sounds/en|qrtl|Q return to home flight mode +WIDGETS/Yaapu/sounds/en|qstabilize|Q stabilize flight mode +WIDGETS/Yaapu/sounds/en|rtl|Return to home +WIDGETS/Yaapu/sounds/en|rtl_r|Return to home mode +WIDGETS/Yaapu/sounds/en|selected|selected +WIDGETS/Yaapu/sounds/en|simple_r|simple mode +WIDGETS/Yaapu/sounds/en|simpleoff|simple mode disabled +WIDGETS/Yaapu/sounds/en|simpleon|simple mode enabled +WIDGETS/Yaapu/sounds/en|smartrtl|Smart return to home flight mode +WIDGETS/Yaapu/sounds/en|smartrtl_r|Smart return to home mode +WIDGETS/Yaapu/sounds/en|sport|Sport flight mode +WIDGETS/Yaapu/sounds/en|ssimpleoff|super simple mode disabled +WIDGETS/Yaapu/sounds/en|ssimpleon|super simple mode enabled +WIDGETS/Yaapu/sounds/en|stabilize|Stabilize flight mode +WIDGETS/Yaapu/sounds/en|started|started +WIDGETS/Yaapu/sounds/en|steering_r|Steering mode +WIDGETS/Yaapu/sounds/en|systemid|System I D flight mode +WIDGETS/Yaapu/sounds/en|takeoff|takeoff flight mode +WIDGETS/Yaapu/sounds/en|terrainko|no terrain data +WIDGETS/Yaapu/sounds/en|thermal|Thermal flight mode +WIDGETS/Yaapu/sounds/en|throw|Throw flight mode +WIDGETS/Yaapu/sounds/en|timealert|Timer alert +WIDGETS/Yaapu/sounds/en|training|Training flight mode +WIDGETS/Yaapu/sounds/en|turtle|turtle mode +WIDGETS/Yaapu/sounds/en|velocity|velocity flight mode +WIDGETS/Yaapu/sounds/en|yaapu|Yaapu telemetry ready +WIDGETS/Yaapu/sounds/en|zigzag|Zigzag flight mode diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_msg_hash.psv b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_msg_hash.psv new file mode 100644 index 00000000..c2a13d2e --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_msg_hash.psv @@ -0,0 +1,34 @@ +/WIDGETS/yaapu/sounds/en|264977348|PreArming: Need 3D Fix +/WIDGETS/yaapu/sounds/en|1834616480|Smart RTL Unavailable +/WIDGETS/yaapu/sounds/en|2386213680|EKF variance +/WIDGETS/yaapu/sounds/en|2310179660|GPS Glitch cleared +/WIDGETS/yaapu/sounds/en|4137200300|GPS Glitch +/WIDGETS/yaapu/sounds/en|2664106240|Parachute: Released +/WIDGETS/yaapu/sounds/en|656739232|Flight plan received +/WIDGETS/yaapu/sounds/en|3708582640|Mission complete +/WIDGETS/yaapu/sounds/en|1809087708|Geofence triggered +/WIDGETS/yaapu/sounds/en|116655276|Flight mode change failed +/WIDGETS/yaapu/sounds/en|1008001424|AutoTune: Success +/WIDGETS/yaapu/sounds/en|1396289024|AutoTune: Failed +/WIDGETS/yaapu/sounds/en|986165592|Transition done +/WIDGETS/yaapu/sounds/en|1249672288|Transition started +/WIDGETS/yaapu/sounds/en|4019153925|Transition done +/WIDGETS/yaapu/sounds/en|3417557720|Transition VTOL done +/WIDGETS/yaapu/sounds/en|1204090832|Land descend started +/WIDGETS/yaapu/sounds/en|2890289840|Land final +/WIDGETS/yaapu/sounds/en|158533322|Trick +/WIDGETS/yaapu/sounds/en|121896728|trick aborted +/WIDGETS/yaapu/sounds/en|3351294456|Soaring: Outside MAX RADIUS, RTL +/WIDGETS/yaapu/sounds/en|3538212740|Soaring: restoring previous mode +/WIDGETS/yaapu/sounds/en|142400872|Soaring: Climb below VERTICAL SPEED +/WIDGETS/yaapu/sounds/en|1746499976|Soaring: Exit via RC switch +/WIDGETS/yaapu/sounds/en|981284144|Soaring: Thermal detected +/WIDGETS/yaapu/sounds/en|883458048|Soaring: Enabled +/WIDGETS/yaapu/sounds/en|2561543032|Soaring: Disabled +/WIDGETS/yaapu/sounds/en|4091124880|reached command: +/WIDGETS/yaapu/sounds/en|3311875476|reached waypoint: +/WIDGETS/yaapu/sounds/en|1997782032|Passed waypoint: +/WIDGETS/yaapu/sounds/en|554623408|Takeoff complete +/WIDGETS/yaapu/sounds/en|3025044912|Smart RTL deactivated +/WIDGETS/yaapu/sounds/en|3956583920|GPS home acquired +/WIDGETS/yaapu/sounds/en|1309405592|GPS home acquired diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_px4.psv b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_px4.psv new file mode 100644 index 00000000..99d8a855 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_px4.psv @@ -0,0 +1,10 @@ +WIDGETS/Yaapu/sound/en|altctl|Altitude control mode +WIDGETS/Yaapu/sound/en|posctl|Position control mode +WIDGETS/Yaapu/sound/en|ready|ready +WIDGETS/Yaapu/sound/en|takeoff|Auto takeoff mode +WIDGETS/Yaapu/sound/en|mission|Auto mission mode +WIDGETS/Yaapu/sound/en|rtgs|link loss failsafe mode +WIDGETS/Yaapu/sound/en|precland|Precision landing mode +WIDGETS/Yaapu/sound/en|offboard|Offboard mode +WIDGETS/Yaapu/sound/en|rattitude|rate attitude mode +WIDGETS/Yaapu/sound/en|simple|simple mode diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_tricks.psv b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_tricks.psv new file mode 100644 index 00000000..c4a9a120 --- /dev/null +++ b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/english_tricks.psv @@ -0,0 +1,43 @@ +/WIDGETS/yaapu/sounds/en|trk_up45|Upline-45 +/WIDGETS/yaapu/sounds/en|trk_splits|Split-S +/WIDGETS/yaapu/sounds/en|trk_clicir|Climbing Circle +/WIDGETS/yaapu/sounds/en|trk_prctrn|Procedure Turn +/WIDGETS/yaapu/sounds/en|trk_lotrn|Loop or Turnaround +/WIDGETS/yaapu/sounds/en|trk_f4css|F4C Scale Schedule +/WIDGETS/yaapu/sounds/en|trk_fig8|Figure Eight +/WIDGETS/yaapu/sounds/en|trk_hubu|Humpty Bump +/WIDGETS/yaapu/sounds/en|trk_loop|Loop +/WIDGETS/yaapu/sounds/en|trk_hrvcu8|Half Reverse Cuban Eight +/WIDGETS/yaapu/sounds/en|trk_strfli|Straight Flight +/WIDGETS/yaapu/sounds/en|trk_f3ap23|F3A P 23 +/WIDGETS/yaapu/sounds/en|trk_verbox|Vertical Box +/WIDGETS/yaapu/sounds/en|trk_rolcir|Rolling Circle +/WIDGETS/yaapu/sounds/en|trk_sstep|Side Step +/WIDGETS/yaapu/sounds/en|trk_immtrn|Immelmann Turn +/WIDGETS/yaapu/sounds/en|trk_kniedc|Knife Edge Circle +/WIDGETS/yaapu/sounds/en|trk_horrec|Horizontal Rectangle +/WIDGETS/yaapu/sounds/en|trk_scfig8|Scale Figure Eight +/WIDGETS/yaapu/sounds/en|trk_axirol|Axial Roll +/WIDGETS/yaapu/sounds/en|trk_sashow|Super AirShow +/WIDGETS/yaapu/sounds/en|trk_statrn|Stall Turn +/WIDGETS/yaapu/sounds/en|trk_f3ap25|F3A P 25 +/WIDGETS/yaapu/sounds/en|trk_kniedg|Knife Edge +/WIDGETS/yaapu/sounds/en|trk_cu8|Cuban Eight +/WIDGETS/yaapu/sounds/en|trk_roll|Roll +/WIDGETS/yaapu/sounds/en|trk_mproll|Multi Point Roll +/WIDGETS/yaapu/sounds/en|trk_immfas|Immelmann Fast +/WIDGETS/yaapu/sounds/en|trk_sttest|Stall Turn Test +/WIDGETS/yaapu/sounds/en|trk_spshow|Sport Plane AirShow +/WIDGETS/yaapu/sounds/en|trk_pause|Pause +/WIDGETS/yaapu/sounds/en|trk_barrol|Barrel Roll +/WIDGETS/yaapu/sounds/en|trk_nzclub|NZ Clubman Schedule +/WIDGETS/yaapu/sounds/en|trk_layhu|Laydown Humpty +/WIDGETS/yaapu/sounds/en|trk_f34f23|F3A F 23 +/WIDGETS/yaapu/sounds/en|trk_parcir|Partial Circle +/WIDGETS/yaapu/sounds/en|trk_strhol|Straight Hold +/WIDGETS/yaapu/sounds/en|trk_f3af25|F3A F 25 +/WIDGETS/yaapu/sounds/en|trk_hfclci|Half Climbing Circle +/WIDGETS/yaapu/sounds/en|trk_4ptrol|4pt Roll +/WIDGETS/yaapu/sounds/en|trk_hcu8|Half Cuban Eight +/WIDGETS/yaapu/sounds/en|trk_dw45|Downline 45 + diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/err.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/err.wav new file mode 100644 index 00000000..c09e1b57 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/err.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1050361.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1050361.wav new file mode 100644 index 00000000..d6555058 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1050361.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1061733.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1061733.wav new file mode 100644 index 00000000..2835568b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1061733.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13077757.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13077757.wav new file mode 100644 index 00000000..af750317 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13077757.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13236108.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13236108.wav new file mode 100644 index 00000000..b94384b4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13236108.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13841562.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13841562.wav new file mode 100644 index 00000000..e83b25f1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/13841562.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14444224.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14444224.wav new file mode 100644 index 00000000..47613061 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14444224.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14472699.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14472699.wav new file mode 100644 index 00000000..d78607fe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14472699.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14608272.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14608272.wav new file mode 100644 index 00000000..1dc34d52 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/14608272.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1475990.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1475990.wav new file mode 100644 index 00000000..01359c43 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1475990.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1541806.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1541806.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1541806.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/16455510.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/16455510.wav new file mode 100644 index 00000000..cec6dca5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/16455510.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865158.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865158.wav new file mode 100644 index 00000000..29bee961 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865158.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865209.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865209.wav new file mode 100644 index 00000000..b0b457dd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1865209.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1934808.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1934808.wav new file mode 100644 index 00000000..e2395e46 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/1934808.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2053593.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2053593.wav new file mode 100644 index 00000000..22d56a32 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2053593.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2074081.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2074081.wav new file mode 100644 index 00000000..35cc7653 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2074081.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2131412.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2131412.wav new file mode 100644 index 00000000..4e96f5bb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2131412.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2262475.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2262475.wav new file mode 100644 index 00000000..85307073 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2262475.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2573818.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2573818.wav new file mode 100644 index 00000000..76995200 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/2573818.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3466823.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3466823.wav new file mode 100644 index 00000000..73ae612b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3466823.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3843641.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3843641.wav new file mode 100644 index 00000000..aaffd0e3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/3843641.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4170928.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4170928.wav new file mode 100644 index 00000000..40b1c287 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4170928.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4224177.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4224177.wav new file mode 100644 index 00000000..92415f02 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4224177.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4597275.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4597275.wav new file mode 100644 index 00000000..f76ea52d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/4597275.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6128125.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6128125.wav new file mode 100644 index 00000000..c0c4d645 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6128125.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6634944.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6634944.wav new file mode 100644 index 00000000..e83fddd7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6634944.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6908206.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6908206.wav new file mode 100644 index 00000000..7585e093 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/6908206.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7210780.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7210780.wav new file mode 100644 index 00000000..168c3060 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7210780.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7211373.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7211373.wav new file mode 100644 index 00000000..169b1f1d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/7211373.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/8828501.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/8828501.wav new file mode 100644 index 00000000..bf9fb04f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/8828501.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9430632.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9430632.wav new file mode 100644 index 00000000..de8d9611 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9430632.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9713.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9713.wav new file mode 100644 index 00000000..835fe83e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9713.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9811007.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9811007.wav new file mode 100644 index 00000000..51192563 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/9811007.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro.wav new file mode 100644 index 00000000..8d7d7971 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro_r.wav new file mode 100644 index 00000000..dcb40248 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/acro_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/altctl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/altctl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/althold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/althold.wav new file mode 100644 index 00000000..054fbd51 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/althold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/armed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/armed.wav new file mode 100644 index 00000000..272a4776 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/armed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto.wav new file mode 100644 index 00000000..befac2ac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto_r.wav new file mode 100644 index 00000000..06fa59f1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/auto_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autorotate.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autorotate.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autortl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autortl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autotune.wav new file mode 100644 index 00000000..77796fb6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/autotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/avoidadsb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/avoidadsb.wav new file mode 100644 index 00000000..81f84ad3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/avoidadsb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat10.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat10.wav new file mode 100644 index 00000000..7f780351 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat10.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat15.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat15.wav new file mode 100644 index 00000000..5d543dc7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat15.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat20.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat20.wav new file mode 100644 index 00000000..fb107362 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat20.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat25.wav new file mode 100644 index 00000000..01a90f65 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat30.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat30.wav new file mode 100644 index 00000000..d0bef86c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat30.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat40.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat40.wav new file mode 100644 index 00000000..7e3acdcb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat40.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat5.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat5.wav new file mode 100644 index 00000000..5ee2cb54 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat5.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat50.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat50.wav new file mode 100644 index 00000000..d1b58627 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat50.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat60.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat60.wav new file mode 100644 index 00000000..ce7ea730 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat60.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat70.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat70.wav new file mode 100644 index 00000000..70517c6f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat70.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat80.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat80.wav new file mode 100644 index 00000000..8e656508 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat80.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat90.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat90.wav new file mode 100644 index 00000000..7a6000cb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/bat90.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert.wav new file mode 100644 index 00000000..2b3b63e8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert1.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert1.wav new file mode 100644 index 00000000..cc29cbf5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert1.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert2.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert2.wav new file mode 100644 index 00000000..ecbdf185 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/batalert2.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/brake.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/brake.wav new file mode 100644 index 00000000..4f288a6b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/brake.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/circle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/circle.wav new file mode 100644 index 00000000..fbb1015a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/circle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/cruise.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/cruise.wav new file mode 100644 index 00000000..87b8f2b2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/cruise.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/disarmed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/disarmed.wav new file mode 100644 index 00000000..129b0bf2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/disarmed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/drift.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/drift.wav new file mode 100644 index 00000000..9dd4f7db Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/drift.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ekf.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ekf.wav new file mode 100644 index 00000000..30a85353 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ekf.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/failsafe.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/failsafe.wav new file mode 100644 index 00000000..bbe20edc Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/failsafe.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fence.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fence.wav new file mode 100644 index 00000000..df8a09b5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fence.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fencebreach.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fencebreach.wav new file mode 100644 index 00000000..5c86f1ac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/fencebreach.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flip.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flip.wav new file mode 100644 index 00000000..c2541160 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flip.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flowhold.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flowhold.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywirea.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywirea.wav new file mode 100644 index 00000000..ff6682e2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywirea.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywireb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywireb.wav new file mode 100644 index 00000000..abc788d1 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/flybywireb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/follow.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/follow.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/follow_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/follow_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsfix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsfix.wav new file mode 100644 index 00000000..556fc4d7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsfix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsnofix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsnofix.wav new file mode 100644 index 00000000..d6c6d391 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/gpsnofix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided.wav new file mode 100644 index 00000000..fa6c947d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided_r.wav new file mode 100644 index 00000000..d1562ed0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guided_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guidednogps.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guidednogps.wav new file mode 100644 index 00000000..c495a505 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/guidednogps.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/hold_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/hold_r.wav new file mode 100644 index 00000000..49a59912 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/hold_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/initializing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/initializing.wav new file mode 100644 index 00000000..59c61d25 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/initializing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/initializing_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/initializing_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/land.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/land.wav new file mode 100644 index 00000000..df394620 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/land.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/landing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/landing.wav new file mode 100644 index 00000000..07aaf0bd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/landing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/loiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/loiter.wav new file mode 100644 index 00000000..d7955c22 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/loiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/loiter_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/loiter_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/lowbat.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/lowbat.wav new file mode 100644 index 00000000..4935aa80 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/lowbat.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual.wav new file mode 100644 index 00000000..1a9c7eed Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual_r.wav new file mode 100644 index 00000000..76ea2aa9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/manual_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxalt.wav new file mode 100644 index 00000000..e7ffe698 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxdist.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxdist.wav new file mode 100644 index 00000000..c86cd021 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/maxdist.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/minalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/minalt.wav new file mode 100644 index 00000000..461df171 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/minalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/mission.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/mission.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/offboard.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/offboard.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/posctl.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/posctl.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/poshold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/poshold.wav new file mode 100644 index 00000000..4f65b09e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/poshold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/precland.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/precland.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qacro.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qacro.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qautotune.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qautotune.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qhover.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qhover.wav new file mode 100644 index 00000000..fd6d4c7f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qhover.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qland.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qland.wav new file mode 100644 index 00000000..619af3b8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qland.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qloiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qloiter.wav new file mode 100644 index 00000000..28526564 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qloiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qrtl.wav new file mode 100644 index 00000000..3748fffe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qstabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qstabilize.wav new file mode 100644 index 00000000..eaf9abf9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/qstabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rattitude.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rattitude.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ready.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ready.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtgs.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtgs.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl.wav new file mode 100644 index 00000000..6c07692a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl_r.wav new file mode 100644 index 00000000..a4775ffe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/rtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simple.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simple.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simple_r.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simple_r.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleoff.wav new file mode 100644 index 00000000..c510f8b2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleon.wav new file mode 100644 index 00000000..9313193a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/simpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl.wav new file mode 100644 index 00000000..9627836d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl_r.wav new file mode 100644 index 00000000..7bed6bff Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/smartrtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/sport.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/sport.wav new file mode 100644 index 00000000..f529a9a5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/sport.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ssimpleoff.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ssimpleoff.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ssimpleon.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/ssimpleon.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/stabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/stabilize.wav new file mode 100644 index 00000000..27f2c008 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/stabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/steering_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/steering_r.wav new file mode 100644 index 00000000..cb2faf4a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/steering_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/systemid.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/systemid.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/takeoff.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/takeoff.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/terrainko.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/terrainko.wav new file mode 100644 index 00000000..b7f309ec Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/terrainko.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/thermal.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/thermal.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/throw.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/throw.wav new file mode 100644 index 00000000..c5547888 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/throw.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/timealert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/timealert.wav new file mode 100644 index 00000000..90713490 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/timealert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/training.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/training.wav new file mode 100644 index 00000000..edc7843b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/training.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/turtle.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/turtle.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/velocity.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/velocity.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/yaapu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/yaapu.wav new file mode 100644 index 00000000..a2782f51 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/yaapu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/zigzag.missing b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/fr/zigzag.missing new file mode 100644 index 00000000..e69de29b diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/inf.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/inf.wav new file mode 100644 index 00000000..28ace3cf Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/inf.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1050361.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1050361.wav new file mode 100644 index 00000000..a374b601 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1050361.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1061733.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1061733.wav new file mode 100644 index 00000000..1dce3eb9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1061733.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13077757.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13077757.wav new file mode 100644 index 00000000..9db58cb3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13077757.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13236108.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13236108.wav new file mode 100644 index 00000000..e148541b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13236108.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13841562.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13841562.wav new file mode 100644 index 00000000..82fb0ef7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/13841562.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14444224.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14444224.wav new file mode 100644 index 00000000..1fadd902 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14444224.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14472699.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14472699.wav new file mode 100644 index 00000000..a3ee08ac Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14472699.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14608272.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14608272.wav new file mode 100644 index 00000000..6bad9fbd Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/14608272.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1475990.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1475990.wav new file mode 100644 index 00000000..00a462f6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1475990.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1541806.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1541806.wav new file mode 100644 index 00000000..47b41a30 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1541806.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/16455510.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/16455510.wav new file mode 100644 index 00000000..47b41a30 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/16455510.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865158.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865158.wav new file mode 100644 index 00000000..3c1bd0d0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865158.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865209.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865209.wav new file mode 100644 index 00000000..fce69b31 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1865209.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1934808.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1934808.wav new file mode 100644 index 00000000..c4cdeb20 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/1934808.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2053593.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2053593.wav new file mode 100644 index 00000000..eb16fa42 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2053593.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2074081.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2074081.wav new file mode 100644 index 00000000..8f67c255 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2074081.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2131412.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2131412.wav new file mode 100644 index 00000000..d05ee235 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2131412.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2262475.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2262475.wav new file mode 100644 index 00000000..cbc3c13b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2262475.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2573818.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2573818.wav new file mode 100644 index 00000000..be2160da Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/2573818.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3020298.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3020298.wav new file mode 100644 index 00000000..56167787 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3020298.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3466823.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3466823.wav new file mode 100644 index 00000000..4c398e4a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3466823.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3843641.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3843641.wav new file mode 100644 index 00000000..221615d6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/3843641.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4170928.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4170928.wav new file mode 100644 index 00000000..fa742619 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4170928.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4224177.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4224177.wav new file mode 100644 index 00000000..fa742619 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4224177.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4597275.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4597275.wav new file mode 100644 index 00000000..8941fbc7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/4597275.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6128125.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6128125.wav new file mode 100644 index 00000000..251171a7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6128125.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6634944.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6634944.wav new file mode 100644 index 00000000..ab04108b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6634944.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6908206.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6908206.wav new file mode 100644 index 00000000..6391cf0d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/6908206.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7210780.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7210780.wav new file mode 100644 index 00000000..c4574b2b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7210780.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7211373.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7211373.wav new file mode 100644 index 00000000..2376dc32 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/7211373.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/8828501.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/8828501.wav new file mode 100644 index 00000000..42f76e7c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/8828501.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9430632.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9430632.wav new file mode 100644 index 00000000..a1186d13 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9430632.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9713.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9713.wav new file mode 100644 index 00000000..47b41a30 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9713.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9811007.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9811007.wav new file mode 100644 index 00000000..0bfd9f2e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/9811007.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro.wav new file mode 100644 index 00000000..a2cdd8a9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro_r.wav new file mode 100644 index 00000000..a2cdd8a9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/acro_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/althold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/althold.wav new file mode 100644 index 00000000..78eace03 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/althold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/armed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/armed.wav new file mode 100644 index 00000000..35cf402f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/armed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto.wav new file mode 100644 index 00000000..078f0de2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto_r.wav new file mode 100644 index 00000000..078f0de2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/auto_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autorotate.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autorotate.wav new file mode 100644 index 00000000..6ab64614 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autorotate.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autortl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autortl.wav new file mode 100644 index 00000000..a20409c6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autortl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autotune.wav new file mode 100644 index 00000000..117261ae Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/autotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/avoidadsb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/avoidadsb.wav new file mode 100644 index 00000000..97f4f4ab Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/avoidadsb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat10.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat10.wav new file mode 100644 index 00000000..3aa8c16c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat10.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat15.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat15.wav new file mode 100644 index 00000000..8bb0990c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat15.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat20.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat20.wav new file mode 100644 index 00000000..d284beff Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat20.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat25.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat25.wav new file mode 100644 index 00000000..79129cf5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat25.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat30.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat30.wav new file mode 100644 index 00000000..63cf37fb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat30.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat40.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat40.wav new file mode 100644 index 00000000..f5230d1b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat40.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat5.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat5.wav new file mode 100644 index 00000000..b435fdf2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat5.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat50.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat50.wav new file mode 100644 index 00000000..33c2c5bb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat50.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat60.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat60.wav new file mode 100644 index 00000000..ec540c83 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat60.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat70.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat70.wav new file mode 100644 index 00000000..2d4320a0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat70.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat80.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat80.wav new file mode 100644 index 00000000..2b0020a0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat80.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat90.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat90.wav new file mode 100644 index 00000000..c195007c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/bat90.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert.wav new file mode 100644 index 00000000..515e49e8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert1.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert1.wav new file mode 100644 index 00000000..be879f86 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert1.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert2.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert2.wav new file mode 100644 index 00000000..30e33f81 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/batalert2.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/brake.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/brake.wav new file mode 100644 index 00000000..c2ab899e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/brake.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/circle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/circle.wav new file mode 100644 index 00000000..47e48e86 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/circle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/cruise.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/cruise.wav new file mode 100644 index 00000000..edd348c0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/cruise.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/disarmed.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/disarmed.wav new file mode 100644 index 00000000..d6e6860f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/disarmed.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/drift.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/drift.wav new file mode 100644 index 00000000..0d7e07a2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/drift.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ekf.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ekf.wav new file mode 100644 index 00000000..3b39fc39 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ekf.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/failsafe.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/failsafe.wav new file mode 100644 index 00000000..2d955138 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/failsafe.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fence.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fence.wav new file mode 100644 index 00000000..11742940 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fence.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fencebreach.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fencebreach.wav new file mode 100644 index 00000000..c45eb0fe Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/fencebreach.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flip.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flip.wav new file mode 100644 index 00000000..c4ece814 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flip.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flowhold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flowhold.wav new file mode 100644 index 00000000..f0f15ee2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flowhold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywirea.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywirea.wav new file mode 100644 index 00000000..dec187a8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywirea.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywireb.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywireb.wav new file mode 100644 index 00000000..847022f0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/flybywireb.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow.wav new file mode 100644 index 00000000..214c156e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow_r.wav new file mode 100644 index 00000000..214c156e Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/follow_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsfix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsfix.wav new file mode 100644 index 00000000..7be04f66 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsfix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsnofix.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsnofix.wav new file mode 100644 index 00000000..fb7cd2de Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/gpsnofix.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided.wav new file mode 100644 index 00000000..41f00be0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided_r.wav new file mode 100644 index 00000000..41f00be0 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guided_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guidednogps.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guidednogps.wav new file mode 100644 index 00000000..420b427a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/guidednogps.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/hold_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/hold_r.wav new file mode 100644 index 00000000..10ff06bb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/hold_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing.wav new file mode 100644 index 00000000..5cbc700b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing_r.wav new file mode 100644 index 00000000..5cbc700b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/initializing_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/land.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/land.wav new file mode 100644 index 00000000..ac0e36fb Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/land.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/landing.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/landing.wav new file mode 100644 index 00000000..3e986a66 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/landing.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter.wav new file mode 100644 index 00000000..d3b40615 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter_r.wav new file mode 100644 index 00000000..d3b40615 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/loiter_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/lowbat.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/lowbat.wav new file mode 100644 index 00000000..e607b25d Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/lowbat.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual.wav new file mode 100644 index 00000000..50cf7138 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual_r.wav new file mode 100644 index 00000000..50cf7138 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/manual_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxalt.wav new file mode 100644 index 00000000..7c4b62f3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxdist.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxdist.wav new file mode 100644 index 00000000..7e4f60d5 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/maxdist.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/minalt.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/minalt.wav new file mode 100644 index 00000000..974ce53a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/minalt.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/poshold.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/poshold.wav new file mode 100644 index 00000000..a1549b48 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/poshold.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qacro.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qacro.wav new file mode 100644 index 00000000..77571680 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qacro.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qautotune.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qautotune.wav new file mode 100644 index 00000000..8124f15a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qautotune.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qhover.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qhover.wav new file mode 100644 index 00000000..83cadacf Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qhover.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qland.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qland.wav new file mode 100644 index 00000000..c87a35e4 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qland.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qloiter.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qloiter.wav new file mode 100644 index 00000000..faedcf6a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qloiter.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qrtl.wav new file mode 100644 index 00000000..fa5b5768 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qstabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qstabilize.wav new file mode 100644 index 00000000..a216e986 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/qstabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl.wav new file mode 100644 index 00000000..15fc9610 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl_r.wav new file mode 100644 index 00000000..15fc9610 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/rtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/selected.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/selected.wav new file mode 100644 index 00000000..c6d450f9 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/selected.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simple_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simple_r.wav new file mode 100644 index 00000000..0595397a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simple_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleoff.wav new file mode 100644 index 00000000..6c4000b2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleon.wav new file mode 100644 index 00000000..a3712bad Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/simpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl.wav new file mode 100644 index 00000000..fc9443d8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl_r.wav new file mode 100644 index 00000000..fc9443d8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/smartrtl_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/sport.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/sport.wav new file mode 100644 index 00000000..ea9db480 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/sport.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleoff.wav new file mode 100644 index 00000000..4bb69873 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleon.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleon.wav new file mode 100644 index 00000000..5579a801 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/ssimpleon.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/stabilize.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/stabilize.wav new file mode 100644 index 00000000..56d07e8c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/stabilize.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/started.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/started.wav new file mode 100644 index 00000000..c6fecadc Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/started.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/steering_r.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/steering_r.wav new file mode 100644 index 00000000..1088fdde Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/steering_r.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/systemid.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/systemid.wav new file mode 100644 index 00000000..d3ab445f Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/systemid.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/takeoff.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/takeoff.wav new file mode 100644 index 00000000..09bae642 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/takeoff.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/terrainko.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/terrainko.wav new file mode 100644 index 00000000..001863f8 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/terrainko.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/thermal.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/thermal.wav new file mode 100644 index 00000000..ea34abc6 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/thermal.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/throw.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/throw.wav new file mode 100644 index 00000000..3d80b2d2 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/throw.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/timealert.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/timealert.wav new file mode 100644 index 00000000..8066540a Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/timealert.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/training.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/training.wav new file mode 100644 index 00000000..94ce1fb3 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/training.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/turtle.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/turtle.wav new file mode 100644 index 00000000..1d0d5b0c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/turtle.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/velocity.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/velocity.wav new file mode 100644 index 00000000..2c5a4ef7 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/velocity.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/yaapu.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/yaapu.wav new file mode 100644 index 00000000..b628494b Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/yaapu.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/zigzag.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/zigzag.wav new file mode 100644 index 00000000..630a1688 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/it/zigzag.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/ntc.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/ntc.wav new file mode 100644 index 00000000..a75cb67c Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/ntc.wav differ diff --git a/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/wrn.wav b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/wrn.wav new file mode 100644 index 00000000..c09e1b57 Binary files /dev/null and b/OTX_ETX/c800x480/SD/WIDGETS/yaapu/sounds/wrn.wav differ