blob: 95f1c7d2e49b642277b6036033bded377981d2ca [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_CONTROLS_CONTROL_LOOP_TEST_H_
2#define AOS_CONTROLS_CONTROL_LOOP_TEST_H_
Brian Silverman65e49702014-04-30 17:36:40 -07003
Austin Schuh2001aa42018-10-29 22:57:02 -07004#include <chrono>
5
Brian Silverman65e49702014-04-30 17:36:40 -07006#include "gtest/gtest.h"
7
Austin Schuhdf6cbb12019-02-02 13:46:52 -08008#include "aos/events/shm-event-loop.h"
Austin Schuh2001aa42018-10-29 22:57:02 -07009#include "aos/logging/queue_logging.h"
10#include "aos/robot_state/robot_state.q.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050011#include "aos/testing/test_shm.h"
John Park33858a32018-09-28 23:05:48 -070012#include "aos/time/time.h"
Brian Silverman65e49702014-04-30 17:36:40 -070013
14namespace aos {
15namespace testing {
16
17// Handles setting up the environment that all control loops need to actually
18// run.
19// This includes sending the queue messages and Clear()ing the queues when
20// appropriate.
21// It also includes dealing with ::aos::time.
Austin Schuh2001aa42018-10-29 22:57:02 -070022template <typename TestBaseClass>
23class ControlLoopTestTemplated : public TestBaseClass {
Brian Silverman65e49702014-04-30 17:36:40 -070024 public:
Austin Schuh2001aa42018-10-29 22:57:02 -070025 ControlLoopTestTemplated() {
Austin Schuhdf6cbb12019-02-02 13:46:52 -080026 robot_state_sender_ =
27 test_event_loop_.MakeSender<::aos::RobotState>(".aos.robot_state");
28 joystick_state_sender_ =
29 test_event_loop_.MakeSender<::aos::JoystickState>(".aos.joystick_state");
Austin Schuh2001aa42018-10-29 22:57:02 -070030
31 ::aos::time::EnableMockTime(current_time_);
32
33 SendMessages(false);
34 }
35 virtual ~ControlLoopTestTemplated() {
Austin Schuh2001aa42018-10-29 22:57:02 -070036 ::aos::time::DisableMockTime();
37 }
Brian Silverman65e49702014-04-30 17:36:40 -070038
Philipp Schraderf75a8bf2015-02-02 05:30:16 +000039 void set_team_id(uint16_t team_id) { team_id_ = team_id; }
40 uint16_t team_id() const { return team_id_; }
41
Brian Silvermane6f64ab2015-02-05 17:03:56 -050042 // Sends out all of the required queue messages.
Austin Schuh2001aa42018-10-29 22:57:02 -070043 void SendMessages(bool enabled) {
44 if (current_time_ >= kDSPacketTime + last_ds_time_ ||
45 last_enabled_ != enabled) {
46 last_ds_time_ = current_time_;
Austin Schuhdf6cbb12019-02-02 13:46:52 -080047 auto new_state = joystick_state_sender_.MakeMessage();
Austin Schuh2001aa42018-10-29 22:57:02 -070048 new_state->fake = true;
49
50 new_state->enabled = enabled;
51 new_state->autonomous = false;
52 new_state->team_id = team_id_;
53
54 new_state.Send();
55 last_enabled_ = enabled;
56 }
57
58 {
Austin Schuhdf6cbb12019-02-02 13:46:52 -080059 auto new_state = robot_state_sender_.MakeMessage();
Austin Schuh2001aa42018-10-29 22:57:02 -070060
61 new_state->reader_pid = reader_pid_;
62 new_state->outputs_enabled = enabled;
63 new_state->browned_out = false;
64
65 new_state->is_3v3_active = true;
66 new_state->is_5v_active = true;
67 new_state->voltage_3v3 = 3.3;
68 new_state->voltage_5v = 5.0;
69
70 new_state->voltage_roborio_in = battery_voltage_;
71 new_state->voltage_battery = battery_voltage_;
72
73 LOG_STRUCT(INFO, "robot_state", *new_state);
74 new_state.Send();
75 }
76 }
Brian Silvermane6f64ab2015-02-05 17:03:56 -050077 // Ticks time for a single control loop cycle.
Austin Schuh85387042017-09-13 23:59:21 -070078 void TickTime(::std::chrono::nanoseconds dt = kTimeTick) {
79 ::aos::time::SetMockTime(current_time_ += dt);
80 }
Brian Silvermane6f64ab2015-02-05 17:03:56 -050081
82 // Simulates everything that happens during 1 loop time step.
James Kuszmaul109ed8d2019-02-17 21:41:04 -080083 void SimulateTimestep(bool enabled,
84 ::std::chrono::nanoseconds dt = kTimeTick) {
Brian Silvermane6f64ab2015-02-05 17:03:56 -050085 SendMessages(enabled);
James Kuszmaul109ed8d2019-02-17 21:41:04 -080086 TickTime(dt);
Brian Silvermane6f64ab2015-02-05 17:03:56 -050087 }
Brian Silverman65e49702014-04-30 17:36:40 -070088
Brian Silverman57cad222015-02-14 20:46:41 -050089 // Simulate a reset of the process reading sensors, which tells loops that all
90 // index counts etc will be reset.
91 void SimulateSensorReset() {
92 ++reader_pid_;
93 }
94
Austin Schuhe5f064d2016-03-05 17:43:51 -080095 // Sets the battery voltage in robot_state.
96 void set_battery_voltage(double battery_voltage) {
97 battery_voltage_ = battery_voltage;
98 }
99
Brian Silverman65e49702014-04-30 17:36:40 -0700100 private:
Austin Schuh6a6f90c2016-11-25 21:36:42 -0800101 static constexpr ::std::chrono::milliseconds kTimeTick{5};
102 static constexpr ::std::chrono::milliseconds kDSPacketTime{20};
Brian Silvermane6f64ab2015-02-05 17:03:56 -0500103
Philipp Schraderf75a8bf2015-02-02 05:30:16 +0000104 uint16_t team_id_ = 971;
Brian Silverman57cad222015-02-14 20:46:41 -0500105 int32_t reader_pid_ = 1;
Austin Schuhe5f064d2016-03-05 17:43:51 -0800106 double battery_voltage_ = 12.4;
Philipp Schraderf75a8bf2015-02-02 05:30:16 +0000107
Austin Schuh6a6f90c2016-11-25 21:36:42 -0800108 ::aos::monotonic_clock::time_point last_ds_time_ =
109 ::aos::monotonic_clock::epoch();
110 ::aos::monotonic_clock::time_point current_time_ =
111 ::aos::monotonic_clock::epoch();
Brian Silverman65e49702014-04-30 17:36:40 -0700112
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -0500113 ::aos::testing::TestSharedMemory my_shm_;
Campbell Crowley152c7cf2016-02-14 21:20:50 -0800114
115 bool last_enabled_ = false;
Austin Schuhdf6cbb12019-02-02 13:46:52 -0800116
117 ::aos::ShmEventLoop test_event_loop_;
118
119 ::aos::Sender<::aos::RobotState> robot_state_sender_;
120 ::aos::Sender<::aos::JoystickState> joystick_state_sender_;
Brian Silverman65e49702014-04-30 17:36:40 -0700121};
122
Austin Schuh2001aa42018-10-29 22:57:02 -0700123typedef ControlLoopTestTemplated<::testing::Test> ControlLoopTest;
124
125template <typename TestBaseClass>
126constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kTimeTick;
127
128template <typename TestBaseClass>
129constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kDSPacketTime;
130
Brian Silverman65e49702014-04-30 17:36:40 -0700131} // namespace testing
132} // namespace aos
133
John Park33858a32018-09-28 23:05:48 -0700134#endif // AOS_CONTROLS_CONTROL_LOOP_TEST_H_