131 turn_angle = fabsf(turn_angle);
132 if (turn_angle >= 90) {
135 return distance_90 * turn_angle / 90.0f;
144 float nominal_velocity_sea_level;
146 nominal_velocity_sea_level = 0.0f;
153 if (
is_zero(sanitized_bank_limit) ||
is_zero(nominal_velocity_sea_level) ||
154 is_zero(lateral_accel_sea_level)) {
158 return radius * eas2tas_sq;
160 float sea_level_radius =
sq(nominal_velocity_sea_level) / lateral_accel_sea_level;
161 if (sea_level_radius > radius) {
164 return radius * eas2tas_sq;
167 return MAX(sea_level_radius * eas2tas_sq, radius);
184 const float Nu_limit = 0.9f*
M_PI;
185 if (fabsf(Nu) > Nu_limit &&
230 float groundSpeed = _groundspeed_vector.
length();
231 if (groundSpeed < 0.1
f) {
245 float AB_length = AB.
length();
266 float WP_A_dist = A_air.
length();
267 float alongTrackDist = A_air * AB;
268 if (WP_A_dist >
_L1_dist && alongTrackDist/
MAX(WP_A_dist, 1.0
f) < -0.7071
f)
271 Vector2f A_air_unit = (A_air).normalized();
272 xtrackVel = _groundspeed_vector % (-A_air_unit);
273 ltrackVel = _groundspeed_vector * (-A_air_unit);
274 Nu = atan2f(xtrackVel,ltrackVel);
276 }
else if (alongTrackDist > AB_length + groundSpeed*3) {
280 Vector2f B_air_unit = (B_air).normalized();
281 xtrackVel = _groundspeed_vector % (-B_air_unit);
282 ltrackVel = _groundspeed_vector * (-B_air_unit);
283 Nu = atan2f(xtrackVel,ltrackVel);
288 xtrackVel = _groundspeed_vector % AB;
289 ltrackVel = _groundspeed_vector * AB;
290 float Nu2 = atan2f(xtrackVel,ltrackVel);
295 float Nu1 = asinf(sine_Nu1);
303 }
else if (fabsf(Nu1) <
radians(5)) {
343 float Kx = omega * omega;
359 float groundSpeed =
MAX(_groundspeed_vector.
length() , 1.0f);
379 if (A_air.
length() > 0.1f) {
382 if (_groundspeed_vector.
length() < 0.1f) {
385 A_air_unit = _groundspeed_vector.
normalized();
390 float xtrackVelCap = A_air_unit % _groundspeed_vector;
391 float ltrackVelCap = - (_groundspeed_vector * A_air_unit);
392 float Nu = atan2f(xtrackVelCap,ltrackVelCap);
400 float latAccDemCap = K_L1 * groundSpeed * groundSpeed /
_L1_dist * sinf(Nu);
403 float xtrackVelCirc = -ltrackVelCap;
404 float xtrackErrCirc = A_air.
length() - radius;
410 float latAccDemCircPD = (xtrackErrCirc * Kx + xtrackVelCirc * Kv);
413 float velTangent = xtrackVelCap * float(loiter_direction);
416 if (ltrackVelCap < 0.0
f && velTangent < 0.0
f) {
417 latAccDemCircPD =
MAX(latAccDemCircPD, 0.0
f);
421 float latAccDemCircCtr = velTangent * velTangent /
MAX((0.5
f * radius), (radius + xtrackErrCirc));
424 float latAccDemCirc = loiter_direction * (latAccDemCircPD + latAccDemCircCtr);
429 if (xtrackErrCirc > 0.0
f && loiter_direction * latAccDemCap < loiter_direction * latAccDemCirc) {
466 float groundSpeed = _groundspeed_vector.
length();
470 float VomegaA = groundSpeed * omegaA;
void update_heading_hold(int32_t navigation_heading_cd)
Vector2< float > Vector2f
uint32_t _last_update_waypoint_us
virtual bool get_position(struct Location &loc) const =0
#define AP_GROUPINFO(name, idx, clazz, element, def)
void update_level_flight(void)
int32_t nav_bearing_cd(void) const
auto wrap_180_cd(const T angle) -> decltype(wrap_180(angle, 100.f))
int32_t bearing_error_cd(void) const
AP_Float _L1_xtrack_i_gain
virtual Vector2f groundspeed_vector(void)
const AP_HAL::HAL & hal
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
int32_t get_bearing_cd(const struct Location &loc1, const struct Location &loc2)
float turn_distance(float wp_radius) const
static auto MAX(const A &one, const B &two) -> decltype(one > two ? one :two)
#define RadiansToCentiDegrees(x)
Vector2< T > normalized() const
const AP_SpdHgtControl * _spdHgtControl
int32_t nav_roll_cd(void) const
Vector2f location_diff(const struct Location &loc1, const struct Location &loc2)
float wrap_PI(const T radian)
bool is_zero(const T fVal1)
void update_loiter(const struct Location ¢er_WP, float radius, int8_t loiter_direction)
int32_t target_bearing_cd(void) const
#define AP_GROUPINFO_FRAME(name, idx, clazz, element, def, frame_flags)
bool reached_loiter_target(void)
float constrain_float(const float amt, const float low, const float high)
int32_t _target_bearing_cd
float lateral_acceleration(void) const
std::enable_if< std::is_integral< typename std::common_type< Arithmetic1, Arithmetic2 >::type >::value,bool >::type is_equal(const Arithmetic1 v_1, const Arithmetic2 v_2)
static constexpr float radians(float deg)
static const struct AP_Param::GroupInfo var_info[]
#define AP_PARAM_FRAME_PLANE
L1 Control algorithm. This is a instance of an AP_Navigation class.
AP_Float _loiter_bank_limit
void _prevent_indecision(float &Nu)
float loiter_radius(const float loiter_radius) const
virtual float get_target_airspeed(void) const =0
float get_EAS2TAS(void) const
void update_waypoint(const struct Location &prev_WP, const struct Location &next_WP, float dist_min=0.0f)
float _L1_xtrack_i_gain_prev