L1_Control : Added hysteresis for rear WP capture
This commit is contained in:
parent
49bd45cf3a
commit
4d2fe4a488
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "AP_L1_Control.h"
|
#include "AP_L1_Control.h"
|
||||||
|
|
||||||
|
extern const AP_HAL::HAL& hal;
|
||||||
|
|
||||||
// table of user settable parameters
|
// table of user settable parameters
|
||||||
const AP_Param::GroupInfo AP_L1_Control::var_info[] PROGMEM = {
|
const AP_Param::GroupInfo AP_L1_Control::var_info[] PROGMEM = {
|
||||||
// @Param: PERIOD
|
// @Param: PERIOD
|
||||||
@ -83,6 +85,26 @@ float AP_L1_Control::crosstrack_error(void) const
|
|||||||
return _crosstrack_error;
|
return _crosstrack_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
prevent indecision in our turning by using our previous turn
|
||||||
|
decision if we are in a narrow angle band pointing away from the
|
||||||
|
target and the turn angle has changed sign
|
||||||
|
*/
|
||||||
|
void AP_L1_Control::_prevent_indecision(float &Nu)
|
||||||
|
{
|
||||||
|
const float Nu_limit = 0.9f*M_PI;
|
||||||
|
if (fabs(Nu) > Nu_limit &&
|
||||||
|
fabs(_last_Nu) > Nu_limit &&
|
||||||
|
fabsf(wrap_180_cd(_target_bearing_cd - _ahrs.yaw_sensor)) > 12000 &&
|
||||||
|
Nu * _last_Nu < 0.0f) {
|
||||||
|
// we are moving away from the target waypoint and pointing
|
||||||
|
// away from the waypoint (not flying backwards). The sign
|
||||||
|
// of Nu has also changed, which means we are
|
||||||
|
// oscillating in our decision about which way to go
|
||||||
|
Nu = _last_Nu;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update L1 control for waypoint navigation
|
// update L1 control for waypoint navigation
|
||||||
// this function costs about 3.5 milliseconds on a AVR2560
|
// this function costs about 3.5 milliseconds on a AVR2560
|
||||||
void AP_L1_Control::update_waypoint(const struct Location &prev_WP, const struct Location &next_WP)
|
void AP_L1_Control::update_waypoint(const struct Location &prev_WP, const struct Location &next_WP)
|
||||||
@ -144,15 +166,18 @@ void AP_L1_Control::update_waypoint(const struct Location &prev_WP, const struct
|
|||||||
//Otherwise do normal L1 guidance
|
//Otherwise do normal L1 guidance
|
||||||
float WP_A_dist = A_air.length();
|
float WP_A_dist = A_air.length();
|
||||||
float alongTrackDist = A_air * AB;
|
float alongTrackDist = A_air * AB;
|
||||||
if (WP_A_dist > _L1_dist && alongTrackDist/max(WP_A_dist, 1.0f) < -0.7071f) {
|
if (WP_A_dist > _L1_dist && alongTrackDist/max(WP_A_dist, 1.0f) < -0.7071f)
|
||||||
|
{
|
||||||
//Calc Nu to fly To WP A
|
//Calc Nu to fly To WP A
|
||||||
Vector2f A_air_unit = (A_air).normalized(); // Unit vector from WP A to aircraft
|
Vector2f A_air_unit = (A_air).normalized(); // Unit vector from WP A to aircraft
|
||||||
xtrackVel = _groundspeed_vector % (-A_air_unit); // Velocity across line
|
xtrackVel = _groundspeed_vector % (-A_air_unit); // Velocity across line
|
||||||
ltrackVel = _groundspeed_vector * (-A_air_unit); // Velocity along line
|
ltrackVel = _groundspeed_vector * (-A_air_unit); // Velocity along line
|
||||||
Nu = atan2f(xtrackVel,ltrackVel);
|
Nu = atan2f(xtrackVel,ltrackVel);
|
||||||
|
|
||||||
|
_prevent_indecision(Nu);
|
||||||
|
|
||||||
_nav_bearing = atan2f(-A_air_unit.y , -A_air_unit.x); // bearing (radians) from AC to L1 point
|
_nav_bearing = atan2f(-A_air_unit.y , -A_air_unit.x); // bearing (radians) from AC to L1 point
|
||||||
|
|
||||||
} else { //Calc Nu to fly along AB line
|
} else { //Calc Nu to fly along AB line
|
||||||
|
|
||||||
//Calculate Nu2 angle (angle of velocity vector relative to line connecting waypoints)
|
//Calculate Nu2 angle (angle of velocity vector relative to line connecting waypoints)
|
||||||
@ -168,6 +193,8 @@ void AP_L1_Control::update_waypoint(const struct Location &prev_WP, const struct
|
|||||||
Nu = Nu1 + Nu2;
|
Nu = Nu1 + Nu2;
|
||||||
_nav_bearing = atan2f(AB.y, AB.x) + Nu1; // bearing (radians) from AC to L1 point
|
_nav_bearing = atan2f(AB.y, AB.x) + Nu1; // bearing (radians) from AC to L1 point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_Nu = Nu;
|
||||||
|
|
||||||
//Limit Nu to +-pi
|
//Limit Nu to +-pi
|
||||||
Nu = constrain_float(Nu, -1.5708f, +1.5708f);
|
Nu = constrain_float(Nu, -1.5708f, +1.5708f);
|
||||||
@ -229,7 +256,11 @@ void AP_L1_Control::update_loiter(const struct Location ¢er_WP, float radius
|
|||||||
float xtrackVelCap = A_air_unit % _groundspeed_vector; // Velocity across line - perpendicular to radial inbound to WP
|
float xtrackVelCap = A_air_unit % _groundspeed_vector; // Velocity across line - perpendicular to radial inbound to WP
|
||||||
float ltrackVelCap = - (_groundspeed_vector * A_air_unit); // Velocity along line - radial inbound to WP
|
float ltrackVelCap = - (_groundspeed_vector * A_air_unit); // Velocity along line - radial inbound to WP
|
||||||
float Nu = atan2f(xtrackVelCap,ltrackVelCap);
|
float Nu = atan2f(xtrackVelCap,ltrackVelCap);
|
||||||
Nu = constrain_float(Nu, -1.5708f, +1.5708f); //Limit Nu to +- Pi/2
|
|
||||||
|
_prevent_indecision(Nu);
|
||||||
|
_last_Nu = Nu;
|
||||||
|
|
||||||
|
Nu = constrain_float(Nu, -M_PI_2, M_PI_2); //Limit Nu to +- Pi/2
|
||||||
|
|
||||||
//Calculate lat accln demand to capture center_WP (use L1 guidance law)
|
//Calculate lat accln demand to capture center_WP (use L1 guidance law)
|
||||||
float latAccDemCap = K_L1 * groundSpeed * groundSpeed / _L1_dist * sinf(Nu);
|
float latAccDemCap = K_L1 * groundSpeed * groundSpeed / _L1_dist * sinf(Nu);
|
||||||
@ -241,7 +272,7 @@ void AP_L1_Control::update_loiter(const struct Location ¢er_WP, float radius
|
|||||||
// keep crosstrack error for reporting
|
// keep crosstrack error for reporting
|
||||||
_crosstrack_error = xtrackErrCirc;
|
_crosstrack_error = xtrackErrCirc;
|
||||||
|
|
||||||
//Calculate PD control correction to circle waypoint
|
//Calculate PD control correction to circle waypoint_ahrs.roll
|
||||||
float latAccDemCircPD = (xtrackErrCirc * Kx + xtrackVelCirc * Kv);
|
float latAccDemCircPD = (xtrackErrCirc * Kx + xtrackVelCirc * Kv);
|
||||||
|
|
||||||
//Calculate tangential velocity
|
//Calculate tangential velocity
|
||||||
@ -310,7 +341,7 @@ void AP_L1_Control::update_heading_hold(int32_t navigation_heading_cd)
|
|||||||
_bearing_error = Nu; // bearing error angle (radians), +ve to left of track
|
_bearing_error = Nu; // bearing error angle (radians), +ve to left of track
|
||||||
|
|
||||||
// Limit Nu to +-pi
|
// Limit Nu to +-pi
|
||||||
Nu = constrain_float(Nu, -1.5708f, +1.5708f);
|
Nu = constrain_float(Nu, -M_PI_2, M_PI_2);
|
||||||
_latAccDem = 2.0f*sinf(Nu)*VomegaA;
|
_latAccDem = 2.0f*sinf(Nu)*VomegaA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +90,15 @@ private:
|
|||||||
AP_Float _L1_period;
|
AP_Float _L1_period;
|
||||||
// L1 tracking loop damping ratio
|
// L1 tracking loop damping ratio
|
||||||
AP_Float _L1_damping;
|
AP_Float _L1_damping;
|
||||||
|
|
||||||
//Calculate the maximum of two floating point numbers
|
|
||||||
float _maxf(const float &num1, const float &num2) const;
|
|
||||||
|
|
||||||
|
// previous value of cross-track velocity
|
||||||
|
float _last_Nu;
|
||||||
|
|
||||||
|
// direction of last xtrack velocity - true positive
|
||||||
|
bool _xtrackVelPos;
|
||||||
|
|
||||||
|
// prevent indecision in waypoint tracking
|
||||||
|
void _prevent_indecision(float &Nu);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user