Skip to content

Lua scripting in OpenTX

umbertoghio edited this page Aug 9, 2017 · 2 revisions

English Translation: I managed to write this from the scripts contained in wizard. To write heli I was inspired by the wizard of version 1.52. All parameters are set as in wizard 1.52. As you will see all the orders are not complete.

What I could not write: Selection trim, curve, delays, warning ... The setting of the curves in the curved page The model name in the configuration page The type of swashplate and the collective pitch source in the helicopter page

I have integrated engine safety, volume adjustment, gas locked sound files, unlocked gas is not integrated to allow the possibility of using its own sound files.

If you can please help me on how to pass the missing parameters in order to finish.

Je poste en français car je ne sais pas écrire en anglais, un traducteur donnerait un texte totalement illisible

J'ai réussi à écrire ceci a partir des scripts contenus dans wizard. Pour écrire heli je me suis inspiré de l'assistant de la version 1.52. Tous les paramètres sont imposés comme dans l'assistant 1.52. Comme vous le constaterez toutes les commandes ne sont pas complètes.

Ce que je n'ai pas réussi à écrire: la sélection trim, courbe, delays, warning ... le paramétrage des courbes dans la page courbes le nom du modèle dans la page configuration le type de plateau cyclique et la source du pas collectif dans la page hélicoptère

J'ai intégré la sécurité moteur, le réglage du volume sonore, les fichiers sonores gaz verrouillé, gaz déverrouillé ne son pas intégré pour laisser la possibilité d'utiliser ses propre fichiers son.

Si l'on peut m'aider sur la facon de passer les paramétres manquant afin de terminer.

-- Version Francaise Murphy 1.1
-- Modification fichier par blonblon pour ajout verrouillage Gaz,
-- réglage volume par S1, jouer fichier en fonction du verrouillage Gaz
-- Assistant de configuration hélicoptère version 1.52 vers lua

local THROTTLE_PAGE = 0
local STICKY_PAGE = 1
local CYC1_PAGE = 2
local CYC2_PAGE = 3
local CYC3_PAGE = 4
local DIR_PAGE = 5
local CONFIRMATION_PAGE = 6

-- Navigation variables
local page = THROTTLE_PAGE
local dirty = true
local edit = false
local field = 0
local fieldsMax = 0
local comboBoxMode = 0 -- Scrap variable

-- Model settings
local engineMode = 1
local stickyMode = 1
local thrCH1 = 0
local cyc1CH1 = 0
local cyc2CH1 = 0
local cyc3hCH1 = 0
local dirCH1 = 0
local canal = 0

-- On prépare les paramétres que l'on va passer à LS1 et LS2 (Inters L1 et L2)
local stickyLS1 = {["func"]=4 ; v1=77 ; v2=-98 ; v3=0 ; ["and"]=0; delay=0; duration=0}
local stickyLS2 = {["func"]=18 ; v1=49 ; v2=0 ; v3=0 ; ["and"]=16; delay=0; duration=0}
-- On prépare les paramétres que l'on va passer au SF1 à SF4 (Fonctions SF1 à SF4)
local stickySF1 = {switch=81 ; ["func"]=6 ; param=0 ; value=79 ; mode=0 ; active=1}
local stickySF2 = {switch=-50 ; ["func"]=0 ; param=0 ; value=-100 ; mode=0 ; active=1}
local stickySF3 = {switch=16 ; ["func"]=11 ; param=0 ; value=0 ; mode=0 ; active=0}
local stickySF4 = {switch=17 ; ["func"]=11 ; param=0 ; value=0 ; mode=0 ; active=0}

--------------------------------------------------------------------

-- Common functions
local lastBlink = 0
local function blinkChanged()
  local time = getTime() % 128
  local blink = (time - time % 64) / 64
  if blink ~= lastBlink then
    lastBlink = blink
    return true
  else
    return false
  end
end

--------------------------------------------------------------------

local function fieldIncDec(event, value, max, force)
  if edit or force==true then
    if event == EVT_PLUS_BREAK then
      value = (value + max)
      dirty = true
    elseif event == EVT_MINUS_BREAK then
      value = (value + max + 2)
      dirty = true
    end
    value = (value % (max+1))
  end
  return value
end

--------------------------------------------------------------------

local function valueIncDec(event, value, min, max)
  if edit then
    if event == EVT_PLUS_FIRST or event == EVT_PLUS_REPT then
      if value < max then
        value = (value + 1)
        dirty = true
      end
    elseif event == EVT_MINUS_FIRST or event == EVT_MINUS_REPT then
      if value > min then
        value = (value - 1)
        dirty = true
      end
    end
  end
  return value
end

--------------------------------------------------------------------

local function navigate(event, fieldMax, prevPage, nextPage)
  if event == EVT_ENTER_BREAK then
    edit = not edit
    dirty = true
  elseif edit then
    if event == EVT_EXIT_BREAK then
      edit = false
      dirty = true  
    elseif not dirty then
      dirty = blinkChanged()
    end
  else
    if event == EVT_PAGE_BREAK then     
      page = nextPage
      field = 0
      dirty = true
    elseif event == EVT_PAGE_LONG then
      page = prevPage
      field = 0
      killEvents(event);
      dirty = true
    else
      field = fieldIncDec(event, field, fieldMax, true)
    end
  end
end

--------------------------------------------------------------------

local function fieldIncDec(event, value, max, force)
  if edit or force==true then
    if event == EVT_PLUS_BREAK then
      value = (value + max)
      dirty = true
    elseif event == EVT_MINUS_BREAK then
      value = (value + max + 2)
      dirty = true
    end
    value = (value % (max+1))
  end
  return value
end

--------------------------------------------------------------------

local function getFieldFlags(position)
  flags = 0
  if field == position then
    flags = INVERS
    if edit then
      flags = INVERS + BLINK
    end
  end
  return flags
end

--------------------------------------------------------------------

local function channelIncDec(event, value)
  if not edit and event==EVT_MENU_BREAK then
    servoPage = value
    dirty = true
  else
    value = valueIncDec(event, value, 0, 15)
  end
  return value
end

--------------------------------------------------------------------

local function switchIncDec(event, value)
  if not edit and event==EVT_MENU_BREAK then
    --servoPage = value
    dirty = true
  else
    value = valueIncDec(event, value, 1, 20)
  end
  return value
end

--------------------------------------------------------------------

-- Init function
local function init()
  dirCH1 = defaultChannel(0)
  cyc1CH1 = defaultChannel(1)  
  thrCH1 = defaultChannel(2)
  cyc2CH1 = defaultChannel(3)
  cyc3CH1 = 4   
end

--------------------------------------------------------------------

-- Throttle Menu
local engineModeItems = {"Non", "Oui..."}

local function drawThrottleMenu()
  lcd.clear()
  lcd.drawText(1, 0, "moteur", 0)
  lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
  lcd.drawCombobox(0, 8, LCD_W/2, {"..."}, comboBoxMode, getFieldFlags(1)) 
  lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
  lcd.drawPixmap(120, 8, "engine-4.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function throttleMenu(event)
  if dirty then
    dirty = false
    drawThrottleMenu()
  end
  navigate(event, fieldsMax, page, page+1)
 
  if field==0 then
    engineMode = fieldIncDec(event, engineMode, 1)
  elseif field == 1 then  
  thrCH1 = channelIncDec(event, thrCH1)
end
end

--------------------------------------------------------------------

-- Sticky Throttle Menu

local function drawStickyMenu()
-- Si engine
    if engineMode == 1 then
      lcd.clear()
      lcd.drawText(1, 0, "Voulez-vous une securite moteur?", 0)
      lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
      lcd.drawCombobox(0, 8, LCD_W/2, engineModeItems, stickyMode, getFieldFlags(0))
      lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
        -- use sticky throttle
      if stickyMode == 1 then
        lcd.drawPixmap(132, 8, "engine-2.bmp")
        lcd.drawText(LCD_W/2-19, LCD_H-8, ">>>", 0);
        lcd.drawSwitch(145, LCD_H-8, stickyLS2["and"], getFieldFlags(1))
        fieldsMax = 1
      else
        -- no sticky throttle
        lcd.drawPixmap(132, 8, "engine-3.bmp")
        fieldsMax = 0
      end
    end
end

--------------------------------------------------------------------

local function stickyMenu(event)
  if dirty then
    dirty = false
    drawStickyMenu()
  end

  navigate(event, fieldsMax, page-1, page+1)

  if field==0 then
    stickyMode = fieldIncDec(event, stickyMode, 1)
  elseif field==1 then
    stickyLS2["and"] = switchIncDec(event, stickyLS2["and"])
  end
end

--------------------------------------------------------------------

-- CYC1 Menu
local function drawCYC1Menu()
  lcd.clear()
  lcd.drawText(1, 0, "Cyc1", 0)
  lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
  lcd.drawCombobox(0, 8, LCD_W/2, {"..."}, comboBoxMode, getFieldFlags(1)) 
  lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
  lcd.drawPixmap(120, 8, "flybar.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function cyc1Menu(event)
  if dirty then
    dirty = false
    drawCYC1Menu()
  end
  navigate(event, fieldsMax, page-1, page+1)
  cyc1CH1 = channelIncDec(event, cyc1CH1)
end

--------------------------------------------------------------------

-- CYC2 Menu
local function drawCYC2Menu()
  lcd.clear()
  lcd.drawText(1, 0, "Cyc2", 0)
  lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
  lcd.drawCombobox(0, 8, LCD_W/2, {"..."}, comboBoxMode, getFieldFlags(1)) 
  lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
  lcd.drawPixmap(120, 8, "flybar.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function cyc2Menu(event)
  if dirty then
    dirty = false
    drawCYC2Menu()
  end
  navigate(event, fieldsMax, page-1, page+1)
  cyc2CH1 = channelIncDec(event, cyc2CH1)
end

--------------------------------------------------------------------

-- CYC3 Menu
local function drawCYC3Menu()
  lcd.clear()
  lcd.drawText(1, 0, "Cyc3", 0)
  lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
  lcd.drawCombobox(0, 8, LCD_W/2, {"..."}, comboBoxMode, getFieldFlags(1)) 
  lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
  lcd.drawPixmap(120, 8, "flybar.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function cyc3Menu(event)
  if dirty then
    dirty = false
    drawCYC3Menu()
  end
  navigate(event, fieldsMax, page-1, page+1)
  cyc3CH1 = channelIncDec(event, cyc3CH1)
end

--------------------------------------------------------------------

-- Dir Menu
local function drawDIRMenu()
  lcd.clear()
  lcd.drawText(1, 0, "Dir", 0)
  lcd.drawFilledRectangle(0, 0, LCD_W, 8, GREY_DEFAULT+FILL_WHITE)
  lcd.drawCombobox(0, 8, LCD_W/2, {"..."}, comboBoxMode, getFieldFlags(1)) 
  lcd.drawLine(LCD_W/2-1, 18, LCD_W/2-1, LCD_H, DOTTED, 0)
  lcd.drawPixmap(120, 8, "queue.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function dirMenu(event)
  if dirty then
    dirty = false
    drawDIRMenu()
  end
  navigate(event, fieldsMax, page-1, page+1)
  dirCH1 = channelIncDec(event,dirCH1)
end

--------------------------------------------------------------------

-- Confirmation Menu
local function drawNextLine(x, y, label, channel)
  lcd.drawText(x, y, label, 0);
  lcd.drawSource(x+52, y, MIXSRC_CH1+channel, 0)
  y = y + 8
  if y > 50 then
    y = 12
    x = 120
  end
  return x, y
end

--------------------------------------------------------------------

local function drawConfirmationMenu()
  local x = 22
  local y = 12
  lcd.clear()
  lcd.drawText(40, 1, "Confirmez votre choix SVP...", 0);
  lcd.drawFilledRectangle(0, 0, LCD_W, 9, 0)
  x, y = drawNextLine(x, y, "Moteur:", 5)
  x, y = drawNextLine(x, y, "Cyc1:", 1)
  x, y = drawNextLine(x, y, "Cyc2:", 2)
  x, y = drawNextLine(x, y, "Cyc3:", 3)
  x, y = drawNextLine(x, y, "Dir:", 4)
  lcd.drawText(48, LCD_H-8, "[Enter Long] pour confirmer", 0);
  lcd.drawFilledRectangle(0, LCD_H-9, LCD_W, 9, 0)
  lcd.drawPixmap(LCD_W-18, 0, "confirm-tick.bmp")
  lcd.drawPixmap(0, LCD_H-17, "confirm-plane.bmp")
  fieldsMax = 0
end

--------------------------------------------------------------------

local function addMix(channel, input, name, weight, index)
  local mix = { source=input, name=name }

  if canal == 1 then
    mix.weight = 100
    mix.source = 77
    mix.switch = 4
    index = 0
  end
  if canal == 2 then
    mix.name = "PROF"
    mix.weight = 100
    mix.source = 85
--    mix.carryTrim = "TRIM_OFF"
--    mix.curve = 1, 1
--    mix.trim = 1
--    mix.offset = -50
  end
  if canal == 3 then
    mix.name = "AIL"
    mix.weight = 100
    mix.source = 86
  end
  if canal == 4 then
    mix.name = "PAS"
    mix.weight = 100
    mix.source = 87
  end
  if canal == 5 then
    mix.name = "DIR"
    mix.weight = 100
    mix.source = 75
  end
  if canal == 6 then
    mix.weight = 100
    mix.source = 77
    mix.switch = 5
--    mix.curveparam(0, "cstm")
--    model.setOutput(5, mixparam1)    
--    mix.delayup = 0.5
--    mix.curveParam = 3 -- <-----
--    mix.subtrim = 0 -- <-----
    index = 1
  end
  if canal == 7 then
    mix.weight = 100
    mix.source = 77
    mix.switch = 6
    index = 2
  end
  if canal == 8 then
    mix.weight = -100
    mix.source = 84
    mix.switch = 17
    mix.multiplex = 2
    index = 3
  end
  if canal == 9 then
    mix.weight = 100
    mix.source = 77
    mix.switch = 4
    index = 0
  end
  if canal == 10 then
    mix.weight = 100  
    mix.source = 77
    mix.switch = 5
    index = 1
  end
  if canal == 11 then
    mix.weight = 100
    mix.source = 77
    mix.switch = 6
    mix.multiplex = 2
    index = 2
  end
  if index == nil then
    index = 0
  end
  model.insertMix(channel, index, mix)
end

--------------------------------------------------------------------

local function applySettings()
  model.defaultInputs()
  model.deleteMixes()
  canal = 1
  addMix(4, MIXSRC_Thr)
  
  if engineMode > 0 then
    if stickyMode > 0 then
        -- Logical Switches
        model.setLogicalSwitch(0,stickyLS1)
        model.setLogicalSwitch(1,stickyLS2)
        -- Special Function
        stickySF1.param=thrCH1
        model.setCustomFunction(0,stickySF1)
        model.setCustomFunction(1,stickySF2)        
        model.setCustomFunction(2,stickySF3)
        model.setCustomFunction(3,stickySF4)        
    end
  end
  canal = 2
  addMix(0, MIXSRC_CYC1, "Cyc1")
  canal = 3
  addMix(1, MIXSRC_CYC2, "Cyc2")
  canal = 4
  addMix(2, MIXSRC_CYC3, "Cyc3")
  canal = 5
  addMix(3, MIXSRC_Rud, "Dir")
  canal = 6
  addMix(4, MIXSRC_Thr)
  canal = 7
  addMix(4, MIXSRC_Thr)
  canal = 8
  addMix(4, MIXSRC_Thr)
  canal = 9
  addMix(10, MIXSRC_Thr)
  canal = 10
  addMix(10, MIXSRC_Thr)  
  canal = 11
  addMix(10, MIXSRC_Thr)  
end

--------------------------------------------------------------------

local function confirmationMenu(event)
  if dirty then
    dirty = false
    drawConfirmationMenu()
  end

  navigate(event, fieldsMax, YAW_PAGE, page)

  if event == EVT_EXIT_BREAK then
    return 2
  elseif event == EVT_ENTER_LONG then
    killEvents(event)
    applySettings()
    return 2
  else
    return 0
  end
end

--------------------------------------------------------------------

-- Main
local function run(event)
  if event == nil then
    error("Ne peut pas etre execute comme un script de modele!")
  end
  lcd.lock()
  if page == THROTTLE_PAGE then
    throttleMenu(event)
-- Ajout du choix Verrouillage GAZ
  elseif page == STICKY_PAGE then
    stickyMenu(event)    
  elseif page == CYC1_PAGE then
    cyc1Menu(event)
  elseif page == CYC2_PAGE then
    cyc2Menu(event)
  elseif page == CYC3_PAGE then
    cyc3Menu(event)
  elseif page == DIR_PAGE then
    dirMenu(event)
  elseif page == CONFIRMATION_PAGE then
    return confirmationMenu(event)
  end
  return 0
end

return { init=init, run=run }