diff --git a/src/modules/mc_pos_control/mc_pos_control_main.cpp b/src/modules/mc_pos_control/mc_pos_control_main.cpp index 4a13c7b36a94..66ffefa4a8b6 100644 --- a/src/modules/mc_pos_control/mc_pos_control_main.cpp +++ b/src/modules/mc_pos_control/mc_pos_control_main.cpp @@ -1626,7 +1626,19 @@ MulticopterPositionControl::control_offboard(float dt) _att_sp.yaw_body = _pos_sp_triplet.current.yaw; } else if (_pos_sp_triplet.current.yawspeed_valid) { - _att_sp.yaw_body = _att_sp.yaw_body + _pos_sp_triplet.current.yawspeed * dt; + float yaw_target = _wrap_pi(_att_sp.yaw_body + _pos_sp_triplet.current.yawspeed * dt); + float yaw_offs = _wrap_pi(yaw_target - _yaw); + const float yaw_rate_max = (_params.man_yaw_max < _params.global_yaw_max) ? _params.man_yaw_max : + _params.global_yaw_max; + const float yaw_offset_max = yaw_rate_max / _params.mc_att_yaw_p; + + // If the yaw offset became too big for the system to track stop + // shifting it, only allow if it would make the offset smaller again. + if (fabsf(yaw_offs) < yaw_offset_max || + (_pos_sp_triplet.current.yawspeed > 0 && yaw_offs < 0) || + (_pos_sp_triplet.current.yawspeed < 0 && yaw_offs > 0)) { + _att_sp.yaw_body = yaw_target; + } } } else {