blob: ae04d6c29b13464164aa04c1fe86373e25104fac [file] [log] [blame]
Lee Mracek65686142020-01-10 22:21:39 -05001#include "frc971/control_loops/coerce_goal.h"
2
3#include <unistd.h>
4
James Kuszmaul0ee1fce2020-01-11 16:59:21 -08005#include "aos/controls/polytope.h"
Lee Mracek65686142020-01-10 22:21:39 -05006#include "gtest/gtest.h"
7
8namespace frc971 {
9namespace control_loops {
James Kuszmaul0ee1fce2020-01-11 16:59:21 -080010
Lee Mracek65686142020-01-10 22:21:39 -050011namespace {
12
James Kuszmaul0ee1fce2020-01-11 16:59:21 -080013aos::controls::HVPolytope<2, 4, 4> MakeBox(double x1_min, double x1_max,
14 double x2_min, double x2_max) {
15 Eigen::Matrix<double, 4, 2> box_H;
16 box_H << /*[[*/ 1.0, 0.0 /*]*/,
17 /*[*/ -1.0, 0.0 /*]*/,
18 /*[*/ 0.0, 1.0 /*]*/,
19 /*[*/ 0.0, -1.0 /*]]*/;
20 Eigen::Matrix<double, 4, 1> box_k;
21 box_k << /*[[*/ x1_max /*]*/,
22 /*[*/ -x1_min /*]*/,
23 /*[*/ x2_max /*]*/,
24 /*[*/ -x2_min /*]]*/;
25 aos::controls::HPolytope<2> t_poly(box_H, box_k);
26 return aos::controls::HVPolytope<2, 4, 4>(t_poly.H(), t_poly.k(),
27 t_poly.Vertices());
28}
29} // namespace
30
31class CoerceGoalTest : public ::testing::Test {
32 public:
33 void SetUp() override { aos::controls::HPolytope<2>::Init(); }
34 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
35};
36
37
38TEST_F(CoerceGoalTest, Inside) {
39 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
40
41 Eigen::Matrix<double, 1, 2> K;
42 K << /*[[*/ 1, -1 /*]]*/;
43
44 Eigen::Matrix<double, 2, 1> R;
45 R << /*[[*/ 1.5, 1.5 /*]]*/;
46
47 Eigen::Matrix<double, 2, 1> output =
48 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
49
50 EXPECT_EQ(R(0, 0), output(0, 0));
51 EXPECT_EQ(R(1, 0), output(1, 0));
Lee Mracek65686142020-01-10 22:21:39 -050052}
53
James Kuszmaul0ee1fce2020-01-11 16:59:21 -080054TEST_F(CoerceGoalTest, LineOutside) {
55 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
56
57 // Make a line equivalent to y = -x, which does not pass through the box and
58 // is nearest the box at (1, 1).
59 Eigen::Matrix<double, 1, 2> K;
60 K << 1, 1;
61
62 Eigen::Matrix<double, 2, 1> R;
63 R << /*[[*/ 0.0, 0.0 /*]]*/;
64
65 Eigen::Matrix<double, 2, 1> output =
66 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
67
68 EXPECT_EQ(1.0, output(0, 0));
69 EXPECT_EQ(1.0, output(1, 0));
70
71 // Test the same line, but on the other side of the box, where the (2, 2)
72 // vertex will be closest.
73 output = frc971::control_loops::CoerceGoal<double>(box, K, 5, R);
74 EXPECT_EQ(2.0, output(0, 0));
75 EXPECT_EQ(2.0, output(1, 0));
76}
77
78TEST_F(CoerceGoalTest, GoalOutsideLineInsideThroughOrigin) {
79 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
80
81 Eigen::Matrix<double, 1, 2> K;
82 K << 1, -1;
83
84 Eigen::Matrix<double, 2, 1> R;
85 R << 5, 5;
86
87 Eigen::Matrix<double, 2, 1> output =
88 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
89
90 EXPECT_EQ(2.0, output(0, 0));
91 EXPECT_EQ(2.0, output(1, 0));
92}
93
94TEST_F(CoerceGoalTest, GoalOutsideLineNotThroughOrigin) {
95 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
96
97 Eigen::Matrix<double, 1, 2> K;
98 K << 1, 1;
99
100 Eigen::Matrix<double, 2, 1> R;
101 R << 0, 3;
102
103 Eigen::Matrix<double, 2, 1> output =
104 frc971::control_loops::CoerceGoal<double>(box, K, 3, R);
105
106 EXPECT_EQ(1.0, output(0, 0));
107 EXPECT_DOUBLE_EQ(2.0, output(1, 0));
108}
109
110TEST_F(CoerceGoalTest, GoalOutsideLineThroughVertex) {
111 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
112
113 Eigen::Matrix<double, 1, 2> K;
114 K << 1, -1;
115
116 Eigen::Matrix<double, 2, 1> R;
117 R << 5, 5;
118
119 Eigen::Matrix<double, 2, 1> output =
120 frc971::control_loops::CoerceGoal<double>(box, K, 1, R);
121
122 EXPECT_EQ(2.0, output(0, 0));
123 EXPECT_EQ(1.0, output(1, 0));
124}
125
126TEST_F(CoerceGoalTest, LineAndGoalOutside) {
127 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(3, 4, 1, 2);
128
129 Eigen::Matrix<double, 1, 2> K;
130 K << 1, -1;
131
132 Eigen::Matrix<double, 2, 1> R;
133 R << 5, 5;
134
135 Eigen::Matrix<double, 2, 1> output =
136 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
137
138 EXPECT_EQ(3.0, output(0, 0));
139 EXPECT_EQ(2.0, output(1, 0));
140}
141
142TEST_F(CoerceGoalTest, LineThroughEdgeOfBox) {
143 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(0, 4, 1, 2);
144
145 Eigen::Matrix<double, 1, 2> K;
146 K << -1, 1;
147
148 Eigen::Matrix<double, 2, 1> R;
149 R << 5, 5;
150
151 Eigen::Matrix<double, 2, 1> output =
152 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
153
154 EXPECT_EQ(2.0, output(0, 0));
155 EXPECT_EQ(2.0, output(1, 0));
156}
157
158TEST_F(CoerceGoalTest, PerpendicularLine) {
159 aos::controls::HVPolytope<2, 4, 4> box = MakeBox(1, 2, 1, 2);
160
161 Eigen::Matrix<double, 1, 2> K;
162 K << 1, 1;
163
164 Eigen::Matrix<double, 2, 1> R;
165 R << 5, 5;
166
167 Eigen::Matrix<double, 2, 1> output =
168 frc971::control_loops::CoerceGoal<double>(box, K, 0, R);
169
170 EXPECT_EQ(1.0, output(0, 0));
171 EXPECT_EQ(1.0, output(1, 0));
172}
173
174TEST_F(CoerceGoalTest, WithinRegion) {
175 const auto upoly = MakeBox(-12.0, 12.0, -12.0, 12.0);
Lee Mracek65686142020-01-10 22:21:39 -0500176 Eigen::Matrix<double, 1, 2> k;
177 k << 2, 2;
178
179 Eigen::Matrix<double, 2, 1> goal;
180 goal << -2, 2;
181
182 auto result = CoerceGoal<double>(upoly, k, 0, goal);
183
James Kuszmaul0ee1fce2020-01-11 16:59:21 -0800184 EXPECT_EQ(result(0, 0), goal(0, 0));
185 EXPECT_EQ(result(1, 0), goal(1, 0));
Lee Mracek65686142020-01-10 22:21:39 -0500186}
187
James Kuszmaul0ee1fce2020-01-11 16:59:21 -0800188TEST_F(CoerceGoalTest, VerticalLine) {
189 const auto upoly = MakeBox(-12.0, 12.0, -12.0, 12.0);
Lee Mracek65686142020-01-10 22:21:39 -0500190 Eigen::Matrix<double, 1, 2> k;
191 k << 2, 0;
192
193 Eigen::Matrix<double, 2, 1> goal;
194 goal << 0, 13;
195
196 auto result = CoerceGoal<double>(upoly, k, 0, goal);
197
198 EXPECT_EQ(result(0, 0), 0);
199 EXPECT_EQ(result(1, 0), 12);
200}
201
James Kuszmaul0ee1fce2020-01-11 16:59:21 -0800202TEST_F(CoerceGoalTest, HorizontalLine) {
203 const auto upoly = MakeBox(-12.0, 12.0, -12.0, 12.0);
Lee Mracek65686142020-01-10 22:21:39 -0500204 Eigen::Matrix<double, 1, 2> k;
205 k << 0, 2;
206
207 Eigen::Matrix<double, 2, 1> goal;
208 goal << 13, 2;
209
210 auto result = CoerceGoal<double>(upoly, k, 0, goal);
211
212 EXPECT_EQ(result(0, 0), 12);
213 EXPECT_EQ(result(1, 0), 0);
214}
215
Lee Mracek65686142020-01-10 22:21:39 -0500216} // namespace control_loops
217} // namespace frc971