77 float xtrack_vel = 0.0f;
78 float ltrack_vel = 0.0f;
84 float ground_speed =
math::max(ground_speed_vector.length(), 0.1f);
96 if (vector_AB.length() < 1.0e-6
f) {
100 vector_AB.normalize();
113 float distance_A_to_airplane = vector_A_to_airplane.length();
114 float alongTrackDist = vector_A_to_airplane * vector_AB;
122 float AB_to_BP_bearing = atan2f(vector_B_to_P_unit % vector_AB, vector_B_to_P_unit * vector_AB);
125 if (distance_A_to_airplane > _L1_distance && alongTrackDist /
math::max(distance_A_to_airplane, 1.0
f) < -0.7071
f) {
130 Vector2f vector_A_to_airplane_unit = vector_A_to_airplane.normalized();
132 xtrack_vel = ground_speed_vector % (-vector_A_to_airplane_unit);
134 ltrack_vel = ground_speed_vector * (-vector_A_to_airplane_unit);
135 eta = atan2f(xtrack_vel, ltrack_vel);
137 _nav_bearing = atan2f(-vector_A_to_airplane_unit(1), -vector_A_to_airplane_unit(0));
157 xtrack_vel = ground_speed_vector % (-vector_B_to_P_unit);
159 ltrack_vel = ground_speed_vector * (-vector_B_to_P_unit);
160 eta = atan2f(xtrack_vel, ltrack_vel);
162 _nav_bearing = atan2f(-vector_B_to_P_unit(1), -vector_B_to_P_unit(0));
169 xtrack_vel = ground_speed_vector % vector_AB;
171 ltrack_vel = ground_speed_vector * vector_AB;
173 float eta2 = atan2f(xtrack_vel, ltrack_vel);
175 float xtrackErr = vector_A_to_airplane % vector_AB;
176 float sine_eta1 = xtrackErr /
math::max(_L1_distance, 0.1
f);
179 float eta1 = asinf(sine_eta1);
182 _nav_bearing = atan2f(vector_AB(1), vector_AB(0)) + eta1;
201 int8_t loiter_direction,
const Vector2f &ground_speed_vector)
207 float K_crosstrack = omega * omega;
214 float ground_speed =
math::max(ground_speed_vector.length(), 0.1f);
227 vector_A_to_airplane_unit = vector_A_to_airplane.normalized();
230 vector_A_to_airplane_unit = vector_A_to_airplane;
236 float xtrack_vel_center = vector_A_to_airplane_unit % ground_speed_vector;
238 float ltrack_vel_center = - (ground_speed_vector * vector_A_to_airplane_unit);
239 float eta = atan2f(xtrack_vel_center, ltrack_vel_center);
244 float lateral_accel_sp_center =
_K_L1 * ground_speed * ground_speed / _L1_distance * sinf(eta);
249 float xtrack_vel_circle = -ltrack_vel_center;
251 float xtrack_err_circle = vector_A_to_airplane.length() - radius;
257 float lateral_accel_sp_circle_pd = (xtrack_err_circle * K_crosstrack + xtrack_vel_circle * K_velocity);
260 float tangent_vel = xtrack_vel_center * loiter_direction;
263 if (tangent_vel < 0.0
f) {
264 lateral_accel_sp_circle_pd =
math::max(lateral_accel_sp_circle_pd, 0.0
f);
268 float lateral_accel_sp_circle_centripetal = tangent_vel * tangent_vel /
math::max((0.5
f * radius),
269 (radius + xtrack_err_circle));
272 float lateral_accel_sp_circle = loiter_direction * (lateral_accel_sp_circle_pd + lateral_accel_sp_circle_centripetal);
280 if ((lateral_accel_sp_center < lateral_accel_sp_circle && loiter_direction > 0 && xtrack_err_circle > 0.0
f) ||
281 (lateral_accel_sp_center > lateral_accel_sp_circle && loiter_direction < 0 && xtrack_err_circle > 0.0f)) {
287 _nav_bearing = atan2f(-vector_A_to_airplane_unit(1), -vector_A_to_airplane_unit(0));
294 _nav_bearing = atan2f(-vector_A_to_airplane_unit(1), -vector_A_to_airplane_unit(0));
301 const Vector2f &ground_speed_vector)
318 float ground_speed = ground_speed_vector.length();
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
void set_l1_damping(float damping)
Set the L1 damping factor.
static constexpr double CONSTANTS_RADIUS_OF_EARTH
float _dt
control loop time in seconds
float _roll_slew_rate
roll angle setpoint slew rate limit in rad/s
float _K_L1
L1 control gain for _L1_damping.
bool _circle_mode
flag for loiter mode
float switch_distance(float waypoint_switch_radius)
Get the switch distance.
void update_roll_setpoint()
Update roll angle setpoint.
float _target_bearing
the heading setpoint
void navigate_loiter(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_curr_position, float radius, int8_t loiter_direction, const matrix::Vector2f &ground_speed_vector)
Navigate on an orbit around a loiter waypoint.
static constexpr float CONSTANTS_ONE_G
Implementation of L1 position control.
Vector normalized() const
float _nav_bearing
bearing to L1 reference point
float _L1_ratio
L1 ratio for navigation.
constexpr T radians(T degrees)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Vector2< float > Vector2f
float _L1_distance
L1 lead distance, defined by period and damping.
float _roll_lim_rad
maximum roll angle in radians
float get_bearing_to_next_waypoint(double lat_now, double lon_now, double lat_next, double lon_next)
Returns the bearing to the next waypoint in radians.
void set_l1_period(float period)
Set the L1 period.
constexpr _Tp min(_Tp a, _Tp b)
Type wrap_pi(Type x)
Wrap value in range [-π, π)
void navigate_waypoints(const matrix::Vector2f &vector_A, const matrix::Vector2f &vector_B, const matrix::Vector2f &vector_curr_position, const matrix::Vector2f &ground_speed)
Navigate between two waypoints.
constexpr _Tp max(_Tp a, _Tp b)
float _heading_omega
Normalized frequency.
float _bearing_error
bearing error
float _crosstrack_error
crosstrack error in meters
float _roll_setpoint
current roll angle setpoint in radians
void navigate_level_flight(float current_heading)
Keep the wings level.
float _L1_damping
L1 damping ratio.
void navigate_heading(float navigation_heading, float current_heading, const matrix::Vector2f &ground_speed)
Navigate on a fixed bearing.
float _L1_period
L1 tracking period in seconds.
matrix::Vector2f get_local_planar_vector(const matrix::Vector2f &origin, const matrix::Vector2f &target) const
Convert a 2D vector from WGS84 to planar coordinates.
float _lateral_accel
Lateral acceleration setpoint in m/s^2.