TubeTareMechanism.h
Go to the documentation of this file.
00001 #ifndef TUBE_TARE_UTILITIES_H
00002 #define TUBE_TARE_UTILITIES_H
00003 
00004 #include <boost/array.hpp>
00005 #include "robodyn_mechanisms/TubeTareInterface.h"
00006 #include "robot_instance/StringUtilities.h"
00007 #include "robodyn_mechanisms/FingerController.h"
00008 
00009 template<unsigned int N>
00010 class TubeTareMechanism : public TubeTareInterface
00011 {
00012 public:
00013     TubeTareMechanism(const std::string& mechanism, TubeTareInterface::IoFunctions ioFunctions, float freq);
00014     virtual ~TubeTareMechanism();
00015 
00016     virtual void setStop(const std::vector<std::string>& actuators = std::vector<std::string>()); //the motcom command for stop (0)
00017     virtual bool isMoving(); //checks if the velocity is 0
00018     virtual void setRelease(const std::vector<std::string>& actuators = std::vector<std::string>()); //the motcom command for release (limited)
00019     virtual void getEncoderTarePos(); //perform the tare (TareEncoderAbsolute)
00020     virtual void setTighten(const std::vector<std::string>& actuators = std::vector<std::string>()); //set motcom to tighten position (limited)
00021     virtual int  goodPosition(); //checks if near end of travel
00022     virtual void getSliderTarePos();//SliderVectorType &encoderOffsets, SliderVectorType &sliderOffsets);
00023     virtual void getTensionTareValue();
00024     virtual void resetTensionCounter();
00025 
00026     FingerController<N> finger;
00027     typedef typename FingerController<N>::SliderVectorType      SliderVectorType;
00028     typedef typename FingerController<N>::ReferenceMatrixType   ReferenceMatrixType;
00029     typedef typename FingerController<N>::JointVectorType       hallVec;
00030 
00031 private:
00032     //    FingerController<N> finger;
00033     //    typedef typename FingerController<N>::SliderVectorType      SliderVectorType;
00034     //    typedef typename FingerController<N>::ReferenceMatrixType   ReferenceMatrixType;
00035     //    typedef typename FingerController<N>::JointVectorType       hallVec;
00036 
00037 
00038     boost::array<std::string, N>            hallStateElements;
00039     boost::array < std::string, N + 1 >          encoderStateElements;
00040     boost::array < std::string, N + 1 >          tensionAStateElements;
00041     boost::array < std::string, N + 1 >          tensionBStateElements;
00042     boost::array < std::string, N + 1 >          motComCommandElements;
00043 
00044     float encoderVelZeroThreshold, encoderMinTravel, encoderMaxTravel;
00045 
00046     SliderVectorType motComReleaseVal, motComTightenVal;
00047     SliderVectorType tensionGainA, tensionGainB, tensionSensorCalOffset, tension_out;
00048 
00049     boost::array < std::string, N + 1 >          encoderOffsetElements;
00050     boost::array < std::string, N + 1 >          sliderOffsetElements;
00051     boost::array < std::string, N + 1 >          sliderTarePosElements;
00052     boost::array < std::string, N + 1 >          tensionOffsetElements;
00053 
00054     // filter values
00055     typename FingerController<N>::SliderVectorType encoderVec;
00056     typename FingerController<N>::SliderVectorType filteredEncoderVec;
00057     typename FingerController<N>::SliderVectorType encoderVels;
00058     typename FingerController<N>::SliderVectorType prevEncoderVec;
00059     double timestep;
00060     double positionAlpha;
00061     bool filterInitialized;
00062 
00063     unsigned int tensionCounter;
00064 
00065     void setParameters();
00066 
00067 };
00068 
00069 template <unsigned int N>
00070 TubeTareMechanism<N>::TubeTareMechanism(const std::string& mechanism, TubeTareInterface::IoFunctions ioFunctions, float freq)
00071     : TubeTareInterface(mechanism, ioFunctions), filterInitialized(false)
00072 {
00073     if (mechanism == "")
00074     {
00075         std::stringstream err;
00076         err << "Constructor requires mechanism be non-empty.";
00077         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::FATAL, err.str());
00078         throw std::invalid_argument(err.str());
00079     }
00080 
00081     if (freq <= 0.)
00082     {
00083         std::stringstream err;
00084         err << "frequency must be positive";
00085         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::FATAL, err.str());
00086         throw std::invalid_argument(err.str());
00087     }
00088 
00089     if (io.getUInt16.empty() or
00090             io.getInt16.empty() or
00091             io.setInt16.empty() or
00092             io.getMotorCoeff.empty() or
00093             io.hasLiveCoeff.empty() or
00094             io.getLiveCoeff.empty() or
00095             io.setLiveCoeff.empty() or
00096             io.getJointNames.empty() or
00097             io.getActuatorNames.empty() or
00098             io.getCommandFile.empty())
00099     {
00100         std::stringstream err;
00101         err << "Constructor requires 'io.getUInt16', 'io.setUInt16', 'io.getMotorCoeff', 'io.hasLiveCoeff', 'io.getLiveCoeff', 'io.setLiveCoeff', io.getJointNames', 'io.getActuatorNames', and 'io.getCommandFile' be non-empty.";
00102         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::FATAL, err.str());
00103         throw std::invalid_argument(err.str());
00104     }
00105 
00106     roboDynJoints    = io.getJointNames(mechanism);
00107     roboDynActuators = io.getActuatorNames(mechanism);
00108 
00109     if (roboDynJoints.size() != N or
00110             roboDynActuators.size() != N + 1)
00111     {
00112         std::stringstream err;
00113         err << "Constructor requires roboDynJoints have N and roboDynActuators have N+1 values, with N for this instance being " << N << std::endl;
00114         err << "Number of roboDynJoints: " << roboDynJoints.size() << std::endl;
00115         err << "Number of roboDynActuators: " << roboDynActuators.size() << std::endl;
00116         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::FATAL, err.str());
00117         throw std::invalid_argument(err.str());
00118 
00119     }
00120 
00121     timestep = 1 / freq;
00122     this->setParameters();
00123 }
00124 
00125 template <unsigned int N>
00126 TubeTareMechanism<N>::~TubeTareMechanism()
00127 {}
00128 
00129 template <unsigned int N>
00130 void TubeTareMechanism<N>::setParameters()
00131 {
00132     std::string parameterFile = io.getCommandFile(mechanism);
00133 
00135     TiXmlDocument file(parameterFile.c_str());
00136     bool loadOkay = file.LoadFile();
00137 
00138     if (!loadOkay)
00139     {
00140         std::stringstream err;
00141         err << "Failed to load file [" << parameterFile << "]";
00142         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::FATAL, err.str());
00143         throw std::runtime_error(err.str());
00144     }
00145 
00146     TiXmlHandle doc(&file);
00147     NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::INFO, "CommandFile [" + parameterFile + "] successfully loaded.");
00148 
00149     // Check for ApiMap
00150     TiXmlHandle parametersElement(doc.FirstChildElement("ApiMap"));
00151 
00152     if (parametersElement.ToElement())
00153     {
00155         std::stringstream str;
00156 
00157         for (unsigned int i = 0; i < N + 1; ++i)
00158         {
00159             str.str("");
00160             str << "Actuator" << i << "EncoderState";
00161             encoderStateElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], ApiMap::getXmlElementValue(parametersElement, str.str()));
00162             str.str("");
00163             str << "Actuator" << i << "TensionAState";
00164             tensionAStateElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], ApiMap::getXmlElementValue(parametersElement, str.str()));
00165             str.str("");
00166             str << "Actuator" << i << "TensionBState";
00167             tensionBStateElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], ApiMap::getXmlElementValue(parametersElement, str.str()));
00168             str.str("");
00169             str << "Actuator" << i << "MotComCommand";
00170             motComCommandElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], ApiMap::getXmlElementValue(parametersElement, str.str()));
00171         }
00172 
00173         for (unsigned int i = 0; i < N; ++i)
00174         {
00175             str.str("");
00176             str << "Joint" << i << "HallState";
00177             hallStateElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynJoints[i], ApiMap::getXmlElementValue(parametersElement, str.str()));
00178         }
00179 
00181 
00182         encoderVelZeroThreshold =   io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism, ApiMap::getXmlElementValue(parametersElement, "EncoderVelZeroThreshold")));
00183         encoderMinTravel =          io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism, ApiMap::getXmlElementValue(parametersElement, "EncoderMinTravel")));
00184         encoderMaxTravel =          io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism, ApiMap::getXmlElementValue(parametersElement, "EncoderMaxTravel")));
00185 
00186         //motcom coeffs
00187         for (unsigned int i = 0; i < motComReleaseVal.rows(); ++i)
00188         {
00189             str.str("");
00190             str << "Actuator" << i << "MotComReleaseVal";
00191             motComReleaseVal[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00192             str.str("");
00193             str << "Actuator" << i << "MotComTightenVal";
00194             motComTightenVal[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00195             str.str("");
00196         }
00197 
00198         double hallScale;
00199         typename FingerController<N>::JointVectorType hallCoeffs0, hallCoeffs1, hallCoeffs2, hallCoeffs3;
00200         hallScale = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, "HallScaleFactor")));
00201 
00202         for (unsigned int i = 0; i < hallCoeffs0.rows(); ++i)
00203         {
00204             str.str("");
00205             str << "Joint" << i << "HallCoeff0";
00206             hallCoeffs0[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00207             str.str("");
00208             str << "Joint" << i << "HallCoeff1";
00209             hallCoeffs1[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00210             str.str("");
00211             str << "Joint" << i << "HallCoeff2";
00212             hallCoeffs2[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00213             str.str("");
00214             str << "Joint" << i << "HallCoeff3";
00215             hallCoeffs3[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00216         }
00217 
00218         finger.setHallAngleParameters(hallScale, hallCoeffs0, hallCoeffs1, hallCoeffs2, hallCoeffs3);
00219 
00220         // tension sensor coeffs
00221         for ( unsigned int i = 0; i < N + 1; i++)
00222         {
00223             str.str("");
00224             str << "Actuator" << i << "TensionAGain";
00225             tensionGainA[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00226             str.str("");
00227             str << "Actuator" << i << "TensionBGain";
00228             tensionGainB[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00229             str.str("");
00230             str << "Actuator" << i << "TensionSensorCalOffset";
00231             tensionSensorCalOffset[i] = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00232             tension_out[i] = 0;
00233         }
00234 
00235 
00236         //Output elements
00237         for (unsigned int i = 0; i < N + 1; ++i)
00238         {
00239             encoderOffsetElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "EncoderOffset");
00240             sliderOffsetElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "SliderOffset");
00241             sliderTarePosElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "SliderTarePosition");
00242             tensionOffsetElements[i] = StringUtilities::makeFullyQualifiedRoboDynElement(roboDynActuators[i], "TensionOffset");
00243         }
00244 
00245         // filter
00246         positionAlpha = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, "PositionAlpha")));
00247 
00248         // tension counter
00249         tensionCounter = 0;
00250 
00252         typename FingerController<N>::ReferenceMatrixType refMatrix;
00253 
00254         for (unsigned int i = 0; i < refMatrix.rows(); ++i)
00255         {
00256             for (unsigned int j = 0; j < refMatrix.cols(); ++j)
00257             {
00258                 str.str("");
00259                 str << "ReferenceMatrix" << i << j;
00260                 refMatrix(i, j) = io.getMotorCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( mechanism,  ApiMap::getXmlElementValue(parametersElement, str.str())));
00261             }
00262         }
00263 
00264         finger.setReferenceMatrix(refMatrix);
00265     }
00266     else
00267     {
00268         std::stringstream err;
00269         err << "The file " << parameterFile << " has no element named [ApiMap]";
00270         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::ERROR, err.str());
00271         throw std::runtime_error(err.str());
00272     }
00273 }
00274 
00275 
00276 template <unsigned int N>
00277 void TubeTareMechanism<N>::setStop(const std::vector<std::string>& actuators)
00278 {
00279     //if no actuators sent in, do them all
00280     if (actuators.empty())
00281     {
00282         std::stringstream err;
00283         err << "Stopping all actuators for " << mechanism;
00284         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00285 
00286         for (unsigned int i = 0; i < motComCommandElements.size(); ++i)
00287         {
00288             io.setInt16(motComCommandElements[i], static_cast<int16_t>(0));
00289         }
00290     }
00291     else
00292     {
00293         for (unsigned int i = 0; i < roboDynActuators.size(); ++i)
00294         {
00295             if (std::find(actuators.begin(), actuators.end(), roboDynActuators[i]) != actuators.end() )
00296             {
00297                 std::stringstream err;
00298                 err << "Stopping " << mechanism << " actuator: " << roboDynActuators[i] << " motcomCommandElement: " << motComCommandElements[i];
00299                 NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00300                 io.setInt16(motComCommandElements[i], static_cast<int16_t>(0));
00301             }
00302         }
00303     }
00304 }
00305 
00306 template <unsigned int N>
00307 bool TubeTareMechanism<N>::isMoving()
00308 {
00309     for (unsigned int i = 0; i < encoderStateElements.size(); ++i)
00310     {
00311         encoderVec[i] = io.getInt16(encoderStateElements[i]);
00312     }
00313 
00314     // filter
00315     if (!filterInitialized)
00316     {
00317         filteredEncoderVec = encoderVec;
00318         encoderVels.setZero();
00319         filterInitialized = true;
00320     }
00321     else
00322     {
00323         filteredEncoderVec = filteredEncoderVec * positionAlpha + encoderVec * (1 - positionAlpha);
00324         encoderVels = (filteredEncoderVec - prevEncoderVec) / timestep;
00325     }
00326 
00327     prevEncoderVec = filteredEncoderVec;
00328 
00329     for (unsigned int i = 0; i < encoderVels.size(); ++i)
00330     {
00331         if (-encoderVelZeroThreshold > encoderVels[i] || encoderVels[i] > encoderVelZeroThreshold)
00332         {
00333             return true;
00334         }
00335     }
00336 
00337     return false;
00338 }
00339 
00340 template <unsigned int N>
00341 void TubeTareMechanism<N>::setRelease(const std::vector<std::string>& actuators)
00342 {
00343     if (actuators.empty())
00344     {
00345         std::stringstream err;
00346         err << "Set release for all actuators in " << mechanism;
00347 
00348         for (unsigned int i = 0; i < motComCommandElements.size(); ++i )
00349         {
00350             err << "\n\t" << motComCommandElements[i] << ": " << static_cast<int16_t>(motComReleaseVal[i]);
00351             io.setInt16(motComCommandElements[i], static_cast<int16_t>(motComReleaseVal[i]) );
00352         }
00353 
00354         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00355     }
00356     else
00357     {
00358         for (unsigned int i = 0; i < roboDynActuators.size(); ++i)
00359         {
00360             if (std::find(actuators.begin(), actuators.end(), roboDynActuators[i]) != actuators.end() )
00361             {
00362                 std::stringstream err;
00363                 err << "Set release for " << mechanism << " actuator: " << roboDynActuators[i] << " motcomCommandElement: " << motComCommandElements[i];
00364                 NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00365                 io.setInt16(motComCommandElements[i], static_cast<int16_t>(motComReleaseVal[i]));
00366             }
00367         }
00368     }
00369 
00370     filterInitialized = false;
00371 }
00372 
00373 
00374 template <unsigned int N>
00375 void TubeTareMechanism<N>::getEncoderTarePos()
00376 {
00377     for (unsigned int i = 0; i < encoderOffsetElements.size(); ++i)
00378     {
00379         io.setLiveCoeff(encoderOffsetElements[i], io.getInt16(encoderStateElements[i]));
00380     }
00381 }
00382 
00383 template <unsigned int N>
00384 void TubeTareMechanism<N>::setTighten(const std::vector<std::string>& actuators)
00385 {
00386     if (actuators.empty())
00387     {
00388         std::stringstream err;
00389         err << "Set tighten for all actuators in " << mechanism;
00390 
00391         for (unsigned int i = 0; i < motComCommandElements.size(); ++i )
00392         {
00393             err << "\n\t" << motComCommandElements[i] << ": " << static_cast<int16_t>(motComTightenVal[i]);
00394             io.setInt16(motComCommandElements[i], static_cast<int16_t>(motComTightenVal[i]) );
00395         }
00396 
00397         NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00398     }
00399     else
00400     {
00401         //std::cout<<"Set tighten on list"<<std::endl;
00402         for (unsigned int i = 0; i < roboDynActuators.size(); ++i)
00403         {
00404             //std::cout<<"looking for actuator: "<< roboDynActuators[i]<<std::endl;
00405             if (std::find(actuators.begin(), actuators.end(), roboDynActuators[i]) != actuators.end() )
00406             {
00407                 std::stringstream err;
00408                 err << "Set tighten for " << mechanism << " actuator: " << roboDynActuators[i] << " motcomCommandElement: " << motComCommandElements[i];
00409                 NasaCommonLogging::Logger::log("gov.nasa.robonet.TubeTareMechanism", log4cpp::Priority::DEBUG, err.str());
00410                 io.setInt16(motComCommandElements[i], static_cast<int16_t>(motComTightenVal[i]));
00411             }
00412 
00413             //            else
00414             //            {
00415             //              std::cout<<"actuator not found"<<std::endl;
00416             //          }
00417         }
00418     }
00419 
00420     filterInitialized = false;
00421 }
00422 
00423 template <unsigned int N>
00424 int TubeTareMechanism<N>::goodPosition()
00425 {
00426 
00427     for (unsigned int i = 0; i < encoderStateElements.size(); ++i)
00428     {
00429         int encoderAbsolute = io.getInt16(encoderStateElements[i]) - io.getLiveCoeff(encoderOffsetElements[i]);
00430 
00431         if (-encoderMinTravel < encoderAbsolute && encoderAbsolute < encoderMinTravel)
00432         {
00433             return -1;
00434         }
00435 
00436         if (encoderAbsolute < -encoderMaxTravel || encoderAbsolute > encoderMaxTravel)
00437         {
00438             return 1;
00439         }
00440     }
00441 
00442     return 0;
00443 
00444 }
00445 
00446 template<unsigned int N>
00447 void TubeTareMechanism<N>::getSliderTarePos()
00448 {
00449     hallVec currentHalls;
00450     SliderVectorType sliderPos;
00451 
00452     for (unsigned int i = 0; i < hallStateElements.size(); ++i)
00453     {
00454         currentHalls[i] = io.getUInt16(hallStateElements[i]);
00455     }
00456 
00457     finger.getHallAngles(currentHalls, currentHalls);
00458     finger.getSlidersFromJoints(currentHalls, sliderPos);
00459 
00460     for (unsigned int i = 0; i < sliderPos.size(); ++i)
00461     {
00462         io.setLiveCoeff(sliderOffsetElements[i], io.getInt16(encoderStateElements[i]));
00463         io.setLiveCoeff(sliderTarePosElements[i], sliderPos[i]);
00464     }
00465 
00466 }
00467 
00468 template<unsigned int N>
00469 void TubeTareMechanism<N>::getTensionTareValue()
00470 {
00471     SliderVectorType tensionA, tensionB;
00472 
00473     tensionCounter++;
00474 
00475     for (unsigned int i = 0; i < tensionAStateElements.size(); i++)
00476     {
00477         tensionA[i] = io.getUInt16(tensionAStateElements[i]);
00478         tensionB[i] = io.getUInt16(tensionBStateElements[i]);
00479     }
00480 
00481     for (unsigned int i = 0; i < tension_out.size(); i++)
00482     {
00483         // find "calibrated" value
00484         double temp = tensionA[i] * tensionGainA[i] + tensionB[i] * tensionGainB[i] + tensionSensorCalOffset[i];
00485 
00486         // take running average
00487         tension_out[i] = ((tensionCounter - 1) * tension_out[i] + temp) / tensionCounter;
00488 
00489         // send it out into the world
00490         io.setLiveCoeff(tensionOffsetElements[i], tension_out[i]);
00491     }
00492 
00493 }
00494 
00495 template<unsigned int N>
00496 void TubeTareMechanism<N>::resetTensionCounter()
00497 {
00498     tensionCounter = 0;
00499 
00500     for (unsigned int i = 0; i < tension_out.size(); i++)
00501     {
00502         tension_out[i] = 0;
00503     }
00504 }
00505 
00506 #endif // TUBE_TARE_UTILITIES_H


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