Brian Silverman | 8d3816a | 2017-07-03 18:52:15 -0700 | [diff] [blame] | 1 | #include "motors/math.h" |
| 2 | |
| 3 | #include "gtest/gtest.h" |
| 4 | #include "gmock/gmock.h" |
| 5 | |
| 6 | namespace frc971 { |
| 7 | namespace salsa { |
| 8 | namespace testing { |
| 9 | |
| 10 | class SinCosIntTest : public ::testing::Test { |
| 11 | public: |
| 12 | void SetUp() override { |
| 13 | MathInit(); |
| 14 | } |
| 15 | |
| 16 | template <class Rotation> |
| 17 | void CheckSinCos() { |
| 18 | static constexpr float kTolerance = 0.004; |
| 19 | for (uint32_t theta = 0; theta < Rotation::den; ++theta) { |
| 20 | EXPECT_THAT( |
| 21 | FastSinInt<Rotation>(theta), |
| 22 | ::testing::FloatNear(sin(ThetaToFloat<Rotation>(theta)), kTolerance)); |
| 23 | EXPECT_THAT( |
| 24 | FastCosInt<Rotation>(theta), |
| 25 | ::testing::FloatNear(cos(ThetaToFloat<Rotation>(theta)), kTolerance)); |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | private: |
| 30 | template <class Rotation> |
| 31 | double ThetaToFloat(uint32_t theta) { |
| 32 | const double rotation_double = |
| 33 | static_cast<double>(Rotation::num) / static_cast<double>(Rotation::den); |
| 34 | return (static_cast<double>(theta) + 0.5) * rotation_double * 2.0 * M_PI; |
| 35 | } |
| 36 | }; |
| 37 | |
| 38 | TEST_F(SinCosIntTest, Numerator1) { |
| 39 | CheckSinCos<::std::ratio<1, 2>>(); |
| 40 | CheckSinCos<::std::ratio<1, 4>>(); |
| 41 | CheckSinCos<::std::ratio<1, 8>>(); |
| 42 | CheckSinCos<::std::ratio<1, 128>>(); |
| 43 | CheckSinCos<::std::ratio<1, 1024>>(); |
Brian Silverman | a6e53b4 | 2018-01-03 20:33:15 -0800 | [diff] [blame^] | 44 | CheckSinCos<::std::ratio<1, 4096>>(); |
Brian Silverman | 8d3816a | 2017-07-03 18:52:15 -0700 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | TEST_F(SinCosIntTest, Numerator5) { |
| 48 | CheckSinCos<::std::ratio<5, 8>>(); |
| 49 | CheckSinCos<::std::ratio<5, 128>>(); |
| 50 | CheckSinCos<::std::ratio<5, 1024>>(); |
Brian Silverman | a6e53b4 | 2018-01-03 20:33:15 -0800 | [diff] [blame^] | 51 | CheckSinCos<::std::ratio<5, 4096>>(); |
Brian Silverman | 8d3816a | 2017-07-03 18:52:15 -0700 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | class SinCosFloatTest : public ::testing::Test { |
| 55 | public: |
| 56 | void SetUp() override { |
| 57 | MathInit(); |
| 58 | } |
| 59 | |
| 60 | void CheckSinCos(float theta) { |
| 61 | ASSERT_GE(theta, -0.2f); |
| 62 | ASSERT_LE(theta, 0.2f); |
| 63 | |
| 64 | static constexpr float kTolerance = 0.002; |
| 65 | EXPECT_THAT(FastSinFloat(theta), |
| 66 | ::testing::FloatNear(sin(theta), kTolerance)); |
| 67 | EXPECT_THAT(FastCosFloat(theta), |
| 68 | ::testing::FloatNear(cos(theta), kTolerance)); |
| 69 | } |
| 70 | }; |
| 71 | |
| 72 | TEST_F(SinCosFloatTest, Endpoints) { |
| 73 | CheckSinCos(0); |
| 74 | CheckSinCos(-0.2); |
| 75 | CheckSinCos(0.2); |
| 76 | } |
| 77 | |
| 78 | } // namespace testing |
| 79 | } // namespace salsa |
| 80 | } // namespace frc971 |