pid_tests.cpp
Go to the documentation of this file.
00001 
00002 #include <ros/ros.h>
00003 
00004 #include <gtest/gtest.h>
00005 
00006 #include <control_toolbox/pid.h>
00007 
00008 #include <boost/math/special_functions/fpclassify.hpp>
00009 
00010 using namespace control_toolbox;
00011 
00012 TEST(ParameterTest, zeroITermBadIBoundsTest)
00013 {
00014   RecordProperty("description","This test checks robustness against divide-by-zero errors when given integral term bounds which do not include 0.0.");
00015 
00016   Pid pid(1.0, 0.0, 0.0, -1.0, 0.0);
00017 
00018   double cmd = 0.0;
00019   double pe,ie,de;
00020 
00021   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00022 
00023   pid.getCurrentPIDErrors(&pe,&ie,&de);
00024   EXPECT_FALSE(boost::math::isinf(ie));
00025   EXPECT_FALSE(boost::math::isnan(cmd));
00026 
00027   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00028   pid.getCurrentPIDErrors(&pe,&ie,&de);
00029   EXPECT_FALSE(boost::math::isinf(ie));
00030   EXPECT_FALSE(boost::math::isnan(cmd));
00031 }
00032 
00033 TEST(ParameterTest, integrationWindupTest)
00034 {
00035   RecordProperty("description","This test succeeds if the integral error is prevented from winding up when the integral gain is non-zero.");
00036 
00037   Pid pid(0.0, 1.0, 0.0, 1.0, -1.0);
00038 
00039   double cmd = 0.0;
00040   double pe,ie,de;
00041 
00042   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00043   pid.getCurrentPIDErrors(&pe,&ie,&de);
00044   EXPECT_EQ(-1.0, ie);
00045   EXPECT_EQ(-1.0, cmd);
00046 
00047   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00048   pid.getCurrentPIDErrors(&pe,&ie,&de);
00049   EXPECT_EQ(-1.0, ie);
00050   EXPECT_EQ(-1.0, cmd);
00051 }
00052 
00053 TEST(ParameterTest, integrationWindupZeroGainTest)
00054 {
00055   RecordProperty("description","This test succeeds if the integral error is prevented from winding up when the integral gain is zero. If the integral error is allowed to wind up while it is disabled, it can cause sudden jumps to the minimum or maximum bound in control command when re-enabled.");
00056 
00057   double i_gain = 0.0;
00058   double i_min = -1.0;
00059   double i_max = 1.0;
00060   Pid pid(0.0, i_gain, 0.0, i_max, i_min);
00061 
00062   double cmd = 0.0;
00063   double pe,ie,de;
00064 
00065   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00066   pid.getCurrentPIDErrors(&pe,&ie,&de);
00067   EXPECT_LE(i_min, ie);
00068   EXPECT_LE(ie, i_max);
00069   EXPECT_EQ(0.0, cmd);
00070 
00071   cmd = pid.computeCommand(-1.0, ros::Duration(1.0));
00072   pid.getCurrentPIDErrors(&pe,&ie,&de);
00073   EXPECT_LE(i_min, ie);
00074   EXPECT_LE(ie, i_max);
00075   EXPECT_EQ(0.0, cmd);
00076 }
00077 
00078 TEST(ParameterTest, gainSettingCopyPIDTest)
00079 {
00080   RecordProperty("description","This test succeeds if a PID object has its gain set at different points in time then the values are get-ed and still remain the same, as well as when PID is copied.");
00081 
00082   // Test values
00083   double p_gain = rand() % 100;
00084   double i_gain = rand() % 100;
00085   double d_gain = rand() % 100;
00086   double i_max = rand() % 100;
00087   double i_min = -1 * rand() % 100;
00088 
00089   // Initialize the default way
00090   Pid pid1(p_gain, i_gain, d_gain, i_max, i_min);
00091   
00092   // Test return values  -------------------------------------------------
00093   double p_gain_return, i_gain_return, d_gain_return, i_max_return, i_min_return;
00094   pid1.getGains(p_gain_return, i_gain_return, d_gain_return, i_max_return, i_min_return);
00095 
00096   EXPECT_EQ(p_gain, p_gain_return);
00097   EXPECT_EQ(i_gain, i_gain_return);
00098   EXPECT_EQ(d_gain, d_gain_return);
00099   EXPECT_EQ(i_max, i_max_return);
00100   EXPECT_EQ(i_min, i_min_return);
00101 
00102   // Test return values using struct -------------------------------------------------
00103 
00104   // New values
00105   p_gain = rand() % 100;
00106   i_gain = rand() % 100;
00107   d_gain = rand() % 100;
00108   i_max = rand() % 100;
00109   i_min = -1 * rand() % 100;
00110   pid1.setGains(p_gain, i_gain, d_gain, i_max, i_min);
00111 
00112   Pid::Gains g1 = pid1.getGains();
00113   EXPECT_EQ(p_gain, g1.p_gain_);
00114   EXPECT_EQ(i_gain, g1.i_gain_);
00115   EXPECT_EQ(d_gain, g1.d_gain_);
00116   EXPECT_EQ(i_max, g1.i_max_);
00117   EXPECT_EQ(i_min, g1.i_min_);
00118 
00119   // \todo test initParam() -------------------------------------------------
00120   
00121 
00122   // \todo test bool init(const ros::NodeHandle &n); -----------------------------------
00123 
00124 
00125   // Send update command to populate errors -------------------------------------------------
00126   pid1.setCurrentCmd(10);
00127   pid1.computeCommand(20, ros::Duration(1.0));
00128 
00129   // Test copy constructor -------------------------------------------------
00130   Pid pid2(pid1);
00131 
00132   pid2.getGains(p_gain_return, i_gain_return, d_gain_return, i_max_return, i_min_return);
00133 
00134   EXPECT_EQ(p_gain, p_gain_return);
00135   EXPECT_EQ(i_gain, i_gain_return);
00136   EXPECT_EQ(d_gain, d_gain_return);
00137   EXPECT_EQ(i_max, i_max_return);
00138   EXPECT_EQ(i_min, i_min_return);
00139 
00140   // Test that errors are zero
00141   double pe, ie, de;
00142   pid2.getCurrentPIDErrors(&pe, &ie, &de);
00143   EXPECT_EQ(0.0, pe);
00144   EXPECT_EQ(0.0, ie);
00145   EXPECT_EQ(0.0, de);
00146     
00147   // Test assignment constructor -------------------------------------------------
00148   Pid pid3;
00149   pid3 = pid1;
00150 
00151   pid3.getGains(p_gain_return, i_gain_return, d_gain_return, i_max_return, i_min_return);
00152 
00153   EXPECT_EQ(p_gain, p_gain_return);
00154   EXPECT_EQ(i_gain, i_gain_return);
00155   EXPECT_EQ(d_gain, d_gain_return);
00156   EXPECT_EQ(i_max, i_max_return);
00157   EXPECT_EQ(i_min, i_min_return);
00158 
00159   // Test that errors are zero
00160   double pe2, ie2, de2;
00161   pid3.getCurrentPIDErrors(&pe2, &ie2, &de2);
00162   EXPECT_EQ(0.0, pe2);
00163   EXPECT_EQ(0.0, ie2);
00164   EXPECT_EQ(0.0, de2);
00165 
00166   // Test return values using struct - const version  -------------------------------------------------
00167 
00168   const Pid pid4(pid3);
00169 
00170   Pid::Gains g3 = pid4.getGains();
00171   EXPECT_EQ(p_gain, g3.p_gain_);
00172   EXPECT_EQ(i_gain, g3.i_gain_);
00173   EXPECT_EQ(d_gain, g3.d_gain_);
00174   EXPECT_EQ(i_max, g3.i_max_);
00175   EXPECT_EQ(i_min, g3.i_min_);
00176 
00177 
00178 }
00179 
00180 
00181 
00182 int main(int argc, char** argv) {
00183   testing::InitGoogleTest(&argc, argv);
00184   return RUN_ALL_TESTS();
00185 }


control_toolbox
Author(s): Melonee Wise, Sachin Chitta, John Hsu
autogenerated on Wed Aug 26 2015 11:09:13