OpenTx - Key Concepts

Mike Shellim 25 July 2014
Updated: 26 April 2017

Introduction

OpenTx is a uniquely capable operating system, however pilots coming from mainstream brands may find the way of working a little unfamiliar. My aim with this article is to banish some of the mystery, and to enable users to design their own setups with confidence.

I'll cover the following topics:

Background

If you're familiar with Futaba, Spektrum and similar, OpenTx may appear a little, well, basic. There are no high-level menus to hold your hand, and no special mixers - mixers in OpenTx are simple generic constructs.

Paradoxically, this sparseness makes OpenTx both supremely flexible and easy to adjust. It can also enable setups of great functionality and elegance.

However, in order to use OpenTx effectively it's necessary to understand a few key concepts.

OpenTx: an overview of processing

The core of OpenTx is the processing loop which is executed several times a second. With each cycle, the positions of all the controls are read, any mixing is applied, and channel outputs calculated:

flow

Let's look at each stage in more detail

The starting point: Sources

OpenTx's input data consists of the transmitter controls, telemetry streams and Lua scripts. A generic term for these is 'sources'. For this introduction we'll focus on the transmitter controls, in other words the sticks, sliders and knobs on your transmitter.

Each source has an identifier. For example the elevator stick is 'Ele', the switch SA is 'SA' and so on.

At the start of each processing loop, OpenTx reads the position of all the sources, and assigns a value according to its position; -100 and +100 correspond to the end points, and 0 to the centre. For example:

The processing loop is cycled several time each second, so these values will vary in real time as you move the controls.

Channels (MIXERS and OUTPUTS menu)

The Taranis can command up to 32 independent channels. The lowest numbered channels will be normally be assigned to devices such as servos, ESCs, flight controller etc. A channel which is not assigned to any device may be left unused, or used as a virtual channel.

Management of channels is split between the MIXERS and OUTPUTS menus. We'll look at the MIXERS menu in more detail in the next section. The OUTPUTS menu is where you can assign a meaningful name to each channel, and set the direction, limits and centre. You only need to make these adjustments for those channels which actually drive a servo.

Here's a view of the OUTPUTS menu showing the channel assignment for a 3-channel 'RES' sailplane. I've named the channels 'Rudder', 'Elev' and 'Spoilr' to describe their function:

Outputs

Note that this menu doesn't say anything about how each channel is driven - or even that it's driven at all! For that, we need to define some mixers...

Mixers (MIXER menu)

Mixers are the wiring between the sources and channels; they define which channels should respond when you move the sticks/sliders. And how they should respond.

Mixers in OpenTx are simple building blocks:

It follows that in order to drive a servo, a channel must have at least one mixer. In practice, a channel may have more than one mixer associated, for example the flapperon channels on a glider.

Mixer notation

I'll use two notations to describe a mix:

The two forms are interchangable. Typically you'll use the src->ch form when designing a setup ('cause and effect'), while the src<-ch form corresponds better to the Mixers menu where you'll enter your mixer definitions.

Three mixing scenarios

There are three basic scenarios which need to be modelled:

Let's see how each scenario can be implemented using OpenTx's simple mixing model. I'll illustrate each with an example:

Scenario 1: One source affects one channel

Example: A rudder driven by the rudder stick.

There is just one interaction involved, and it can be written as:

When creating the mix, the alternative notation is more useful:

Here's a screen grab of the MIXER menu showing our single mix:

Mixers

 

Scenario 2: One source affects multiple channels

In this scenario, a single source drives more than one channel at the same time.

Example: the aileron stick driving left and right aileron channels.
Using the 'source->channel' notation we have:

To convert to mixer definitions we simply reverse each line:

Once in this form it can be entered directly in the mixer menu.

onetomany

Note: this is more flexible than using a Y-lead, as each channel can be adjusted independently for centre, rotation and travel.

Scenario 3: Multiple sources affect one channel

In this scenario, several sources drive a single channel.

Example: the flap channel on a sailplane may be driven by a combination of three controls:

Throttle stick (spoiler) )
LS (flap)) => right flap servo (CH4)
Aileron stick )


The interactions can be written as:

And the MIXER screen looks like this:

many to one

Note that this time all the inputs are assigned to the same channel. The '+' sign at the start of the 2nd and 3rd mixes shows that their contributions are additive.

Designing real mixing schemes!

The scenarios above illustrate the basic building blocks. Real models are more complicated, and will often combine several of the scenarios above. Consequently it's easy to get confused when designing a mixing scheme.

The solution is to break it down into simple steps. This is the procedure I've used for many years both on the Taranis and prior to that the Multiplex 4000 which employed a similar mixing model.

and finally:

As you become more experienced, you'll find that the logic is easy to assimilate and you'll be able to shortcut these steps.

Example: setup for a simple flying wing

We'll use a flying wing as an example. A flying wing has two elevons, each of which is driven by elevator and elevator commands. Elevator drives both surfaces in the same direction, aileron drives them in opposing directions.

Step 1. List the sources (control sticks)

The first step is to list all the control sticks required to fly the model. These will be the sources of the mixes:

Note that trims are included by default, so there is no need to list these separately. You can also ignore switches, flight modes etc.

Step 2. List servo channels

The second step is to assign servo channel numbers - let's use channels 1 and 2. We'll give them memorable names 'RtEvon' and 'LtEvon' (names are limited to 6 characters). These can be entered directly into the OUTPUTS menu:

Outputs

Step 3. Identify interactions

In this key step, we identify every possible interaction between sources and channels.

On our flying wing, the first source is the aileron stick (Ail). As it's displaced, both elevons must move. The interactions are therefore:

Same for the elevator stick (Ele):

It's important to model all the interactions in this step. Later you can selectively disable mixes according to a switch and/or flight mode.

Note that we're not interested in how the channels are affected, just the fact that the interactions exist.

Step 4: Convert interactions into mixer definitions

Next, swap the left and right sides of each interaction so that they read as "channel is affected by source".

Step 5: Reorder interactions by channel number

Re-order the mixer definitions so that they're grouped by channel (because mixer lines are ordered by channel in the Mixers menu).

Step 6: Enter definitions into the Mixers menu

Finally, enter the interactions from Step 5 into the Mixers menu:

mixers

The same design approach can be applied to very complex setups. If you're familiar with F3X sailplanes, you may wish to look at interactions and mixes for F3X sailplanes.

Note: while the mixing scheme produced by this method will work fine, more complex setups will invariably benefit from some optimisation using Inputs (described later in this article), GVARs and high mixes.

Setting mixer rates

So far we've said nothing about control surface movements. There are three menus where the adjustments influence the control surface movements - Mixers, Inputs and Outputs. For now, I'll just consider the mixers.

On our flying wing , the elevons must be more sensitive to roll commands than pitch. In other words, the aileron input must have a higher 'weight' than elevator. We'll set weight=90 for the aileron mixes and 30 for the elevator mixes.

Also, the elevons must move in opposite directions in response to roll commands, so for the second Ail mix, we make the weight negative.

MIXERS menu

CH1 (right elevon)

Src = 'Ail', weight=90%
Src = 'Ele', weight=30%

 

CH2 (left elevon)

Src = 'Ail', weight=-90%
Src = 'Ele, weight=30%

That's our basic setup completed. However, it can be improved.

Using Inputs (INPUTS menu)

Our flying wing will work fine. However, in order to adjust the aileron (or elevator) rate, we have to alter weight in two places, once in CH1 and once in CH2:

MIXERS menu

CH1 (right elevon)

Src = 'Ail', weight=90%
Src = 'Ele', weight=30%

 

CH2 (left elevon)

Src = 'Ail', weight=-90%
Src = 'Ele, weight=30

This kind of redundancy is undesirable. Fortunately we can get round this by using Inputs.

Inputs were introduced in OpenTx v. 2.0. Think of an Input as a source which has been pre-conditioned. Here's an example of an input based on the aileron stick, with weight 90% and 10% expo.

INPUTS menu

[I1]Ail

Src=Ail, wt=90%, expo=10%, trim=Yes

We'll see later how this can be applied to our flying wing example. First let's see how to create and manage inputs in more detail:

Managing inputs

Inputs are managed in the INPUTS menu. OpenTx provides 32 inputs. Each input has:

In order to do anything useful, an input must have at least one line containing src, weight etc. (Inputs can have more than one line, each dedicated to specific switch amd/or flight mode. However for this article I will only consider inputs with a single line.)

When you create a new model, OpenTx generates inputs for the main flight controls: [I1]Ail, [I2]Ele, [I3]Thr, [I4]Rud. However you can define your own inputs, and clear any which are not needed. The use of inputs is optional; just because they're available doesn't mean you have to use them - you can still use the raw stick as source where it's more appropriate.

Using inputs (flying wing example)

Let's modify our flying wing example to use inputs as mixer sources (instead of sticks).

The first task is to define a couple of inputs. Any inputs will do, let's use [I1] and [I2] .

The sources will the aileron and elevator sticks. We'll name the inputs 'Ail' and 'Ele'. Finally, we set appropriate values for weight and expo:

INPUTS menu

[I1]Ail

Src=Ail, wt=90%, expo=10%

 

[I2]Ele

Src=Ele, wt=30%, expo=15%

So now we can use [I1] and [I2] as sources in place of Ail and Ele.

Next, we'll need to modify the mixers so they reference [I1]Ail and [I2]Ele (instead of the raw stick sources). We also reset the mixer rates to 100%, since the rates are now specified in the inputs.

Here's the completed setup:

INPUTS menu

[I1]Ail

Src=Ail, wt=90%, expo=10%

 

[I2]Ele

Src=Ele, wt=30%, expo=15%

 

MIXERS menu

CH1 (right elevon)

Src = [I1], wt=100%
Src = [I2], wt=100%

 

CH2 (left elevon)

Src = [I1], wt=-100%
Src = [I2], wt=100%

Screen captures of the INPUTS, OUTPUTS and MIXERS:

inputs

channels

mixers

Note that elevator and aileron rates can be altered via a single parameter in the Inputs menu.

Choosing between Inputs and sticks

We've seen how the source of a mix can be specified as a preconditions Input (e.g. '[I1]Ail') or as a raw stick ('Ail') . So which to choose? A good rule of thumb is as follows:

It's a good idea to clear unused inputs so they don't clutter up the INPUTS screen.

Mixer and channel outputs

In this section we'll look in more detail how OpenTx converts stick movements into position commands. An understanding will help you debug issues with your setups.

OpenTx performs two stages of calculation, first at the level of the mixers, and then for the channel as a whole:

  1. First, OpenTx calculates the contribution from each mix
  2. Secondly, aggregates the effects of all the mixers for each channel

Let's look at each stage in detail:

Mixer output

For each mix, OpenTx calculates the mixer output according the weight (and other parameters we'll look at later). Taking our flying wing example, at any moment the mixer outputs are as follows:

Channel 1

mix_output_1 = Ail_stick_value x 90%

mix_output_2 = Ele_stick_value x 30%

 

Channel 2

mix_output_1 = Ail_stick_value x -90%

mix_output_2 = Ele_stick_value x 30%

Channel output

For each channel, OpenTx sums the mixer outputs. The result represents the commanded servo position:

ch1_output = (Ail_stick_val x 90%)+(Ele_stick_val x 30%)
ch2_output = (Ail_stick_val x -90%)+(Ele_stick_val x 30%)

Using our elevon example, we can see how the outputs vary with stick inputs. Recall that stick values vary between -100 and +100, with zero in the centre.
S T I C K S C H A N N E L S
Aileron Elevator CH1 CH2
(centre) 0  (centre) 0 0 0
(full  right) 100% (centre) 0 90+0=90 -90+0=-90
(full left) -100%  (centre) 0  -90+0=-90 90+0=90
(centre) 0 (full forward) 100% 0+30=30 0+30=30
(half right) 50% (half forward) 50%  45+15=60 -45+15=-30
(full  right) 100% (full forward) 100% 90+30=120 -90+30=-60

The last line shows the effect of "stick in the corner" - note the commanded position for CH1 is 120. OpenTx automatically clips servo commands to +/- 100, in order to keep servo travel within defined bounds. More on that later.

More about mixers

OpenTx offers a number of mechanisms for conditioning the output of a mix. We've looked at weight, however this is just the simplest example. Other parameters include offset, expo or diff, functions and curves.

Offsets

The offset parameter adds a positive or negative value after the weight has been applied. The governing equation is:

Output = (Source * weight) + Offset

In the following mixer line, the output varies from -80 to +120 as S1 is rotated.

Src = 'S1', wt=100%, offset=20

When you create a new mix, default are: weight=100% and offset=0 i.e. the source value is passed through unchanged.

Using offsets to bias Throttle and Spoiler

Offsets are commonly used for throttle and spoiler controls. These differ from the main flight controls because their 'idle' position corresponds to an end point of the control. This mix must therefore output zero (instead of +/-100) at one end point. We can achieve this by using offsets.

Example: motor-to-elevator compensation on an electric model.

The elevator channel in an electric mode will typically have two mixes:

MIXERS menu

CH2 (elevator)

Src=Ele, wt=100%, offset = 0

Src=Thr, wt=20%, offset=20

In this example, setting wt=offset=20% will vary the mix from 0 to 40 as the throttle is moved from the idle position. To reverse the range, we would change the sign of weight.

Note: offsets should be used sparingly! Never use them to make ad-hoc adjustments to your servo centres - use Subtrim for that.

Diff, expo, functions and curves

In addition to weight & offset, the mixer editor in OpenTx allows you to specify one additional option from the following:

The 'Curve' option provides the most granularity - it can implement all the other options, but requires the most data entry.

How to implement aileron diff

There are one or two gotchas to be aware of when implementing aileron diff

INPUTS menu

[I1]Ail

Src=Ail, wt=90%, expo=10, diff=0

 

[I2]Ail

Src=Ele, wt=30%, expo=15, diff=0

 

MIXERS menu

CH1 (right elevon)

Src = [I1], wt=100%, diff=20%
Src = [I2], wt=100%

 

CH2 (left elevon)

Src = [I1], wt=-100%, diff=20%
Src = [I2], wt=100%

In the above example you will see that we applied diff separately for each aileron mix, even though the INPUTS editor also offers a diff setting. This is because diff in inputs produces an asymmetric stick response. We want the servo response to be assymetric, so it diff must be specified at the channel level.

To summarise: specify diff separately for each aileron channel. Do not specify diff at the Input level.

[Note: to avoid having to enter the same diff value twice, use a GVAR.]

Including/excluding trims

By default, trim values are included in source values. You can exclude trims on a per-mixer basis. You do this by unchecking "Include Trim" in the mixer dialog.

For our flying wing example, both aileron and elevator trims must be active, so we'll use the default settings.

Order of processing

When calculating the output of a mix, OpenTx first applies source trims (if enabled for the mix). Then it applies the function (diff, function, curve, expo), followed by weight, and finally adds the offset. Order may be important when combining operators especially where offsets are involved.

Channel clipping

We've seen how the channel output is calculated as the sum of all these the mixer outputs:

CHxOutput = SUM (CHxMixerOutput1, CHxMixerOutput2, ...)

If a channel has several mixers active, then the sum of all the mixer outputs could potentially exceed safe limits. This might happen if you apply aggressive control inputs.

To avoid this, OpenTx limits channel values to +/- 100 before passing them to the Outputs. If the sum of the mixer outputs is outside the limits, the channel value is clipped. Clipping manifests itself as deadband at the transmitter control.

Example:

[Note: individual mixer outputs are not clipped, only channel values. Also, channel values are only clipped when possed to the Outputs layer, they not clipped when used as mixer sources.]

Channel scaling (OUTPUTS menu)

Outputs is the final stage in the processing pipeline. Outputs apply a scaling to the channel values, so that each servo (a) moves within defined limits, and (b) centres where you want.

Here's a screenshot of the Outputs menu:

outputs

The key fields are MIN, MAX and SUBTRIM, and CURVE

By setting appropriate end points, you can prevent damage to your linkages from excess servo movement.

Where to adjust weights

At any moment in time, each of the three processing layers (Inputs, Mixers, and Outputs) can be considered to apply a nominal rate to their inputs. These rates are applied cumulatively, so that the final servo command is the product of three rates:

OutputValue = SourceValue x Rateinput x Ratemix x Rateoutput

Clearly there is an infinite combination of rates which will produce the same movement at the servo. So how should you go about making the adjustments? Here's the procedure which I recommend:

  1. Start by calibrating your control surface movements in the OUTPUTS menu (setting up end points, centres and equalising movements). Calibration should be done with inputs and mixer weights at their defaults (100%), and all trims to centre. The aim is to define the widest possible operating range of your control surfaces consistent with left/right and up/down symmetry.
  2. Reduce control surface travel via INPUTS.
  3. Any remaining interactions can be adjusted in the MIXERS menu.

 

Slight more advanced...

Mixer operators: ADD, REPL, MULT

So far, we've assumed that mixer outputs are always added together in order to calculate the channel output.

In fact OpenTx is a good deal more flexible - it also permits multiplication and replace operations on mixer outputs. These can be extremely useful. For example, multiplication is key to implementing in-flight adjusters, and 'replace' can be used to implement throttle safety switches.

The mixer operation is specified in the mixer's MULTIPLEX parameter. The options are 'ADD' (the default), 'REPL' and 'MULT'. When calculating a channel value, OpenTx steps through the active mixers, starting with the first mix in the channel:

Note:

Example: The following mixer lines illustrate the effect of the various MULTIPLEX parameters and the importance of mixer order.

Src = I1, op=ADD

Src = I2, op=ADD

output = I1 + I2

Src = I1, op=ADD

Src = I2, op=ADD

Src = I3, op=MULT

output = (I1 + I2) * I3

Src = I1, op=ADD

Src = I2, op=MULT

Src = I3, op=ADD

output = (I1 * I2) + I3

Src = I1, op=ADD

Src = I2, op=MULT (disabled)

Src = I3, op=ADD

output = I1 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=ADD

output = I2 + I3

Src = I1, op=ADD

Src = I2, op=REPL

Src = I3, op=ADD

output = I2 + I3

Src = I1, op=ADD (disabled)

output = 0

The 'MAX' source

MAX is a special souce which doesn't correspond to a physical control. Instead, MAX supplies a fixed value of +100. In conjunction with weight, it can be used to simulate the effect of a fixed stick position.

Src = MAX, wt =100 -- output = 100%

Src = MAX, wt=50 -- output = 50%

Src = MAX, wt=-100 -- output = -100%

Here's a simple example, showing a crude motor arming system using switch SA. The MAX line is always active, and provides a fixed value of -100 corresponding to motor off. The Thr line is active when SA is down. When active, it over-rides the previous line ('multiplex=REPLACE'), providing variable motor control via the throttle stick.

MIXERS menu

CH7 (motor)

Src = MAX, wt=-100%

Src = Thr, wt=100%, switch=SA-DOWN, multiplex = REPL

Links

LapinFou has produced some useful data flow diagrams which describe the internal workings of OpenTx (Note: at the time of writing, there are one or two errors in the order of processing of curves).