Setpoint_attitude/attitude quaternion transformation

I am trying to implement a closed loop hover control using setpoint_attitude/attitude (I know I can directly use set_point/position/local, but this is not what I want). After the get the control command from feedback and goal position, I can get desired roll pitch, yaw and thrust. However, when transformation the roll pitch yaw into quaternion so that px4 can accept the signal. I am confused what transformation should I use? I googled it seems for different transformation sequence or method, the equation to get the quaterniion is different. And in tf2::Quarternion, there are several methods, ie, setRPY, setEulerZYX. I am wondering which one should I use. (I did directly use the roll pitch yaw to control Crazyflie before, but for px4 seems I need to transform angles to quaternion).
Thanks for your time!

1 Like

@Haijie_Zhang You can use my personal project as reference. This sends the body angular rates and thrust as a command. Most of the transformation is implemented inside geometric_controller

Hi Jaeyoung,
I have several more questions.

  1. Is there a reason you use angular rates instead of desired roll pitch yaw to do this?

  2. I saw there is a function quaternion acc2quaternion(acceleration, yaw). Does that mean after I get aceleration from my own PID controller, I directly use directly use this function to get the desired quaternion angle? Then I can pub this quaternion angle to setpoin_attitude/attitude ?

  3. If question 2 is correct, what should I use for cmd_att.pose.position.x y z as shown in your post?
    My understanding is that px4 wouldn’t use these three position values since it is the attitude control, only concentrate on the attitude values. Is it correct?

  4. From your answer this post,, it seems I can directly use three desired accelerations to control the quad with setpoint_accel/accel. Is it correct? (Actually my desired attitude and thrust is calculated from desired accelerations based on the flatness equation). If yes, it would simplify my work.

Thanks for your time.

  1. Heading is one of the states that are inaccurate and hard to obtain on real vehicles. Also it is something that does not need to be too accurate for trajectory tracking. Using rates make the planner be more resilient for these kind of uncertainties

  2. Yes

  3. You can set the type mask depending on what setpoint you want to send

  4. I am not sure what the status is with acceleration setpoints. It would depend on your implementation how reliable it is since you can’t input jerk to the system

Hi Jaeyoung-Lim,
Sorry that I have more questions came up.

  1. I tried to implement the setpoint_accel controller and it seems difficult to tune. I searched and found the acceleration control is not closed on px4. I guess that is the reason why there is almost no project based on this control method.

  2. When using setpoing_raw/attitude, according to your code pubRateCommands , you set the msgs.type_mask = 128, which means you only need angular rates and thrust to do the control. I understand this together with the paper you mentioned. But when I want to only use angle setpoints and thrust to control this. It seems impossible becase the msgs.type_mask can only be set to 1, 2 or 4. I cann’t block all the angular rates at the same time. So sending attitude_setpoint and thrust is impossible. Is my understanding corret?

  3. If use setpoint_attitude/attitude and setpoint_attitude/thrust to control it, I have to cope with the pose.positoin.x, y ,z, since there is no such msgs.type_mask in PoseStamped. Which means I have to send position, attitude and thrust to control it. Is it correct? Or I can just leave the position.x, y z blank?

Because I don’t want position feedback used in my real MAV project(I will use images to calculate the desired attitudes), the only way is to send angular rates and thrust. Also, I need to change the controller implementation using images based on the paper you mentioned.

2, 3 those are both bitmasks you can mask whatever you want

I didn’t figure out how to set the type_mask correctly. It should be something like type_mask = IGNORE_ROOL_RATE | IGNORE_PITCH_RATE | IGNORE_YAW_RATE

Thanks for your explanation.