This thread is privately moderated by Miami Mike, who may elect to delete unwanted replies.
Mar 13, 2017, 05:40 PM
Glider Guider
Mini-HowTo

# Taranis: Optimized Offsets, Continued

This is a continuation of What happens when an offset is applied to a stick-controlled channel, where I'll describe how to implement optimizing of offsets to prevent clipping and stopping short. It's also an example of deriving a method with algebra and then translating it into OpenTX code. For another example, I recommend Differential without GVARs, posted today by Mike Shellim.

To recap, the principle of what I'm calling Optimized Outputs is to maintain access to both Min and Max limits even when the center position is offset. It's equivalent to what happens with off-center subtrims on the Outputs page if subtrims are set to "normal", but not if they're set to "linear." The desired behavior is represented by the green line in this graph:

The red line represents an offset that's not optimized, so that if full stick travel is used with 100% weight, the result is clipping at one end and stopping short at the other end.

The blue line represents an input without any offset.

My algorithm is to compute the distance the stick is from the end of its travel and reduce the weight of the offset accordingly, so that by the time the stick has reached the end of its travel the offset has been reduced to zero and the output has arrived exactly at its limit, just as it does when no offset is applied.

For any position (P) that a stick can be in within the range of -100% to +100%, the distance from the nearest endpoint (D) equals one minus the absolute value of P.
Code:
`D = 1 - |P|`
D represents the amount of weight the offset should be given. At stick center, D is at its maximum value of 100%, and as the stick nears either limit, D is reduced accordingly, reaching zero as the stick reaches its travel limit.

Multiplying D by the offset (O), gives the adjusted offset (A) to be added to the stick position:
Code:
`A = O * ( 1  - |P| )`
And adding the adjusted offset to the stick position gives the optimized position to pass to the Outputs stage or to another mix that may add an additional offset.

For ailerons, my first step was to optimize the offset due to aileron trim. I created an input equivalent to 1 - |D| which I call "aileron distance from end" or "Adfe":
Code:
`[I21]Adfe Ail Weight(-100%) Function(|x|) NoTrim Offset(100%)`
Then I created two more inputs for the aileron trim and the aileron stick input:
Code:
```[I22]TrmA MAX Weight(0%) TrmA
[I23]Aile Ail Weight(+100%) NoTrim```
And then combined the three on the Mixes page:
Code:
```CH30 (Aile) [I21]Adfe Weight(+100%)
*= [I22]TrmA Weight(+100%)
+= [I23]Aile Weight(+100%)```
CH30 is now my new aileron input, to which I can add rates and expo back on the Inputs page:
Code:
```[I1]Aile CH30 Weight(+100%) Switch(SB↑) [High]
CH30 Weight(+50%) Switch(SB↓) [Low]
CH30 Weight(+75%) [Medium]```
With [I1] as a new input that incorporates the aileron stick with rates, expo, and any added trim, I can now optimize the additional offsets that are applied to the ailerons in Launch, Zoom, Thermal, Speed, and Crow flight modes. First I need a new "distance from end" calculation for CH30:
Code:
`[I24]CH30 CH30 Weight(-100%) Function(|x|) Offset(100%)`
I can combine all of the camber and reflex modes into a single input. This is a good example of saving mix lines with the Mixes are for mixing, inputs are for selecting principle that I previously wrote about, because these offsets are right at home together on the Inputs page where there's no mixing, only selecting:
Code:
```[I4]RxCm TrmT Weight(+50%) Flight mode(Zoom) Offset(50%) [Zoom]
TrmT Weight(+25%) Flight mode(Speed) Offset(25%) [Speed]
TrmT Weight(+25%) Flight mode(Thermal) Offset(-25%) [Thermal]
TrmT Weight(+50%) Flight mode(Launch) Offset(-50%) [Launch]
MAX Weight(0%) [Default]```
(Notice that these offsets are all adjustable with TrmT but the ranges are different.)

Crow is off by itself on the Mixes page because it's mixed with the flap stick.

Finally, everything comes together on the Mixes page where you'll see a few things that I haven't explained, but if you're curious, just ask!
Code:
```CH01 (RtAil) [I4]RxCm Weight(+50%)
+= CH27 Weight(-50%) Flight mode(Crow) Offset(50%)
*= [I24]CH30 Weight(+100%)
+= [I1]Aile Weight(+100%) Diff(GV8)
:= CH28 Weight(+100%) Flight mode(Cal) Slow(u5:d5)
:= MAX Weight(+100%) Switch(L8)
CH02 (LtAil) [I4]RxCm Weight(+50%)
+= CH27 Weight(-50%) Flight mode(Crow) Offset(50%)
*= [I24]CH30 Weight(+100%)
+= [I1]Aile Weight(-100%) Diff(GV8)
:= CH28 Weight(+100%) Flight mode(Cal) Slow(u5:d5)
:= MAX Weight(+100%) Switch(L8)```