RosMsgGainCalculator.cpp
Go to the documentation of this file.
00001 #include "robodyn_controllers/RosMsgGainCalculator.h"
00002 
00003 RosMsgGainCalculator::RosMsgGainCalculator() : initialized(false)
00004 {
00005 }
00006 
00007 RosMsgGainCalculator::~RosMsgGainCalculator()
00008 {
00009 }
00010 
00011 void RosMsgGainCalculator::initialize()
00012 {
00013     std::string jntName;
00014 
00015     // Grab tree segment map and iterator
00016     KDL::SegmentMap segments = tree.getSegments();
00017     KDL::SegmentMap::const_iterator it = segments.begin();
00018 
00019     // Iterate through map
00020     while (it != segments.end())
00021     {
00022         // Find joints, and add to map
00023         if (it->second.segment.getJoint().getType() != KDL::Joint::None)
00024         {
00025             jntName = it->second.segment.getJoint().getName();
00026             jointGainsData[jntName] = JointGainsData();
00027         }
00028 
00029         // Next element, please
00030         ++it;
00031     }
00032 
00033     initialized = true;
00034 }
00035 
00036 void RosMsgGainCalculator::storeGainInformation(const r2_msgs::Gains& desiredDyn)
00037 {
00038     if (desiredDyn.joint_names.size() != desiredDyn.naturalFreq.size() || desiredDyn.joint_names.size() != desiredDyn.dampingRatio.size())
00039     {
00040         throw std::runtime_error("StoreGainInformation input desired dynamics invalid");
00041         return;
00042     }
00043 
00044     // Store gain info in maps
00045     for (unsigned int i = 0; i < desiredDyn.joint_names.size(); i++)
00046     {
00047         jointGainsIt = jointGainsData.find(desiredDyn.joint_names[i]);
00048 
00049         if (jointGainsIt != jointGainsData.end())
00050         {
00051             if (desiredDyn.naturalFreq[i] < 0 || desiredDyn.dampingRatio[i] <= 0 || desiredDyn.windupLimit[i] < 0)
00052             {
00053                 throw std::runtime_error("StoreGainInformation input desired dynamics invalid");
00054                 return;
00055             }
00056 
00057             if (desiredDyn.naturalFreq[i]  > jointGainsIt->second.maxWn)
00058             {
00059                 jointGainsIt->second.naturalFreq  = jointGainsIt->second.maxWn;
00060             }
00061             else
00062             {
00063                 jointGainsIt->second.naturalFreq  = desiredDyn.naturalFreq[i];
00064             }
00065 
00066             if (desiredDyn.dampingRatio[i]  > jointGainsIt->second.maxZeta)
00067             {
00068                 jointGainsIt->second.dampingRatio  = jointGainsIt->second.maxZeta;
00069             }
00070             else
00071             {
00072                 jointGainsIt->second.dampingRatio  = desiredDyn.dampingRatio[i];
00073             }
00074 
00075             jointGainsIt->second.windupLim    = desiredDyn.windupLimit[i];
00076         }
00077     }
00078 }
00079 
00080 void RosMsgGainCalculator::setDefaultGains(const double& wn, const double& zeta, const double& windup)
00081 {
00082     // Store gain info in maps
00083     for (jointGainsIt = jointGainsData.begin(); jointGainsIt != jointGainsData.end(); ++jointGainsIt)
00084     {
00085         jointGainsIt->second.naturalFreq  = wn;
00086 
00087         if (jointGainsIt->second.naturalFreq  > jointGainsIt->second.maxWn)
00088         {
00089             jointGainsIt->second.naturalFreq  = jointGainsIt->second.maxWn;
00090         }
00091 
00092         jointGainsIt->second.dampingRatio = zeta;
00093 
00094         if (jointGainsIt->second.dampingRatio  > jointGainsIt->second.maxZeta)
00095         {
00096             jointGainsIt->second.dampingRatio  = jointGainsIt->second.maxZeta;
00097         }
00098 
00099         jointGainsIt->second.windupLim    = windup;
00100     }
00101 }
00102 
00103 void RosMsgGainCalculator::storeGainProperties()
00104 {
00105     double temp;
00106 
00107     for (jointGainsIt = jointGainsData.begin(); jointGainsIt != jointGainsData.end(); ++jointGainsIt)
00108     {
00110         if (!(getCommandFile(jointGainsIt->first).empty()) && JointCommandFactory::Private::getJointTypeFromParameterFile(getCommandFile(jointGainsIt->first)) == "SeriesElastic")
00111         {
00112             if ((temp = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "MaxStiffness"))) >= 0)
00113             {
00114                 jointGainsIt->second.maxK = temp;
00115             }
00116             else
00117             {
00118                 throw std::runtime_error("Negative max stiffness found!");
00119             }
00120 
00121             if ((temp = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "MaxDamping"))) >= 0)
00122             {
00123                 jointGainsIt->second.maxD = temp;
00124             }
00125             else
00126             {
00127                 throw std::runtime_error("Negative max damping found!");
00128             }
00129 
00130             if ((temp = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "MinDamping"))) >= 0)
00131             {
00132                 jointGainsIt->second.minD = temp;
00133             }
00134             else
00135             {
00136                 throw std::runtime_error("Negative min damping found!");
00137             }
00138 
00139             if ((temp = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "MaxNaturalFreq"))) >= 0)
00140             {
00141                 jointGainsIt->second.maxWn = temp;
00142             }
00143             else
00144             {
00145                 throw std::runtime_error("Negative max natural frequency found!");
00146             }
00147 
00148             if ((temp = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "MaxDampingRatio"))) >= 0)
00149             {
00150                 jointGainsIt->second.maxZeta = temp;
00151             }
00152             else
00153             {
00154                 throw std::runtime_error("Negative max damping ratio found!");
00155             }
00156 
00157             jointGainsIt->second.scaleI = getBrainstemCoeff(StringUtilities::makeFullyQualifiedRoboDynElement( jointGainsIt->first, "IntegralScalar"));
00158         }
00159         else
00160         {
00161             jointGainsIt->second.maxK    = 0.0;
00162             jointGainsIt->second.maxD    = 0.0;
00163             jointGainsIt->second.minD    = 0.0;
00164             jointGainsIt->second.maxWn   = 0.0;
00165             jointGainsIt->second.maxZeta = 0.0;
00166             jointGainsIt->second.scaleI  = 0.0;
00167 
00168         }
00169     }
00170 }
00171 
00172 void RosMsgGainCalculator::findDesiredDynamics(const sensor_msgs::JointState& inertia,
00173         r2_msgs::Gains& desiredGains)
00174 {
00175     // Return if des dyn maps not yet initialized
00176     if (!initialized)
00177     {
00178         throw std::runtime_error("findDesiredDynamics input not initialized");
00179         return;
00180     }
00181 
00182     // Return if inertia is not well formed
00183     if (inertia.name.size() != inertia.position.size())
00184     {
00185         throw std::runtime_error("findDesiredDynamics inertia message malformed");
00186         return;
00187     }
00188 
00189     // init message
00190     desiredGains.joint_names.resize(inertia.name.size());
00191     desiredGains.naturalFreq.resize(inertia.name.size());
00192     desiredGains.dampingRatio.resize(inertia.name.size());
00193     desiredGains.K.resize(inertia.name.size());
00194     desiredGains.D.resize(inertia.name.size());
00195     desiredGains.I.resize(inertia.name.size());
00196     desiredGains.windupLimit.resize(inertia.name.size());
00197 
00198     double temp;
00199 
00200     for (unsigned int i = 0; i < inertia.name.size(); ++i)
00201     {
00202         jointGainsIt = jointGainsData.find(inertia.name[i]);
00203 
00204         if (jointGainsIt == jointGainsData.end())
00205         {
00206             throw std::runtime_error("findDesiredDynamics inertia message includes unknown joints");
00207             return;
00208         }
00209 
00210         if (inertia.position[i] < 0)
00211         {
00212             throw std::runtime_error("findDesiredDynamics negative inertia value found");
00213             return;
00214         }
00215 
00216         jointGainsIt->second.mass = inertia.position[i];
00217         temp                      = jointGainsIt->second.stiffness;
00218         GainCalculator::CalculateGains(jointGainsIt->second);
00219 
00220         // Check yank limits
00221         temp = yl.getLimitedValue(jointGainsIt->second.stiffness, temp);
00222 
00223         if (temp != jointGainsIt->second.stiffness)
00224         {
00225             jointGainsIt->second.stiffness = temp;
00226             GainCalculator::CalculateDamping(jointGainsIt->second);
00227         }
00228 
00229         jointGainsIt->second.prevWindup = ylWindup.getLimitedValue(jointGainsIt->second.windupLim, jointGainsIt->second.prevWindup);
00230 
00231         // put in message
00232         desiredGains.joint_names[i]  = inertia.name[i];
00233         desiredGains.naturalFreq[i]  = jointGainsIt->second.naturalFreq;
00234         desiredGains.dampingRatio[i] = jointGainsIt->second.dampingRatio;
00235         desiredGains.K[i]            = jointGainsIt->second.stiffness;
00236         desiredGains.D[i]            = jointGainsIt->second.damping;
00237         desiredGains.I[i]            = jointGainsIt->second.scaleI * jointGainsIt->second.stiffness;
00238         desiredGains.windupLimit[i]  = jointGainsIt->second.prevWindup;
00239 
00240 
00241     }
00242 
00243     return;
00244 }
00245 
00246 bool RosMsgGainCalculator::getCompletionMessage(r2_msgs::StringArray& completionMsg)
00247 {
00248 
00249     if (yl.getCompletionCondition() == 1)
00250     {
00251         completionMsg.header.stamp = ros::Time::now();
00252         completionMsg.data.clear();
00253         completionMsg.data.push_back("gains");
00254 
00255         return true;
00256     }
00257 
00258     return false;
00259 }
00260 


robodyn_controllers
Author(s):
autogenerated on Sat Jun 8 2019 20:20:53