--[[ F3K Launch Tracker Telemetry script REQUIRES OpenTX 2.1.X Detects and measures launch hights Releases 1.0 31/10/15 Initial release 1.1 14/11/15 moved the launch detection to the background start dealing with units 1.2 18/11/15 playNumber now supports 'feet' 1.3 18/06/18 adapted to OpenTX-2.2.1 + sensitivity adaptation removed (C) 2018 Axel Barnitzke --]] -- constants (you may change the 's1' pot and/or the 'sf' switch to your needs) local thr_id = getFieldInfo('thr').id -- field index throttle stick (demo) -- local s1_id = getFieldInfo('s1').id -- field index s1 (sensitivity) local launch_id = getFieldInfo('sf').id -- field index launch enable switch local LAUNCH_ENABLED = 1024 -- switch value to enable launch detection -- (1024 back; -1024 front) local title = "F3K Launch Tracker" local demo = false -- use throttle stick to simulate hight -- runtime variables local altitudes local alt_id = 0 -- field index telemetry altitude local vsp_id = 0 -- field index telemetry vertical speed local vMin = 5 -- launch detected at 5 m/s asc rate local newTime = 0 local oldTime = 0 local status = 0 local useFeets = false -- Use general settings -> Measurement Units = "imperial" for "feet" -- Don't forget to adapt the sensor units to feet local unit_name = 'm' local units = 9 -- the lady says 'meters' local m2f = 1.0 ------------------------------------------------------------------------- -- Check if vario is enabled in telemetry section ------------------------------------------------------------------------- local function initVariometer() if( getFieldInfo('VSpd') == nil ) then title = 'Error in Telemtry!' else alt_id = getFieldInfo('Alt').id vsp_id = getFieldInfo('VSpd').id end end ------------------------------------------------------------------------- -- make the launch detection variable ------------------------------------------------------------------------- local function adjustLaunchDetection() -- vMin = 5 m/s +/- 3 m/s -- return (5.0 + (3.0/1024.0 * getValue(s1_id))) * m2f return (5.0 * m2f) end ------------------------------------------------------------------------- -- get altitude from variometer (or throttle stick for testing purposes) ------------------------------------------------------------------------- local function getAlt() if(demo) then local alt -- get altitude from throttle alt = (getValue(thr_id) + 1024 ) * 100.0 / 2048.0 -- 0m until 100m return (alt * m2f) else -- get altitude from variometer return getValue(alt_id) end end ------------------------------------------------------------------------- -- demo: compute vertical speed by comparing current height against last height ------------------------------------------------------------------------- local newAlt = 0.0 local oldAlt = 0.0 local doldTime = 0 local dnewTime = 0 local deltaAlt local function demoVspeed() local vsp dnewTime = getTime() newAlt = getAlt() if(oldAlt == 0.0) then oldAlt = newAlt end deltaAlt = newAlt - oldAlt vsp = deltaAlt / (dnewTime - doldTime) oldAlt = newAlt doldTime = dnewTime return vsp * 10.0 end ------------------------------------------------------------------------- -- return variometer Vspd value ------------------------------------------------------------------------- local function getVspeed() if (demo) then -- in demo mode the vertical speed needs some computation return demoVspeed() * m2f else return getValue(vsp_id) end end ------------------------------------------------------------------------- -- draw last 6 altitues on the right side of the screen ------------------------------------------------------------------------- local function drawAltitudes() for i=1,6 do altitudes.draw( 175, 9*(i-1)+5, i, PREC2 + LEFT) end end ------------------------------------------------------------------------- -- draw the frame to add values ------------------------------------------------------------------------- local function drawFrame() lcd.drawLine( 0, 47, 159, 47, SOLID, 2 ) lcd.drawLine( 159, 0, 159, 63, SOLID, 2 ) lcd.drawText( 10, 50, title, MIDSIZE) lcd.drawNumber( lcd.getLastPos() + 9 , 54, status, 0) -- debug end ------------------------------------------------------------------------- -- draw a BIG actual altitude in the center of the screen ------------------------------------------------------------------------- local function drawAltitude() local alt = getAlt() lcd.drawNumber( 24, 4, 10.0 * alt, PREC1 + XXLSIZE + LEFT) lcd.drawText( lcd.getLastPos(), 4, unit_name, DBLSIZE) end ------------------------------------------------------------------------- -- background (periodically called when custom telemetry screen is not visible) ------------------------------------------------------------------------- local function background( event ) ----------------------------------------------------------------------- -- the launch tracker state machine ----------------------------------------------------------------------- if status == 10 then -- loop enabled: prepare launch detection -- I think 5 m/s is a good value -> no need to make it variable vMin = adjustLaunchDetection() status = 20 elseif status == 20 then -- detect a launch if(getVspeed() >= vMin) then oldTime = getTime() status = 30 end elseif status == 30 then -- wait 500ms if ((getTime() - oldTime) >= 50) then status = 32 end elseif status == 32 then -- launched: now detect maximum in launch curve if(getVspeed() <= 0.1 ) then -- maximum reached oldTime = getTime() status = 40 end elseif status == 40 then -- wait 100ms (a vario is not that fast) if ((getTime() - oldTime) >= 10) then status = 42 end elseif status == 42 then -- get max height local maxAlt = getAlt() -- (TBD: F3B wait for a second maximum before disable launch mode) altitudes.push(maxAlt) playNumber( 10.0 * maxAlt, units, PREC1 ) status = 0 else -- wait for launch detection to be enabled if (getValue(launch_id) == LAUNCH_ENABLED) then status = 10 end end end ------------------------------------------------------------------------- -- run (periodically called when custom telemetry screen is visible) ------------------------------------------------------------------------- local function run(event) -- call background functionality background(event) -- draw screen lcd.clear() drawFrame() drawAltitude() drawAltitudes() end ------------------------------------------------------------------------- -- create a stacked display ------------------------------------------------------------------------- local function numericStack( s ) local tab = {} local size -- called by constructor local function initialize( s ) size = s for i=1,size do tab[ i ] = 0.0 end end -- stacks nums, discarding the older values local function push( a ) for i=2,size do tab[ i-1 ] = tab[ i ] end tab[size] = a end -- get one num local function get( i ) if( i > size) then i = size end return tab[ i ] end -- clean stack local function reset() initialize( size ) end -- draw num local function draw( x, y, i, att ) local val = tab[ i ] if val > 0.0 then lcd.drawNumber( x, y, 100.0 * val, att ) else lcd.drawText( x, y, "-----", att + LEFT) end end -- constructor initialize( s ) return { push=push, get=get, reset=reset, draw=draw } end ------------------------------------------------------------------------- -- init (the script init function) ------------------------------------------------------------------------- local function init() initVariometer() if (getGeneralSettings().imperial > 0) then useFeets = true unit_name = 'ft' units = 10 -- the lady says 'feet' m2f = 3.28 end altitudes = numericStack(6) end return { init=init, background=background, run=run }