Support varying table sizes in the fast math code
Our code is currently running pretty tight on memory on the K22 (used on
fet12v2). Our encoder there also doesn't as many counts as the ones on
the pistol grip. Therefore, with a bit of cleverness and templates, we
can free up some RAM to have enough breathing room to split up the heap
and stack better.
Change-Id: Ibea73887b5570326ec1338b296f71ecab3d4ba7a
diff --git a/motors/math_test.cc b/motors/math_test.cc
index 06f168f..91100e8 100644
--- a/motors/math_test.cc
+++ b/motors/math_test.cc
@@ -13,16 +13,20 @@
MathInit();
}
- template <class Rotation>
+ template <class Rotation, int kTableSize>
void CheckSinCos() {
static constexpr float kTolerance = 0.004;
+ SCOPED_TRACE("num=" + ::std::to_string(Rotation::num) + " den=" +
+ ::std::to_string(Rotation::den) + " table_size=" +
+ ::std::to_string(kTableSize));
for (uint32_t theta = 0; theta < Rotation::den; ++theta) {
- EXPECT_THAT(
- FastSinInt<Rotation>(theta),
- ::testing::FloatNear(sin(ThetaToFloat<Rotation>(theta)), kTolerance));
- EXPECT_THAT(
- FastCosInt<Rotation>(theta),
- ::testing::FloatNear(cos(ThetaToFloat<Rotation>(theta)), kTolerance));
+ const float theta_float = ThetaToFloat<Rotation>(theta);
+ SCOPED_TRACE("theta=" + ::std::to_string(theta) + " theta_float=" +
+ ::std::to_string(theta_float));
+ EXPECT_THAT((FastSinInt<Rotation, kTableSize>(theta)),
+ ::testing::FloatNear(sin(theta_float), kTolerance));
+ EXPECT_THAT((FastCosInt<Rotation, kTableSize>(theta)),
+ ::testing::FloatNear(cos(theta_float), kTolerance));
}
}
@@ -35,20 +39,40 @@
}
};
-TEST_F(SinCosIntTest, Numerator1) {
- CheckSinCos<::std::ratio<1, 2>>();
- CheckSinCos<::std::ratio<1, 4>>();
- CheckSinCos<::std::ratio<1, 8>>();
- CheckSinCos<::std::ratio<1, 128>>();
- CheckSinCos<::std::ratio<1, 1024>>();
- CheckSinCos<::std::ratio<1, 4096>>();
+TEST_F(SinCosIntTest, Numerator1DefaultTable) {
+ CheckSinCos<::std::ratio<1, 2>, 2>();
+ CheckSinCos<::std::ratio<1, 4>, 4>();
+ CheckSinCos<::std::ratio<1, 8>, 8>();
+ CheckSinCos<::std::ratio<1, 128>, 128>();
+ CheckSinCos<::std::ratio<1, 1024>, 1024>();
+ CheckSinCos<::std::ratio<1, 4096>, 4096>();
}
-TEST_F(SinCosIntTest, Numerator5) {
- CheckSinCos<::std::ratio<5, 8>>();
- CheckSinCos<::std::ratio<5, 128>>();
- CheckSinCos<::std::ratio<5, 1024>>();
- CheckSinCos<::std::ratio<5, 4096>>();
+TEST_F(SinCosIntTest, Numerator1LargerTable) {
+ // Don't include silly things like a denominator of 2 and table size of 4
+ // here. It will fail because the slope varies so much that linearly
+ // interpolating between 0.5pi/1.5pi vs 0.25pi/0.75pi/1.25pi/1.75pi gives very
+ // different results.
+ CheckSinCos<::std::ratio<1, 2>, 4096>();
+ CheckSinCos<::std::ratio<1, 2>, 1024>();
+ CheckSinCos<::std::ratio<1, 8>, 4096>();
+ CheckSinCos<::std::ratio<1, 128>, 4096>();
+ CheckSinCos<::std::ratio<1, 1024>, 2048>();
+}
+
+TEST_F(SinCosIntTest, Numerator5DefaultTable) {
+ CheckSinCos<::std::ratio<5, 8>, 8>();
+ CheckSinCos<::std::ratio<5, 128>, 128>();
+ CheckSinCos<::std::ratio<5, 1024>, 1024>();
+ CheckSinCos<::std::ratio<5, 4096>, 4096>();
+}
+
+TEST_F(SinCosIntTest, Numerator5LargerTable) {
+ CheckSinCos<::std::ratio<5, 2>, 4096>();
+ CheckSinCos<::std::ratio<5, 2>, 1024>();
+ CheckSinCos<::std::ratio<5, 8>, 4096>();
+ CheckSinCos<::std::ratio<5, 128>, 4096>();
+ CheckSinCos<::std::ratio<5, 1024>, 2048>();
}
class SinCosFloatTest : public ::testing::Test {