An idea for AP_Tuning library for transmitter tuning

I’ve recently been thinking about how to improve transmitter based tuning for both copter and quadplane. The quadplane code now supports similar transmitter tuning to copter, which uses TUNE_CHAN, TUNE_PARM, TUNE_LOW and TUNE_HIGH to control tuning of a single parameter.
It works, but it really is quite tedious and is also quite error prone. If when changing parameters you get the range wrong it can be disastrous.
What I’d like to do is have a much faster and less error prone transmitter tuning interface that allows a pilot to tune multiple parameters in one flight.

What I have come up with so far is a method that relies on the user using two switches on their transmitter. One switch would need to be a 3 position switch, and the other a 2 position switch. The ideal setup would be for the 2 position switch to be spring loaded (like a typical trainer switch).

The parameters to control tuning would be:

  • TUNE_CHAN1: the 3 position switch channel
  • TUNE_CHAN2: the 2 position switch channel
  • TUNE_PARMSET: the set of parameters to be tuned
  • TUNE_CHANGE: the rate at which the parameter changes (default 1.1 for 10% changes)

The TUNE_PARMSET chooses a set of parameters to tune. While tuning the user can cycle between the individual parameters within the set. TUNE_PARMSET would be an enum, with typical parameter sets for “roll and pitch rate tuning” which would be 4 parameters (RATE_RLL_D, RATE_RLL_PI, RATE_PIT_D, RATE_PIT_PI).

When the TUNE_CHAN1 switch is in the middle position then briefly raising TUNE_CHAN2 would cycle to the next parameter to be tuned in the param set. So if you are currently tuning RATE_RLL_D and you cycle to the next one then you’ll start tuning RATE_RLL_PI. Using a spring loaded switch for TUNE_CHAN2 would make this particularly easy. If you cycle past the end of the list then it goes back to the beginning of the list.

When TUNE_CHAN1 is in the lower position you would be lowering the current tuning parameter. Pulling on TUNE_CHAN2 in that case would lower the current parameter by a factor of TUNE_CHANGE (10% by default).

When TUNE_CHAN1 is in the upper position you would be raising the current tuning parameter. Pulling on TUNE_CHAN2 in that case would raise the current parameter by a factor of TUNE_CHANGE (10% by default).

A “long pull” on TUNE_CHAN2 (defined as more than 3 seconds) would save the current parameter value. That gives a way to save without mucking about in the GCS.

So the process for tuning a multicopter or quadplane would be:

  • set the parameter set to what you want to tune (eg. roll and pitch gains)
  • takeoff with TUNE_CHAN1 in the middle position
  • switch TUNE_CHAN1 to the upper position
  • pull on TUNE_CHAN2 a few times. Each pull will raise that parameter by 10%
  • when the vehicle starts to oscillate then switch TUNE_CHAN1 to the lower position and do 4 quick pulls on TUNE_CHAN2 to lower the gain by around 50%
  • if you are happy with the new value for that parameter then save by pulling on TUNE_CHAN2 for 3 seconds
  • switch TUNE_CHAN1 to the middle position and pull on TUNE_CHAN2 to change to the next parameter in the set
  • continuing tuning with the next parameter

I envisage implementing this as an AP_Tuning library with callbacks for setting the parameters, and a static const table of parameter sets passed into the constructor.

Comments welcome!

I also think we’d have a TUNING_REPORT MAVLink message so the GCS could report which parameter you are tuning, what the current value is, when you’ve saved etc. The GCS could announce these with text to speech

With regards to the TUNING_REPORT message isn’t this essentially covered? Saving a param on the aircraft should emit a param message to the GCS, which updates the value on the GCS, and it’s fairly easy for the GCS to sort if that was a live tuning parameter or not? A TUNING_REPORT message would have the added benefit of ease of implementation on the GCS, but I don’t think it would add a fundamentally new capability?

the main purpose of TUNING_REPORT is so the GCS can announce which parameter you have started tuning. So when you cycle through them you can stop at the one you want without having to actually change a value

Ah, that’s true I hadn’t considered that aspect.

I admit I find that description incredibly complicated as an approach to tuning. I’ve worked briefly with an autopilot (ruby) that did commands like that via a RC system, and it was just incredibly complicated with a low confidence value on the users side that they were issuing the commands they thought they were. However, nothing forces you to use it, and someone with a GCS could continue to use that to tune better then they can now so I don’t have any fundamental objections. It just ties a lot of behavior onto several surfaces, and seems to me that it is rather difficult to quickly revert a undesired change, but I’m not the target for this type of tuning,

To use this safely there would need to be some limiting factors, IE don’t allow some to tune past a recommended default value either direction, and if they need a value outside the range they should do it with a GCS. Also TUNE_CHANGE should probably be 0.1 for a 10% change. The TUNE_CHAN1 position is supposed to indicate the direction, so you are just adding or subtracting 10% of the current value (not just multiplying). How would handling values that reach 0 be done? IE with the proposed solution I don’t see anyway to change a value off of 0 once it hits it? It might make more sense for TUNE_CHANGE to be a percentage of the recommended step size, that way you have a decent level of granularity through out the range, as well avoiding the problems around 0.

The target is people who want to tune a multicopter by themselves. To do that with the GCS requires you to takeoff, test, land, adjust and takeoff again. It can mean dozens of takeoffs for one parameter. I think this is one of the reasons so many people just fly the defaults.
For fixed wing autotune is easy, but now we have quadplanes it has become hard, and the copter autotune mode doesn’t work well on quadplanes (as it takes far too long for the limited battery sizes of typical quadplanes).
I don’t think adjustment by a fixed value will work (ie. based on recommended step size) as the range of the copter params is huge. A value value for a D term can cover a massive range, but the value can also be very sensitive. So a change by a percentage seems to make more sense.

Although I understand the concerns from Michael, I like the proposal. But I still have one doubt: does the percentage increase is always relative to the saved value or is it relative to the last value? An example:

  • we start with a value 0.09 and the TUNE_CHANGE is set to 10%
  • then we increase the value, so the value is now 0.099
  • if we increase again will the value be 0.108 or 0.1089?
  • if instead of the previous increase we had decreased would we be back at 0.09 or at 0.0891?

@OXINARF, it would be relative to the current value, not the saved value.
So if you increase 3 times and then decrease 3 times you would be back to where you started.

So, in the 10% example, when increasing you multiply the current value by 1.10 and when decreasing you divide by 1.10? I’m only asking because that means that when decreasing you aren’t reducing 10%.

that’s right, it divides when reducing to make it symmetric.
I don’t think it not being exactly 10% really matters, as this sort of tuning is never precise. I do like being able to get back to where you were though.

I like that too, that’s why I was asking if it was relative to the saved value. I also don’t think it matters, as long as the documents explain it.

I agree with Michael’s comments above that it sounds very complicated and is thus unlikely to be adopted by many people. Wouldn’t it be better to improve the tuning interface in the ground stations? I know that’s slightly out of the control of the people in this group but I think it would lead to a better user experience for a far wider range of users.

For example, we’ve had a lot of users ask that we improve the autotune feature so that it does position hold in between twitches. Also we could improve the interface (in hand with the GCS developers) to allows easier triggering of a single axis tune (i.e. roll, pitch or yaw) instead of the current method which involves setting parameters before the flight starts.

In a general sense, I think we’ve pretty much reached the limit of what our primitive transmitter interface allows and it’s really a better GCS interface that will allow us to add more features without making the system too complicated.

The problem with GCS tuning is you can’t do it while flying with a transmitter, plus it is hard to react quickly enough to an oscillation when using a GCS.
The problem with autotune for quadplanes isn’t just that it drifts, it is also that it takes far too long. A quadplane will typically only have enough battery for a very short flight in VTOL mode. Even doing just one axis is unlikely to complete before you run out of battery.
It is also not at all clear that the autotune algorithm can cope properly with quadplanes, or even with very large quadcopters.
I agree that improving autotune would be nice, but I don’t think it can replace the need for good transmitter based tuning on all aircraft.
As far as the complexity is concerned, the proposal should actually be much simpler to use than the current transmitter based tuning if you want to tune all of the key parameters. You would have to be a very careful user to get all the parameter changes right, and if you get them wrong then you can crash due to a very bad parameter value.

Hello
friends

I 'm
Felipe Viveiros from Brazil
I study computer engineering at PUC Campinas University
In my
course competition assignment ,
'm build- a quad with pixhawk and the drone fly auto (no radio control)
the destination chosen by the User from a smart phone android,
with an application developed by me .
I need to choose a sonar, the sonar will be necessary if you have any obstacle
in the way,
my doubt is, what the best sonar ?
which has cost-benefit relationship ?
I will implement the algorithm in the best way.
I accept suggestions from other forum for developers
tanks my friends

I’m with Michael and Randy. I don’t see anything technically wrong with the proposal, but I find it complicated and I think human factors/ergonomically it’s not ideal. I have professional experience in this area doing machine control design. Retrofitting machinery which historically had used potentiometers for settings, with touchscreens, pushbuttons for up/down do not work, as they simultaneously are too coarse for small changes, while being too slow for fast changes. Operators hated it, and it was rejected. Eventually the pots were replaced with digital encoder knobs.

And it’s the same thing with cars. Every time push-buttons (whether physical or touchscreen) have been attempted for controls such as AC temperature, radio volume, etc. they have been a failure.

I very much prefer using the tuning knob, and would prefer to see it expanded to allow for 3 knobs for 3 parameters. I had started this work a year ago but it never got adopted…

I also agree, that a better GUI interface would be good. One page, with the most commonly used tuning parameters all listed, so the ranges can be pre-set. Then the user can chose between param targets very quickly without also have to change the parameter range.

One thing Michael, we cannot lock the param ranges to the specified ranges. There are quite a few specified ranges for multicopter that are totally unsuitable for helicopters, and it’s annoying enough already to have to force the change in the Full Parameter List every time I change them. (using the standard parameter list, it won’t even let you!).

I’ve thought about this a bit more and I think I’ve come up with an interface that addresses the concerns raised above.
First though I’ll explain what I’m trying to achieve and why.

  • I think we need transmitter tuning as autotune for copter doesn’t work for all vehicles, doesn’t work for helis, doesn’t work for quadplanes and doesn’t allow for a user controlled fine adjustment of tuning
  • the existing transmitter tuning for copter (see http://ardupilot.org/copter/docs/ac_rollpitchtuning.html#ac-rollpitchtuning-in-flight-tuning) is really not good. You can only tune one param per flight, it is very easy to get the range wrong (eg. move a decimal point on a D term) and the save method is downright strange
    What I think we need is a transmitter tune with these properties:
  • able to tune multiple params per flight
  • remove the need for the user to specify the high/low values for each parameter
  • ability to save the tune easily
  • ability to have fine control of tuning
  • ability to quickly move to a lower value when instability occurs
    The new scheme works like this:
  • it uses two input channels, one is a tuning knob, the other a selector switch (two position switch)
  • for discussion imagine you are using a taranis with the tuning knob on the right slider and the selector switch on the spring loaded training switch just below that slider
  • the role of the selector switch is to change which param you are tuning, to re-center the value being tuned and to save the params
  • the role of the tuning knob is to raise or lower the tuning value

when tuning a parameter the tuning knob acts like this:

  • raising the tuning knob raises the parameter
  • lowering the tuning knob lowers the parameter
  • the mid-point of the knob gives you the value you had at the start of tuning this parameter
  • the top of the knob range gives you 2x the parameter value
  • the bottom of the knob range gives you 0.5x the parameter value
  • the tuning knob only activates when you move it past the mid-point. So if the knob starts fully up then it does nothing until you move it to the mid-point
  • when the tuning knob activates the vehicle will beep once to let you know you are starting tuning

the selector switch works like this:

  • a short pull on the selector switch (going high for less than 2 seconds) will re-center the parameter value being tuned and also put the knob back in the state that it is waiting for the knob to go to the mid-point
  • when you re-center with a short pull you’ll get a distinctive beep from the vehicle to let you know you’ve done it (a single low pitch beep perhaps?)
  • a longer pull on the selector switch (over 2 seconds) will move to the next parameter from the set of parameters being tuned. You’ll get a double beep from the vehicle to let you know you’ve changed parameter
  • when you change parameter the tuning knob will go back to waiting for mid-value
  • a really long pull on the selector switch (over 4 seconds) will save the current parameters for all parameters in the set being tuned. A triple beep from the vehicle will let you know you’ve done the save
  • changing flight mode will undo the current tuning change, taking you back to where you started

The parameters would be:

  • TUNE_PARMSET the set of parameters being tuned (enum with common parameter sets to tune)
  • TUNE_RANGE the multiplier for the tuning knob. Default value 2.0. Use this to allow for fine or course tuning
  • TUNE_SELECTOR the input channel for the selector switch
  • TUNE_KNOB the input channel for the tuning knob

implementation is here:
https://github.com/tridge/ardupilot/tree/tuning-wip/libraries/AP_Tuning

plane specific code is here:
https://github.com/tridge/ardupilot/blob/tuning-wip/ArduPlane/tuning.h
https://github.com/tridge/ardupilot/blob/tuning-wip/ArduPlane/tuning.cpp

and here is the implementation for Copter:

I tested this today on a copter and two quadplanes. It works very nicely! Extremely easy to do a complete tune

Regarding this:
https://github.com/tridge/ardupilot/blob/tuning-wip/libraries/AP_Tuning/AP_Tuning.cpp#L44

Isn’t it redundant, considering that the RC_channels already have been “calibrated”

https://github.com/ArduPilot/ardupilot/blob/master/libraries/RC_Channel/RC_Channel.cpp

Then further down, you’re considering pre-determined PWM values that might be off if the radio is not correctly calibrated

https://github.com/tridge/ardupilot/blob/tuning-wip/libraries/AP_Tuning/AP_Tuning.cpp#L66