Skip to content

Commit d7284f5

Browse files
mergify[bot]saikishorchristophfroehlich
authored
Don't return cmd if called with dt=0 or garbage (backport #326) (#412)
Co-authored-by: Sai Kishor Kothakota <[email protected]> Co-authored-by: Christoph Froehlich <[email protected]>
1 parent 13cff26 commit d7284f5

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

control_toolbox/src/pid.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <algorithm>
4040
#include <cmath>
4141
#include <iostream>
42+
#include <limits>
4243
#include <stdexcept>
4344

4445
#include "control_toolbox/pid.hpp"
@@ -306,7 +307,19 @@ double Pid::compute_command(double error, const double & dt_s)
306307
{
307308
if (is_zero(dt_s))
308309
{
309-
return 0.0;
310+
// don't update anything
311+
return cmd_;
312+
}
313+
else if (dt_s < 0.0)
314+
{
315+
throw std::invalid_argument("Pid is called with negative dt");
316+
}
317+
318+
// don't reset controller but return NaN
319+
if (!std::isfinite(error))
320+
{
321+
std::cout << "Received a non-finite error value\n";
322+
return cmd_ = std::numeric_limits<double>::quiet_NaN();
310323
}
311324

312325
// Calculate the derivative error
@@ -350,7 +363,7 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
350363
{
351364
if (is_zero(dt_s))
352365
{
353-
// Don't update anything
366+
// don't update anything
354367
return cmd_;
355368
}
356369
else if (dt_s < 0.0)
@@ -364,11 +377,11 @@ double Pid::compute_command(double error, double error_dot, const double & dt_s)
364377
p_error_ = error; // This is error = target - state
365378
d_error_ = error_dot; // This is the derivative of error
366379

367-
// Don't reset controller but return NaN
380+
// don't reset controller but return NaN
368381
if (!std::isfinite(error) || !std::isfinite(error_dot))
369382
{
370383
std::cout << "Received a non-finite error/error_dot value\n";
371-
return cmd_ = std::numeric_limits<double>::quiet_NaN();
384+
return cmd_ = std::numeric_limits<float>::quiet_NaN();
372385
}
373386

374387
// Calculate proportional contribution to command

control_toolbox/test/pid_tests.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,29 @@ TEST(CommandTest, timeArgumentTest)
897897
EXPECT_EQ(cmd1, cmd2);
898898
EXPECT_EQ(cmd1, cmd3);
899899
EXPECT_EQ(cmd1, cmd4);
900+
901+
// call with dt=0, nothing should change
902+
double pe, ie1, de, ie2;
903+
pid1.get_current_pid_errors(pe, ie1, de);
904+
cmd1 = pid1.compute_command(-0.5, 0.0, 0.0);
905+
pid1.get_current_pid_errors(pe, ie2, de);
906+
EXPECT_EQ(-2.0, cmd1);
907+
EXPECT_EQ(ie1, ie2);
908+
// should throw if called with negative dt
909+
EXPECT_THROW(cmd1 = pid1.compute_command(-0.5, 0.0, -1.0), std::invalid_argument);
910+
// call with nan, should return NaN but not reset internal states
911+
cmd1 = pid1.compute_command(std::numeric_limits<double>::quiet_NaN(), 0.0, 1.0);
912+
cmd3 = pid1.get_current_cmd();
913+
EXPECT_FALSE(std::isfinite(cmd1));
914+
EXPECT_FALSE(std::isfinite(cmd3));
915+
pid1.get_current_pid_errors(pe, ie2, de);
916+
EXPECT_EQ(ie1, ie2);
917+
cmd2 = pid2.compute_command(-0.5, std::numeric_limits<double>::quiet_NaN(), 1.0);
918+
cmd4 = pid2.get_current_cmd();
919+
EXPECT_FALSE(std::isfinite(cmd2));
920+
EXPECT_FALSE(std::isfinite(cmd4));
921+
pid1.get_current_pid_errors(pe, ie2, de);
922+
EXPECT_EQ(ie1, ie2);
900923
}
901924

902925
int main(int argc, char ** argv)

0 commit comments

Comments
 (0)