Limiting error between attitude controller target (ghost) and aircraft attitude in Trad Heli

Prior to AC 3.4, the attitude controller target was limited in how far it could get away from the actual aircraft attitude. The current implementation of the attitude controller has no limit to how far the target can be from the actual aircraft attitude in pitch and roll. There is an angle error limit in the yaw axis that is dictated by the max yaw axis controller acceleration and the angle P gain. This effectively limits the rate that the attitude controller can command to null the angle error. This is an accepted implementation because it is well known that tailrotor effectiveness or blowouts can cause uncommanded yaw motion. But it is my understanding from @Leonardthall that limiting the angle error in pitch and roll is not acceptable in the attitude controller design. This was discussed at length in unusual swashplate behavior discussion post.
In my opinion, I believe that this ghost limit is needed in flight because it doesn’t allow the ghost to run away in situations of uncontrolled flight, whatever the reason, when the pilot is trying to regain control. It keeps the ghost relatively close so when control is regained the ghost can resume tracking the desired attitude. I think this is significantly more important when the aircraft is being externally piloted because at that point the pilot is flying the aircraft by sight and expecting his commands to be followed by the controller. I know there are several other trad heli users that agree with the idea of limiting the angle error between the ghost and the actual aircraft attitude.
I think the angle error at which it is limited should not be dictated to 10 deg but I like the implementation used for the yaw angle error limit which is based on the max rate that the attitude controller is allowed to command. I had worked on implementing an angle error limit in pitch and roll about 6 month ago. It uses a fixed angle error limit defined by a parameter which I would recommend changing. I learned some about quaternions but am no expert. I was able to come up with a workable solution that showed normal aircraft response conducting aerobatics in the SITL and demonstrated that you could drag the ghost around by arming the aircraft with the ESC disconnected and then pitching and rolling the aircraft. My implementation can be found in this commit on my fork of ardupilot.

Any suggestions to improve my implementation are appreciated. I would like to PR this change once it discussed, modified as needed and accepted.

1 Like

I also like limiting the angle error, particularly as I want to move to a quaternion controller in plane acro mode in the future as well.
My preference would be to limit it in the quaternion, not in the eulers. I can try to create a version of this patch that works on the quaternion if there is interest.
Cheers, Tridge

What are the limitations of the EKF in a situation where the ghost would be in a runaway? Or to maybe rephrase that question, which is the weaker link in the chain?

Not that having an angle error limit would be a bad thing. Just wondering what the practical situation would be (other than ground checks and possibly ground to air transition) where it could make a difference. I think of the one situation I had where I was flying an Auto flight and I lost the tail servo. It was in a hard left turn when the servo failed. The autopilot totally lost control of the helicopter. The EKF was blown at the point where I switched to manual control, got it back and autorotated it to arrest the high-speed yaw. If the EKF estimator is off by ~60 degrees in roll and ~20 degrees in pitch, which it was in that case when it suddenly yawed in dynamic flight and flipped over, where the ghost is didn’t make any difference. The reason the autopilot lost control of the helicopter is because the EKF failed when it assumed a yaw rate of 400+ degrees/sec and tumbled in a high speed turn.

So my point is, if the part of the attitude controller that determines what desired attitude is fails in a situation where the ghost can (maybe) run away, whether or not the ghost is tracking desired at that point is moot.

It isn’t related to the EKF. There are really only two potential issues:

  • if the target attitude gets so far from the current attitude that you get control reversal. This happens as the attitude controller will look for the shortest path to achieve the desired attitude. So if it gets far enough ahead in roll then when it passes the 180 degree mark it decides to roll the other way, and the pilot sees control reversal
  • the pilot expects the vehicle to stop its rotation when the sticks are released, but it actually keeps going for a while until it reaches the target. This can be avoided by forcing target attitude to current attitude when sticks are zeroed (the controller may already be doing this).

I tried hard to produce either of these effects in flight on the Raptor720 in realflight8 this morning and I wasn’t able to, even when I switched the rotor off to give lower control authority, and I turned up all the relevant rates to maximum.
It obviously can happen on the ground, but I have yet to find any way to make it happen when flying.
Cheers, Triidge

Interesting. Isn’t the EKF what determines aircraft attitude? When I played back the tlog from my tail servo failure I noticed the attitude indicator in the ground station showed the heli in a ~45 degree left roll after I got it landed. Over a period of about 5-10 seconds after landing the AI gradually returned to level and the red bars on the EKF monitor went back to green. I was still able to control the helicopter, just that the stick inputs were not normal. I had to hold almost full left aileron to make it come down level in autorotation (Stabilize flight mode). Otherwise it wanted flip over to the right.

I realize we’re talking about two different things in acro vs stabilize. But I assumed the same EKF state estimator is used for both flight modes.

yes, but it’s a separate issue from the target chasing. Clearly the EKF did have a problem maintaining attitude state correctly, and if you post the DF log we could try to work out why that was, but that is a separate issue from the one we’re discussing.
The most common reasons for EKF attitude error is clipping of IMU data (accel/gyro) or aliasing.

I don’t claim to be an expert or even proficient with quaternions but I have spent a lot of time trying to understand the attitude controller. The angle error is determined as difference in Euler angles. This error is determined in the thrust_heading_rotation_angles routine. If you look at that code you will see that an angle limit was already there for the yaw axis. It was easy to just follow the same logic in limiting pitch and roll.
Were you planning to apply on limit to all three axes or break out pitch and roll and use one limit on them and another limit on yaw. From what I can tell you would have to determine the rotation from the target to the actual aircraft attitude and then limit beyond a certain rotation. I guess you could make it simpler by staying in the quaternions but it has to be done in the correct part of the attitude controller which is what I learned the hard way.
I will definitely be interested to see how it’s done with just quaternions. I know that I’m just scratching the surface. :grimacing:

Yes, and that’s the reason the EKF blew when my tail servo failed. The resultant spin and tumble caused severe spikes in the x and y axis vibrations that aliased the IMU’s and it lost attitude control.

What I’m trying to figure out is how anybody can generate a real-world log showing the ghost error to be huge that @Leonardthall wanted to look at. Bill suggested it could happen in an out of control situation where the pilot is trying to regain control. That is what I had happen, even though it was in a different flight mode.

The part I don’t understand is:

  1. we need to limit the ghost error from the current attitude
  2. current attitude is determined by the EKF state estimator in all flight modes
  3. the ghost will be limited to say 10 degrees from current attitude
  4. current attitude may be wrong if the EKF can’t handle the out-of-control situation

So what would one have to do to produce that log that Leonard would like to see? I’m willing to try to produce a log like that if I knew what I had to do. I have a 500 stretch pylon racer that I could refit with a Pixhawk and have my friend, Dave, fly it in hard 3D to see if it can handle it. But my gut instinct is the EKF will give out and current attitude will go bonkers before the ghost error diverges. Just a simple tic-toc will instantly blow the EKF due to the accelerations experienced by the IMU’s interpreting them as severe vibration. And then you have no attitude controller at all.

I think this was Leonard’s point, and it’s a good one - prove that it’s actually broken. But how?

I think the other thing that should be considered is how much acceleration should the controller be allowed to apply to the aircraft. I know the feedforward is limited by the max accel parameter but is the rate applied due to the attitude error limited? From what I can tell, I don’t think it is. That would be my argument that maybe there is some finite angle the controlller is limited to protect the aircraft from a controller request that could damage the aircraft.

I do not know that. I thought the angular acceleration limits applied at all times. But maybe they don’t. That would be a concern.

we can use a simulator where we have perfect sensors. I tried to do that with the Raptor720 heli in RF8, but I wasn’t able to produce a problem.

Immmmmmm baaaaacccckkkkkkk :smile:

Hi all,

Everybody knows my opinion on liming the ghost relative to the aircraft so I won’t go into it unless somebody wants to ask questions on exactly how the attitude controller works.

But I have a list of features I want to add to the controller to facilitate experimentation and flexibility. (just because they are available does not mean we should use them :open_mouth: )
Maximum angle error based on output saturation.
Maximum angle error specified by the user
Maximum correction rate specified by the user
Maximum output to the mixers.

I need to go over all our conversations and make sure I can support all the features we need to deal with the start up phases of heli. So I will probably need some I term handling as well. I am sure there are a few more. It would be great if you could chime in if there is something you think I have missed.

Another thing I intend to do is separate the output of the feed forward terms from the PID terms. I suspect we should be scaling them differently on the input to the mixers. In general the feedforward term should be linear and PID square rooted for single and coax copters and I suspect heli’s too (but I will need help here). For multi’s the feed forward should be squared and PID linear. More thought needed here though.

1 Like

Hi Leonard! Glad to have you back!

I’m not sure how much we want the user specifying this so I would shy away from 2 and 3. Plus in specifying angle error there is no basis for the limit other than what the user thinks it should be. It makes sense that this should either be limited by the maximum output to the mixers (because that is all the control authority available) or maximum angle error based on output saturation. I’m not sure quite how 1 and 4 are different. I would guess that in number 4 you would feed back the limit of the mixers to the attitude controller to slow the rate request and the ghost. In number 1, does the rate addition due to angle error get included in the calculation of where the ghost is?
The only other limit would be limit angle error (and subsequently rate request) based on max acceleration which is what I think you do now with the yaw axis. The big question there is how do you determine what that acceleration limit should be. It could be based on the acceleration limit the user specifies in setting up the aircraft.

What I’m failing to see is how the start up phases play into what you have discussed above.

So I have not figured out why the square root factor is used. After our discussions on the attitude controller, I’m assuming this handles the nonlinearities in controlling multicopters. Yet the square root controller is tied to a smoothing gain set by the RC_feel parameter. We should have a discussion on this, maybe skype. I think your idea is to remove the nonlinear effects in the control response so that a rate request input made by the autopilot can be linearly mapped to a rate response? So to compare a multicopter to a heli, your control scheme used to linearize multicopter response would only work on the yaw and heave axis of a heli since they are effectively using the same method to create force/moments (thrust). However, I would think constant speed, variable pitch systems may behave differently than variable speed, fixed pitch but I don’t have any data on that. Now in the pitch and roll axis, moments are created through cyclic blade pitch. The resulting blade flapping causes two types of moments, one due to the thrust vector offset from the CG and the other due to head stiffness (either due to hingeless head design or a teetering head with at stiff dampener). So I don’t know if the square root controller would apply here.

As I said, I think this would be best discussed in person.


I agree on the

Bill. As a default they will be set to no angle error limit but the user will be able to choose between a defined limit and limiting based on output saturation and this is what I would recommend to the Heli yaw controller and quad plane. At the moment I am thinking 0 is no limit and anything above zero will be the minimum of the saturated limit and that number.

People will use incorrectly to address yaw overshoot caused by high rates and poor yaw acceleration ability but that is life.

It will also be used to keep the ghost close to the real aircraft because that idea spooks people out but that will create a slower correction in the case of a flip or large attitude disturbance. In some cases that may be desirable though.

Again this will be set to be off but it is nice for larger aircraft that are carrying gimbals to limit the maximum roll or pitch rate when rotating from left to right. It is also critical for optical flow to ensure the sensor can follow the ground movement.

Again this will be set to be off but it is useful for preventing multirotor aircraft from stalling propellers during fast forward flight and getting control reversal.

I will not be encouraging people to mess with either of these parameters or even publicizing them widely. I have already added maximum rate and will look at limiting the yaw based on output saturation next. The other axis and functions will take longer.

Yes, the idea is that any limit in the controller will set the maximum rate and angle error and therefore ghost position that results in the current output at saturation. This is pretty easy in a single axis controller so I will do it first in the yaw controller and then Alt_Hold. Then I will do it in the 2 axis position controller and finally the quaternion controller for the thrust vector.

Yes, it will limit the maximum rate request but also the angle error and therefore the ghost postion.

So you can limit the output to the roll and pitch mixers to ensure the aircraft settles onto the ground or does not immediately snap level.
You can use the maximum altitude limit to keep the ghost near the current attitude. I personally think that keeping the ghost locked and I term zero will be the way to go but we could also limit the error (and therefore ghost) based on output saturation with the I term kept zero.
Maximum velocity is not relevant here.

The last point has nothing to do with the square root controller but instead the relation of actuator output to acceleration and velocity. I will need to implement this for single and coax copter anyway so it will have to get done. I suspect that heli will benefit from it too but we will need to do some characterisation work first. In any case this is still some time away. In any case that was a side note about tuning, not really relevant. Sorry. But that brings me to another thing. I have pretty much finalised the types and implementation of the system characterisation stuff. So I think I can get that done with the implementation of the Rate controller clean up.

So just to directly address some of the issues talked abou there:

This is the wrong way of thinking about this. In reality, when control is regained, the aircraft tracks the ghost not the other way round. And the ghost is the desired attitude. If a pilot is flying and actively correcting the aircraft in acro when the aircraft is out of control, neither the ghost or the heli are the same as the pilots desired attitude. Because the aircraft is out of control nothing can be done about it.
If the aircraft is in stabilize or alt_hold then the ghost is always equal to the pilots desired attitude no matter what happens to the aircraft attitude (although limiting attitude error will make this statement false).

I have asked if anybody can show a log, real or simulated, that demonstrates a situation where the roll and pitch attitude can be significantly different from the actual aircraft. Also, nobody has pointed to a mechanism where the attitude controller is unable to keep the aircraft on the ghost but the pilot’s inputs are able to control the aircraft. This is not an engineering argument but instead based entirely on an emotional argument. The most basic demonstration of this is the output of the attitude controller has saturated the swash movement trying to level the aircraft, there is nothing the pilot’s inputs can do. Even if you went full manual, the pilot would saturate the swash range and the aircraft would continue to roll/pitch out of control. If the aircraft is controllable then the attitude of the aircraft and ghost are very close.



This is where


come in. There already is maximum requested acceleration there.

So the requested acceleration is limited. You can get a higher acceleration by forcing the aircraft into a different attitude then letting go. The only way to limit this acceleration is to limit the output to the swash.

So to give an example. You have a heli hovering level. you have a string tied to the end of the tail. You pull on the tail until the aircraft has maxed out it’s pitch output to the swash. So you are in a situation where the aircraft is almost level but with full forward pitch. Then you let go of the string. There is nothing the controller can do because it can’t predict that you will let go of the string and it can’t instantaneously move the swash. In this situation the only way to limit the resultant acceleration is to limit the movement of the swash in pitch.

So yes, the aircraft can experience a higher acceleration but only when an external disturbance suddenly adds or removes a force on the aircraft.

Maybe a reason for the confusion here is that people are getting mixed up with “stabilization” and “attitude control”. Stabilization is easy because you simply feed some stick input to counter any movement in the airframe. You don’t need a ghost because you are relying on the pilot to do all the work and the stabilization is just helping deal with some drift and reacting to sudden disturbances for a fraction of a second. In this situation the pilot commands 75% of the output to the swash. This is like flying next to your instructor in a real heli and have him hold the stick and add a little pressure here and there to correct for things you missed.

In “attitude control” there needs to be a reference, the ghost, that the pid loops are working to achieve with the airframe. Here the pilot does not send any commands to the swash, the pilot only controls the ghost. Here the attitude controller has 100% of the output to the swash. Even when the pilot has a rate input that effectively goes directly to the swash via the feed forward in the rate loop, there is no more control authority left for the pilot’s input to use when the aircraft has lost control. In this situation the ghost IS the pilot and the person on the ground is just giving instructions. The goal is to make sure the Ghost is the better pilot.

  • If the aircraft is controllable, the ghost and aircraft will be very close to each other.
  • If the aircraft and ghost are far apart the full defection of the swash is not enough to maintain control and therefore any input from the pilot to correct the disturbance will not do anything other than make things worse.
  • If the aircraft becomes controllable there will be a fraction of a second where the aircraft will return to the ghost attitude. After this fraction of a second everything will make sense.

Currently the discussion to limit the attitude error (and therefore the difference between the ghost and real aircraft) has focused on the “fraction of a second” for a gun pilot flying in ACRO. A “fraction of a second” that nobody can demonstrate in reality or simulation.

I will eventually limit the attitude error in the quaternion controller but I will do it first in the yaw, altitude and finally the position controller because there is a demonstrable need and justification. I can think of a couple of valid reasons someone may want to limit the attitude controller error so I will do that too but it is not a priority.

Again, I am stoked about the work you are all doing on Heli. Don’t take my long reply as negative in any way!!

This is where I was at when I lost the yaw servo in my 626. The heli was in auto at a fairly high flight speed when the yaw servo went full travel to the left and failed. Honestly, I don’t even remember or know what I did to get it back under control. But it flipped and I know I went for Acro flight mode, got Stabilize by accident, got it upright in a wild spin and managed to fight it in a little closer to me where I had better visual reference. I finally shut down the motor in a spin, which allowed me to autorotate the thing and land it without damage.

Thru all this, I don’t think the attitude controller itself caused any problem, and I think the Stabilize controller helped get it more stabilized upright where if I had actually gotten Acro I likely would’ve crashed it. The attitude estimate was off because the EKF didn’t like what happened in the severe vibration/acceleration levels experienced in the unusual flight attitude. But I was still able to control it and make it do what I wanted - kind of. I don’t even know if I could duplicate it because it was ~1 minute and a few seconds of intense focus in the fight with an uncontrollable machine. So I’m kind of wondering if we aren’t looking at the extreme theoretical here, when in reality the performance of the attitude controller probably exceeds the skill level of even the best pilots?

Let me know what you need to characterize this for tradheli. I would be happy to help.

You confused me here. Finalized what types and implementation of characterization stuff? Please explain.

Yeh, emergency reaction is best to go with Stab because it will keep the thrust vector vertical. If the aircraft is moving the way I suspect it was then I can almost guarantee it was the attitude controller that got it level… ish. It is probably a good indication that there are not any videos on youtube showing a heli with a lost yaw servo being landed. With simple mode it would have made it a little easier for you. Provided the EKF is hanging in there the attitude controller can handle a fast spin.

So I am looking at providing a number of excitation signals:
Chirp function
Sinusoide stepped in frequency
Maximal length BPSK sequence

I may also provide a magnitude sweep capability to do multiple tests at increasing magnitude.

The signal will be injected into the rate loop output. We will record the excitation signal, the rate loop input and output and the RAW IMU output, all at full rate. We may need to subsample some of this data if we run out of bandwidth.

This will be great! What frequency range are you looking to characterize? Do you have an idea of what helicopter rotor head types you want data on or were you just going to look at a fairly typical setup (2 blade teetering). By the way, what is BPSK?
This is coincidental because I was planning on doing some characterization work over the Christmas holiday. I have a chirp set up in my repository to look at pilot stick to response, rate output to response, and disturbance rejection (chirp input on attitude signal into attitude controller). The chirp code was built on AC 3.5.0-rc7 but I was going to bring it into 3.5.3 or 3.5.4 if it comes out in a week or two. In any case, I would be interested in working with you on this from the Tradheli side of it.

Binary Phase Shift Keying. It is a widely used modulation scheme for one of the most popular digital modes in ham radio (PSK31).