@@ -54,7 +54,6 @@ constexpr double UMAX_INFINITY = std::numeric_limits<double>::infinity();
54
54
#pragma GCC diagnostic push
55
55
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
56
56
Pid::Pid (double p, double i, double d, double i_max, double i_min, bool antiwindup)
57
- : gains_buffer_()
58
57
{
59
58
if (i_min > i_max)
60
59
{
@@ -77,7 +76,6 @@ Pid::Pid(double p, double i, double d, double i_max, double i_min, bool antiwind
77
76
Pid::Pid (
78
77
double p, double i, double d, double u_max, double u_min,
79
78
const AntiWindupStrategy & antiwindup_strat)
80
- : gains_buffer_()
81
79
{
82
80
if (u_min > u_max)
83
81
{
@@ -93,8 +91,8 @@ Pid::Pid(
93
91
94
92
Pid::Pid (const Pid & source)
95
93
{
96
- // Copy the realtime buffer to the new PID class
97
- gains_buffer_ = source.gains_buffer_ ;
94
+ // Copy the realtime box to the new PID class
95
+ gains_box_ = source.gains_box_ ;
98
96
99
97
// Initialize saved i-term values
100
98
clear_saved_iterm ();
@@ -147,6 +145,9 @@ void Pid::reset(bool save_i_term)
147
145
{
148
146
clear_saved_iterm ();
149
147
}
148
+
149
+ // blocking, as reset() is not called in the RT thread
150
+ gains_ = gains_box_.get ();
150
151
}
151
152
152
153
void Pid::clear_saved_iterm () { i_term_ = 0.0 ; }
@@ -177,8 +178,7 @@ void Pid::get_gains(
177
178
double & p, double & i, double & d, double & u_max, double & u_min,
178
179
AntiWindupStrategy & antiwindup_strat)
179
180
{
180
- Gains gains = *gains_buffer_.readFromRT ();
181
-
181
+ Gains gains = get_gains ();
182
182
p = gains.p_gain_ ;
183
183
i = gains.i_gain_ ;
184
184
d = gains.d_gain_ ;
@@ -187,7 +187,11 @@ void Pid::get_gains(
187
187
antiwindup_strat = gains.antiwindup_strat_ ;
188
188
}
189
189
190
- Pid::Gains Pid::get_gains () { return *gains_buffer_.readFromRT (); }
190
+ Pid::Gains Pid::get_gains ()
191
+ {
192
+ // blocking, as get_gains() is called from non-RT thread
193
+ return gains_box_.get ();
194
+ }
191
195
192
196
#pragma GCC diagnostic push
193
197
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
@@ -253,7 +257,8 @@ bool Pid::set_gains(const Gains & gains_in)
253
257
gains.antiwindup_strat_ .tracking_time_constant = gains.p_gain_ / gains.i_gain_ ;
254
258
}
255
259
}
256
- gains_buffer_.writeFromNonRT (gains);
260
+ // blocking, as set_gains() is called from non-RT thread
261
+ gains_box_.set (gains);
257
262
return true ;
258
263
}
259
264
return false ;
@@ -326,8 +331,12 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
326
331
{
327
332
throw std::invalid_argument (" Pid is called with negative dt" );
328
333
}
329
- // Get the gain parameters from the realtime buffer
330
- Gains gains = *gains_buffer_.readFromRT ();
334
+ // Get the gain parameters from the realtime box
335
+ auto gains_opt = gains_box_.try_get ();
336
+ if (gains_opt.has_value ())
337
+ {
338
+ gains_ = gains_opt.value ();
339
+ }
331
340
332
341
double p_term, d_term;
333
342
p_error_ = error; // This is error = target - state
@@ -341,57 +350,58 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
341
350
}
342
351
343
352
// Calculate proportional contribution to command
344
- p_term = gains .p_gain_ * p_error_;
353
+ p_term = gains_ .p_gain_ * p_error_;
345
354
346
355
// Calculate derivative contribution to command
347
- d_term = gains .d_gain_ * d_error_;
356
+ d_term = gains_ .d_gain_ * d_error_;
348
357
349
- if (gains .antiwindup_strat_ .type == AntiWindupStrategy::UNDEFINED)
358
+ if (gains_ .antiwindup_strat_ .type == AntiWindupStrategy::UNDEFINED)
350
359
{
351
360
throw std::runtime_error (
352
361
" PID: Antiwindup strategy cannot be UNDEFINED. Please set a valid antiwindup strategy." );
353
362
}
354
363
355
364
// Calculate integral contribution to command
356
365
const bool is_error_in_deadband_zone =
357
- control_toolbox::is_zero (error, gains .antiwindup_strat_ .error_deadband );
358
- if (!is_error_in_deadband_zone && gains .antiwindup_strat_ .type == AntiWindupStrategy::LEGACY)
366
+ control_toolbox::is_zero (error, gains_ .antiwindup_strat_ .error_deadband );
367
+ if (!is_error_in_deadband_zone && gains_ .antiwindup_strat_ .type == AntiWindupStrategy::LEGACY)
359
368
{
360
- if (gains .antiwindup_strat_ .legacy_antiwindup )
369
+ if (gains_ .antiwindup_strat_ .legacy_antiwindup )
361
370
{
362
371
// Prevent i_term_ from climbing higher than permitted by i_max_/i_min_
363
- i_term_ = std::clamp (i_term_ + gains.i_gain_ * dt_s * p_error_, gains.i_min_ , gains.i_max_ );
372
+ i_term_ =
373
+ std::clamp (i_term_ + gains_.i_gain_ * dt_s * p_error_, gains_.i_min_ , gains_.i_max_ );
364
374
}
365
375
else
366
376
{
367
- i_term_ += gains .i_gain_ * dt_s * p_error_;
377
+ i_term_ += gains_ .i_gain_ * dt_s * p_error_;
368
378
}
369
379
}
370
380
371
381
// Compute the command
372
382
if (
373
- !gains .antiwindup_strat_ .legacy_antiwindup &&
374
- gains .antiwindup_strat_ .type == AntiWindupStrategy::LEGACY)
383
+ !gains_ .antiwindup_strat_ .legacy_antiwindup &&
384
+ gains_ .antiwindup_strat_ .type == AntiWindupStrategy::LEGACY)
375
385
{
376
386
// Limit i_term so that the limit is meaningful in the output
377
- cmd_unsat_ = p_term + std::clamp (i_term_, gains .i_min_ , gains .i_max_ ) + d_term;
387
+ cmd_unsat_ = p_term + std::clamp (i_term_, gains_ .i_min_ , gains_ .i_max_ ) + d_term;
378
388
}
379
389
else
380
390
{
381
391
cmd_unsat_ = p_term + i_term_ + d_term;
382
392
}
383
393
384
- if (std::isfinite (gains .u_min_ ) || std::isfinite (gains .u_max_ ))
394
+ if (std::isfinite (gains_ .u_min_ ) || std::isfinite (gains_ .u_max_ ))
385
395
{
386
- if (gains .u_min_ > gains .u_max_ )
396
+ if (gains_ .u_min_ > gains_ .u_max_ )
387
397
{
388
398
throw std::runtime_error (" Pid: Error while saturating the command : u_min > u_max" );
389
399
}
390
- if (std::isnan (gains .u_min_ ) || std::isnan (gains .u_max_ ))
400
+ if (std::isnan (gains_ .u_min_ ) || std::isnan (gains_ .u_max_ ))
391
401
{
392
402
throw std::runtime_error (" Pid: Error while saturating the command : u_min or u_max is NaN" );
393
403
}
394
- cmd_ = std::clamp (cmd_unsat_, gains .u_min_ , gains .u_max_ );
404
+ cmd_ = std::clamp (cmd_unsat_, gains_ .u_min_ , gains_ .u_max_ );
395
405
}
396
406
else
397
407
{
@@ -401,17 +411,17 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
401
411
if (!is_error_in_deadband_zone)
402
412
{
403
413
if (
404
- gains .antiwindup_strat_ .type == AntiWindupStrategy::BACK_CALCULATION &&
405
- !is_zero (gains .i_gain_ ))
414
+ gains_ .antiwindup_strat_ .type == AntiWindupStrategy::BACK_CALCULATION &&
415
+ !is_zero (gains_ .i_gain_ ))
406
416
{
407
- i_term_ += dt_s * (gains .i_gain_ * error +
408
- 1 / gains .antiwindup_strat_ .tracking_time_constant * (cmd_ - cmd_unsat_));
417
+ i_term_ += dt_s * (gains_ .i_gain_ * error +
418
+ 1 / gains_ .antiwindup_strat_ .tracking_time_constant * (cmd_ - cmd_unsat_));
409
419
}
410
- else if (gains .antiwindup_strat_ .type == AntiWindupStrategy::CONDITIONAL_INTEGRATION)
420
+ else if (gains_ .antiwindup_strat_ .type == AntiWindupStrategy::CONDITIONAL_INTEGRATION)
411
421
{
412
422
if (!(!is_zero (cmd_unsat_ - cmd_) && error * cmd_unsat_ > 0 ))
413
423
{
414
- i_term_ += dt_s * gains .i_gain_ * error;
424
+ i_term_ += dt_s * gains_ .i_gain_ * error;
415
425
}
416
426
}
417
427
}
0 commit comments