00001 #include "robodyn_mechanisms/JointCommandGripper.h"
00002
00003 using namespace std;
00004 using namespace log4cpp;
00005 namespace SU = StringUtilities;
00006
00007 JointCommandGripper::JointCommandGripper(const std::string& mechanism, IoFunctions ioFunctions)
00008 : JointCommandInterface(mechanism, ioFunctions),
00009 completeMessageSize(3)
00010 {
00011 if (mechanism == "")
00012 {
00013 stringstream err;
00014 err << "Constructor requires mechanism be non-empty.";
00015 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00016 throw invalid_argument(err.str());
00017 }
00018
00019 if (io.getFloat.empty())
00020 {
00021 stringstream err;
00022 err << "Constructor requires 'io.getFloat' be non-empty.";
00023 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00024 throw invalid_argument(err.str());
00025 }
00026
00027 if (io.setFloat.empty())
00028 {
00029 stringstream err;
00030 err << "Constructor requires 'io.setFloat' be non-empty.";
00031 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00032 throw invalid_argument(err.str());
00033 }
00034
00035 if (io.getMotorCoeff.empty())
00036 {
00037 stringstream err;
00038 err << "Constructor requires 'io.getMotorCoeff' be non-empty.";
00039 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00040 throw invalid_argument(err.str());
00041 }
00042
00043 if (io.hasBrainstemCoeff.empty())
00044 {
00045 stringstream err;
00046 err << "Constructor requires 'io.hasBrainstemCoeff' be non-empty.";
00047 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00048 throw invalid_argument(err.str());
00049 }
00050
00051 if (io.getBrainstemCoeff.empty())
00052 {
00053 stringstream err;
00054 err << "Constructor requires 'io.getBrainstemCoeff' be non-empty.";
00055 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00056 throw invalid_argument(err.str());
00057 }
00058
00059 if (io.getCommandFile.empty())
00060 {
00061 stringstream err;
00062 err << "Constructor requires 'io.getCommandFile' be non-empty.";
00063 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00064 throw invalid_argument(err.str());
00065 }
00066
00067 roboDynJoints.push_back(mechanism);
00068 jawLeftName = SU::getRoboDynEverythingButJoint(mechanism) + SU::TOKEN_DELIMITER + string("jawLeft");
00069 jawRightName = SU::getRoboDynEverythingButJoint(mechanism) + SU::TOKEN_DELIMITER + string("jawRight");
00070
00071 loadCoeffs();
00072 }
00073
00074 JointCommandGripper::~JointCommandGripper()
00075 {}
00076
00077 void JointCommandGripper::loadCoeffs()
00078 {
00079 std::string parameterFile = io.getCommandFile(mechanism);
00080
00082 simpleMeasuredStateMsg.name.resize(completeMessageSize);
00083 simpleMeasuredStateMsg.position.resize(completeMessageSize);
00084 simpleMeasuredStateMsg.velocity.resize(completeMessageSize);
00085 simpleMeasuredStateMsg.effort.resize(completeMessageSize);
00086
00087 simpleMeasuredStateMsg.name[0] = roboDynJoints[0];
00088 simpleMeasuredStateMsg.name[1] = jawLeftName;
00089 simpleMeasuredStateMsg.name[2] = jawRightName;
00090
00091 completeMeasuredStateMsg.name.resize(completeMessageSize);
00092 completeMeasuredStateMsg.position.resize(completeMessageSize);
00093 completeMeasuredStateMsg.velocity.resize(completeMessageSize);
00094 completeMeasuredStateMsg.effort.resize(completeMessageSize);
00095
00096 completeMeasuredStateMsg.name[0] = roboDynJoints[0];
00097 completeMeasuredStateMsg.name[1] = jawLeftName;
00098 completeMeasuredStateMsg.name[2] = jawRightName;
00099
00100
00101
00102 jointCapabilityMsg.name.resize(1);
00103 jointCapabilityMsg.positionLimitMax.resize(1);
00104 jointCapabilityMsg.positionLimitMin.resize(1);
00105 jointCapabilityMsg.velocityLimit.resize(1);
00106 jointCapabilityMsg.torqueLimit.resize(1);
00107
00108 jointCapabilityMsg.name[0] = roboDynJoints[0];
00109
00110 positionVals.resize(completeMessageSize, 0.);
00111 velocityVals.resize(completeMessageSize, 0.);
00112 effortVals.resize(completeMessageSize, 0.);
00113
00115 TiXmlDocument file(parameterFile.c_str());
00116 bool loadOkay = file.LoadFile();
00117
00118 if (!loadOkay)
00119 {
00120 stringstream err;
00121 err << "Failed to load file [" << parameterFile << "]";
00122 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::FATAL, err.str());
00123 throw runtime_error(err.str());
00124 }
00125
00126 TiXmlHandle doc(&file);
00127 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::INFO, "CommandFile [" + parameterFile + "] successfully loaded.");
00128
00129
00130 TiXmlHandle parametersElement(doc.FirstChildElement("ApiMap"));
00131
00132 if (parametersElement.ToElement())
00133 {
00135 jointPositionStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JointPositionStatus"));
00136 jawLeftPositionStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JawLeftPositionStatus"));
00137 jawRightPositionStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JawRightPositionStatus"));
00138 jointVelocityStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JointVelocityStatus"));
00139 jawLeftTorqueStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JawLeftTorqueStatus"));
00140 jawRightTorqueStatusElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "JawRightTorqueStatus"));
00142 desiredPositionCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "DesiredPositionCommand"));
00143 desiredPositionVelocityLimitCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "DesiredPositionVelocityLimitCommand"));
00144 feedForwardTorqueCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "FeedForwardTorqueCommand"));
00145 proportionalGainCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "ProportionalGainCommand"));
00146 derivativeGainCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "DerivativeGainCommand"));
00147 integralGainCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "IntegralGainCommand"));
00148 positionLoopTorqueLimitCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PositionLoopTorqueLimitCommand"));
00149 positionLoopWindupLimitCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PositionLoopWindupLimitCommand"));
00151 jointCapabilityMsg.positionLimitMax[0] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PositionLimitMax")));
00152 jointCapabilityMsg.positionLimitMin[0] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PositionLimitMin")));
00153 jointCapabilityMsg.velocityLimit[0] = io.getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "VelLimit")));
00154 jointCapabilityMsg.torqueLimit[0] = 0.;
00155
00157 velLimitCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "VelLimit"));
00158 curLimitCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "CurLimit"));
00159 posKpCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PosKp"));
00160 pLKiCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PLKi"));
00161 posKdCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PosKd"));
00162 pLWindupLimCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PLWindupLim"));
00163 pLKiMinCommandElement = StringUtilities::makeFullyQualifiedRoboDynElement( roboDynJoints[0], ApiMap::getXmlElementValue(parametersElement, "PLKiMin"));
00164
00165 if (not(io.hasBrainstemCoeff(velLimitCommandElement)))
00166 {
00167 stringstream err;
00168 err << "The BrainstemCoeff " << velLimitCommandElement << " does not exist";
00169 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00170 throw runtime_error(err.str());
00171 }
00172
00173 if (not(io.hasBrainstemCoeff(curLimitCommandElement)))
00174 {
00175 stringstream err;
00176 err << "The BrainstemCoeff " << curLimitCommandElement << " does not exist";
00177 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00178 throw runtime_error(err.str());
00179 }
00180
00181 if (not(io.hasBrainstemCoeff(posKpCommandElement)))
00182 {
00183 stringstream err;
00184 err << "The BrainstemCoeff " << posKpCommandElement << " does not exist";
00185 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00186 throw runtime_error(err.str());
00187 }
00188
00189 if (not(io.hasBrainstemCoeff(pLKiCommandElement)))
00190 {
00191 stringstream err;
00192 err << "The BrainstemCoeff " << pLKiCommandElement << " does not exist";
00193 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00194 throw runtime_error(err.str());
00195 }
00196
00197 if (not(io.hasBrainstemCoeff(posKdCommandElement)))
00198 {
00199 stringstream err;
00200 err << "The BrainstemCoeff " << posKdCommandElement << " does not exist";
00201 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00202 throw runtime_error(err.str());
00203 }
00204
00205 if (not(io.hasBrainstemCoeff(pLWindupLimCommandElement)))
00206 {
00207 stringstream err;
00208 err << "The BrainstemCoeff " << pLWindupLimCommandElement << " does not exist";
00209 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00210 throw runtime_error(err.str());
00211 }
00212
00213 if (not(io.hasBrainstemCoeff(pLKiMinCommandElement)))
00214 {
00215 stringstream err;
00216 err << "The BrainstemCoeff " << pLKiMinCommandElement << " does not exist";
00217 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00218 throw runtime_error(err.str());
00219 }
00220
00221 io.setFloat(velLimitCommandElement, io.getBrainstemCoeff(velLimitCommandElement));
00222 io.setFloat(curLimitCommandElement, io.getBrainstemCoeff(curLimitCommandElement));
00223 io.setFloat(posKpCommandElement, io.getBrainstemCoeff(posKpCommandElement));
00224 io.setFloat(pLKiCommandElement, io.getBrainstemCoeff(pLKiCommandElement));
00225 io.setFloat(posKdCommandElement, io.getBrainstemCoeff(posKdCommandElement));
00226 io.setFloat(pLWindupLimCommandElement, io.getBrainstemCoeff(pLWindupLimCommandElement));
00227 io.setFloat(pLKiMinCommandElement, io.getBrainstemCoeff(pLKiMinCommandElement));
00228 }
00229 else
00230 {
00231 stringstream err;
00232 err << "The file " << parameterFile << " has no element named [ApiMap]";
00233 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00234 throw runtime_error(err.str());
00235 }
00236 }
00237
00238 void JointCommandGripper::updateMeasuredState(r2_msgs::JointControlData msg)
00239 {
00240
00241 if (msg.coeffState.state == r2_msgs::JointControlCoeffState::LOADED)
00242 {
00244 positionVals[0] = io.getFloat(jointPositionStatusElement);
00245 velocityVals[0] = io.getFloat(jointVelocityStatusElement);
00246 effortVals[0] = 0;
00247
00249 positionVals[1] = io.getFloat(jawLeftPositionStatusElement);
00250 velocityVals[1] = 0;
00251 effortVals[1] = io.getFloat(jawLeftTorqueStatusElement);
00252
00254 positionVals[2] = io.getFloat(jawRightPositionStatusElement);
00255 velocityVals[2] = 0;
00256 effortVals[2] = io.getFloat(jawRightTorqueStatusElement);
00257 }
00258 else
00259 {
00260 positionVals.assign(completeMessageSize, 0.0);
00261 velocityVals.assign(completeMessageSize, 0.0);
00262 effortVals.assign(completeMessageSize, 0.0);
00263 }
00264 }
00265
00266 sensor_msgs::JointState JointCommandGripper::getSimpleMeasuredState()
00267 {
00268 simpleMeasuredStateMsg.header.stamp = ros::Time::now();
00269
00270 simpleMeasuredStateMsg.position = positionVals;
00271 simpleMeasuredStateMsg.velocity = velocityVals;
00272 simpleMeasuredStateMsg.effort = effortVals;
00273
00274 return simpleMeasuredStateMsg;
00275 }
00276
00277 sensor_msgs::JointState JointCommandGripper::getCompleteMeasuredState()
00278 {
00279 completeMeasuredStateMsg.header.stamp = ros::Time::now();
00280
00281 completeMeasuredStateMsg.position = positionVals;
00282 completeMeasuredStateMsg.velocity = velocityVals;
00283 completeMeasuredStateMsg.effort = effortVals;
00284
00285 return completeMeasuredStateMsg;
00286 }
00287
00288 void JointCommandGripper::setFaultState()
00289 {
00290 }
00291
00292 r2_msgs::JointCommand JointCommandGripper::getCommandedState()
00293 {
00294
00295
00296 return commandedStateMsg;
00297 }
00298
00299 void JointCommandGripper::setCommand(r2_msgs::JointCommand msg, r2_msgs::JointControlData)
00300 {
00301 if (msg.name.size() != 1)
00302 {
00303 stringstream err;
00304 err << "setCommand() requires one and only one entry in JointCommand.name when setCommand() is called.";
00305 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00306 throw runtime_error(err.str());
00307 }
00308
00309 if ((msg.desiredPosition.size() > 1) ||
00310 (msg.desiredPositionVelocityLimit.size() > 1) ||
00311 (msg.feedForwardTorque.size() > 1) ||
00312 (msg.proportionalGain.size() > 1) ||
00313 (msg.derivativeGain.size() > 1) ||
00314 (msg.integralGain.size() > 1) ||
00315 (msg.positionLoopTorqueLimit.size() > 1) ||
00316 (msg.positionLoopWindupLimit.size() > 1) ||
00317 (msg.torqueLoopVelocityLimit.size() > 1))
00318 {
00319 stringstream err;
00320 err << "setCommand() requires at most one entry in JointCommand.* when setCommand() is called.";
00321 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00322 throw runtime_error(err.str());
00323 }
00324
00325 if (msg.name[0] != roboDynJoints[0])
00326 {
00327 stringstream err;
00328 err << "setCommand() received JointCommand message for joint [" << msg.name[0] << "]. It expected [" << roboDynJoints[0] << "].";
00329 NasaCommonLogging::Logger::log("gov.nasa.robonet.JointCommandGripper", Priority::ERROR, err.str());
00330 throw runtime_error(err.str());
00331 }
00332
00333 if (not msg.desiredPosition.empty())
00334 {
00335 io.setFloat(desiredPositionCommandElement, msg.desiredPosition[0]);
00336 }
00337
00338 if (not msg.desiredPositionVelocityLimit.empty())
00339 {
00340 io.setFloat(desiredPositionVelocityLimitCommandElement, msg.desiredPositionVelocityLimit[0]);
00341 }
00342
00343 if (not msg.feedForwardTorque.empty())
00344 {
00345 io.setFloat(feedForwardTorqueCommandElement, msg.feedForwardTorque[0]);
00346 }
00347
00348 if (not msg.proportionalGain.empty())
00349 {
00350 io.setFloat(proportionalGainCommandElement, msg.proportionalGain[0]);
00351 }
00352
00353 if (not msg.derivativeGain.empty())
00354 {
00355 io.setFloat(derivativeGainCommandElement, msg.derivativeGain[0]);
00356 }
00357
00358 if (not msg.integralGain.empty())
00359 {
00360 io.setFloat(integralGainCommandElement, msg.integralGain[0]);
00361 }
00362
00363 if (not msg.positionLoopTorqueLimit.empty())
00364 {
00365 io.setFloat(positionLoopTorqueLimitCommandElement, msg.positionLoopTorqueLimit[0]);
00366 }
00367
00368 if (not msg.positionLoopWindupLimit.empty())
00369 {
00370 io.setFloat(positionLoopWindupLimitCommandElement, msg.positionLoopWindupLimit[0]);
00371 }
00372 }
00373
00374 r2_msgs::JointCapability JointCommandGripper::getCapability()
00375 {
00376 return jointCapabilityMsg;
00377 }