GCC Code Coverage Report


Directory: ./
File: tests/test_pid_cpp.cpp
Date: 2023-02-07 15:30:53
Exec Total Coverage
Lines: 88 90 97.8%
Functions: 26 26 100.0%
Branches: 64 206 31.1%

Line Branch Exec Source
1 /**
2 * @file package_template_ut.cpp
3 * @author Vincent Berenz
4 * license License BSD-3-Clause
5 * @copyright Copyright (c) 2019, New York University and Max Planck
6 * Gesellschaft.
7 * @date 2019-05-22
8 *
9 * @brief example of unit tests
10 * @see
11 * https://git-amd.tuebingen.mpg.de/amd-clmc/package_template/wikis/catkin:-how-to-implement-unit-tests
12 */
13
14 #include <fstream>
15 #include <iostream>
16
17 #include "gtest/gtest.h"
18 #include "package_template/file_configuration.hpp"
19 #include "package_template/pid.hpp"
20
21 // more info:
22 // http://www.ibm.com/developerworks/aix/library/au-googletestingframework.html
23
24 // quick reference:
25 // http://www.cheezyworld.com/wp-content/uploads/2010/12/PlainGoogleQuickTestReferenceGuide1.pdf
26
27 #define YAML_CONFIG_FILE "package_template_unit_test.yaml"
28
29 /* **************** setup of test *************** */
30
31 // in setup for test, we write the yaml file that will be used
32 // to test File_configuration. In TearDown, we delete the file.
33 class PID_tests : public ::testing::Test
34 {
35 protected:
36 9 void SetUp()
37 {
38 18 YAML::Node node;
39
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 node["kp"] = DEFAULT_KP;
40
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 node["kd"] = DEFAULT_KD;
41
2/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
9 node["ki"] = DEFAULT_KI;
42
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
18 std::ofstream fout(YAML_CONFIG_FILE);
43
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
9 fout << node;
44 9 }
45 9 void TearDown()
46 {
47 9 std::remove(YAML_CONFIG_FILE);
48 9 }
49 };
50
51 /* **************** testing DefaultConfiguration **************** */
52
53 8 TEST_F(PID_tests, default_configuration_test)
54 {
55 package_template::DefaultConfiguration config;
56
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_kp(), DEFAULT_KP);
57
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_kd(), DEFAULT_KD);
58
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_ki(), DEFAULT_KI);
59
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.has_error(), false);
60 }
61
62 /* **************** testing File_configuration **************** */
63
64 8 TEST_F(PID_tests, file_configuration_ok_test)
65 {
66 // see CMakeLists.txt to see how this change to valid path
67
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
4 package_template::File_configuration config(YAML_CONFIG_FILE);
68
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_kp(), DEFAULT_KP);
69
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_kd(), DEFAULT_KD);
70
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.get_ki(), DEFAULT_KI);
71 }
72
73 8 TEST_F(PID_tests, file_configuration_fail_test)
74 {
75
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
4 package_template::File_configuration config("None existing file");
76
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.has_error(), true);
77 }
78
79 /* **************** testing File_configuration **************** */
80 /* **************** with default configuration file **************** */
81
82 8 TEST_F(PID_tests, read_config_file_test)
83 {
84
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
4 package_template::File_configuration config(YAML_CONFIG_FILE);
85
3/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
2 ASSERT_EQ(config.has_error(), false);
86 }
87
88 8 TEST_F(PID_tests, configurations_same_results_test)
89 {
90 // random data for testing
91 2 double position = 1;
92 2 double velocity = 1;
93 2 double position_target = 2;
94 2 double delta_time = 0.01;
95
96 package_template::DefaultConfiguration default_config;
97
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 package_template::PID controller_default(default_config);
98
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 double force_default = controller_default.compute(
99 2 position, velocity, position_target, delta_time);
100
101
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
4 package_template::File_configuration file_config(YAML_CONFIG_FILE);
102
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 package_template::PID controller_file(file_config);
103
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 double force_file = controller_file.compute(
104 2 position, velocity, position_target, delta_time);
105
106
2/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2 ASSERT_EQ(force_default, force_file);
107 }
108
109 // does integral integrates ?
110 8 TEST_F(PID_tests, integral)
111 {
112 // random data for testing
113 2 double position = 1;
114 2 double velocity = 1;
115 2 double position_target = 2;
116 2 double delta_time = 0.01;
117
118
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 package_template::PID& controller = package_template::get_default_pid();
119 double force_1 =
120
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.compute(position, velocity, position_target, delta_time);
121 double force_2 =
122
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.compute(position, velocity, position_target, delta_time);
123
124
2/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2 ASSERT_NE(force_1, force_2);
125 }
126
127 // does reset of integral work ?
128 8 TEST_F(PID_tests, reset_integral)
129 {
130 // random data for testing
131 2 double position = 1;
132 2 double velocity = 1;
133 2 double position_target = 2;
134 2 double delta_time = 0.01;
135
136 // running pid and integrating
137
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 package_template::PID& controller = package_template::get_default_pid();
138 double force_1 =
139
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.compute(position, velocity, position_target, delta_time);
140
141 // reset integral
142
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.reset_integral();
143
144 // run controller again
145 double force_reset =
146
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.compute(position, velocity, position_target, delta_time);
147
148
2/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2 ASSERT_EQ(force_1, force_reset);
149 }
150
151 // generated force is zero if already at target ?
152 8 TEST_F(PID_tests, zero_force_at_target)
153 {
154 // random data for testing
155 2 double position = 1;
156 2 double velocity = 0;
157 2 double position_target = position;
158 2 double delta_time = 0.01;
159
160
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 package_template::PID& controller = package_template::get_default_pid();
161 double force =
162
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 controller.compute(position, velocity, position_target, delta_time);
163
164
2/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
2 ASSERT_EQ(force, 0);
165 }
166
167 // does the controller push to the right direction ?
168 4 TEST_F(PID_tests, right_direction)
169 {
170 // random data for testing
171 1 double position = 0;
172 1 double velocity = 0;
173 1 double position_target = 1;
174 1 double delta_time = 0.01;
175
176 1 package_template::PID& controller = package_template::get_default_pid();
177 double force =
178 1 controller.compute(position, velocity, position_target, delta_time);
179 1 ASSERT_GT(force, 0);
180
181 1 controller.reset_integral();
182 1 position_target = -1;
183 1 force = controller.compute(position, velocity, position_target, delta_time);
184 1 ASSERT_LT(force, 0);
185
186 1 controller.reset_integral();
187 1 position_target = position;
188 1 velocity = -1;
189 1 force = controller.compute(position, velocity, position_target, delta_time);
190 1 ASSERT_GT(force, 0);
191
192 1 controller.reset_integral();
193 1 velocity = 1;
194 1 force = controller.compute(position, velocity, position_target, delta_time);
195 1 ASSERT_LT(force, 0);
196 }
197