On my small and light foam planes I like the stability offered in ACRO mode with ACRO_LOCKING=2 (and therefore YAW_RATE_ENABLE=1), especially when it is windy/gusty.
However, even though I am not bad at it I am not a real big fan of the ‘must coordinate perfectly to turn perfectly’ property of YAW_RATE_ENABLE=1. It feels a bit too different from manual mode and ACRO_LOCKING=0.
I don’t know how exactly yet, but I am sure it is possible to calculate the yaw rate required given bank angle, airspeed, etc. (Radius of turn formula is probably a good start)
I would like to play around a bit with this in SITL/Realflight using lua to calculate a yaw rate and adding it to the RC-commanded yaw rate. Sort of what happens in auto modes when STICK_MIXING is enabled. Is this possible?
I scanned through the the sport_aerobatics.lua script script and tried vehicle:set_target_throttle_rate_rpy in ACRO mode, but without success yet.
I don’t use Plane very often, but I am very familiar with fixed wing flight dynamics.
For a constant bank, coordinated, steady turn, zero rudder is required. Rudder to coordinate a turn is really only required to counteract adverse yaw during roll-in and roll-out, and the amount is a function of individual aircraft flight characteristics.
Traditional RC stick mixing between aileron and rudder is a “cheat” to help coordinate roll inputs, and the proper amount is usually achieved experimentally by increasing the rudder proportion until roll inputs are generally coordinated.
We usually discourage transmitter control mixing with ArduPilot, however in this case, perhaps you could enable an optional (switched) aileron/rudder mix on your transmitter for use in this mode. It would be far simpler than trying to script a yaw rate controller or a brute-force mixer via Lua.
You can’t really guess needed yaw rate for acro as it doesn’t know if you are doing horizontal 30° roll turn or 30° inclined turn with 60° effective roll.
Yes, it assumes an otherwise well trimmed condition, but it is true regardless of aileron “symmetry.”
A proportional mixer potentially assumes symmetric adverse yaw (in both left and right roll directions), depending on exactly how the mixer is implemented.
Earth frame yaw rate is also very deterministic for coordinated control at any attitude. The vehicle frame yaw angle target is simply zero, and vehicle frame yaw rate should be near zero throughout (ideally exactly zero). What you can’t guess is pilot intent when doing uncoordinated aerobatics, but that is beyond the scope here.
You CAN guess at the proportion of rudder input required for a given amount of aileron input to achieve a coordinated turn. But it’s always just a guess when using a proportional “dumb” mix. And such a mixer could be very counterproductive for an accomplished aerobatic pilot. But for someone simply having a little fun in ACRO mode, I suppose it might be ok (applying mixed rudder during roll input and then relying on attitude locking and yaw rate control once the sticks are released).
Unless there’s a detriment that I’m missing, I stand by my assertion that a transmitter selectable “old school” rudder mix is a reasonable solution here.
I don’t think I was able to communicate my question properly.
Here are two quick and very dirty videos where I used the same controls in the same order.
ACRO_LOCKING=0, YAW_RATE_ENABLE=0:
ACRO_LOCKING=2, YAW_RATE_ENABLE=1
Please don’t judge the flying and start of the second video due to improper reset. The videos serve to illustrate ACRO_LOCKING=0 vs ACRO_LOCKING=2 and I was more concerned about giving the desired inputs and juggling the recording.
Realflight was used as virtual plane, Mission Planner builtin simulation using the flightaxis target was used to control that virtual plane, my regular TX was used to fly in ACRO mode and I used Config->Full Parameter List in Mission Planner to change the parameters while the simulation was running.
In the first video I get airborne, bank the plane, and use pitch to make a ‘looping on its side’ to turn the plane. No rudder was used.
In the second video I do the same. Notice that pitch now actually means ‘rotate the vehicle in the pitch plane / around the roll axis’.
This is communicated in the documentation (ACRO Mode — Plane documentation) in the note at the bottom of the page. Thus, to make a clean turn enough yaw has to be fed in to make the tail follow cleanly. This is different from flying using ACRO_LOCKING=0 or manual mode.
It is also easy to see why mixes in the transmitter won’t work for ACRO_LOCKING=2. When we add a bit of roll to yaw the tails swings around a bit when banking, but then it is heading-hold once bank angle is reached.
Then why use ACRO_LOCKING=2? Because it makes a small foam plane ridiculously stable in autumn weather. There is no/way less yawing or wings being kicked up by the wind. But it does fly very different and I think I can compensate for that using some lua trickery by generating the required yaw rate and adding it to the RC commanded yaw rate.
Stick mixing works well in manual mode and non-locked acro mode to push the tail slightly into the turn.
For the quaternion based locking a constant nonzero yaw input is required throughout the turn. With simple stick mixing this would also require constant nonzero roll input.
[edit]
Ah, OK.
Not sure whether it is easy or not. Sometimes I like to play around a little. Try something, see where it ends. It may not work out as expected, but usually I learn a lot from those small experiments.
But for this one I must add a bit of yaw rate to the RC input to accomplish that. ‘stick mixing’.
I can probably use an unused RC channel for yaw, read it in lua, do whatever I need to do, and override the yaw channel with the modified value. Or the other way around, probably easier with Realflight. But that is quite crude and depends a lot on lua execution consistency
[/edit]
Oh, by the way, I know ACRO_LOCKING=1 also exists. But I never had good results with that one. Or at least, not significantly better than with ACRO_LOCKING=0
I don’t really like this script much, but it’s basically what you asked for (an RC yaw override proportional to bank angle).
I think you’ll probably find that there’s a better way to get what you want than this, but I was curious if it would even have a prayer of working. It behaves ok in SITL. Highly recommend you test it there before flying it. I only spent about 15 minutes on it, and there’s a good chance I goofed something up.
Adjust MIX_RATIO in the script to something that feels right. I have a feeling that 10% is probably a bit light.
Yes, I could do some additional speed/bank angle math to calculate the percentage of max yaw rate required for a level turn. But that (just like the attached method) would get increasingly weird as pitch deviates from level. It’d take some more refinement to account for pitch angle. A rough approximation would decrease the yaw rate by the ratio of actual pitch angle to 90 degrees, such that we’d stop yawing at a pure vertical climb or dive. My apologies, but I don’t find this use case compelling enough to do all the mental gymnastics.
Wow, even a script attached. Now that is Helping with a capital ‘H’, thanks!
I tried the script in SITL and indeed it feels weird in any other attitude than a level turn. But I never expected it to be that simple.
However, this script just overrides the RC input. I would like to have ‘yaw_rate_setpoint = rc_input_yawrate + lua_generated_yawrate’ instead of ‘yaw_rate_setpoint = override_input when input_is_overridden==true else rc_input’.
One really crude way to accomplish this would probably be:
Relocate rc yaw channel to an unused one (e.g. RCMAP_YAW=10)
in lua, read in the rc-link yaw channel (e.g. channel 4), do math, override the ‘dummy’ channel, thus effectively making ch10 = ch4 + x
But that is a bit too crude, even for me. Is there a cleaner method to accomplish yaw_rate_setpoint = rc_input_yawrate + lua_generated_yawrate?
@DaBit
If I understand you correctly, you prefer non-acrobatic flying in acro mode because it stabilises the aircraft’s attitude better in sudden gusts of wind than FBWA or manual mode does ?
That’s an interesting observation. I can imagine that, but I haven’t flown it myself yet. I have set up the acro mode on aircraft for aerobatics, but I don’t do aerobatics in gusty weather. As soon as the weather improves here, I would like to fly a wind-sensitive light motor glider in gusty weather in Acromode.
If I understand correctly, you want to fly coordinated turns in acromode with YAW_RATE_ENABLE set to 1.
Then why don’t you set acrolocking to 1 and YAW_RATE_ENABLE to 0? Then you’ll be able to fly curves properly in acro mode without having to use the rudder.
When YAW_RATE_ENABLE is set to 1, the aircraft “only” rolls when the aileron is applied, but the longitudinal axis remains unchanged (as long as it is aerodynamically capable of doing so e.g., knife-edge flight) . It continues to fly straight ahead. This is precisely the desired feature. However, you want to revert the control system to how it behaves with YAW_RATE_ENABLE = 0.
Thank you, Rolf. I suspected there was a set of parameters that would approximate the desired control scheme without the janky mixing, but I’m not very familiar with ACRO mode for Plane.
I don’t like the behaviour of ACRO_LOCKING=1. It works fine until a gust of side wind hits the wings or a quick manouver overloads some internal logic. Then it produces a wonky attitude change. It is not unusable but a bit unpredictable and not really an improvement from ACRO_LOCKING=0 or even just manual.
ACRO_LOCKING=2 however, works really, really well. We have a line of trees at the field that produce a lot of turbulence when it is windy. I flew my sub-1 meter wingspan, sub-1kg foam plane today in that turbulence and gusty bft 3-4 wind and still had fun. I would not have had much fun in manual mode today.
(and indeed; straight line stabilisation during takeoff and landing seems better in ACRO_LOCKING=2/YAW_RATE_ENABLE=1 than FBWA mode).
Also, it is not about aerobatic or non-aerobatic flying. It is about making ACRO_LOCKING=2 feel more like ACRO_LOCKING=0/1 while retaining the excellent attitude holding when no attitude change is commanded.
And although it is not very necessary (it took a bit of getting used to but nowadays I have no issues flying ACRO_LOCKING=2/YAW_RATE_ENABLE=1, until I change rates) I had a little nagging voice in the back of my head talking ‘well, we only need to inject a bit of yaw derived from current attitude, airspeed and RC demand to emulate the normal unstabilised plane behaviour. Should be possible…’. I am quite sure you guys are familiar with those nagging voices.
Not really, the issue is that inferring yaw and pitch (because plane rolled 45° to turn will need pitch rate too to maintain altitude) rate from your current attitude and ailerons input is very complex problem that requires a lot of assumptions.
In my experience Ardupilot handles turbulence pretty well even in FBWA and above though I use bigger planes.
PS work probably should be focused on improving stabilization in FBWA and above if there are issues.
I race quads, fly fast and small FPV planes and since a few months I am dabbling around with line of sight flying. Currently I am using an F803 Skylark for that. Small planes are cheaper to (re)build, easier to transport, easier to fly in places where you want to stay a bit below the radar, and Arduplane extends the point where flying becomes fighting quite a bit. Features like the geofence (teach yourself tricky stuff, introduce others to RC planes), RTL for panic and autoland for electronics issues are a huge bonus too. I am grateful for what you guys accomplished.
By the way; I got that Skylark initially to hit gaps in knife-edge using FPV because I thought it would be fun (it is!) and because it was cheap (not all gaps cooperate well). My usual go-to FPV plane (AtomRC Penguin) cannot sustain a knife-edge.
There are no issues with FBWA. FBWA works fine. Yaw stabilisation of ACRO_LOCKING=2/YAW_RATE_ENABLE=1 (with a fairly agressive tune) feels slightly better, but I would have to analyse logs to prove it is objectively better. It is not important anyway; if I need stabilised straight line stability beyond a little nudge with the rudder to compensate for side wind I can use CRUISE mode.
Too bad the original idea cannot be done. Oh well..
I do have another purpose for ‘lua script commanding attitude change in acro mode on top of remote control’: slowly levelling out the wings at 0.5 deg/sec or so when they are just off level in a straight section sounds like something I would like. An ‘artifical dihedral’ that is only active when roll angle is between, say, -2/2 degrees. Or maybe this is just another one of my stupid ideas.
(an adjustable mixer like Betaflight provides would be a nice feature to have in Ardupilot, especially when there is also one for the inputs. One can dream…)
I am curious to see for myself how different ACRO_LOCKING 1 and 2 feel. I have therefore prepared a LUA script so that you can choose between four options on a light foam aircraft (Skywalker Mini Plus) using the 6-pos potentiometer on the MX16s before activating ACRO mode:
a) YAW_RATE_ENABLE=0 and ACRO_LOCKING = 0
a) YAW_RATE_ENABLE=0 and ACRO_LOCKING = 1
b) YAW_RATE_ENABLE=1 and ACRO_LOCKING = 1
c) YAW_RATE_ENABLE=1 and ACRO_LOCKING = 2
As soon as the weather is suitable, I want to do some test flights and will report back.
This is not surprising, as FBWA primarily stabilizes pitch and roll, not heading.
It is possible to stabilize the heading during takeoff and landing even in FBWA: Ground Steering: Tuning Ground Steering for a Plane — Plane documentation
This keeps the heading very stable. I have activated it on some aircraft with landing gear.
I am using a similar script to switch between ACRO_LOCKING=0 and 2. I will attach my quick&dirty solution (that works fine) here for reference.
Last time I checked ground steering requires a compass which my small planes lack. Not sure if it would work with the GSF nowadays?
However, YAW_RATE_ENABLE=1 also stabilises well when the tail wheel is connected to the rudder.
ACRO mode makes takeoff a very smooth process anyway. The natural pose of the plane when standing still on it’s three wheels is with the tail slightly down. ACRO keeps it that way during the ‘ground contact’ phase of takeoff and the natural tail slightly down/nose slightly up attitude causes a nice slow lift up in the sky when airspeed is high enough. Feels very natural. Yaw stabilisation keeps the line quite straight, even on our bumpy runway with the very small wheels.
FBWA is far less smooth, at least with me on the sticks. When airspeed rises FBWA tends to level out the plane and that is when bumps tend to throw the plane off course. Which is the point where you either cut the throttle, watch it flip over on it’s nose when the wheels bite in a ditch somewhere outside the designated runway, and walk to the plane for the second try. Or you give it full throttle and up elevator making the takeoff rather ‘digital’.
Sure, ground steering would help, a tiny bit of up during takeoff would help, so it comes down to pilot skills and not fundamental flaws in FBWA mode. But I prefer ACRO mode.
-- BvH: change acro mode according to switch input.
--
-- If Scripting1 RC channel is HIGH, ACRO_LOCKING is set to 2
-- and YAW_RATE_ENABLE is turned on
--
-- If Scripting1 RC channel is LOW, ACRO_LOCKING is set to 0
-- and YAW_RATE_ENABLE is turned off
--
-- find RC channel with RCx_OPTION=Scripting1. This will be used for switching
local scripting_rc_1 = rc:find_channel_for_option(300)
-- create parameter objects
local ACRO_LOCKING = Parameter()
ACRO_LOCKING:init('ACRO_LOCKING')
local YAW_RATE_ENABLE = Parameter()
YAW_RATE_ENABLE:init('YAW_RATE_ENABLE')
local acro_locking_state = ACRO_LOCKING:get()
function check_acro ()
if scripting_rc_1 then
local sw_pos = scripting_rc_1:get_aux_switch_pos()
if (sw_pos ~= 0 and acro_locking_state ~= 2) then
gcs:send_text(6, "(BvH) Change to ACRO_LOCKING=2")
acro_locking_state = 2
ACRO_LOCKING:set(2)
YAW_RATE_ENABLE:set(1)
elseif (sw_pos == 0 and acro_locking_state == 2) then
gcs:send_text(6, "(BvH) Change to ACRO_LOCKING=0")
acro_locking_state = 0
ACRO_LOCKING:set(0)
YAW_RATE_ENABLE:set(0)
end
end
end
function protected_wrapper()
local success, err = pcall(check_acro)
if not success then
gcs:send_text(2, "Internal Error: " .. err)
-- when we fault we run the update function again after 1s, slowing it
-- down a bit so we don't flood the console with errors
return protected_wrapper, 2000
end
return protected_wrapper, 500
end
-- start running update loop
return protected_wrapper()