# Position and attitud controllers diagram

**URL:** <https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186>\
**Category:** PX4 Autopilot\
**Created:** [May 2, 2017, 11:38am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186 "2017-05-02T11:38:54Z")\
**Posts on this page:** 19\
**Page:** 2

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [March 12, 2018, 10:02am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/21 "2018-03-12T10:02:32Z")

</div>

@Abel Correct, the thrust needed to hover is added to the velocity controller so the integral doesn’t need to compensate for the weight of the drone. It is added with a negative sign since `thrust_sp` is computed in the NED frame (vertical thrust, pointing to the sky is negative in this frame).

---

<div class="post-metadata">

**Author:** ![Akash\_Patil](https://discuss.px4.io/letter_avatar_proxy/v4/letter/a/d26b3c/32.png) [@Akash\_Patil](https://discuss.px4.io/u/Akash_Patil)\
**Post date:** [July 21, 2018, 4:54pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/22 "2018-07-21T16:54:03Z")

</div>

which is input θref and θ in the code of pixhwak?.  
vehicle\_attitude\_setpoint\_poll();  
\_thrust\_sp = \_v\_att\_sp.thrust;

```
/* prepare yaw weight from the ratio between roll/pitch and yaw gains */
Vector3f attitude_gain = _attitude_p;
const float roll_pitch_gain = (attitude_gain(0) + attitude_gain(1)) / 2.f;
const float yaw_w = math::constrain(attitude_gain(2) / roll_pitch_gain, 0.f, 1.f);
attitude_gain(2) = roll_pitch_gain;

/* get estimated and desired vehicle attitude */
Quatf q(_v_att.q);
Quatf qd(_v_att_sp.q_d);

/* ensure input quaternions are exactly normalized because acosf(1.00001) == NaN */
q.normalize();
qd.normalize();

/* calculate reduced desired attitude neglecting vehicle's yaw to prioritize roll and pitch */
Vector3f e_z = q.dcm_z();
Vector3f e_z_d = qd.dcm_z();
Quatf qd_red(e_z, e_z_d);

if (abs(qd_red(1)) > (1.f - 1e-5f) || abs(qd_red(2)) > (1.f - 1e-5f)) {
	/* In the infinitesimal corner case where the vehicle and thrust have the completely opposite direction,
	 * full attitude control anyways generates no yaw input and directly takes the combination of
	 * roll and pitch leading to the correct desired yaw. Ignoring this case would still be totally safe and stable. */
	qd_red = qd;

} else {
	/* transform rotation from current to desired thrust vector into a world frame reduced desired attitude */
	qd_red *= q;
}

/* mix full and reduced desired attitude */
Quatf q_mix = qd_red.inversed() * qd;
q_mix *= math::signNoZero(q_mix(0));
/* catch numerical problems with the domain of acosf and asinf */
q_mix(0) = math::constrain(q_mix(0), -1.f, 1.f);
q_mix(3) = math::constrain(q_mix(3), -1.f, 1.f);
qd = qd_red * Quatf(cosf(yaw_w * acosf(q_mix(0))), 0, 0, sinf(yaw_w * asinf(q_mix(3))));

/* quaternion attitude control law, qe is rotation from q to qd */
Quatf qe = q.inversed() * qd;

/* using sin(alpha/2) scaled rotation axis as attitude error (see quaternion definition by axis angle)
 * also taking care of the antipodal unit quaternion ambiguity */
Vector3f eq = 2.f * math::signNoZero(qe(0)) * qe.imag();

```

Please help me to understand. I am new to this pixhwak and learning it now?..

---

<div class="post-metadata">

**Author:** ![Kyuhyong\_You](https://discuss.px4.io/user_avatar/discuss.px4.io/kyuhyong_you/32/2210_2.png) [@Kyuhyong\_You](https://discuss.px4.io/u/Kyuhyong_You)\
**Post date:** [July 25, 2018, 3:19am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/23 "2018-07-25T03:19:04Z")

</div>

I am trying to achieve more accurate and stable altitude hold.  
Position control looks like it only has proportional gain and does not account for integral errors.  
As shown my test below, I am having state error problem when maintaining altitude.

 ![](https://discuss.px4.io/uploads/default/original/2X/3/37c13a4c274f07251e017b28f4b478719e8b53e0.png)  
Adding integral terms will help making better position control especially for altitude hold?  
Please give me any advice.  
Thanks,

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [July 25, 2018, 6:35am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/24 "2018-07-25T06:35:34Z")

</div>

@Kyuhyong_You The altitude controller is composed by two cascaded position-velocity loops. The position loop contains only a P controller (as you said) but the velocity loop contains a PID controller which removes steady-state errors. Therefore, the position controller doesn’t need an integrator and tuning the velocity controller should fix your issue.

See: [https://dev.px4.io/en/flight\_stack/controller\_diagrams.html](https://dev.px4.io/en/flight_stack/controller_diagrams.html)

---

<div class="post-metadata">

**Author:** ![Kyuhyong\_You](https://discuss.px4.io/user_avatar/discuss.px4.io/kyuhyong_you/32/2210_2.png) [@Kyuhyong\_You](https://discuss.px4.io/u/Kyuhyong_You)\
**Post date:** [July 25, 2018, 9:00am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/25 "2018-07-25T09:00:43Z")

</div>

I’m bit confused now.  
Looking at the plot where velocity commanded during altitude hold mode, the drone seem to follow velocity command quite accurate. Isn’t this means the velocity controller is already tuned well?  
If that’s the case, shouldn’t the drone also very accurate maintaining certain altitude as well?  
FYI, the entire log is here [https://review.px4.io/plot\_app?log=dca4dfa5-051e-491d-8ab4-c25afe2098af](https://review.px4.io/plot_app?log=dca4dfa5-051e-491d-8ab4-c25afe2098af)

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [July 25, 2018, 9:41am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/26 "2018-07-25T09:41:43Z")

</div>

@Kyuhyong_You If the velocity tracking is good, it usually means that the velocity estimation is no correct. Check if the estimated velocity corresponds to the derivative of the position.

---

<div class="post-metadata">

**Author:** ![Kyuhyong\_You](https://discuss.px4.io/user_avatar/discuss.px4.io/kyuhyong_you/32/2210_2.png) [@Kyuhyong\_You](https://discuss.px4.io/u/Kyuhyong_You)\
**Post date:** [July 26, 2018, 11:41am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/27 "2018-07-26T11:41:18Z")

</div>

Attached is the comparison of derivative of the position Z and estimated VZ.  
Are they look corresponding to each other? If not, what can I do to resolve this problem?  
Thanks for helping me out,

 ![](https://discuss.px4.io/uploads/default/original/2X/f/f9bb0ba148ca1456e8eec2a0d4a7a3b4047661d8.png)  
Kyu

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [August 20, 2018, 9:07am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/28 "2018-08-20T09:07:42Z")

</div>

Hi @Kyuhyong_You , sorry for the late answer,

The estimated velocity looks to be not good enough. I would recommend you to increase the noise variance of the accelerometer in the EKF.  
Please tell me if it solves the issue.

---

<div class="post-metadata">

**Author:** ![Kyuhyong\_You](https://discuss.px4.io/user_avatar/discuss.px4.io/kyuhyong_you/32/2210_2.png) [@Kyuhyong\_You](https://discuss.px4.io/u/Kyuhyong_You)\
**Post date:** [September 19, 2018, 7:59am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/29 "2018-09-19T07:59:52Z")

</div>

Hi @bresch , Thanks for your comment.  
I see some improvements with increasing the EKF2\_ACC\_NOISE parameter but not completely remove the problem.  
Will do more testing tho. 😉

---

<div class="post-metadata">

**Author:** ![tecdee](https://discuss.px4.io/user_avatar/discuss.px4.io/tecdee/32/4474_2.png) [@tecdee](https://discuss.px4.io/u/tecdee)\
**Post date:** [August 14, 2019, 7:53pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/30 "2019-08-14T19:53:49Z")

</div>

Indeed you did a really nice job here man. Just saved me a lot of hassle. Thanks a lot.

---

<div class="post-metadata">

**Author:** ![Asghari936](https://discuss.px4.io/user_avatar/discuss.px4.io/asghari936/32/9666_2.png) [@Asghari936](https://discuss.px4.io/u/Asghari936)\
**Post date:** [November 10, 2021, 8:21pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/31 "2021-11-10T20:21:41Z")

</div>

Hello,  
I am modeling the flight controller diagram in simulink and I want to know what is the output of the cascade p-pid loops for attitude and altitude in common flight controllers like pixhawk. Is it moment and force? Or throttle percentage or pwm or anything else?  
Because I have considered moments and forces as outputs of my diagrams and as long as my multirotor is heavy and large (with a high mass and moments of inertia) my pid gains in the inner loop has become very high (about 200 - 300).  
I want to know what I should consider for the output of my diagrams so that I can use the pid gains which are tuned in simulink, for the real multirotor and pixhawk.  
Thanks.

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [November 15, 2021, 1:54pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/32 "2021-11-15T13:54:37Z")

</div>

Hi @Asghari936 ,

In PX4, the outputs are normalized values. For a rotor: 1 = maximum speed, 0 = minimum speed

---

<div class="post-metadata">

**Author:** ![Asghari936](https://discuss.px4.io/user_avatar/discuss.px4.io/asghari936/32/9666_2.png) [@Asghari936](https://discuss.px4.io/u/Asghari936)\
**Post date:** [November 17, 2021, 3:00am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/34 "2021-11-17T03:00:22Z")

</div>

Hi bresch, @bresch  
Thanks for your reply​👌  
So normalized value for roll or pitch moment is the condition in which on rotor is at the maximum speed and the other on the opposite side is at the minimum speed?

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [November 17, 2021, 9:38am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/35 "2021-11-17T09:38:16Z")

</div>

> [@Asghari936](#):
>
> So normalized value for roll or pitch moment is the condition in which on rotor is at the maximum speed and the other on the opposite side is at the minimum speed?

For torques, we have -1 (maximum negative) and +1 (maximum positive). So for example, a maximum pitch down demand will be “-1”.  
The actual rotor speed will depend on the control allocation gains (mixer).

---

<div class="post-metadata">

**Author:** ![Asghari936](https://discuss.px4.io/user_avatar/discuss.px4.io/asghari936/32/9666_2.png) [@Asghari936](https://discuss.px4.io/u/Asghari936)\
**Post date:** [November 17, 2021, 10:20am UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/36 "2021-11-17T10:20:28Z")

</div>

@bresch  
I got it. So what are the default mixer gains? Actually I want to assume a default condition so that I can simulate it in simulink. For example, if the input is just maximum roll (+1) in the hover condition and not anything else like pitch, yaw or throttle, what command would mixer send to motor? Is it to maximize the left motor speed and minimize the right one for + configuration? (And also maximize the two left motor speeds and minimize the right ones for x configuration?)

---

<div class="post-metadata">

**Author:** ![bresch](https://discuss.px4.io/user_avatar/discuss.px4.io/bresch/32/2343_2.png) [@bresch](https://discuss.px4.io/u/bresch)\
**Post date:** [November 17, 2021, 12:52pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/37 "2021-11-17T12:52:35Z")

</div>

You can look at the generated control allocation matrices when compiling the code under  
`build/px4_sitl_default/src/lib/mixer/MultirotorMixer/mixer_multirotor_normalized.generated.h`

To generate the motor output, use the following formula:  
`u = P m`  
Where `u` is the normalized motor output vector, `P` is the control allocation matrix and `m` is the normalized torques (roll/pitch/yaw) and vertical thrust.

For a quad\_plus, the control allocation matrix is straightforward:

```auto
static constexpr MultirotorMixer::Rotor _config_quad_plus[] {
	{ -1.000000, -0.000000, 1.000000, 1.000000 },
	{ 1.000000, -0.000000, 1.000000, 1.000000 },
	{ -0.000000, 1.000000, -1.000000, 1.000000 },
	{ -0.000000, -1.000000, -1.000000, 1.000000 },
};

```

And for a quad\_x, the gains are slightly lower to get the same roll/pitch/yaw gains (note that 0.707 \* 0.707 = 0.5):

```auto
static constexpr MultirotorMixer::Rotor _config_quad_x[] {
	{ -0.707107, 0.707107, 1.000000, 1.000000 },
	{ 0.707107, -0.707107, 1.000000, 1.000000 },
	{ 0.707107, 0.707107, -1.000000, 1.000000 },
	{ -0.707107, -0.707107, -1.000000, 1.000000 },
};

```

---

<div class="post-metadata">

**Author:** ![Asghari936](https://discuss.px4.io/user_avatar/discuss.px4.io/asghari936/32/9666_2.png) [@Asghari936](https://discuss.px4.io/u/Asghari936)\
**Post date:** [November 18, 2021, 8:18pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/38 "2021-11-18T20:18:25Z")

</div>

Thanks bresch @bresch. Is this mixer code usually the same for every flight controller that ardupilot supports?  
Like other pixhawk versions or old flight controllers like apm that was supported before?

---

<div class="post-metadata">

**Author:** ![auturgy](https://discuss.px4.io/letter_avatar_proxy/v4/letter/a/e480ec/32.png) [@auturgy](https://discuss.px4.io/u/auturgy)\
**Post date:** [November 18, 2021, 9:04pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/39 "2021-11-18T21:04:27Z")

</div>

ArduPilot is completely different software. Best to ask about ArduPilot at [discuss.ardupilot.org](http://discuss.ardupilot.org) or perhaps for this question in their developers discord ([ArduPilot](https://ardupilot.org/discord))

---

<div class="post-metadata">

**Author:** ![Shd](https://discuss.px4.io/letter_avatar_proxy/v4/letter/s/c2a13f/32.png) [@Shd](https://discuss.px4.io/u/Shd)\
**Post date:** [January 6, 2022, 7:37pm UTC](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186/40 "2022-01-06T19:37:21Z")

</div>

Could you please check your messages?

[Previous page](https://discuss.px4.io/t/position-and-attitud-controllers-diagram/3186.md?page=1)
