blob: 0acf9e7f359f33b918bd822825e39db084f7dd7c [file] [log] [blame]
Parker Schuh18dbbb42017-10-18 21:45:33 -07001#include "frc971/codelab/basic.h"
2
3#include <unistd.h>
4
5#include <chrono>
6#include <memory>
7
8#include "aos/common/controls/control_loop_test.h"
9#include "aos/common/queue.h"
10#include "frc971/codelab/basic.q.h"
11#include "frc971/control_loops/team_number_test_environment.h"
12#include "gtest/gtest.h"
13
14namespace frc971 {
15namespace codelab {
16namespace testing {
17
18// Class which simulates stuff and sends out queue messages with the
19// position.
20class BasicSimulation {
21 public:
22 BasicSimulation()
23 : basic_queue_(".frc971.codelab.basic_queue", 0x78d8e372,
24 ".frc971.codelab.basic_queue.goal",
25 ".frc971.codelab.basic_queue.position",
26 ".frc971.codelab.basic_queue.output",
27 ".frc971.codelab.basic_queue.status") {}
28
29 // Sends a queue message with the position data.
30 void SendPositionMessage() {
31 ::aos::ScopedMessagePtr<BasicQueue::Position> position =
32 basic_queue_.position.MakeMessage();
33
34 position->limit_sensor = limit_sensor_;
35
36 position.Send();
37 }
38
39 void VerifyResults(double voltage, bool status) {
40 basic_queue_.output.FetchLatest();
41 basic_queue_.status.FetchLatest();
42
43 ASSERT_TRUE(basic_queue_.output.get() != nullptr);
44 ASSERT_TRUE(basic_queue_.status.get() != nullptr);
45
46 EXPECT_EQ(basic_queue_.output->intake_voltage, voltage);
47 EXPECT_EQ(basic_queue_.status->intake_complete, status);
48 }
49
50 void set_limit_sensor(bool value) { limit_sensor_ = value; }
51
52 // Simulates basic control loop for a single timestep.
53 void Simulate() { EXPECT_TRUE(basic_queue_.output.FetchLatest()); }
54
55 private:
56 BasicQueue basic_queue_;
57 bool limit_sensor_ = false;
58};
59
60class BasicControlLoopTest : public ::aos::testing::ControlLoopTest {
61 public:
62 BasicControlLoopTest()
63 : basic_queue_(".frc971.codelab.basic_queue", 0x78d8e372,
64 ".frc971.codelab.basic_queue.goal",
65 ".frc971.codelab.basic_queue.position",
66 ".frc971.codelab.basic_queue.output",
67 ".frc971.codelab.basic_queue.status"),
68 basic_loop_(&basic_queue_) {
69 set_team_id(control_loops::testing::kTeamNumber);
70 }
71
72 // Runs one iteration of the whole simulation.
73 void RunIteration(bool enabled = true) {
74 SendMessages(enabled);
75
76 basic_simulation_.SendPositionMessage();
77 basic_loop_.Iterate();
78 basic_simulation_.Simulate();
79
80 TickTime();
81 }
82
83 BasicQueue basic_queue_;
84 Basic basic_loop_;
85 BasicSimulation basic_simulation_;
86};
87
88// Tests that when the motor has finished intaking it stops.
89TEST_F(BasicControlLoopTest, IntakeLimitTransitionsToTrue) {
90 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(true).Send());
91 basic_simulation_.set_limit_sensor(false);
92
93 RunIteration();
94
95 basic_simulation_.VerifyResults(12.0, false);
96
97 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(true).Send());
98 basic_simulation_.set_limit_sensor(true);
99
100 RunIteration();
101
102 basic_simulation_.VerifyResults(0.0, true);
103}
104
105// Tests that the intake goes on if the sensor is not pressed
106// and intake is requested.
107TEST_F(BasicControlLoopTest, IntakeLimitNotSet) {
108 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(true).Send());
109 basic_simulation_.set_limit_sensor(false);
110
111 RunIteration();
112
113 basic_simulation_.VerifyResults(12.0, false);
114}
115
116// Tests that the intake is off if no intake is requested,
117// even if the limit sensor is off.
118TEST_F(BasicControlLoopTest, NoIntakeLimitNotSet) {
119 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(false).Send());
120 basic_simulation_.set_limit_sensor(false);
121
122 RunIteration();
123
124 basic_simulation_.VerifyResults(0.0, false);
125}
126
127// Tests that the intake is off even if the limit sensor
128// is pressed and intake is requested.
129TEST_F(BasicControlLoopTest, IntakeLimitSet) {
130 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(true).Send());
131 basic_simulation_.set_limit_sensor(true);
132
133 RunIteration();
134
135 basic_simulation_.VerifyResults(0.0, true);
136}
137
138// Tests that the intake is off if no intake is requested,
139TEST_F(BasicControlLoopTest, NoIntakeLimitSet) {
140 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(false).Send());
141 basic_simulation_.set_limit_sensor(true);
142
143 RunIteration();
144
145 basic_simulation_.VerifyResults(0.0, false);
146}
147
148// Tests that the control loop handles things properly if no goal is set.
149TEST_F(BasicControlLoopTest, NoGoalSet) {
150 basic_simulation_.set_limit_sensor(true);
151
152 RunIteration();
153
154 basic_simulation_.VerifyResults(0.0, false);
155}
156
157// Tests that the control loop handles things properly if disabled.
158TEST_F(BasicControlLoopTest, Disabled) {
159 basic_simulation_.set_limit_sensor(true);
160
161 ASSERT_TRUE(basic_queue_.goal.MakeWithBuilder().intake(true).Send());
162
163 RunIteration(false);
164
165 basic_simulation_.VerifyResults(0.0, false);
166}
167
168} // namespace testing
169} // namespace codelab
170} // namespace frc971