blob: e88b1b760332d50658bcc1f3de1b3fabcdde5845 [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 Schuh2001aa42018-10-29 22:57:02 -07008#include "aos/logging/queue_logging.h"
9#include "aos/robot_state/robot_state.q.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050010#include "aos/testing/test_shm.h"
John Park33858a32018-09-28 23:05:48 -070011#include "aos/time/time.h"
Brian Silverman65e49702014-04-30 17:36:40 -070012
13namespace aos {
14namespace testing {
15
16// Handles setting up the environment that all control loops need to actually
17// run.
18// This includes sending the queue messages and Clear()ing the queues when
19// appropriate.
20// It also includes dealing with ::aos::time.
Austin Schuh2001aa42018-10-29 22:57:02 -070021template <typename TestBaseClass>
22class ControlLoopTestTemplated : public TestBaseClass {
Brian Silverman65e49702014-04-30 17:36:40 -070023 public:
Austin Schuh2001aa42018-10-29 22:57:02 -070024 ControlLoopTestTemplated() {
25 ::aos::joystick_state.Clear();
26 ::aos::robot_state.Clear();
27
28 ::aos::time::EnableMockTime(current_time_);
29
30 SendMessages(false);
31 }
32 virtual ~ControlLoopTestTemplated() {
33 ::aos::joystick_state.Clear();
34 ::aos::robot_state.Clear();
35
36 ::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_;
47 auto new_state = ::aos::joystick_state.MakeMessage();
48 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 {
59 auto new_state = ::aos::robot_state.MakeMessage();
60
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.
83 void SimulateTimestep(bool enabled) {
84 SendMessages(enabled);
85 TickTime();
86 }
Brian Silverman65e49702014-04-30 17:36:40 -070087
Brian Silverman57cad222015-02-14 20:46:41 -050088 // Simulate a reset of the process reading sensors, which tells loops that all
89 // index counts etc will be reset.
90 void SimulateSensorReset() {
91 ++reader_pid_;
92 }
93
Austin Schuhe5f064d2016-03-05 17:43:51 -080094 // Sets the battery voltage in robot_state.
95 void set_battery_voltage(double battery_voltage) {
96 battery_voltage_ = battery_voltage;
97 }
98
Brian Silverman65e49702014-04-30 17:36:40 -070099 private:
Austin Schuh6a6f90c2016-11-25 21:36:42 -0800100 static constexpr ::std::chrono::milliseconds kTimeTick{5};
101 static constexpr ::std::chrono::milliseconds kDSPacketTime{20};
Brian Silvermane6f64ab2015-02-05 17:03:56 -0500102
Philipp Schraderf75a8bf2015-02-02 05:30:16 +0000103 uint16_t team_id_ = 971;
Brian Silverman57cad222015-02-14 20:46:41 -0500104 int32_t reader_pid_ = 1;
Austin Schuhe5f064d2016-03-05 17:43:51 -0800105 double battery_voltage_ = 12.4;
Philipp Schraderf75a8bf2015-02-02 05:30:16 +0000106
Austin Schuh6a6f90c2016-11-25 21:36:42 -0800107 ::aos::monotonic_clock::time_point last_ds_time_ =
108 ::aos::monotonic_clock::epoch();
109 ::aos::monotonic_clock::time_point current_time_ =
110 ::aos::monotonic_clock::epoch();
Brian Silverman65e49702014-04-30 17:36:40 -0700111
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -0500112 ::aos::testing::TestSharedMemory my_shm_;
Campbell Crowley152c7cf2016-02-14 21:20:50 -0800113
114 bool last_enabled_ = false;
Brian Silverman65e49702014-04-30 17:36:40 -0700115};
116
Austin Schuh2001aa42018-10-29 22:57:02 -0700117typedef ControlLoopTestTemplated<::testing::Test> ControlLoopTest;
118
119template <typename TestBaseClass>
120constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kTimeTick;
121
122template <typename TestBaseClass>
123constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kDSPacketTime;
124
Brian Silverman65e49702014-04-30 17:36:40 -0700125} // namespace testing
126} // namespace aos
127
John Park33858a32018-09-28 23:05:48 -0700128#endif // AOS_CONTROLS_CONTROL_LOOP_TEST_H_