blob: 87cb5b58a2dfddac421c5b2972e68ebc6cd599bb [file] [log] [blame]
Brian Silverman8d3816a2017-07-03 18:52:15 -07001#include "motors/algorithms.h"
2
3#include <inttypes.h>
4
5#include "gtest/gtest.h"
6
7namespace frc971 {
8namespace salsa {
9namespace testing {
10
11class BalanceReadingsTest : public ::testing::Test {
12 protected:
13 void CheckReadingsResult(const ReadingsToBalance &to_balance) {
14 ASSERT_GE((to_balance.weights[0] > 0) + (to_balance.weights[1] > 0) +
15 (to_balance.weights[2] > 0),
16 2)
17 << "Need at least 2 readings";
18 ASSERT_GE(to_balance.weights[0], 0);
19 ASSERT_GE(to_balance.weights[1], 0);
20 ASSERT_GE(to_balance.weights[2], 0);
21
22 const BalancedReadings result = BalanceReadings(to_balance);
23
24 {
25 const auto sum =
26 result.readings[0] + result.readings[1] + result.readings[2];
27 EXPECT_GE(sum, -2);
28 EXPECT_LE(sum, 2);
29 }
30
31 if (to_balance.weights[0] == 0) {
32 const double averages[3] = {
33 0, static_cast<double>(to_balance.sums[1]) / to_balance.weights[1],
34 static_cast<double>(to_balance.sums[2]) / to_balance.weights[2]};
35 EXPECT_LE(::std::abs((averages[1] - averages[2]) -
36 (result.readings[1] - result.readings[2])),
37 0.5);
38 } else if (to_balance.weights[1] == 0) {
39 const double averages[3] = {
40 static_cast<double>(to_balance.sums[0]) / to_balance.weights[0], 0,
41 static_cast<double>(to_balance.sums[2]) / to_balance.weights[2]};
42 EXPECT_LE(::std::abs((averages[0] - averages[2]) -
43 (result.readings[0] - result.readings[2])),
44 0.5);
45 } else if (to_balance.weights[2] == 0) {
46 const double averages[3] = {
47 static_cast<double>(to_balance.sums[0]) / to_balance.weights[0],
48 static_cast<double>(to_balance.sums[1]) / to_balance.weights[1], 0};
49 EXPECT_LE(::std::abs((averages[0] - averages[1]) -
50 (result.readings[0] - result.readings[1])),
51 0.5);
52 } else {
53 const double averages[3] = {
54 static_cast<double>(to_balance.sums[0]) / to_balance.weights[0],
55 static_cast<double>(to_balance.sums[1]) / to_balance.weights[1],
56 static_cast<double>(to_balance.sums[2]) / to_balance.weights[2]};
57
58 const double middle = (averages[0] + averages[1] + averages[2]) / 3;
59 const double average_distances[3] = {
60 ::std::abs(averages[0] - middle - result.readings[0]),
61 ::std::abs(averages[1] - middle - result.readings[1]),
62 ::std::abs(averages[2] - middle - result.readings[2])};
63 // distances[0]/distances[1] = weights[1]/weights[0]
64 // distances[0]*weights[0]/weights[1] = distances[1]
65 EXPECT_LE(::std::abs(average_distances[0] *
66 static_cast<double>(to_balance.weights[0]) /
67 static_cast<double>(to_balance.weights[1]) -
68 average_distances[1]),
69 0.01);
70 EXPECT_LE(::std::abs(average_distances[2] *
71 static_cast<double>(to_balance.weights[2]) /
72 static_cast<double>(to_balance.weights[1]) -
73 average_distances[1]),
74 0.01);
75 EXPECT_LE(::std::abs(average_distances[0] *
76 static_cast<double>(to_balance.weights[0]) /
77 static_cast<double>(to_balance.weights[2]) -
78 average_distances[2]),
79 0.01);
80 }
81 }
82};
83
84TEST_F(BalanceReadingsTest, Basic) {
85 CheckReadingsResult({{50, 50, 50}, {1, 1, 1}});
86 CheckReadingsResult({{50, 50, 0}, {1, 1, 0}});
87 CheckReadingsResult({{50, 0, 50}, {1, 0, 1}});
88 CheckReadingsResult({{0, 50, 50}, {0, 1, 1}});
89 CheckReadingsResult({{0, 50, 100}, {0, 1, 2}});
90 CheckReadingsResult({{100, 50, 50}, {2, 1, 1}});
91 CheckReadingsResult({{100, 100, 50}, {2, 2, 1}});
92
93 CheckReadingsResult({{150, 50, 50}, {1, 1, 1}});
94 CheckReadingsResult({{150, 50, 50}, {2, 2, 2}});
95 CheckReadingsResult({{3424, 5013, 3424}, {2, 2, 2}});
96}
97
98} // namespace testing
99} // namespace salsa
100} // namespace frc971