1 ---- #########################################################################
3 ---- # Copyright (C) OpenTX #
5 ---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html #
7 ---- # This program is free software; you can redistribute it and/or modify #
8 ---- # it under the terms of the GNU General Public License version 2 as #
9 ---- # published by the Free Software Foundation. #
11 ---- # This program is distributed in the hope that it will be useful #
12 ---- # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 ---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 ---- # GNU General Public License for more details. #
16 ---- #########################################################################
17 -- Multicopter Wizard pages
18 local THROTTLE_PAGE
= 0
22 local CONFIRMATION_PAGE
= 4
24 -- Navigation variables
25 local page
= THROTTLE_PAGE
39 local function blinkChanged()
40 local time
= getTime() % 128
41 local blink
= (time
- time
% 64) / 64
42 if blink
~= lastBlink
then
50 local function fieldIncDec(event
, value
, max, force
)
51 if edit
or force
==true then
52 if event
== EVT_PLUS_BREAK
or event
== EVT_ROT_LEFT
then
55 elseif event
== EVT_MINUS_BREAK
or event
== EVT_ROT_RIGHT
then
56 value
= (value
+ max + 2)
59 value
= (value
% (max+1))
64 local function valueIncDec(event
, value
, min, max)
66 if event
== EVT_PLUS_FIRST
or event
== EVT_PLUS_REPT
or event
== EVT_ROT_RIGHT
then
71 elseif event
== EVT_MINUS_FIRST
or event
== EVT_MINUS_REPT
or event
== EVT_ROT_LEFT
then
81 local function navigate(event
, fieldMax
, prevPage
, nextPage
)
82 if event
== EVT_ENTER_BREAK
then
86 if event
== EVT_EXIT_BREAK
then
90 dirty
= blinkChanged()
93 if event
== EVT_PAGE_BREAK
then
97 elseif event
== EVT_PAGE_LONG
then
103 field
= fieldIncDec(event
, field
, fieldMax
, true)
108 local function getFieldFlags(position
)
110 if field
== position
then
113 flags
= INVERS
+ BLINK
119 local function channelIncDec(event
, value
)
120 if not edit
and event
==EVT_MENU_BREAK
then
124 value
= valueIncDec(event
, value
, 0, 15)
130 local function init()
131 thrCH1
= defaultChannel(2)
132 rollCH1
= defaultChannel(3)
133 yawCH1
= defaultChannel(0)
134 pitchCH1
= defaultChannel(1)
138 local function drawThrottleMenu()
140 lcd
.drawText(1, 0, "Select multicopter throttle channel", 0)
141 lcd
.drawFilledRectangle(0, 0, LCD_W
, 8, GREY_DEFAULT
+FILL_WHITE
)
142 lcd
.drawLine(LCD_W
/2-1, 18, LCD_W
/2-1, LCD_H
-1, DOTTED
, 0)
143 lcd
.drawPixmap(120, 8, "multi-thr.bmp")
144 lcd
.drawText(25, LCD_H
-16, "Assign channel", 0);
145 lcd
.drawText(LCD_W
/2-19, LCD_H
-8, ">>>", 0);
146 lcd
.drawSource(113, LCD_H
-8, MIXSRC_CH1
+thrCH1
, getFieldFlags(0))
150 local function throttleMenu(event
)
155 navigate(event
, fieldsMax
, page
, page
+1)
156 thrCH1
= channelIncDec(event
, thrCH1
)
160 local function drawRollMenu()
162 lcd
.drawText(1, 0, "Select multicopter roll channel", 0)
163 lcd
.drawFilledRectangle(0, 0, LCD_W
, 8, GREY_DEFAULT
+FILL_WHITE
)
164 lcd
.drawLine(LCD_W
/2-1, 18, LCD_W
/2-1, LCD_H
-1, DOTTED
, 0)
165 lcd
.drawPixmap(120, 8, "multi-roll.bmp")
166 lcd
.drawText(25, LCD_H
-16, "Assign channel", 0);
167 lcd
.drawText(LCD_W
/2-19, LCD_H
-8, ">>>", 0);
168 lcd
.drawSource(113, LCD_H
-8, MIXSRC_CH1
+rollCH1
, getFieldFlags(0))
172 local function rollMenu(event
)
177 navigate(event
, fieldsMax
, page
-1, page
+1)
178 rollCH1
= channelIncDec(event
, rollCH1
)
182 local function drawPitchMenu()
184 lcd
.drawText(1, 0, "Select multicopter pitch channel", 0)
185 lcd
.drawFilledRectangle(0, 0, LCD_W
, 8, GREY_DEFAULT
+FILL_WHITE
)
186 lcd
.drawLine(LCD_W
/2-1, 18, LCD_W
/2-1, LCD_H
-1, DOTTED
, 0)
187 lcd
.drawPixmap(120, 8, "multi-pitch.bmp")
188 lcd
.drawText(25, LCD_H
-16, "Assign channel", 0);
189 lcd
.drawText(LCD_W
/2-19, LCD_H
-8, ">>>", 0);
190 lcd
.drawSource(113, LCD_H
-8, MIXSRC_CH1
+pitchCH1
, getFieldFlags(0))
194 local function pitchMenu(event
)
199 navigate(event
, fieldsMax
, page
-1, page
+1)
200 pitchCH1
= channelIncDec(event
, pitchCH1
)
204 local function drawYawMenu()
206 lcd
.drawText(1, 0, "Select multicopter yaw channel", 0)
207 lcd
.drawFilledRectangle(0, 0, LCD_W
, 8, GREY_DEFAULT
+FILL_WHITE
)
208 lcd
.drawLine(LCD_W
/2-1, 18, LCD_W
/2-1, LCD_H
-1, DOTTED
, 0)
209 lcd
.drawPixmap(120, 8, "multi-yaw.bmp")
210 lcd
.drawText(25, LCD_H
-16, "Assign channel", 0);
211 lcd
.drawText(LCD_W
/2-19, LCD_H
-8, ">>>", 0);
212 lcd
.drawSource(113, LCD_H
-8, MIXSRC_CH1
+yawCH1
, getFieldFlags(0))
216 local function yawMenu(event
)
221 navigate(event
, fieldsMax
, page
-1, page
+1)
222 yawCH1
= channelIncDec(event
, yawCH1
)
226 local function drawNextLine(x
, y
, label
, channel
)
227 lcd
.drawText(x
, y
, label
, 0);
228 lcd
.drawText(x
+48, y
, ":", 0);
229 lcd
.drawSource(x
+52, y
, MIXSRC_CH1
+channel
, 0)
238 local function drawConfirmationMenu()
242 lcd
.drawText(48, 1, "Ready to go?", 0);
243 lcd
.drawFilledRectangle(0, 0, LCD_W
, 9, 0)
244 x
, y
= drawNextLine(x
, y
, "Throttle", thrCH1
)
245 x
, y
= drawNextLine(x
, y
, "Roll", rollCH1
)
246 x
, y
= drawNextLine(x
, y
, "Pitch", pitchCH1
)
247 x
, y
= drawNextLine(x
, y
, "Yaw", yawCH1
)
248 lcd
.drawText(48, LCD_H
-8, "Long [ENT] to confirm", 0);
249 lcd
.drawFilledRectangle(0, LCD_H
-9, LCD_W
, 9, 0)
250 lcd
.drawPixmap(LCD_W
-18, LCD_H
-17, "confirm-tick.bmp")
254 local function addMix(channel
, input
, name
, weight
, index
)
255 local mix
= { source
=input
, name
=name
}
256 if weight
~= nil then
262 model
.insertMix(channel
, index
, mix
)
265 local function applySettings()
266 model
.defaultInputs()
268 addMix(thrCH1
, MIXSRC_FIRST_INPUT
+defaultChannel(2), "Engine")
269 addMix(rollCH1
, MIXSRC_FIRST_INPUT
+defaultChannel(3), "Roll")
270 addMix(yawCH1
, MIXSRC_FIRST_INPUT
+defaultChannel(0), "Yaw")
271 addMix(pitchCH1
, MIXSRC_FIRST_INPUT
+defaultChannel(1), "Pitch")
274 local function confirmationMenu(event
)
277 drawConfirmationMenu()
280 navigate(event
, fieldsMax
, YAW_PAGE
, page
)
282 if event
== EVT_EXIT_BREAK
then
284 elseif event
== EVT_ENTER_LONG
then
294 local function run(event
)
296 error("Cannot be run as a model script!")
298 if page
== THROTTLE_PAGE
then
300 elseif page
== ROLL_PAGE
then
302 elseif page
== YAW_PAGE
then
304 elseif page
== PITCH_PAGE
then
306 elseif page
== CONFIRMATION_PAGE
then
307 return confirmationMenu(event
)
312 return { init
=init
, run
=run
}