PIDTest.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/UnitTest/TestTypes.h>
  9. #include <AzTest/AzTest.h>
  10. #include <ROS2Controllers/Controllers/PidConfiguration.h>
  11. namespace UnitTest
  12. {
  13. static const uint64_t secToNanosec = 1e9;
  14. class PIDTest : public LeakDetectionFixture
  15. {
  16. };
  17. TEST_F(PIDTest, iClampAntiwindup)
  18. {
  19. double iGain = 1.0;
  20. double iMin = -1.0;
  21. double iMax = 1.0;
  22. ROS2Controllers::PidConfiguration pid(0.0, iGain, 0.0, iMax, iMin, true, 1.0);
  23. pid.InitializePid();
  24. double output = 0.0;
  25. output = pid.ComputeCommand(-10.0, 1 * secToNanosec);
  26. EXPECT_EQ(0.0, output);
  27. output = pid.ComputeCommand(30.0, 1 * secToNanosec);
  28. EXPECT_EQ(1.0, output);
  29. }
  30. TEST_F(PIDTest, iClampNoGain)
  31. {
  32. double iGain = 0.0;
  33. double iMin = -1.0;
  34. double iMax = 1.0;
  35. ROS2Controllers::PidConfiguration pid(0.0, iGain, 0.0, iMax, iMin, false, 0.0);
  36. pid.InitializePid();
  37. double output = 0.0;
  38. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  39. EXPECT_LE(iMin, output);
  40. EXPECT_LE(output, iMax);
  41. EXPECT_EQ(0.0, output);
  42. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  43. EXPECT_LE(iMin, output);
  44. EXPECT_LE(output, iMax);
  45. EXPECT_EQ(0.0, output);
  46. }
  47. TEST_F(PIDTest, iAntiwindup)
  48. {
  49. double iGain = 2.0;
  50. double iMin = -1.0;
  51. double iMax = 1.0;
  52. ROS2Controllers::PidConfiguration pid(0.0, iGain, 0.0, iMax, iMin, true, 0.0);
  53. pid.InitializePid();
  54. double output = 0.0;
  55. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  56. EXPECT_EQ(-1.0, output);
  57. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  58. EXPECT_EQ(-1.0, output);
  59. output = pid.ComputeCommand(0.5, 1 * secToNanosec);
  60. EXPECT_EQ(0.0, output);
  61. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  62. EXPECT_EQ(-1.0, output);
  63. }
  64. TEST_F(PIDTest, negativeIAntiwindup)
  65. {
  66. double iGain = -2.5;
  67. double iMin = -0.2;
  68. double iMax = 0.5;
  69. ROS2Controllers::PidConfiguration pid(0.0, iGain, 0.0, iMax, iMin, true, 0.0);
  70. pid.InitializePid();
  71. double output = 0.0;
  72. output = pid.ComputeCommand(0.1, 1 * secToNanosec);
  73. EXPECT_EQ(-0.2, output);
  74. output = pid.ComputeCommand(0.1, 1 * secToNanosec);
  75. EXPECT_EQ(-0.2, output);
  76. output = pid.ComputeCommand(-0.05, 1 * secToNanosec);
  77. EXPECT_EQ(-0.075, output);
  78. output = pid.ComputeCommand(0.1, 1 * secToNanosec);
  79. EXPECT_EQ(-0.2, output);
  80. }
  81. TEST_F(PIDTest, pOnly)
  82. {
  83. ROS2Controllers::PidConfiguration pid(1.0, 0.0, 0.0, 0.0, 0.0, false, 0.0);
  84. pid.InitializePid();
  85. double output = 0.0;
  86. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  87. EXPECT_EQ(-0.5, output);
  88. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  89. EXPECT_EQ(-0.5, output);
  90. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  91. EXPECT_EQ(-1.0, output);
  92. output = pid.ComputeCommand(0.5, 1 * secToNanosec);
  93. EXPECT_EQ(0.5, output);
  94. }
  95. TEST_F(PIDTest, iOnly)
  96. {
  97. ROS2Controllers::PidConfiguration pid(0.0, 1.0, 0.0, 5.0, -5.0, false, 0.0);
  98. pid.InitializePid();
  99. double output = 0.0;
  100. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  101. EXPECT_EQ(-0.5, output);
  102. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  103. EXPECT_EQ(-1.0, output);
  104. output = pid.ComputeCommand(0.0, 1 * secToNanosec);
  105. EXPECT_EQ(-1.0, output);
  106. output = pid.ComputeCommand(0.0, 1 * secToNanosec);
  107. EXPECT_EQ(-1.0, output);
  108. output = pid.ComputeCommand(1.0, 1 * secToNanosec);
  109. EXPECT_EQ(0.0, output);
  110. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  111. EXPECT_EQ(-0.5, output);
  112. }
  113. TEST_F(PIDTest, dOnly)
  114. {
  115. ROS2Controllers::PidConfiguration pid(0.0, 0.0, 1.0, 0.0, 0.0, false, 0.0);
  116. pid.InitializePid();
  117. double output = 0.0;
  118. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  119. EXPECT_EQ(-0.5, output);
  120. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  121. EXPECT_EQ(0.0, output);
  122. output = pid.ComputeCommand(-0.5, 0 * secToNanosec);
  123. EXPECT_EQ(0.0, output);
  124. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  125. EXPECT_EQ(-0.5, output);
  126. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  127. EXPECT_EQ(0.5, output);
  128. }
  129. TEST_F(PIDTest, completePID)
  130. {
  131. ROS2Controllers::PidConfiguration pid(1.0, 1.0, 1.0, 5.0, -5.0, false, 0.0);
  132. pid.InitializePid();
  133. double output = 0.0;
  134. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  135. EXPECT_EQ(-1.5, output);
  136. output = pid.ComputeCommand(-0.5, 1 * secToNanosec);
  137. EXPECT_EQ(-1.5, output);
  138. output = pid.ComputeCommand(-1.0, 1 * secToNanosec);
  139. EXPECT_EQ(-3.5, output);
  140. }
  141. } // namespace UnitTest