Add mju_euler2Quat.
PiperOrigin-RevId: 623469398 Change-Id: Ia86b29a764018cd4c3bc57d23616bed7393081f5
This commit is contained in:
committed by
Copybara-Service
parent
2b3f336bd3
commit
5a365603f8
@@ -19,8 +19,10 @@
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gtest/gtest-spi.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "src/engine/engine_util_blas.h"
|
||||
#include "src/engine/engine_util_spatial.h"
|
||||
#include "test/fixture.h"
|
||||
@@ -28,7 +30,9 @@
|
||||
namespace mujoco {
|
||||
namespace {
|
||||
|
||||
using ::testing::DoubleNear;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Pointwise;
|
||||
|
||||
using Quat2MatTest = MujocoTest;
|
||||
|
||||
@@ -103,9 +107,10 @@ TEST_F(RotVecQuatTest, TinyRotation) {
|
||||
);
|
||||
}
|
||||
|
||||
// Alternative way of rotating a vector by explicitly converting the quaternion to a 3x3 matrix
|
||||
void RotVecQuatWithMatrix(mjtNum res[3], const mjtNum vec[3], const mjtNum quat[4]) {
|
||||
if (quat[0]==1 && quat[1]==0 && quat[2]==0 && quat[3]==0) {
|
||||
// Rotate a vector by explicitly converting the quaternion to a 3x3 matrix
|
||||
void RotVecQuatWithMatrix(mjtNum res[3], const mjtNum vec[3],
|
||||
const mjtNum quat[4]) {
|
||||
if (quat[0] == 1 && quat[1] == 0 && quat[2] == 0 && quat[3] == 0) {
|
||||
mju_copy3(res, vec);
|
||||
} else {
|
||||
mjtNum mat[9];
|
||||
@@ -122,10 +127,10 @@ TEST_F(RotVecQuatTest, TestEquivalence) {
|
||||
// List of angles to rotate by, in degrees
|
||||
mjtNum angles[6] = {0.0, 1e-8, 31, 47, 181, 271};
|
||||
static const mjtNum eps = 1e-15;
|
||||
for (auto vec: vecs) {
|
||||
for (auto vec : vecs) {
|
||||
// Unit-normalize the vector
|
||||
mju_normalize3(vec);
|
||||
for (auto angleDegree: angles) {
|
||||
for (auto angleDegree : angles) {
|
||||
// Convert the axis-angle to a quaternion
|
||||
auto angleRad = angleDegree * mjPI / 180;
|
||||
mju_axisAngle2Quat(quat, vec, angleRad);
|
||||
@@ -140,5 +145,61 @@ TEST_F(RotVecQuatTest, TestEquivalence) {
|
||||
}
|
||||
}
|
||||
|
||||
using Euler2QuatTest = MujocoTest;
|
||||
|
||||
TEST_F(Euler2QuatTest, BadSeq) {
|
||||
EXPECT_FATAL_FAILURE({
|
||||
mjtNum quat[4];
|
||||
mjtNum euler[3] = {0};
|
||||
char seq[] = "xiz";
|
||||
mju_euler2Quat(quat, euler, seq);
|
||||
}, "mju_euler2Quat: seq[1] is 'i', should be one of x, y, z, X, Y, Z");
|
||||
}
|
||||
|
||||
TEST_F(Euler2QuatTest, BadSeqLength) {
|
||||
EXPECT_FATAL_FAILURE({
|
||||
mjtNum quat[4];
|
||||
mjtNum euler[3] = {0};
|
||||
char seq[] = "xyzy";
|
||||
mju_euler2Quat(quat, euler, seq);
|
||||
}, "mju_euler2Quat: seq must contain exactly 3 characters");
|
||||
}
|
||||
|
||||
TEST_F(Euler2QuatTest, Euler2Quat) {
|
||||
double quat[4] = {0};
|
||||
double tol = 1e-14;
|
||||
|
||||
char seq[] = "xyz";
|
||||
double euler[3] = {mjPI, 0, 0};
|
||||
double expected[4] = {0, 1, 0, 0};
|
||||
mju_euler2Quat(quat, euler, seq);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected));
|
||||
|
||||
euler[1] = mjPI;
|
||||
double expected2[4] = {0, 0, 0, 1};
|
||||
mju_euler2Quat(quat, euler, seq);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected2));
|
||||
|
||||
char seq2[] = "XYZ";
|
||||
double expected3[4] = {0, 0, 0, -1};
|
||||
mju_euler2Quat(quat, euler, seq2);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected3));
|
||||
|
||||
double euler2[3] = {2*mjPI, 2*mjPI, 2*mjPI};
|
||||
double expected4[4] = {-1, 0, 0, 0};
|
||||
mju_euler2Quat(quat, euler2, seq);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected4));
|
||||
mju_euler2Quat(quat, euler2, seq2);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected4));
|
||||
|
||||
double euler3[3] = {mjPI/2, mjPI/2, mjPI/2};
|
||||
double expected5[4] = {0, mju_sqrt(.5), 0, mju_sqrt(.5)};
|
||||
mju_euler2Quat(quat, euler3, seq);
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected5));
|
||||
mju_euler2Quat(quat, euler3, seq2);
|
||||
double expected6[4] = {mju_sqrt(.5), 0, mju_sqrt(.5), 0};
|
||||
EXPECT_THAT(quat, Pointwise(DoubleNear(tol), expected6));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user