00001 #include <gtest/gtest.h>
00002 #include <boost/shared_ptr.hpp>
00003 #include <boost/make_shared.hpp>
00004 #include "robot_instance/RobotInstanceFactory.h"
00005 #include "robot_instance/CoeffMapLoader.h"
00006 #include "robodyn_mechanisms/JointCommandFinger.h"
00007 #include <ros/package.h>
00008 #include "r2_msgs/JointControlData.h"
00009
00010 using namespace std;
00011 using namespace Eigen;
00012
00013 std::map<std::string, int16_t> testInt16;
00014 std::map<std::string, uint16_t> testUint16;
00015 std::map<std::string, float> testLiveCoeffs;
00016 ParamMap testParamMap;
00017 CoeffMapPtr motorCoeffMap;
00018 CoeffMapPtr brainstemCoeffMap;
00019 RobotInstancePtr instance;
00020
00021
00022 float getInt16(std::string item)
00023 {
00024 if (testInt16.find(item) != testInt16.end())
00025 {
00026 return testInt16[item];
00027 }
00028 else
00029 {
00030 return 0.f;
00031 }
00032 }
00033
00034 float getUint16(std::string item)
00035 {
00036 if (testUint16.find(item) != testUint16.end())
00037 {
00038 return testUint16[item];
00039 }
00040 else
00041 {
00042 return 0.f;
00043 }
00044 }
00045
00046 void setInt16(std::string item, int16_t value)
00047 {
00048 testInt16[item] = value;
00049 }
00050
00051 void setUint16(std::string item, uint16_t value)
00052 {
00053 testUint16[item] = value;
00054 }
00055
00056 float getBrainstemCoeff(std::string item)
00057 {
00058 return brainstemCoeffMap->operator[](item);
00059 }
00060
00061 float getMotorCoeff(std::string item)
00062 {
00063 return motorCoeffMap->operator[](item);
00064 }
00065
00066 bool hasLiveCoeff(std::string coeff)
00067 {
00068 return testLiveCoeffs.find(coeff) != testLiveCoeffs.end();
00069 }
00070
00071 float getLiveCoeff(std::string coeff)
00072 {
00073 if (hasLiveCoeff(coeff))
00074 {
00075 return testLiveCoeffs[coeff];
00076 }
00077 else
00078 {
00079 throw std::runtime_error(std::string("GetLiveCoeff: coeff (") + coeff + ") doesn't exist");
00080 return -12345.f;
00081 }
00082 }
00083
00084 void setLiveCoeff(std::string coeff, float value)
00085 {
00086 testLiveCoeffs[coeff] = value;
00087 }
00088
00089 bool hasParam(std::string paramName)
00090 {
00091 return (testParamMap.find(paramName) != testParamMap.end());
00092 }
00093
00094 bool getBoolParam(std::string paramName, bool& value)
00095 {
00096 value = boost::get<bool>(testParamMap[paramName]);
00097 return true;
00098 }
00099
00100 bool getStringParam(std::string paramName, std::string& value)
00101 {
00102 value = boost::get<std::string>(testParamMap[paramName]);
00103 return true;
00104 }
00105
00106 bool getDoubleParam(std::string paramName, double& value)
00107 {
00108 value = boost::get<double>(testParamMap[paramName]);
00109 return true;
00110 }
00111
00112 bool getIntParam(std::string paramName, int& value)
00113 {
00114 value = boost::get<int>(testParamMap[paramName]);
00115 return true;
00116 }
00117
00118 void setBoolParam(std::string paramName, bool value)
00119 {
00120 testParamMap[paramName] = value;
00121 }
00122
00123 void setStringParam(std::string paramName, std::string value)
00124 {
00125 testParamMap[paramName] = value;
00126 }
00127
00128 void setDoubleParam(std::string paramName, double value)
00129 {
00130 testParamMap[paramName] = value;
00131 }
00132
00133 void setIntParam(std::string paramName, int value)
00134 {
00135 testParamMap[paramName] = value;
00136 }
00137
00138
00139 std::vector<std::string> getJointNames(std::string mechanism)
00140 {
00141 return instance->mechanismJointsMap[mechanism];
00142 }
00143
00144 std::vector<std::string> getAllJointNames(std::string mechanism)
00145 {
00146 return instance->mechanismAllJointsMap[mechanism];
00147 }
00148
00149 std::vector<std::string> getActuatorNames(std::string mechanism)
00150 {
00151 return instance->mechanismActuatorsMap[mechanism];
00152 }
00153
00154 std::string getCommandFile(std::string mechanism)
00155 {
00156 return instance->configurationSafetyBasePath + instance->APIMAP_PATH + instance->mechanismCommandMap[mechanism];
00157 }
00158
00159 void tubeTare(std::string mechanism, JointCommandInterface::IoFunctions& io)
00160 {
00161 std::vector<std::string> roboDynActuators = io.getActuatorNames(mechanism);
00162
00163 for (unsigned int i = 0; i < roboDynActuators.size(); ++i)
00164 {
00165 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "EncoderOffset"), 0.);
00166 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "SliderOffset"), 0.);
00167 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "SliderTarePosition"), 0.);
00168 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "TensionOffset"), 0.);
00169 }
00170
00171 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(mechanism, "IsCalibrated"), 1);
00172 }
00173
00174 class JointCommandFingerTest : public ::testing::Test
00175 {
00176 protected:
00177 virtual void SetUp()
00178 {
00179 packagePath = ros::package::getPath("robot_instance");
00180 configPath = packagePath + "/test/config";
00181 configSafetyPath = packagePath + "/test/configSafety";
00182 fileName = "TestRobotInstanceFinger.xml";
00183 instance = RobotInstanceFactory::createRobotInstanceFromFile(configPath, configSafetyPath, fileName);
00184
00185 motorCoeffMap = boost::make_shared<CoeffMap>();
00186 brainstemCoeffMap = boost::make_shared<CoeffMap>();
00187 CoeffMapLoader::loadElements(instance, motorCoeffMap, brainstemCoeffMap);
00188
00189 testInt16.clear();
00190 testUint16.clear();
00191 testLiveCoeffs.clear();
00192
00193 io.setInt16 = setInt16;
00194 io.getInt16 = getInt16;
00195 io.getUInt16 = getUint16;
00196 io.getBrainstemCoeff = getBrainstemCoeff;
00197 io.getMotorCoeff = getMotorCoeff;
00198 io.getJointNames = getJointNames;
00199 io.getAllJointNames = getAllJointNames;
00200 io.getActuatorNames = getActuatorNames;
00201 io.getCommandFile = getCommandFile;
00202 io.hasLiveCoeff = hasLiveCoeff;
00203 io.getLiveCoeff = getLiveCoeff;
00204 io.setLiveCoeff = setLiveCoeff;
00205 io.hasParam = hasParam;
00206 io.getBoolParam = getBoolParam;
00207 io.getIntParam = getIntParam;
00208 io.getDoubleParam = getDoubleParam;
00209 io.getStringParam = getStringParam;
00210 io.setBoolParam = setBoolParam;
00211 io.setIntParam = setIntParam;
00212 io.setDoubleParam = setDoubleParam;
00213 io.setStringParam = setStringParam;
00214
00215 ros::Time::init();
00216 mechanism = "r2/right_arm/hand/index";
00217
00218
00219 controlMsg.calibrationMode.state = r2_msgs::JointControlCalibrationMode::DISABLE;
00220 controlMsg.clearFaultMode.state = r2_msgs::JointControlClearFaultMode::DISABLE;
00221 controlMsg.coeffState.state = r2_msgs::JointControlCoeffState::LOADED;
00222 controlMsg.commandMode.state = r2_msgs::JointControlCommandMode::MULTILOOPSMOOTH;
00223 controlMsg.controlMode.state = r2_msgs::JointControlMode::DRIVE;
00224
00225
00226 commandMsg.name.push_back("r2/right_arm/hand/index/yaw");
00227 commandMsg.name.push_back("r2/right_arm/hand/index/proximal");
00228 commandMsg.name.push_back("r2/right_arm/hand/index/medial");
00229 commandMsg.derivativeGain.resize(3, 0.);
00230 commandMsg.desiredPosition.resize(3, 0.);
00231 commandMsg.desiredPositionVelocityLimit.resize(3, 0.);
00232 commandMsg.feedForwardTorque.resize(3, 0.);
00233 commandMsg.integralGain.resize(3, 0.);
00234 commandMsg.positionLoopTorqueLimit.resize(3, 0.);
00235 commandMsg.positionLoopWindupLimit.resize(3, 0.);
00236 commandMsg.proportionalGain.resize(3, 0.);
00237 commandMsg.torqueLoopVelocityLimit.resize(3, 0.);
00238 }
00239
00240 virtual void TearDown()
00241 {
00242 testInt16.clear();
00243 testUint16.clear();
00244 testLiveCoeffs.clear();
00245 motorCoeffMap.reset();
00246 brainstemCoeffMap.reset();
00247 instance.reset();
00248 }
00249
00250 string packagePath, configPath, configSafetyPath, fileName;
00251 string mechanism;
00252 JointCommandInterface::IoFunctions io;
00253 r2_msgs::JointControlData controlMsg;
00254 r2_msgs::JointCommand commandMsg;
00255
00256 typedef JointCommandFinger<3, 4> index_type;
00257 };
00258
00259 TEST_F(JointCommandFingerTest, Constructor)
00260 {
00261 ASSERT_NO_THROW(index_type index(mechanism, io));
00263 io.getInt16 = 0;
00264 EXPECT_THROW(index_type index(mechanism, io), std::invalid_argument);
00265 }
00266
00267 TEST_F(JointCommandFingerTest, updateMeasuredState)
00268 {
00269 index_type index(mechanism, io);
00270 EXPECT_NO_THROW(index.updateMeasuredState(controlMsg));
00271
00272 setLiveCoeff(StringUtilities::makeFullyQualifiedRoboDynElement(mechanism, "CalibrationMode"), r2_msgs::JointControlCalibrationMode::DISABLE);
00273 EXPECT_THROW(index.updateMeasuredState(controlMsg), std::runtime_error);
00274
00275 tubeTare(mechanism, io);
00276 ASSERT_NO_THROW(index.updateMeasuredState(controlMsg));
00277 }
00278
00279 TEST_F(JointCommandFingerTest, getSimpleMeasuredState)
00280 {
00281 index_type index(mechanism, io);
00282 tubeTare(mechanism, io);
00283 index.updateMeasuredState(controlMsg);
00284
00285 sensor_msgs::JointState js = index.getSimpleMeasuredState();
00286 EXPECT_EQ(4, js.name.size());
00287 EXPECT_EQ(4, js.effort.size());
00288 EXPECT_EQ(4, js.position.size());
00289 EXPECT_EQ(4, js.velocity.size());
00290
00291
00292 }
00293
00294 TEST_F(JointCommandFingerTest, getCompleteMeasuredState)
00295 {
00296 index_type index(mechanism, io);
00297 tubeTare(mechanism, io);
00298 index.updateMeasuredState(controlMsg);
00299
00300 sensor_msgs::JointState js = index.getCompleteMeasuredState();
00301 EXPECT_EQ(18, js.name.size());
00302 EXPECT_EQ(18, js.effort.size());
00303 EXPECT_EQ(18, js.position.size());
00304 EXPECT_EQ(18, js.velocity.size());
00305 }
00306
00307 TEST_F(JointCommandFingerTest, setCommand)
00308 {
00309 index_type index(mechanism, io);
00310 tubeTare(mechanism, io);
00311 index.updateMeasuredState(controlMsg);
00312
00313 index.setCommand(commandMsg, controlMsg);
00314 r2_msgs::JointCommand cm = index.getCommandedState();
00315 EXPECT_EQ(commandMsg.derivativeGain, cm.derivativeGain);
00316 EXPECT_EQ(commandMsg.desiredPosition, cm.desiredPosition);
00317 EXPECT_EQ(commandMsg.desiredPositionVelocityLimit, cm.desiredPositionVelocityLimit);
00318 EXPECT_EQ(commandMsg.feedForwardTorque, cm.feedForwardTorque);
00319 EXPECT_EQ(commandMsg.integralGain, cm.integralGain);
00320 EXPECT_EQ(commandMsg.name, cm.name);
00321 EXPECT_EQ(commandMsg.positionLoopTorqueLimit, cm.positionLoopTorqueLimit);
00322 EXPECT_EQ(commandMsg.positionLoopWindupLimit, cm.positionLoopWindupLimit);
00323 EXPECT_EQ(commandMsg.proportionalGain, cm.proportionalGain);
00324 EXPECT_EQ(commandMsg.torqueLoopVelocityLimit, cm.torqueLoopVelocityLimit);
00325 }
00326
00327 TEST_F(JointCommandFingerTest, getCapability)
00328 {
00329 index_type index(mechanism, io);
00330
00331 r2_msgs::JointCapability msg = index.getCapability();
00332
00333 EXPECT_EQ(3, msg.name.size());
00334 EXPECT_EQ(3, msg.positionLimitMax.size());
00335 EXPECT_EQ(3, msg.positionLimitMin.size());
00336
00337 EXPECT_STREQ("r2/right_arm/hand/index/yaw", msg.name[0].c_str());
00338 EXPECT_STREQ("r2/right_arm/hand/index/proximal", msg.name[1].c_str());
00339 EXPECT_STREQ("r2/right_arm/hand/index/medial", msg.name[2].c_str());
00340 }
00341
00342 int main(int argc, char** argv)
00343 {
00344 testing::InitGoogleTest(&argc, argv);
00345 return RUN_ALL_TESTS();
00346 }