blob: 66fb174fc8dad5817f8edd094c6b630d2f26d777 [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.
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;
Brian Silverman65e49702014-04-30 17:36:40 -0700116};
117
Austin Schuh2001aa42018-10-29 22:57:02 -0700118typedef ControlLoopTestTemplated<::testing::Test> ControlLoopTest;
119
120template <typename TestBaseClass>
121constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kTimeTick;
122
123template <typename TestBaseClass>
124constexpr ::std::chrono::milliseconds ControlLoopTestTemplated<TestBaseClass>::kDSPacketTime;
125
Brian Silverman65e49702014-04-30 17:36:40 -0700126} // namespace testing
127} // namespace aos
128
John Park33858a32018-09-28 23:05:48 -0700129#endif // AOS_CONTROLS_CONTROL_LOOP_TEST_H_