Open jilinzhou opened 6 years ago
Applying the right-hand rule on the x, y and z axes of vehicle frame, the Euler angles (roll, pitch and yaw) are defined, respectively. Yaw is positive when the vehicle turns left; Pitch is positive when the vehicle is nose up; Roll is positive when the left side of the vehicle is up. In novatel_parser.cc, vehicle frame is FLU. The original idea is publish sensor-independent vehicle frame in driver. In data_parser.cc, vehicle frame is converted back to RFU(Localization module use RFU vehicle body frame); Because yaw is positive when the vehicle turns left, yaw is counterclockwise from North(opposite to azimuth). In the following code,
// 2. orientation
Eigen::Quaterniond q =
Eigen::AngleAxisd(ins->euler_angles().z() - 90 * DEG_TO_RAD_LOCAL,
Eigen::Vector3d::UnitZ()) *
Eigen::AngleAxisd(-ins->euler_angles().y(), Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(ins->euler_angles().x(), Eigen::Vector3d::UnitY());
Since euler angle in ins messgae is FLU frame, the auler angle in RFU frame is below:
yaw_rfu = ins->euler_angles().z() - 90 * DEG_TO_RAD_LOCAL;
pitch_rfu = -ins->euler_angles().y();
roll_rfu = ins->euler_angles().x();
Using intrinsic z-y-x sequence, quaternion is below:
Eigen::Quaterniond q =
Eigen::AngleAxisd(yaw_rfu,
Eigen::Vector3d::UnitZ()) *
Eigen::AngleAxisd(pitch_rfu, Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(roll_rfu, Eigen::Vector3d::UnitY());
In Planning, heading is counterclockwise from x-axis (ENU frame).
@hillbrook :
Is the sequence in the following code z-x-y (UnitZ(), UnitX(), then UnitY())?
// 2. orientation
Eigen::Quaterniond q =
Eigen::AngleAxisd(ins->euler_angles().z() - 90 * DEG_TO_RAD_LOCAL,
Eigen::Vector3d::UnitZ()) *
Eigen::AngleAxisd(-ins->euler_angles().y(), Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(ins->euler_angles().x(), Eigen::Vector3d::UnitY());
The sequence is z-x-y.
@hillbrook: Absolutely right! For clarification and most important, I paste the definition of Euler angle in apollo project below:
// in world coordinate (East/North/Up)
// The roll, in (-pi/2, pi/2), corresponds to a rotation around the y-axis.
// The pitch, in [-pi, pi), corresponds to a rotation around the x-axis.
// The yaw, in [-pi, pi), corresponds to a rotation around the z-axis.
// The direction of rotation follows the right-hand rule.
optional apollo.common.Point3D euler_angles = 9;
as well as @xinwf 's good analyse: #5713
@hillbrook @jilinzhou if it is z-x-y, shouldn't the rotation around z be at the right most? just like
// 2. orientation
Eigen::Quaterniond q =
Eigen::AngleAxisd(ins->euler_angles().x(), Eigen::Vector3d::UnitY())*
Eigen::AngleAxisd(-ins->euler_angles().y(), Eigen::Vector3d::UnitX()) *
Eigen::AngleAxisd(ins->euler_angles().z() - 90 * DEG_TO_RAD_LOCAL,
Eigen::Vector3d::UnitZ());
And also, in the document (apn37 https://www.novatel.com/support/search/items/Application%20Note) from Novatel, the rotation around z is at the right most.
@zhixy you need to check "Relating the Body Frame to the Local Level Frame" in (https://www.novatel.com/support/search/items/Application%20Note),the rotation matrix is formed by euler angles of intrinsic rotation in z-x-y order. And you can refer to https://en.wikipedia.org/wiki/Euler_angles.
I notice the issue as I am swapping out gnss driver with our own sensor framework.
In novatel_parser.cc, the orientation is converted from RFU to FLU. Specially, the azimuth angle (measured clockwise from North) is converted to Yaw (counterclockwise from East).
Then in data_parser.cpp, all of them are converted back to RFU and these are all fine. The problem is the yaw angle is funnily converted back to azimuth (measured from North but counterclockwise, so not in real azimuth sense) and quaternion is formed using azimuth angle which is incorrectly as my understanding (Please see application note apn037.pdf from Novatel at https://www.novatel.com/support/search/items/Application%20Note).
There are a few consequences here:
Luckily these world frame (map reference) acceleration and angular velocity are never used in the control node, so we do not see the actual problem. But the rotated vectors are certainly not what we are expecting.
Any comments will be appreciated!