blob: c6e811c7293b998fc40b440344defa3d49948c9e [file] [log] [blame]
briansf0165ca2013-03-02 06:17:47 +00001#include "gtest/gtest.h"
2
3#include "Eigen/Dense"
4
5#include "aos/common/util/trapezoid_profile.h"
6
7namespace aos {
8namespace util {
9namespace testing {
10
11class TrapezoidProfileTest : public ::testing::Test {
12 public:
13 EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
14
15 protected:
16 TrapezoidProfileTest() : profile_(delta_time) {
17 position_.setZero();
18 profile_.set_maximum_acceleration(0.75);
19 profile_.set_maximum_velocity(1.75);
20 }
21
22 // Runs an iteration.
23 void RunIteration(double goal_position,
24 double goal_velocity) {
25 position_ = profile_.Update(goal_position,
26 goal_velocity);
27 }
28
29 const Eigen::Matrix<double, 2, 1> &position() { return position_; }
30
31 TrapezoidProfile profile_;
32
33 ::testing::AssertionResult At(double position, double velocity) {
briansd412b3f2013-03-03 21:13:44 +000034 static const double kDoubleNear = 0.00001;
35 if (::std::abs(velocity - position_(1)) > kDoubleNear) {
briansf0165ca2013-03-02 06:17:47 +000036 return ::testing::AssertionFailure() << "velocity is " << position_(1) <<
37 " not " << velocity;
38 }
briansd412b3f2013-03-03 21:13:44 +000039 if (::std::abs(position - position_(0)) > kDoubleNear) {
briansf0165ca2013-03-02 06:17:47 +000040 return ::testing::AssertionFailure() << "position is " << position_(0) <<
41 " not " << position;
42 }
43 return ::testing::AssertionSuccess() << "at " << position <<
44 " moving at " << velocity;
45 }
46
47 private:
Austin Schuh214e9c12016-11-25 17:26:20 -080048 static constexpr ::std::chrono::nanoseconds delta_time =
49 ::std::chrono::milliseconds(10);
briansf0165ca2013-03-02 06:17:47 +000050
51 Eigen::Matrix<double, 2, 1> position_;
52};
Austin Schuh214e9c12016-11-25 17:26:20 -080053
54constexpr ::std::chrono::nanoseconds TrapezoidProfileTest::delta_time;
briansf0165ca2013-03-02 06:17:47 +000055
56TEST_F(TrapezoidProfileTest, ReachesGoal) {
57 for (int i = 0; i < 450; ++i) {
58 RunIteration(3, 0);
59 }
60 EXPECT_TRUE(At(3, 0));
61}
62
Ben Fredricksonf33d6532015-03-15 00:29:29 -070063// Tests that decresing the maximum velocity in the middle when it is already
64// moving faster than the new max is handled correctly.
65TEST_F(TrapezoidProfileTest, ContinousUnderVelChange) {
66 profile_.set_maximum_velocity(1.75);
67 RunIteration(12.0, 0);
68 double last_pos = position()(0);
69 double last_vel = 1.75;
70 for (int i = 0; i < 1600; ++i) {
71 if (i == 400) {
72 profile_.set_maximum_velocity(0.75);
73 }
74 RunIteration(12.0, 0);
75 if (i >= 400) {
76 EXPECT_TRUE(::std::abs(last_pos - position()(0)) <= 1.75 * 0.01);
77 EXPECT_NEAR(last_vel, ::std::abs(last_pos - position()(0)), 0.0001);
78 }
79 last_vel = ::std::abs(last_pos - position()(0));
80 last_pos = position()(0);
81 }
82 EXPECT_TRUE(At(12.0, 0));
83}
84
briansf0165ca2013-03-02 06:17:47 +000085// There is some somewhat tricky code for dealing with going backwards.
86TEST_F(TrapezoidProfileTest, Backwards) {
87 for (int i = 0; i < 400; ++i) {
88 RunIteration(-2, 0);
89 }
90 EXPECT_TRUE(At(-2, 0));
91}
92
93TEST_F(TrapezoidProfileTest, SwitchGoalInMiddle) {
94 for (int i = 0; i < 200; ++i) {
95 RunIteration(-2, 0);
96 }
97 EXPECT_FALSE(At(-2, 0));
98 for (int i = 0; i < 550; ++i) {
99 RunIteration(0, 0);
100 }
101 EXPECT_TRUE(At(0, 0));
102}
103
104// Checks to make sure that it hits top speed.
105TEST_F(TrapezoidProfileTest, TopSpeed) {
106 for (int i = 0; i < 200; ++i) {
107 RunIteration(4, 0);
108 }
109 EXPECT_NEAR(1.5, position()(1), 10e-5);
110 for (int i = 0; i < 2000; ++i) {
111 RunIteration(4, 0);
112 }
113 EXPECT_TRUE(At(4, 0));
114}
115
116} // namespace testing
117} // namespace util
118} // namespace aos