ArduPilot / ardupilot

ArduPlane, ArduCopter, ArduRover, ArduSub source
http://ardupilot.org/
GNU General Public License v3.0
11.02k stars 17.57k forks source link

New Z controller changes Tailsitter back transition behaviour radically and incorrectly #18410

Open Hwurzburg opened 3 years ago

Hwurzburg commented 3 years ago

while working with the HWing tailsitter discovered that the FW->VTOL transition inits z controller to current climb rate for demand instead of resetting it as it did prior....result is massive zoom after transition as climb rate demand remains and slowly decays....changing Q_ACCEL_Z also does not correctly reduce velocity, in fact, raising it actually slows the decay of climb rate...an additional issue

since HWing does not work in Stable, used TVBS SkyCat for these graphs to show problem

Stable behaviour....climb rate reset to zero or less depending on stick input upon transition to QLOITER is completed...very minor zoom due to inertia Climb_Rate_stable master behaviour.....climb rate set to current and decays (but changing Q_ACCEL_Z has little effect and can actually slow velocity reduction) resulting in prolonged climb at start of pure VTOL Climb_Rate_master

checked master also at April point and behavior was correct...something changed in z controller init and operation I think Platform [ ] All [ ] AntennaTracker [ ] Copter [ x ] Plane [ ] Rover [ ] Submarine

IamPete1 commented 3 years ago

The clear change is that we have gone from using Z stopping point to 'no descent'. This commit puts that back.

https://github.com/IamPete1/ardupilot/commit/407faabedaf980b32e84aaaa21dcd63472e96894

But I suspect it is not so easy as that, the underlying methods have also changed.

Hwurzburg commented 3 years ago

I tested that...no change

IamPete1 commented 3 years ago

I do think the new init_z_controller_no_descent method is not right for our use case, what we want to do is stop as soon as possible, the no decent method does not allow to init with deceleration, certainty something that we would need to stop as quickly as possible.

IamPete1 commented 3 years ago

It looks to me that the init function may be wrong, (or I have not understood it).

https://github.com/IamPete1/ardupilot/blob/df7321c0da7fd327561e1f6fc0e6ba4a1e3ab317/libraries/AC_AttitudeControl/AC_PosControl.cpp#L791

It inits both the target and desired to the same value. They are then added in the when the controller is run so we get a target of twice the current value? I think we should init the target as we are but then 0 the desired?

This is just speculation from trying to understand the code, I have not tested.

Unfortunately both the init_z_controller_no_descent and init_z_controller_stopping_point are only used in a couple of places in the code, so there is no easy way to test on a none tailsitter vehicle.

The other issue could just be that using the earth frame Z accel for the init is nonsense because of the rapid pull up. In the old code only the position was re-set so this suspect accel was not used.

lthall commented 3 years ago

There was a problem with the initialisation of the z controller using the stopping point in the z axis. I think I can now simplify the stopping point calculation that I missed after some clean up.

https://github.com/lthall/Leonard_ardupilot/tree/20210822_Tailsitter-back-transition-fix

However, this does not fix the problem. From what I can see previously the tailsitter would target the stopping point and that would result in the aircraft climbing as it does now, higher the velocity and the lower the acceleration, the higher the climb.

It looks like previously plane wasn't initialising at all in a sensible way but would just set the target altitude to the current altitude without resetting the vertical velocities at all. (in general planes use of PosControl was a mess so it may have been setting velocity elsewhere)

Can we define the expected desired behaviour in kinematic terms referencing the various kinematic limits defined in the Position Controller?

Hwurzburg commented 3 years ago

IMO, the behavior upon completed transition to a vertical position controlled mode (QHOVER,AUTO,QLOITER,GUIDED) from a non controlled mode should set the desired z vel to whatever the demand is (pilot stick or auto/guided) and the ACCEL_Z/WP_ACCEL_Z determine how fast the autopilot tries to attain that speed...it will be up to the tailsitter transition code to get the z vel in the right spot at the transition (ie control the climb while pitching up) and I have a PR ( #18419) to help with that by better throttle control during that phase...but if the pilot/autopilot is demanding 0 climb rate, the z controller should have that as its target and decel as fast as ACCEL_Z allows....even if we set it at ballistic, ie ~10m/s/s (which I think is desired at the transition point...we cant do better than that to moderate an existing climb rate at transition complete)...I am not sure if that ACCEL causes problems within the z position controlled modes or not..so having a real vertical stopping point using up to a ballistic ACCEL_Z would be an acceptable soultion...we can control that initial end of transition climb rate in the tailsitter code before the transition is complete,I beleive...

lthall commented 3 years ago

What you have said there does not make sense in relation to the way the position controller works.

The position controller works by defining:

We change our desired acceleration in a jerk limited way and use it to control our desired velocity and target position.

We initialise our desired acceleration, desired velocity and target position to the values at the time of initialisation.

We then pass the commanded velocity into the kinematic shaping algorithm and it moves the desired velocity to the commanded velocity by adjusting the desired acceleration.

The aircraft is currently following initial conditions and respecting the kinematic limits that we have set.

If you want something else we need to change the initial conditions and accept that there will be a significant discontinuity.

For example if we set our initial conditions to be zero desired climb rate the target altitude will be set at that point and will not change. The aircraft will climb at 10m/s then descend back down to the initialisation altitude without kinematic shaping and using only the PID loop parameters and limits.

The alternative is to delay the initialisation until the vertical velocity has decayed to zero.

Hwurzburg commented 3 years ago

Indeed I am ignorant of the details of the position controller...I can only speak to how I would want the tailisitter, copter or otherwise, to behave from a user perspective, having flown them a lot....I think we can manage the fixed wing side of the transition to minimize the horizontal and vertical velocities upon transition to a VTOL mode, but it wont have zero z and horizontal velocity at transition completion in every case....in those cases where it does have z and xy velocity upon VTOL mode entry:

  1. I would desire that the altitude at entry be recovered as soon as possible when there is z velocity at entry...ie at ballistic rates, even if that means climbing while decelerating at 10m/s/s and re-descending back to the entry point using normal descent velocity...less desirable IMO would be a ballistic coast to a stopping point and hold, but acceptable...the current behavior of a slow deceleration with accompanying large altitude gain is not acceptable...this all assumes there is no climb demand from pilot or autopilot navigation
  2. with respect to XY position I am much less concerned...gliding to a stopping point using the ACCEL_XY and holding in xy hold modes is fine..I think that is how non-tailisitters handle that now....but returning to the entry xy position would be fine also
IamPete1 commented 3 years ago

I think what I would want for a transition to Q loiter or Q hover with zero pilot desired climb rate would be the fastest slow down and then hold at the highest point. I don't think we should then descend back down to the entry altitude. Doing the decent just delays reaching of the target altitude leaving controls feeling different from usual for longer.

Basically I would summarise as "reach 0 vertical velocity ASAP".

The existing 'no descent' method does not allow this because you cannot enter with a deceleration even if the vehicle is climbing.

Of course in the case of true altitude control (rather than climb rate) we would get that decent back to target altitude anyway.

lthall commented 3 years ago

Ok, trying to break this down.

The fundamental problem is we are initialising altitude hold during a 10m/s climb with very low acceleration and jerk limits (I assume, I have not seen your parameters). If we follow these kinematic limits it necessarily takes a long distance to come to a stop.

We have a number of options here:

So what solution do you what to use?

Hwurzburg commented 3 years ago

I tried increasing Q_ACCEL_Z from its default of 250 cm/s/s to larger values (should be 10m/s/s for ballistic recovery), but it did nothing to actually increasing the time to decay the entry climb rate to zero, or is it some other parameter?

IamPete1 commented 3 years ago

@lthall Do you think the earth frame Z accel is valid to init the controller with during this rapid pitch up manoeuvre? Its not really a genuine vehicle acceleration, that is to say the speed of the vehicle is not really changing much it is just the rotating of the velocity vector that is causing this large earth frame accel.

This large initial accel then takes ages to slew down again.

We could use the body frame X instead with the assumption that when the manoeuvre is complete this would be aligned with the earth frame Z.

I suspect @Hwurzburg is seeing it taking longer with a larger Q_ACCEL_Z because were actually jerk limited. @Hwurzburg you could try increasing Q_P_JERK_Z (or setting to -1 to disable) you should then start to see the benefit of the larger accel limit.

lthall commented 3 years ago

Do you think the earth frame Z accel is valid to init the controller with during this rapid pitch up manoeuvre? Its not really a genuine vehicle acceleration, that is to say the speed of the vehicle is not really changing much it is just the rotating of the velocity vector that is causing this large earth frame accel.

I think this is a very valid acceleration and directly predicts the rate of change of the vertical velocity.

This large initial accel then takes ages to slew down again.

The vertical acceleration is limited to our maximum input accelerations so this isn't as bad as it was initially.

Why can't we add a phase where we only run stabilize and wait for the aircraft to slow down rather than initialise Alt_Hold in such a aggressive state? It seems to me that this is the way to get exactly what you want and in a much more reliable and predictable way too.

lthall commented 3 years ago

Can you share logs?