2021-05-19 11:22:59 -03:00
|
|
|
|
|
|
|
// given we are in the Math library, you're epected to know what
|
|
|
|
// you're doing when directly comparing floats:
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
|
|
|
#define ALLOW_DOUBLE_MATH_FUNCTIONS
|
|
|
|
#include <AP_gtest.h>
|
|
|
|
|
|
|
|
#include <AP_Math/AP_Math.h>
|
|
|
|
|
|
|
|
const AP_HAL::HAL& hal = AP_HAL::get_HAL();
|
|
|
|
|
|
|
|
|
|
|
|
TEST(MathTest, IsZeroDouble)
|
|
|
|
{
|
|
|
|
EXPECT_FALSE(is_zero(0.1));
|
|
|
|
EXPECT_FALSE(is_zero(0.0001));
|
|
|
|
EXPECT_TRUE(is_zero(0.0));
|
|
|
|
EXPECT_TRUE(is_zero(DBL_MIN));
|
|
|
|
EXPECT_TRUE(is_zero(-DBL_MIN));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, MAXDouble)
|
|
|
|
{
|
|
|
|
AP_Float t_float;
|
|
|
|
t_float = 0.1f;
|
|
|
|
EXPECT_EQ(2.0, MAX(t_float, 2.0));
|
|
|
|
}
|
|
|
|
TEST(MathTest, IsEqualDouble)
|
|
|
|
{
|
|
|
|
EXPECT_FALSE(is_equal(1.0, 0.0));
|
|
|
|
EXPECT_TRUE(is_equal(1.0, 1.0));
|
|
|
|
EXPECT_FALSE(is_equal(0.1, 0.10001));
|
|
|
|
EXPECT_FALSE(is_equal(0.1, -0.1001));
|
|
|
|
EXPECT_TRUE(is_equal(0.0, 0.0));
|
|
|
|
EXPECT_FALSE(is_equal(1.0, 1.0 + DBL_EPSILON));
|
|
|
|
EXPECT_TRUE(is_equal(1.0, 1.0 + DBL_EPSILON / 2.0));
|
|
|
|
EXPECT_FALSE(is_equal((double)1.0, (double)(1.0 - DBL_EPSILON)));
|
|
|
|
|
|
|
|
// false because the common type is double
|
|
|
|
EXPECT_FALSE(is_equal(double(1.0), 1 + 2 * std::numeric_limits<double>::epsilon()));
|
|
|
|
|
|
|
|
// true because the common type is float
|
|
|
|
EXPECT_FALSE(is_equal((double)1.0, (double)(1.0 + std::numeric_limits<double>::epsilon())));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, ConstrainDouble)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 1000; i++) {
|
|
|
|
if (i < 250) {
|
|
|
|
EXPECT_EQ(250.0, constrain_value((double)i, 250.0, 500.0));
|
|
|
|
} else if (i > 500) {
|
|
|
|
EXPECT_EQ(500.0, constrain_value((double)i, 250.0, 500.0));
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(i, constrain_value((double)i, 250.0, 500.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i <= 1000; i++) {
|
|
|
|
int c = i - 1000;
|
|
|
|
if (c < -250) {
|
|
|
|
EXPECT_EQ(-250.0, constrain_value((double)c, -250.0, -50.0));
|
|
|
|
} else if(c > -50) {
|
|
|
|
EXPECT_EQ(-50.0, constrain_value((double)c, -250.0, -50.0));
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(c, constrain_value((double)c, -250.0, -50.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i <= 2000; i++) {
|
|
|
|
int c = i - 1000;
|
|
|
|
if (c < -250) {
|
|
|
|
EXPECT_EQ(-250.0, constrain_value((double)c, -250.0, 50.0));
|
|
|
|
} else if(c > 50) {
|
|
|
|
EXPECT_EQ(50.0, constrain_value((double)c, -250.0, 50.0));
|
|
|
|
} else {
|
|
|
|
EXPECT_EQ(c, constrain_value((double)c, -250.0, 50.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPECT_EQ(20.0, constrain_value(20.0, 19.9, 20.1));
|
|
|
|
|
|
|
|
EXPECT_EQ(20.1, constrain_value(21.0, 19.9, 20.1));
|
|
|
|
|
|
|
|
EXPECT_EQ(19.9, constrain_value(19.9, 19.9, 20.1));
|
|
|
|
|
|
|
|
EXPECT_EQ(19.9, constrain_value(19.8, 19.9, 20.1));
|
|
|
|
|
2021-08-20 02:57:41 -03:00
|
|
|
#if CONFIG_HAL_BOARD == HAL_BOARD_LINUX
|
2021-05-19 11:22:59 -03:00
|
|
|
EXPECT_EQ(1.0, constrain_value(nan("0x4152"), 1.0, 1.0));
|
2021-08-20 02:57:41 -03:00
|
|
|
#elif CONFIG_HAL_BOARD == HAL_BOARD_SITL
|
|
|
|
EXPECT_EXIT(constrain_value(nan("0x4152"), 1.0, 1.0), testing::KilledBySignal(SIGABRT), "AP_InternalError::error_t::cnstring_nan");
|
|
|
|
#endif
|
2021-05-19 11:22:59 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathWrapTest, Angle180Double)
|
|
|
|
{
|
|
|
|
EXPECT_EQ(4500.0, wrap_180_cd(4500.0));
|
|
|
|
EXPECT_EQ(9000.0, wrap_180_cd(9000.0));
|
|
|
|
EXPECT_EQ(18000.0, wrap_180_cd(18000.0));
|
|
|
|
EXPECT_EQ(-17990.0, wrap_180_cd(18010.0));
|
|
|
|
EXPECT_EQ(-9000.0, wrap_180_cd(27000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(36000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(72000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(360000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(720000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(-3600000000.0));
|
|
|
|
|
|
|
|
EXPECT_EQ(-4500.0, wrap_180_cd(-4500.0));
|
|
|
|
EXPECT_EQ(-9000.0, wrap_180_cd(-9000.0));
|
|
|
|
EXPECT_EQ(18000.0, wrap_180_cd(-18000.0));
|
|
|
|
EXPECT_EQ(17990.0, wrap_180_cd(-18010.0));
|
|
|
|
EXPECT_EQ(9000.0, wrap_180_cd(-27000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(-36000.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180_cd(-72000.0));
|
|
|
|
|
|
|
|
EXPECT_EQ(-45.0, wrap_180(-45.0));
|
|
|
|
EXPECT_EQ(-90.0, wrap_180(-90.0));
|
|
|
|
EXPECT_EQ(180.0, wrap_180(-180.0));
|
|
|
|
EXPECT_EQ(90.0, wrap_180(-270.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180(-360.0));
|
|
|
|
EXPECT_EQ(0.0, wrap_180(-720.0));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathWrapTest, Angle360Double)
|
|
|
|
{
|
|
|
|
// Full circle test
|
|
|
|
for (int32_t i = 0; i <= 36000; i += 100) {
|
|
|
|
if (i == 0) {
|
|
|
|
// hit pole position
|
|
|
|
EXPECT_EQ(i, wrap_360_cd(static_cast<double>(i)));
|
|
|
|
EXPECT_EQ(i, wrap_360_cd(static_cast<double>(-i)));
|
|
|
|
} else if (i < 36000) {
|
|
|
|
// between pole position
|
|
|
|
EXPECT_EQ(i, wrap_360_cd(static_cast<double>(i)));
|
|
|
|
EXPECT_EQ(36000.0 - i, wrap_360_cd(static_cast<double>(-i)));
|
|
|
|
} else if (i == 36000) {
|
|
|
|
// hit pole position
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(i)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(-i)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPECT_EQ(4500.0, wrap_360_cd(static_cast<double>(4500.0)));
|
|
|
|
EXPECT_EQ(9000.0, wrap_360_cd(static_cast<double>(9000.0)));
|
|
|
|
EXPECT_EQ(18000.0, wrap_360_cd(static_cast<double>(18000.0)));
|
|
|
|
EXPECT_EQ(27000.0, wrap_360_cd(static_cast<double>(27000.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(36000.0)));
|
|
|
|
EXPECT_EQ(5.0, wrap_360_cd(static_cast<double>(36005.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(72000.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(360000.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(720000.0)));
|
|
|
|
EXPECT_EQ( 0.0, wrap_360_cd(static_cast<double>(-3600000000.0)));
|
|
|
|
|
|
|
|
EXPECT_EQ(31500.0, wrap_360_cd(static_cast<double>(-4500.0)));
|
|
|
|
EXPECT_EQ(27000.0, wrap_360_cd(static_cast<double>(-9000.0)));
|
|
|
|
EXPECT_EQ(18000.0, wrap_360_cd(static_cast<double>(-18000.0)));
|
|
|
|
EXPECT_EQ(9000.0, wrap_360_cd(static_cast<double>(-27000.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(-36000.0)));
|
|
|
|
EXPECT_EQ(35995.0,wrap_360_cd(static_cast<double>(-36005.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360_cd(static_cast<double>(-72000.0)));
|
|
|
|
|
|
|
|
EXPECT_EQ(45.0, wrap_360(static_cast<double>(45.0)));
|
|
|
|
EXPECT_EQ(90.0, wrap_360(static_cast<double>(90.0)));
|
|
|
|
EXPECT_EQ(180.0, wrap_360(static_cast<double>(180.0)));
|
|
|
|
EXPECT_EQ(270.0, wrap_360(static_cast<double>(270.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360(static_cast<double>(360.0)));
|
|
|
|
EXPECT_EQ(1.0, wrap_360(static_cast<double>(361.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360(static_cast<double>(720.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360(static_cast<double>(3600.0)));
|
|
|
|
EXPECT_EQ(0.0, wrap_360(static_cast<double>(7200.0)));
|
|
|
|
EXPECT_EQ(260.0, wrap_360(static_cast<double>(-100.0)));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathWrapTest, AnglePIDouble)
|
|
|
|
{
|
|
|
|
const double accuracy = 1.0e-5;
|
|
|
|
|
|
|
|
EXPECT_NEAR(M_PI, wrap_PI((double)M_PI), accuracy);
|
|
|
|
EXPECT_NEAR(0.0, wrap_PI((double)M_2PI), accuracy);
|
|
|
|
EXPECT_NEAR(0, wrap_PI((double)M_PI * 10.0), accuracy);
|
|
|
|
EXPECT_NEAR(-2.1415925025939941, wrap_PI((double)M_PI+1.0), accuracy);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathWrapTest, Angle2PIDouble)
|
|
|
|
{
|
|
|
|
const double accuracy = 1.0e-5;
|
|
|
|
|
|
|
|
EXPECT_NEAR(M_PI, wrap_2PI((double)M_PI), accuracy);
|
|
|
|
EXPECT_NEAR(0.0, wrap_2PI((double)M_2PI), accuracy);
|
|
|
|
EXPECT_NEAR(0.0, wrap_2PI((double)M_PI * 10.0), accuracy);
|
|
|
|
EXPECT_NEAR(0.0, wrap_2PI(0.0), accuracy);
|
|
|
|
EXPECT_NEAR(M_PI, wrap_2PI((double)-M_PI), accuracy);
|
|
|
|
EXPECT_NEAR(0, wrap_2PI((double)-M_2PI), accuracy);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, ASinDouble)
|
|
|
|
{
|
|
|
|
const double accuracy = 1.0e-5;
|
|
|
|
EXPECT_NEAR(0.0, safe_asin(double(0.0)), accuracy);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, SqrtDouble)
|
|
|
|
{
|
|
|
|
const double accuracy = 1.0e-5;
|
|
|
|
EXPECT_NEAR(0.0, safe_sqrt(double(0.0)), accuracy);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, SquareDouble)
|
|
|
|
{
|
|
|
|
double sq_0 = sq(0);
|
|
|
|
double sq_1 = sq(1);
|
|
|
|
double sq_2 = sq(2);
|
|
|
|
|
|
|
|
EXPECT_DOUBLE_EQ(0.0, sq_0);
|
|
|
|
EXPECT_DOUBLE_EQ(1.0, sq_1);
|
|
|
|
EXPECT_DOUBLE_EQ(4.0, sq_2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(MathTest, NormDouble)
|
|
|
|
{
|
|
|
|
double norm_1 = norm(1.0, 4.2);
|
|
|
|
double norm_2 = norm(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
|
|
|
|
double norm_3 = norm(0, 5.3);
|
|
|
|
double norm_4 = norm(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
|
|
|
double norm_5 = norm(3,4);
|
|
|
|
double norm_6 = norm(4.0,3.0,12.0);
|
|
|
|
|
2021-05-04 08:12:23 -03:00
|
|
|
EXPECT_DOUBLE_EQ(norm_1, 4.3174066289845809);
|
2021-05-19 11:22:59 -03:00
|
|
|
EXPECT_DOUBLE_EQ(norm_2, 4.0);
|
2021-05-04 08:12:23 -03:00
|
|
|
EXPECT_DOUBLE_EQ(norm_3, 5.2999999999999998);
|
2021-05-19 11:22:59 -03:00
|
|
|
EXPECT_DOUBLE_EQ(norm_4, 0.0);
|
|
|
|
EXPECT_DOUBLE_EQ(norm_5, 5.0);
|
|
|
|
EXPECT_DOUBLE_EQ(norm_6, 13.0);
|
|
|
|
}
|
|
|
|
|
2021-08-20 02:57:41 -03:00
|
|
|
AP_GTEST_PANIC()
|
2021-05-19 11:22:59 -03:00
|
|
|
AP_GTEST_MAIN()
|
|
|
|
|
|
|
|
#pragma GCC diagnostic pop
|