39 #include <mathlib/mathlib.h> 48 checkSetpoints(last_setpoint);
49 const Vector3f vel_prev(last_setpoint.
vx, last_setpoint.
vy, last_setpoint.
vz);
50 const Vector3f pos_prev(last_setpoint.
x, last_setpoint.
y, last_setpoint.
z);
52 for (
int i = 0; i < 3; ++i) {
53 _trajectory[i].reset(last_setpoint.
acceleration[i], vel_prev(i), pos_prev(i));
56 _yaw_sp_prev = last_setpoint.
yaw;
57 _updateTrajConstraints();
65 for (
int i = 0; i < 2; ++i) {
66 _trajectory[i].reset(0.
f, 0.
f, _position(i));
69 _trajectory[2].reset(0.
f, 0.7
f, _position(2));
75 if (!PX4_ISFINITE(setpoints.
x)) { setpoints.
x = _position(0); }
77 if (!PX4_ISFINITE(setpoints.
y)) { setpoints.
y = _position(1); }
79 if (!PX4_ISFINITE(setpoints.
z)) { setpoints.
z = _position(2); }
82 if (!PX4_ISFINITE(setpoints.
vx)) { setpoints.
vx = _velocity(0); }
84 if (!PX4_ISFINITE(setpoints.
vy)) { setpoints.
vy = _velocity(1); }
86 if (!PX4_ISFINITE(setpoints.
vz)) { setpoints.
vz = _velocity(2); }
89 for (
int i = 0; i < 3; i++) {
93 if (!PX4_ISFINITE(setpoints.
yaw)) { setpoints.
yaw = _yaw; }
103 _trajectory[0].setCurrentPosition(_position(0));
104 _trajectory[1].setCurrentPosition(_position(1));
109 _trajectory[0].setCurrentVelocity(_velocity(0));
110 _trajectory[1].setCurrentVelocity(_velocity(1));
115 _trajectory[2].setCurrentPosition(_position(2));
120 _trajectory[2].setCurrentVelocity(_velocity(2));
125 _yaw_sp_prev += delta_psi;
131 _generateTrajectory();
133 if (!PX4_ISFINITE(_yaw_setpoint) && !PX4_ISFINITE(_yawspeed_setpoint)) {
142 if (!_generateHeadingAlongTraj()) {
143 _yaw_setpoint = _yaw_sp_prev;
150 Vector2f vel_sp_xy(_velocity_setpoint);
153 if ((vel_sp_xy.
length() > .1f) &&
154 (traj_to_target.
length() > _target_acceptance_radius)) {
157 _compute_heading_from_2D_vector(_yaw_setpoint, vel_sp_xy);
191 float speed_at_target = 0.0f;
193 const float distance_current_next = (_target - _next_wp).xy().norm();
194 const bool waypoint_overlap = (_target - _prev_wp).xy().norm() < _target_acceptance_radius;
195 const bool yaw_align_check_pass = (_param_mpc_yaw_mode.get() != 4) || _yaw_sp_aligned;
198 if (distance_current_next > 0.001
f &&
200 yaw_align_check_pass) {
202 pos_traj(0) = _trajectory[0].getCurrentPosition();
203 pos_traj(1) = _trajectory[1].getCurrentPosition();
204 pos_traj(2) = _trajectory[2].getCurrentPosition();
206 const float max_speed_current_next = _getMaxSpeedFromDistance(distance_current_next, next_target_speed);
207 const float alpha = acosf(
Vector2f((_target - pos_traj).xy()).unit_or_zero().dot(
208 Vector2f((_target - _next_wp).xy()).unit_or_zero()));
212 float accel_tmp = _param_mpc_xy_traj_p.get() * _param_mpc_acc_hor.get();
215 _target_acceptance_radius);
216 speed_at_target =
math::min(
math::min(max_speed_in_turn, max_speed_current_next), _mc_cruise_speed);
219 return speed_at_target;
225 _param_mpc_acc_hor.get(),
238 _want_takeoff =
false;
240 if (_param_mpc_yaw_mode.get() == 4 && !_yaw_sp_aligned) {
242 _velocity_setpoint.setAll(0.
f);
245 if (PX4_ISFINITE(_position_setpoint(0)) &&
246 PX4_ISFINITE(_position_setpoint(1))) {
251 pos_traj(0) = _trajectory[0].getCurrentPosition();
252 pos_traj(1) = _trajectory[1].getCurrentPosition();
253 pos_traj(2) = _trajectory[2].getCurrentPosition();
254 Vector2f pos_traj_to_dest_xy = (_position_setpoint - pos_traj).xy();
257 const bool has_reached_altitude = fabsf(_position_setpoint(2) - pos_traj(2)) < _param_nav_mc_alt_rad.get();
260 const float arrival_speed = has_reached_altitude ? _getSpeedAtTarget(0.
f) : 0.f;
261 const Vector2f max_arrival_vel = u_pos_traj_to_dest_xy * arrival_speed;
263 Vector2f vel_abs_max_xy(_getMaxSpeedFromDistance(fabsf(pos_traj_to_dest_xy(0)), max_arrival_vel(0)),
264 _getMaxSpeedFromDistance(fabsf(pos_traj_to_dest_xy(1)), max_arrival_vel(1)));
267 const Vector2f vel_sp_xy = u_pos_traj_to_dest_xy * _mc_cruise_speed;
270 Vector2f vel_sp_constrained_xy(_constrainAbs(vel_sp_xy(0), vel_abs_max_xy(0)),
271 _constrainAbs(vel_sp_xy(1), vel_abs_max_xy(1)));
273 for (
int i = 0; i < 2; i++) {
275 if (PX4_ISFINITE(_velocity_setpoint(i))) {
276 _velocity_setpoint(i) = _constrainOneSide(vel_sp_constrained_xy(i), _velocity_setpoint(i));
279 _velocity_setpoint(i) = vel_sp_constrained_xy(i);
284 if (PX4_ISFINITE(_position_setpoint(2))) {
285 const float vel_sp_z = (_position_setpoint(2) - _trajectory[2].getCurrentPosition()) *
286 _param_mpc_z_traj_p.get();
289 if (PX4_ISFINITE(_velocity_setpoint(2))) {
290 _velocity_setpoint(2) = _constrainOneSide(vel_sp_z, _velocity_setpoint(2));
293 _velocity_setpoint(2) = vel_sp_z;
296 _want_takeoff = _velocity_setpoint(2) < -0.3f;
304 _trajectory[0].setMaxAccel(_param_mpc_acc_hor.get());
305 _trajectory[1].setMaxAccel(_param_mpc_acc_hor.get());
306 _trajectory[0].setMaxVel(_param_mpc_xy_vel_max.get());
307 _trajectory[1].setMaxVel(_param_mpc_xy_vel_max.get());
308 _trajectory[0].setMaxJerk(_param_mpc_jerk_auto.get());
309 _trajectory[1].setMaxJerk(_param_mpc_jerk_auto.get());
310 _trajectory[2].setMaxJerk(_param_mpc_jerk_auto.get());
312 if (_velocity_setpoint(2) < 0.f) {
313 _trajectory[2].setMaxAccel(_param_mpc_acc_up_max.get());
314 _trajectory[2].setMaxVel(_param_mpc_z_vel_max_up.get());
317 _trajectory[2].setMaxAccel(_param_mpc_acc_down_max.get());
318 _trajectory[2].setMaxVel(_param_mpc_z_vel_max_dn.get());
324 if (!PX4_ISFINITE(_velocity_setpoint(0)) || !PX4_ISFINITE(_velocity_setpoint(1))
325 || !PX4_ISFINITE(_velocity_setpoint(2))) {
332 Vector2f position_trajectory_xy(_trajectory[0].getCurrentPosition(), _trajectory[1].getCurrentPosition());
334 Vector2f vel_traj_xy(_trajectory[0].getCurrentVelocity(), _trajectory[1].getCurrentVelocity());
335 Vector2f drone_to_trajectory_xy(position_trajectory_xy - position_xy);
336 float position_error = drone_to_trajectory_xy.
length();
338 float time_stretch = 1.f -
math::constrain(position_error * 0.5
f, 0.f, 1.f);
341 if (drone_to_trajectory_xy.
dot(vel_traj_xy) < 0.f) {
350 for (
int i = 0; i < 3; ++i) {
351 _trajectory[i].updateTraj(_deltatime, time_stretch);
352 jerk_sp_smooth(i) = _trajectory[i].getCurrentJerk();
353 accel_sp_smooth(i) = _trajectory[i].getCurrentAcceleration();
354 vel_sp_smooth(i) = _trajectory[i].getCurrentVelocity();
355 pos_sp_smooth(i) = _trajectory[i].getCurrentPosition();
358 _updateTrajConstraints();
360 for (
int i = 0; i < 3; ++i) {
361 _trajectory[i].updateDurations(_velocity_setpoint(i));
366 _jerk_setpoint = jerk_sp_smooth;
367 _acceleration_setpoint = accel_sp_smooth;
368 _velocity_setpoint = vel_sp_smooth;
369 _position_setpoint = pos_sp_smooth;
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
static float _constrainOneSide(float val, float constraint)
Constrain val between INF and constraint.
void _ekfResetHandlerPositionZ() override
void checkSetpoints(vehicle_local_position_setpoint_s &setpoints)
float _getMaxSpeedFromDistance(float braking_distance, float final_speed) const
void reActivate() override
Call this to reset an active Flight Task.
void _prepareSetpoints()
Generate velocity target points for the trajectory generator.
void _ekfResetHandlerHeading(float delta_psi) override
static float _constrainAbs(float val, float max)
void _generateTrajectory()
float computeMaxSpeedInWaypoint(const float alpha, const float accel, const float d)
void _ekfResetHandlerVelocityZ() override
bool _generateHeadingAlongTraj()
Generates heading along trajectory.
Flight task for autonomous, gps driven mode.
bool activate(vehicle_local_position_setpoint_s last_setpoint) override
Call once on the event where you switch to the task.
Type dot(const MatrixM1 &b) const
float _getSpeedAtTarget(float next_target_speed) const
Constrain the value -max <= val <= max.
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Vector2< float > Vector2f
void _ekfResetHandlerVelocityXY() override
Dual< Scalar, N > min(const Dual< Scalar, N > &a, const Dual< Scalar, N > &b)
constexpr _Tp min(_Tp a, _Tp b)
float computeMaxSpeedFromDistance(const float jerk, const float accel, const float braking_distance, const float final_speed)
bool activate(vehicle_local_position_setpoint_s last_setpoint) override
Call once on the event where you switch to the task.
static void timeSynchronization(VelocitySmoothing *traj, int n_traj)
Synchronize several trajectories to have the same total time.
Dual< Scalar, N > max(const Dual< Scalar, N > &a, const Dual< Scalar, N > &b)
void _generateSetpoints() override
Generate setpoints along line.
void _ekfResetHandlerPositionXY() override
Reset position or velocity setpoints in case of EKF reset event.
void _updateTrajConstraints()
Vector unit_or_zero(const Type eps=Type(1e-5)) const