mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 18:47:21 +08:00
matrix: add angle unwrapping method
This commit is contained in:
committed by
Matthias Grob
parent
68a0414622
commit
5a3aba9c21
@@ -123,6 +123,27 @@ Type wrap_2pi(Type x)
|
|||||||
return wrap(x, Type(0), Type(M_TWOPI));
|
return wrap(x, Type(0), Type(M_TWOPI));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unwrap angles
|
||||||
|
*
|
||||||
|
* @param[in] last_angle Last unwrapped angle [rad]
|
||||||
|
* @param[in] new_angle New angle in [-pi, pi] [rad]
|
||||||
|
* @return New unwrapped angle [rad]
|
||||||
|
*/
|
||||||
|
template<typename Type>
|
||||||
|
Type unwrap(const Type last_angle, const Type new_angle)
|
||||||
|
{
|
||||||
|
// wrap the last angle in [-pi,pi]
|
||||||
|
const Type last_angle_wrapped = matrix::detail::wrap_floating(last_angle, -Type(M_PI), Type(M_PI));
|
||||||
|
|
||||||
|
// use the shortest distance
|
||||||
|
Type delta = new_angle - last_angle_wrapped;
|
||||||
|
delta += ((delta < -Type(M_PI)) - (delta > Type(M_PI))) * Type(2 *
|
||||||
|
M_PI); // adds or subtracts 2*pi if delta out of range
|
||||||
|
|
||||||
|
return delta + last_angle;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
int sign(T val)
|
int sign(T val)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,3 +44,4 @@ foreach(test_name ${tests})
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
px4_add_unit_gtest(SRC sparseVector.cpp)
|
px4_add_unit_gtest(SRC sparseVector.cpp)
|
||||||
|
px4_add_unit_gtest(SRC unwrap.cpp)
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include <matrix/math.hpp>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace matrix;
|
||||||
|
|
||||||
|
TEST(Unwrap, UnwrapFloats)
|
||||||
|
{
|
||||||
|
const float M_TWO_PI_F = float(M_PI * 2);
|
||||||
|
|
||||||
|
float unwrapped_angles[6] = {0.0, 0.25, 0.5, 0.75, 1.0, 1.25};
|
||||||
|
float wrapped_angles[6] = {0.0, 0.25, 0.5, -0.25, 0.0, 0.25};
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
unwrapped_angles[i] *= M_TWO_PI_F;
|
||||||
|
wrapped_angles[i] *= M_TWO_PI_F;
|
||||||
|
}
|
||||||
|
|
||||||
|
// positive unwrapping
|
||||||
|
float last_angle = wrapped_angles[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < 6; i++) {
|
||||||
|
last_angle = unwrap(last_angle, wrapped_angles[i]);
|
||||||
|
EXPECT_FLOAT_EQ(last_angle, unwrapped_angles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// negative unwrapping
|
||||||
|
last_angle = -wrapped_angles[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < 6; i++) {
|
||||||
|
last_angle = unwrap(last_angle, -wrapped_angles[i]);
|
||||||
|
EXPECT_FLOAT_EQ(last_angle, -unwrapped_angles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Unwrap, UnwrapDoubles)
|
||||||
|
{
|
||||||
|
const double M_TWO_PI = M_PI * 2;
|
||||||
|
|
||||||
|
double unwrapped_angles[6] = {0.0, 0.25, 0.5, 0.75, 1.0, 1.25};
|
||||||
|
double wrapped_angles[6] = {0.0, 0.25, 0.5, -0.25, 0.0, 0.25};
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
unwrapped_angles[i] *= M_TWO_PI;
|
||||||
|
wrapped_angles[i] *= M_TWO_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// positive unwrapping
|
||||||
|
double last_angle = wrapped_angles[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < 6; i++) {
|
||||||
|
last_angle = unwrap(last_angle, wrapped_angles[i]);
|
||||||
|
EXPECT_DOUBLE_EQ(last_angle, unwrapped_angles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// negative unwrapping
|
||||||
|
last_angle = -wrapped_angles[0];
|
||||||
|
|
||||||
|
for (int i = 1; i < 6; i++) {
|
||||||
|
last_angle = unwrap(last_angle, -wrapped_angles[i]);
|
||||||
|
EXPECT_DOUBLE_EQ(last_angle, -unwrapped_angles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user