Skip to content

Commit aac226e

Browse files
christophfroehlichmergify[bot]
authored andcommitted
[Pid] Save i_term instead of error integral (#294)
(cherry picked from commit 37a12e8) # Conflicts: # control_toolbox/src/pid.cpp
1 parent ee359df commit aac226e

File tree

5 files changed

+39
-20
lines changed

5 files changed

+39
-20
lines changed

control_toolbox/include/control_toolbox/pid.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ class Pid
518518
/*!
519519
* \brief Return PID error terms for the controller.
520520
* \param pe The proportional error.
521-
* \param ie The integral error.
521+
* \param ie The weighted integral error.
522522
* \param de The derivative error.
523523
*/
524524
void get_current_pid_errors(double & pe, double & ie, double & de);
@@ -559,8 +559,8 @@ class Pid
559559

560560
double p_error_last_; /** Save state for derivative state calculation. */
561561
double p_error_; /** Error. */
562-
double i_error_; /** Integral of error. */
563562
double d_error_; /** Derivative of error. */
563+
double i_term_; /** Integrator state. */
564564
double cmd_; /** Command to send. */
565565
// TODO(christophfroehlich) remove this -> breaks ABI
566566
[[deprecated("Use d_error_")]] double error_dot_; /** Derivative error */

control_toolbox/include/control_toolbox/pid_ros.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ class PidROS
327327
/*!
328328
* \brief Return PID error terms for the controller.
329329
* \param pe[out] The proportional error.
330-
* \param ie[out] The integral error.
330+
* \param ie[out] The weighted integral error.
331331
* \param de[out] The derivative error.
332332
*/
333333
void get_current_pid_errors(double & pe, double & ie, double & de);

control_toolbox/src/pid.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,14 @@ void Pid::reset(bool save_i_term)
111111
}
112112
}
113113

114+
<<<<<<< HEAD:control_toolbox/src/pid.cpp
114115
void Pid::clear_saved_iterm() { i_error_ = 0.0; }
116+
=======
117+
void Pid::clear_saved_iterm()
118+
{
119+
i_term_ = 0.0;
120+
}
121+
>>>>>>> 37a12e8 ([Pid] Save `i_term` instead of error integral (#294)):src/pid.cpp
115122

116123
void Pid::get_gains(double & p, double & i, double & d, double & i_max, double & i_min)
117124
{
@@ -202,7 +209,7 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
202209
// Get the gain parameters from the realtime buffer
203210
Gains gains = *gains_buffer_.readFromRT();
204211

205-
double p_term, d_term, i_term;
212+
double p_term, d_term;
206213
p_error_ = error; // this is error = target - state
207214
d_error_ = error_dot;
208215

@@ -219,6 +226,7 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
219226
// Calculate proportional contribution to command
220227
p_term = gains.p_gain_ * p_error_;
221228

229+
<<<<<<< HEAD:control_toolbox/src/pid.cpp
222230
// Calculate the integral of the position error
223231
i_error_ += dt_s * p_error_;
224232

@@ -237,13 +245,23 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
237245
{
238246
// Limit i_term so that the limit is meaningful in the output
239247
i_term = std::clamp(i_term, gains.i_min_, gains.i_max_);
248+
=======
249+
// Calculate integral contribution to command
250+
if (gains.antiwindup_) {
251+
// Prevent i_term_ from climbing higher than permitted by i_max_/i_min_
252+
i_term_ = std::clamp(i_term_ + gains.i_gain_ * dt_s * p_error_,
253+
gains.i_min_, gains.i_max_);
254+
} else {
255+
i_term_ += gains.i_gain_ * dt_s * p_error_;
256+
>>>>>>> 37a12e8 ([Pid] Save `i_term` instead of error integral (#294)):src/pid.cpp
240257
}
241258

242259
// Calculate derivative contribution to command
243260
d_term = gains.d_gain_ * d_error_;
244261

245262
// Compute the command
246-
cmd_ = p_term + i_term + d_term;
263+
// Limit i_term so that the limit is meaningful in the output
264+
cmd_ = p_term + std::clamp(i_term_, gains.i_min_, gains.i_max_) + d_term;
247265

248266
return cmd_;
249267
}
@@ -255,7 +273,7 @@ double Pid::get_current_cmd() { return cmd_; }
255273
void Pid::get_current_pid_errors(double & pe, double & ie, double & de)
256274
{
257275
pe = p_error_;
258-
ie = i_error_;
276+
ie = i_term_;
259277
de = d_error_;
260278
}
261279

control_toolbox/src/pid_ros.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ void PidROS::publish_pid_state(double cmd, double error, rclcpp::Duration dt)
297297
{
298298
Pid::Gains gains = pid_.get_gains();
299299

300-
double p_error, i_error, d_error;
301-
get_current_pid_errors(p_error, i_error, d_error);
300+
double p_error, i_term, d_error;
301+
get_current_pid_errors(p_error, i_term, d_error);
302302

303303
// Publish controller state if configured
304304
if (rt_state_pub_)
@@ -310,7 +310,7 @@ void PidROS::publish_pid_state(double cmd, double error, rclcpp::Duration dt)
310310
rt_state_pub_->msg_.error = error;
311311
rt_state_pub_->msg_.error_dot = d_error;
312312
rt_state_pub_->msg_.p_error = p_error;
313-
rt_state_pub_->msg_.i_error = i_error;
313+
rt_state_pub_->msg_.i_error = i_term;
314314
rt_state_pub_->msg_.d_error = d_error;
315315
rt_state_pub_->msg_.p_term = gains.p_gain_;
316316
rt_state_pub_->msg_.i_term = gains.i_gain_;
@@ -340,8 +340,8 @@ void PidROS::print_values()
340340
{
341341
Pid::Gains gains = pid_.get_gains();
342342

343-
double p_error, i_error, d_error;
344-
get_current_pid_errors(p_error, i_error, d_error);
343+
double p_error, i_term, d_error;
344+
get_current_pid_errors(p_error, i_term, d_error);
345345

346346
RCLCPP_INFO_STREAM(node_logging_->get_logger(), "Current Values of PID template:\n"
347347
<< " P Gain: " << gains.p_gain_ << "\n"
@@ -352,7 +352,7 @@ void PidROS::print_values()
352352
<< " Antiwindup: " << gains.antiwindup_
353353
<< "\n"
354354
<< " P_Error: " << p_error << "\n"
355-
<< " I_Error: " << i_error << "\n"
355+
<< " i_term: " << i_term << "\n"
356356
<< " D_Error: " << d_error << "\n"
357357
<< " Command: " << get_current_cmd(););
358358
}

control_toolbox/test/pid_tests.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ TEST(ParameterTest, integrationClampZeroGainTest)
117117
EXPECT_EQ(0.0, cmd);
118118
}
119119

120+
constexpr double EPS = 1e-9;
120121
TEST(ParameterTest, integrationAntiwindupTest)
121122
{
122123
RecordProperty(
@@ -131,16 +132,16 @@ TEST(ParameterTest, integrationAntiwindupTest)
131132
double cmd = 0.0;
132133

133134
cmd = pid.compute_command(-1.0, 1.0);
134-
EXPECT_EQ(-1.0, cmd);
135+
EXPECT_NEAR(-1.0, cmd, EPS);
135136

136137
cmd = pid.compute_command(-1.0, 1.0);
137-
EXPECT_EQ(-1.0, cmd);
138+
EXPECT_NEAR(-1.0, cmd, EPS);
138139

139140
cmd = pid.compute_command(0.5, 1.0);
140-
EXPECT_EQ(0.0, cmd);
141+
EXPECT_NEAR(0.0, cmd, EPS);
141142

142143
cmd = pid.compute_command(-1.0, 1.0);
143-
EXPECT_EQ(-1.0, cmd);
144+
EXPECT_NEAR(-1.0, cmd, EPS);
144145
}
145146

146147
TEST(ParameterTest, negativeIntegrationAntiwindupTest)
@@ -157,16 +158,16 @@ TEST(ParameterTest, negativeIntegrationAntiwindupTest)
157158
double cmd = 0.0;
158159

159160
cmd = pid.compute_command(0.1, 1.0);
160-
EXPECT_EQ(-0.2, cmd);
161+
EXPECT_NEAR(-0.2, cmd, EPS);
161162

162163
cmd = pid.compute_command(0.1, 1.0);
163-
EXPECT_EQ(-0.2, cmd);
164+
EXPECT_NEAR(-0.2, cmd, EPS);
164165

165166
cmd = pid.compute_command(-0.05, 1.0);
166-
EXPECT_EQ(-0.075, cmd);
167+
EXPECT_NEAR(-0.075, cmd, EPS);
167168

168169
cmd = pid.compute_command(0.1, 1.0);
169-
EXPECT_EQ(-0.2, cmd);
170+
EXPECT_NEAR(-0.2, cmd, EPS);
170171
}
171172

172173
TEST(ParameterTest, gainSettingCopyPIDTest)

0 commit comments

Comments
 (0)