mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-02 20:28:37 +08:00
mc_att_control: only apply quat reset if estimate is newer than setpoint
This commit is contained in:
@@ -75,14 +75,23 @@ public:
|
|||||||
* @param qd desired vehicle attitude setpoint
|
* @param qd desired vehicle attitude setpoint
|
||||||
* @param yawspeed_setpoint [rad/s] yaw feed forward angular rate in world frame
|
* @param yawspeed_setpoint [rad/s] yaw feed forward angular rate in world frame
|
||||||
*/
|
*/
|
||||||
void setAttitudeSetpoint(const matrix::Quatf &qd, const float yawspeed_setpoint) { _attitude_setpoint_q = qd; _attitude_setpoint_q.normalize(); _yawspeed_setpoint = yawspeed_setpoint; }
|
void setAttitudeSetpoint(const matrix::Quatf &qd, const float yawspeed_setpoint)
|
||||||
|
{
|
||||||
|
_attitude_setpoint_q = qd;
|
||||||
|
_attitude_setpoint_q.normalize();
|
||||||
|
_yawspeed_setpoint = yawspeed_setpoint;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adjust last known attitude setpoint by a delta rotation
|
* Adjust last known attitude setpoint by a delta rotation
|
||||||
* Optional use to avoid glitches when attitude estimate reference e.g. heading changes.
|
* Optional use to avoid glitches when attitude estimate reference e.g. heading changes.
|
||||||
* @param q_delta delta rotation to apply
|
* @param q_delta delta rotation to apply
|
||||||
*/
|
*/
|
||||||
void adaptAttitudeSetpoint(const matrix::Quatf &q_delta) { _attitude_setpoint_q = q_delta * _attitude_setpoint_q; }
|
void adaptAttitudeSetpoint(const matrix::Quatf &q_delta)
|
||||||
|
{
|
||||||
|
_attitude_setpoint_q = q_delta * _attitude_setpoint_q;
|
||||||
|
_attitude_setpoint_q.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run one control loop cycle calculation
|
* Run one control loop cycle calculation
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ private:
|
|||||||
AlphaFilter<float> _man_y_input_filter;
|
AlphaFilter<float> _man_y_input_filter;
|
||||||
|
|
||||||
hrt_abstime _last_run{0};
|
hrt_abstime _last_run{0};
|
||||||
|
hrt_abstime _last_attitude_setpoint{0};
|
||||||
|
|
||||||
bool _landed{true};
|
bool _landed{true};
|
||||||
bool _reset_yaw_sp{true};
|
bool _reset_yaw_sp{true};
|
||||||
|
|||||||
@@ -211,11 +211,15 @@ MulticopterAttitudeControl::generate_attitude_setpoint(const Quatf &q, float dt,
|
|||||||
Quatf q_sp = Eulerf(attitude_setpoint.roll_body, attitude_setpoint.pitch_body, attitude_setpoint.yaw_body);
|
Quatf q_sp = Eulerf(attitude_setpoint.roll_body, attitude_setpoint.pitch_body, attitude_setpoint.yaw_body);
|
||||||
q_sp.copyTo(attitude_setpoint.q_d);
|
q_sp.copyTo(attitude_setpoint.q_d);
|
||||||
|
|
||||||
attitude_setpoint.thrust_body[2] = -throttle_curve(math::constrain(_manual_control_setpoint.z, 0.0f,
|
attitude_setpoint.thrust_body[2] = -throttle_curve(math::constrain(_manual_control_setpoint.z, 0.f, 1.f));
|
||||||
1.0f));
|
|
||||||
attitude_setpoint.timestamp = hrt_absolute_time();
|
attitude_setpoint.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
_vehicle_attitude_setpoint_pub.publish(attitude_setpoint);
|
_vehicle_attitude_setpoint_pub.publish(attitude_setpoint);
|
||||||
|
|
||||||
|
// update attitude controller setpoint immediately
|
||||||
|
_attitude_control.setAttitudeSetpoint(q_sp, attitude_setpoint.yaw_sp_move_rate);
|
||||||
|
_thrust_setpoint_body = Vector3f(attitude_setpoint.thrust_body);
|
||||||
|
_last_attitude_setpoint = attitude_setpoint.timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -244,28 +248,40 @@ MulticopterAttitudeControl::Run()
|
|||||||
|
|
||||||
if (_vehicle_attitude_sub.update(&v_att)) {
|
if (_vehicle_attitude_sub.update(&v_att)) {
|
||||||
|
|
||||||
|
// Guard against too small (< 0.2ms) and too large (> 20ms) dt's.
|
||||||
|
const float dt = math::constrain(((v_att.timestamp_sample - _last_run) * 1e-6f), 0.0002f, 0.02f);
|
||||||
|
_last_run = v_att.timestamp_sample;
|
||||||
|
|
||||||
|
const Quatf q{v_att.q};
|
||||||
|
|
||||||
// Check for new attitude setpoint
|
// Check for new attitude setpoint
|
||||||
if (_vehicle_attitude_setpoint_sub.updated()) {
|
if (_vehicle_attitude_setpoint_sub.updated()) {
|
||||||
vehicle_attitude_setpoint_s vehicle_attitude_setpoint;
|
vehicle_attitude_setpoint_s vehicle_attitude_setpoint;
|
||||||
_vehicle_attitude_setpoint_sub.update(&vehicle_attitude_setpoint);
|
|
||||||
_attitude_control.setAttitudeSetpoint(Quatf(vehicle_attitude_setpoint.q_d), vehicle_attitude_setpoint.yaw_sp_move_rate);
|
if (_vehicle_attitude_setpoint_sub.copy(&vehicle_attitude_setpoint)
|
||||||
_thrust_setpoint_body = Vector3f(vehicle_attitude_setpoint.thrust_body);
|
&& (vehicle_attitude_setpoint.timestamp > _last_attitude_setpoint)) {
|
||||||
|
|
||||||
|
_attitude_control.setAttitudeSetpoint(Quatf(vehicle_attitude_setpoint.q_d), vehicle_attitude_setpoint.yaw_sp_move_rate);
|
||||||
|
_thrust_setpoint_body = Vector3f(vehicle_attitude_setpoint.thrust_body);
|
||||||
|
_last_attitude_setpoint = vehicle_attitude_setpoint.timestamp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for a heading reset
|
// Check for a heading reset
|
||||||
if (_quat_reset_counter != v_att.quat_reset_counter) {
|
if (_quat_reset_counter != v_att.quat_reset_counter) {
|
||||||
const Quatf delta_q_reset(v_att.delta_q_reset);
|
const Quatf delta_q_reset(v_att.delta_q_reset);
|
||||||
|
|
||||||
// for stabilized attitude generation only extract the heading change from the delta quaternion
|
// for stabilized attitude generation only extract the heading change from the delta quaternion
|
||||||
_man_yaw_sp += Eulerf(delta_q_reset).psi();
|
_man_yaw_sp = wrap_pi(_man_yaw_sp + Eulerf(delta_q_reset).psi());
|
||||||
_attitude_control.adaptAttitudeSetpoint(delta_q_reset);
|
|
||||||
|
if (v_att.timestamp > _last_attitude_setpoint) {
|
||||||
|
// adapt existing attitude setpoint unless it was generated after the current attitude estimate
|
||||||
|
_attitude_control.adaptAttitudeSetpoint(delta_q_reset);
|
||||||
|
}
|
||||||
|
|
||||||
_quat_reset_counter = v_att.quat_reset_counter;
|
_quat_reset_counter = v_att.quat_reset_counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guard against too small (< 0.2ms) and too large (> 20ms) dt's.
|
|
||||||
const float dt = math::constrain(((v_att.timestamp_sample - _last_run) * 1e-6f), 0.0002f, 0.02f);
|
|
||||||
_last_run = v_att.timestamp_sample;
|
|
||||||
|
|
||||||
/* check for updates in other topics */
|
/* check for updates in other topics */
|
||||||
_manual_control_setpoint_sub.update(&_manual_control_setpoint);
|
_manual_control_setpoint_sub.update(&_manual_control_setpoint);
|
||||||
_v_control_mode_sub.update(&_v_control_mode);
|
_v_control_mode_sub.update(&_v_control_mode);
|
||||||
@@ -299,8 +315,6 @@ MulticopterAttitudeControl::Run()
|
|||||||
|
|
||||||
if (run_att_ctrl) {
|
if (run_att_ctrl) {
|
||||||
|
|
||||||
const Quatf q{v_att.q};
|
|
||||||
|
|
||||||
// Generate the attitude setpoint from stick inputs if we are in Manual/Stabilized mode
|
// Generate the attitude setpoint from stick inputs if we are in Manual/Stabilized mode
|
||||||
if (_v_control_mode.flag_control_manual_enabled &&
|
if (_v_control_mode.flag_control_manual_enabled &&
|
||||||
!_v_control_mode.flag_control_altitude_enabled &&
|
!_v_control_mode.flag_control_altitude_enabled &&
|
||||||
@@ -336,7 +350,7 @@ MulticopterAttitudeControl::Run()
|
|||||||
v_rates_sp.pitch = rates_sp(1);
|
v_rates_sp.pitch = rates_sp(1);
|
||||||
v_rates_sp.yaw = rates_sp(2);
|
v_rates_sp.yaw = rates_sp(2);
|
||||||
_thrust_setpoint_body.copyTo(v_rates_sp.thrust_body);
|
_thrust_setpoint_body.copyTo(v_rates_sp.thrust_body);
|
||||||
v_rates_sp.timestamp = now;
|
v_rates_sp.timestamp = hrt_absolute_time();
|
||||||
|
|
||||||
_v_rates_sp_pub.publish(v_rates_sp);
|
_v_rates_sp_pub.publish(v_rates_sp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user