├── README.md └── tricks.lua /README.md: -------------------------------------------------------------------------------- 1 | # trick-on-a-switch 2 | OpenTX Lua script for frsky transmitters to perform various drone tricks automatically. 3 | 4 | A video description of this project, including how to install and use the script is here: 5 | https://youtu.be/tocH6IgbK7k 6 | 7 | -------------------------------------------------------------------------------- /tricks.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- 3 | -- **TRICK ON A SWITCH v0.91** 4 | -- by Mactac 5 | 6 | -- contact: 7 | -- www.youtube.com/mactacfpv 8 | -- www.instagram.com/mactac 9 | -- p a u l (at) w a g o r n (dot) c o m 10 | 11 | -- **Licence:** Creative commons Attribution-NonCommercial-ShareAlike 12 | -- https://creativecommons.org/licenses/by-nc-sa/2.5/ 13 | -- You may: Share and adapt this work only for NON-COMMERCIAL purposes 14 | -- You must give appropriate credit and indicate if changes were made. 15 | -- The header above and this licence must remain intact on redistribution. 16 | -- If you remix, transform, or build upon the material, you must distribute 17 | -- your contributions under the same license as this original. 18 | ---------------------------------------------------------------------------------------- 19 | -- 20 | -- >>>>> **WARNING** <<<<< 21 | -- This script takes control of your sticks! Be VERY careful using the script, 22 | -- especially if you make modifications. Always test in a simulator before using 23 | -- it on a live quad. Things can go VERY wrong, including flyaways, or full throttle 24 | -- loss of control, and potential personal injury. 25 | -- By using this script, you hereby take full responsibility for damage to property 26 | -- or injuries to you or others that takes place directly or indirectly from its use. 27 | -- Provided with no guarantees or warranties of any type. If you don't know what you're 28 | -- doing, you may very well lose a quad or hurt yourself or someone else.... it's all on you! 29 | 30 | -- **THIS SCRIPT WILL NOT WORK FOR YOU** without modifications- see the notes below. 31 | -- You will need to edit the trick timing (& maybe switch assignments) if you want it to 32 | -- work with your setup. 33 | 34 | -- **Trick settings:** 35 | -- up to 3 tricks on one 3-position switch (could multiplex switches for more tricks) 36 | -- each trick consists of one or more moves 37 | -- each move contains stick positions and time to hold each move in 10ms increments 38 | -- sticks go from -1024 to 1024 at full deflections. 39 | -- syntax is: trick[Trick number][move number] = {time,throttle,yaw,roll,pitch} 40 | -- Tricks can have as many moves as you want, just end the trick with all zeroes 41 | 42 | -- **Rates:** 43 | -- These times and stick movements are set up for MY rates. You will have to adjust 44 | -- them to suit your own rates- there is very little chance that these values will work 45 | -- for you. 46 | -- If you want to flip 180 degrees, you will want to look at your degrees/second of your 47 | -- rates and divide to find how long the stick should be held. For example, if you are 48 | -- set to 800 degrees per second for your pitch and want to flip 180, 180 divided by 800 49 | -- equals 0.225 seconds if you use full stick throw ( which is a value of 1024). Times 50 | -- in open tx are in 10ms increments, so .225s = 225ms = a time value of 22 or 23. 51 | -- So in this example, that segment of the trick for a 180 flip would be {22,-1000,0,0, 1024} 52 | -- 53 | -- If you do no want to use full stick deflection (for example you you are mixing roll with 54 | -- a bit of yaw), you can use this calculator to figure out the percentage of stick deflection 55 | -- based on degrees per second: https://apocolipse.github.io/RotorPirates/ just keep in 56 | -- mind that sticks go from -1024 to 1024, so 100% is 1024, and 50% would be 512. 57 | 58 | -- **Still do do:** 59 | -- Allow rates, expo, rc expo to be entered to automatically calculate stick deflections 60 | -- Panic button (resets everything & aborts in the middle of a trick) 61 | 62 | 63 | 64 | trick = {{}, {}, {}} 65 | 66 | -- Inverted Yaw spin 67 | trick[1][1] = {26,-1024,0,0,-1000} 68 | trick[1][2] = {71,-1024,-1000,0,0} 69 | trick[1][3] = {18,-1024,0,0,-1000} 70 | trick[1][4] = {0,0,0,0,0} 71 | 72 | -- Backwards knife edge 73 | trick[2][1] = {23,-1024,0,0,-1000} 74 | trick[2][2] = {10,-1024,-840,1000,0} 75 | trick[2][3] = {0,0,0,0,0} 76 | 77 | -- Rubik's cube 78 | trick[3][1] = {24,-1024,0,0,-1000} 79 | trick[3][2] = {24,-1024,0,-1000,0} 80 | trick[3][3] = {24,-1024,0,0,1000} 81 | trick[3][4] = {24,-1024,0,1000,0} 82 | trick[3][5] = {0,0,0,0,0} 83 | 84 | 85 | -- Switch assignments 86 | -- You can change these around based on how your Taranis is set up. 87 | -- Just make sure you use the correct switch types (ie 3 position or momentary) 88 | 89 | local seg_switch = "sa" -- switch to select only one move of trick (3 position switch) for adjusting timing, etc 90 | local sel_switch = "se" -- switch to select which trick to do (3 position switch) 91 | local go_switch = "sh" -- switch to execute trick (should be a momentary switch) 92 | local disable_switch = "sc" -- switch to turn tricks on/off or act as a panic. Center = enabled, any other position = disabled 93 | 94 | -- Other variables 95 | local elapsed_time 96 | local move = 0 97 | local started = 0 98 | local start_time = 0 99 | local skip = 0 100 | local move_time =0 101 | local timing_mod = {} 102 | local display_timer = 0 103 | local return1 = 0 104 | local return2 = 0 105 | 106 | -- Outputs 107 | local thr = 0 108 | local yaw = 0 109 | local roll = 0 110 | local pitch = 0 111 | 112 | local inputs = { 113 | {"orig_thr", SOURCE}, 114 | {"orig_yaw", SOURCE}, 115 | {"orig_roll", SOURCE}, 116 | {"orig_pitch", SOURCE} 117 | } 118 | 119 | local outputs = { "thr", "yaw", "roll", "pitch","t1,3","t2,4"} 120 | -- Maximum 4 characters 121 | 122 | local function run(orig_thr,orig_yaw,orig_roll,orig_pitch) 123 | 124 | -- Get potentiometer values from radio for adjusting move times 125 | timing_mod[1] = getValue('s1')*.02 -- left knob. Current range is 0-100ms increase the 0.2 number for greater range 126 | timing_mod[2] = getValue('s2')*.02 -- right knob 127 | timing_mod[3] = getValue('ls')*.02 -- left trim slider (Remove for QX7) 128 | timing_mod[4] = getValue('rs')*.02 -- right trim slider (Remove for QX7) 129 | 130 | -- The following section cycles the output display between trimpots 1&2 and 3&4. 131 | -- If you have a QX7, you don't have trimpots 3&4, so you can change this whole block to just: 132 | -- return1 = getValue('s1')*.1 133 | -- return2 = getValue('s2')*.1 134 | 135 | if getTime() - display_timer > 600 then 136 | return1 = getValue('ls')*.1 137 | return2 = getValue('rs')*.1 138 | display_timer = getTime() 139 | elseif getTime() - display_timer > 200 then 140 | return1 = getValue('s1')*.1 141 | return2 = getValue('s2')*.1 142 | end 143 | 144 | -- which trick are we doing? 145 | if getValue(sel_switch) > 0 then 146 | trick_num = 3 147 | elseif getValue(sel_switch) == 0 then 148 | trick_num = 2 149 | else 150 | trick_num = 1 151 | end 152 | 153 | if getValue(go_switch) > 1 and started == 0 then -- if trick not alrady started, then launch 154 | started = 1 155 | move = 1 156 | end 157 | 158 | local segment = getValue(seg_switch) -- choose single trick segment (only segment #1 or #2) for tuning, center means do full trick 159 | 160 | if started == 1 and trick[trick_num][move][1] > 0 and getValue(disable_switch) == 0 then -- make sure we are not at end of trick 161 | 162 | if start_time == 0 then -- start of a new move, reset timer 163 | start_time = getTime() 164 | end 165 | 166 | elapsed = getTime() - start_time 167 | 168 | if (move ~= 2 and segment > 0) or (move ~= 1 and segment < 0) then -- skip all moves except selected segment (1 or 2) 169 | -- if single segment chosen, otherwise don't skip anything 170 | skip = 1 171 | else 172 | skip =0 173 | end 174 | 175 | if move < 5 then -- Change this to 3 instead of 5 for QX7 176 | move_time = trick[trick_num][move][1] + timing_mod[move] 177 | else 178 | move_time = trick[trick_num][move][1] 179 | end 180 | 181 | if elapsed < move_time and skip ~= 1 then -- do this until we reach end time for the move 182 | thr = trick[trick_num][move][2] 183 | yaw = trick[trick_num][move][3] 184 | roll = trick[trick_num][move][4] 185 | pitch= trick[trick_num][move][5] 186 | else 187 | start_time = 0 -- go to next move, reset sticks so no overshoot 188 | yaw = 0 189 | pitch = 0 190 | roll = 0 191 | thr = -1000 192 | move = move + 1 193 | end 194 | 195 | else -- no trick in progress, default to mirroring sticks 196 | yaw = orig_yaw 197 | thr = orig_thr 198 | roll = orig_roll 199 | pitch = orig_pitch 200 | start_time = 0 201 | started = 0 202 | move = 1 203 | end 204 | 205 | 206 | -- Return the values. Note that in addition to the 4 axes, we are also returning the value 207 | -- of 2 of the knobs. The reason for that is that after we tune the timing with the knobs, 208 | -- we can see their exact values and adjust the timing of the moves exactly. OpenTX only 209 | -- supports 6 returns, so we can't put all 4 of the potentiometers here. The output cycles 210 | -- the knobs (1&2) and the sliders (3&4) (QX7 only supports the 2 knobs) 211 | 212 | return thr, yaw, roll, pitch,return1,return2 213 | 214 | end 215 | 216 | return { input=inputs, output=outputs, run=run } 217 | --------------------------------------------------------------------------------