JointCommandGripper.cpp
Go to the documentation of this file.
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     // just send an empty commanded message to bypass robodyn
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     // Check for ApiMap
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     // If coeffs are not loaded, override with zeros RDEV-1075
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     // just send an empty message to bypass robodyn
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 }


robodyn_mechanisms
Author(s):
autogenerated on Thu Jun 6 2019 21:22:48