-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Angular velocity representations differ in mCurrentState.angular and merged_command.command.angular #35
Comments
Hello Gabriel, I have noticed this issue a while back when I was trying to use the However my speculation is that this control chain was designed that way (meaning it is necessary to have the This issue is inherent to the cascaded control architecture, as the output of the position controller is considered as a reference velocity that is fed into the velocity controller. If the Euler difference is used as the error in the position control, that makes life easy as long as the pitch is not close to 90 deg, since this orientation error is a 3-component-vector representation and can be easier perceived geometrically. This would also be transformed to the body frame using the equation (2.28), keeping in mind the singularity. Another method is to use the quaternion error representation described in [Antonelli, 2001]. Assuming the reference attitude is and the actual attitude is , the attitude error can be given as or expanded as the following This method has a dual representation problem (one real attitude can have 2 quaternion representations) however that is fixed by looking at the sign of the and multiplying by -1 if . Pros of this method are no singularities, and equation (2.62) from the book by Fossen can be used to recover the angular velocities in body frame. However, the main issue here is that the control output is nonlinear with respect to angle errors. There is also a third method that was suggested to me by @saarnold is which is to use manifolds to calculate the orientation error. I am not familiar with this method yet, but here is a paper that describes the mathematical formulation. It seems quite dense from the first look, but I will take a deeper look into it when I get the time. |
Hi @bwehbe , thanks for your input. I really appreciate it! I do agree with everything you mentioned, specially that the control-chain might have been designed that way to avoid the singularity around 90 deg. However, I've made this comment on the PR that I think we could leverage from your perspective as well. My point there is that it would be better to perform such transform on the However, doing it on the
I think this is a great idea but, IMHO, if implemented, it should be added as an option for the attitude control for backward compatibility reasons.
I think this is also a great idea, I gave a first look into the paper and it seems interesting. Another reference that I like on that topic is this paper. |
I have notice what appears to be, IMHO, an inconsistency on the angular velocity control due to possibly having different representations for the angular velocity when considering the controller reference and the measured value. From the
updateHook()
method ofPIDController.cpp
As
mCurrentState.angular = pose_sample.angular_velocity
, from theRigidBodyState
documentation, we see thatangular_velocity
is the "Angular Velocity of sourceFrame relative to targetFrame, expressed in sourceFrame, as an axis-angle representation. The direction of the vector is the axis, its length the speed". Until that point, everything appears to be good to me and consistent to what is written in this section of the README of this repository: "in the world-aligned body velocity domain, linear is a (v_x, v_y, v_z) velocity and angular is a scaled-axis representation of the system’s angular velocity."However, the angular part of
merged_command
is not changed neither onWorldToAligned
nor in any other controller task. Thus, in my opinion, unless the velocity control loop is receiving its setpoint from an external component that is actually sending it as it should (an axis-angle representation of the angular velocity), thePIDController
might be using a different representation for the reference angular velocity.This could happen with a simple cascade from a position to an inner velocity control loop. As an example, consider the following, not unusual, use-case:
First, a position control loop is performed considering world-frame as the command frame. In that case, as per the documentation, the expected
LinearAngular6DCommand
"linear is a (x, y, z) position and angular is a (yaw, pitch, roll) expression of an attitude, where (yaw, pitch, roll) are a decomposition of the attitude over euler angles using the (Z, Y, X) decomposition."Then, the output of the position loop could be cascaded to a velocity control loop and for that case, this velocity
LinearAngular6DCommand
would mean: linear is a (vx, vy, vz) reference while angular is an Euler angle rate (v_yaw, v_pitch, v_roll) reference. Thus, performing the velocity control loop either in the world or in the aligned frame would lead to the same issue: a comparison between (v_roll, v_pitch, v_yaw) with (wx, wy, wz).This mapping from angular velocity to Euler angles rate (Jacobian of the representation) is actually not hard to obtain and its expression for the ZYX-order would be (from Fossen):
I guess this is not easily perceived because for
roll ≃ pitch ≃ 0
, which is quite common for AUVs, the Euler angles rate is equal to angular velocity (mapping equals to Identity). I have performed some unit tests that actually confirmed thatmerged_command.angular
is not altered in any case whenposition_control = false
for thePIDController
task.@joaobrittoneto , @saarnold , @doudou , do you have any thoughts on this? It may be that I got something wrong and I apologize in advance if I misunderstood something. If that is the case, I will close this issue.
The text was updated successfully, but these errors were encountered: