Skip to content

Commit e2f9306

Browse files
authored
enu-ned quat convertion (#32)
* enu-ned quat convertion * lambda initialization
1 parent 16802e9 commit e2f9306

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ repos:
7979
rev: v2.4.1
8080
hooks:
8181
- id: codespell
82-
args: ['--write-changes', '--ignore-words-list=theses']
82+
args: ['--write-changes', '--ignore-words-list=theses,ned']
8383
# For more information on pre-commit.ci and its configuration, visit:
8484
# https://pre-commit.ci/
8585
ci:

vortex_utils/cpp_test/test_math.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,32 @@ TEST(average_quaternions, test_degeneracy) {
431431
EXPECT_THROW(average_quaternions({q0, q180}), std::runtime_error);
432432
}
433433

434+
TEST(enu_ned_rotation, explicit_matrix_values) {
435+
Eigen::Quaterniond q_enu = euler_to_quat(0, 0, M_PI / 2);
436+
Eigen::Quaterniond q_ned = enu_ned_rotation(q_enu);
437+
438+
Eigen::Matrix3d R_frame;
439+
R_frame << 0, 1, 0, 1, 0, 0, 0, 0, -1;
440+
441+
Eigen::Matrix3d R_expected = R_frame * q_enu.toRotationMatrix();
442+
Eigen::Matrix3d R_actual = q_ned.toRotationMatrix();
443+
444+
EXPECT_TRUE(R_actual.isApprox(R_expected, 1e-12));
445+
}
446+
447+
TEST(enu_ned_rotation, test_symmetry) {
448+
Eigen::Quaterniond q_enu = Eigen::Quaterniond(
449+
Eigen::AngleAxisd(M_PI / 4, Eigen::Vector3d::UnitZ()));
450+
451+
Eigen::Quaterniond q_ned = enu_ned_rotation(q_enu);
452+
Eigen::Quaterniond q_enu_converted_back = enu_ned_rotation(q_ned);
453+
454+
EXPECT_TRUE(q_enu.isApprox(q_enu_converted_back, 1e-12) ||
455+
q_enu.isApprox(Eigen::Quaterniond(-q_enu_converted_back.w(),
456+
-q_enu_converted_back.x(),
457+
-q_enu_converted_back.y(),
458+
-q_enu_converted_back.z()),
459+
1e-12));
460+
}
461+
434462
} // namespace vortex::utils::math

vortex_utils/include/vortex/utils/math.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,13 @@ Eigen::VectorXd anti_windup(const double dt,
158158
Eigen::Quaterniond average_quaternions(
159159
const std::vector<Eigen::Quaterniond>& quaternions);
160160

161+
/**
162+
* @brief Convert a quaternion between ENU and NED frames. Works both ways.
163+
* @param quat Eigen::Quaterniond
164+
* @return Eigen::Quaterniond
165+
*/
166+
Eigen::Quaterniond enu_ned_rotation(const Eigen::Quaterniond& quat);
167+
161168
} // namespace vortex::utils::math
162169

163170
#endif // VORTEX_UTILS_MATH_HPP

vortex_utils/include/vortex/utils/types.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,28 @@ struct Pose {
183183
return quat.normalized();
184184
}
185185

186+
/**
187+
* @brief Set the position from an Eigen::Vector3d.
188+
* @param pos Eigen::Vector3d
189+
*/
190+
void set_pos(const Eigen::Vector3d& pos) {
191+
x = pos.x();
192+
y = pos.y();
193+
z = pos.z();
194+
}
195+
196+
/**
197+
* @brief Set the orientation from an Eigen::Quaterniond.
198+
* @param ori Eigen::Quaterniond
199+
*/
200+
void set_ori(const Eigen::Quaterniond& ori) {
201+
Eigen::Quaterniond q = ori.normalized();
202+
qw = q.w();
203+
qx = q.x();
204+
qy = q.y();
205+
qz = q.z();
206+
}
207+
186208
/**
187209
* @brief Convert to Eigen::Vector7d
188210
* @return Eigen::Vector7d{x, y, z, qw, qx, qy, qz}

vortex_utils/src/math.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,4 +174,19 @@ Eigen::Quaterniond average_quaternions(
174174
return avg_q.normalized();
175175
}
176176

177+
Eigen::Quaterniond enu_ned_rotation(const Eigen::Quaterniond& quat) {
178+
const Eigen::Matrix3d rotation_matrix_enu_to_ned = [] {
179+
Eigen::Matrix3d rotmat;
180+
rotmat.col(0) = Eigen::Vector3d(0, 1, 0);
181+
rotmat.col(1) = Eigen::Vector3d(1, 0, 0);
182+
rotmat.col(2) = Eigen::Vector3d(0, 0, -1);
183+
return rotmat;
184+
}();
185+
186+
Eigen::Quaterniond q_out =
187+
Eigen::Quaterniond(rotation_matrix_enu_to_ned) * quat.normalized();
188+
189+
return q_out.normalized();
190+
}
191+
177192
} // namespace vortex::utils::math

0 commit comments

Comments
 (0)