Offboard RPYrT - how best to set the yaw setpoint?


I’m using RPYrT setpoints with offboard control. I see that in this mode, the attitude controller overrides the yaw rate calculated by AttitudeController::update() with the one I provide (reference pull request However, AttitudeControl::update() still makes use of the yaw setpoint, and experiments show that this is very important.

In the pull request I mention above, @Pedro-Roque comments “At the moment, the yaw angle is kept to the same one that the UAV has (suggestions for this are welcome!)”. I’m wondering what the best thing to do about this is.

For now, I’ve modified mc_att_control_main.cpp to retrieve the yaw from the platform, and I then override my yaw setpoint (which I leave as 0) with this before calling on AttitudeControl::update(). The platform flies in the correct direction in SITL when I do this.

Can anyone comment on potential issues with my change? Is this a sensible solution to the problem mentioned by Pedro? I don’t want my offboard controller to supply a yaw setpoint; it’s running it’s own state estimation, and I also don’t want to use the attitude I receive from the px4 to set this setpoint, as I’m just going to be introducing delays with that approach.


Hi dunk,

Just to be clear, by “At the moment, the yaw angle is kept to the same one that the UAV has”, I mean that it uses the current yaw of the platform (as you rotate, the yaw will follow).

Is this your question? Which problem are you facing?


Hi Pedro,

I’ve patched as shown at the bottom of this message.

I made this change, as during initial testing, we found that the platform was not responding to roll and pitch setpoints correctly when we were also providing a yaw rate. E.g. if we yawed away from north, and applied pitch only (roll=0, yaw=0, yawrate=0), it didn’t move forward in the body frame. It appears that AttitudeController::update() always requires a yaw setpoint - I don’t fully understand the maths in there, so I tried the method in my patch, and the platform now always moves in the direction we command (at least in SITL).

So, my question is - is the change I’ve made sensible? Do you see any potential issues?

diff --git a/src/modules/mc_att_control/mc_att_control_main.cpp b/src/modules/mc_att_control/mc_att_control_main.cpp
index c4e6c6d..d72226f 100644
--- a/src/modules/mc_att_control/mc_att_control_main.cpp
+++ b/src/modules/mc_att_control/mc_att_control_main.cpp
@@ -359,7 +359,19 @@ MulticopterAttitudeControl::control_attitude()
        // physical thrust axis is the negative of body z axis
        _thrust_sp = -_v_att_sp.thrust_body[2];
-       _rates_sp = _attitude_control.update(Quatf(_v_att.q), Quatf(_v_att_sp.q_d), _v_att_sp.yaw_sp_move_rate);
+  Quatf q(_v_att.q);
+  Quatf q_d(_v_att_sp.q_d);
+  // If the yaw rate override is enabled, set the yaw setpoint equal to body yaw,
+  // as update() requires a sensible value for yaw.
+  if (_v_control_mode.flag_control_yawrate_override_enabled) {
+    Eulerf e(q);
+    Eulerf e_d(q_d);
+    e_d.psi() = e.psi();
+    q_d = Quatf(e_d);
+  }
+  _rates_sp = _attitude_control.update(q, q_d, _v_att_sp.yaw_sp_move_rate);