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
00016 KDL::SegmentMap segments = tree.getSegments();
00017 KDL::SegmentMap::const_iterator it = segments.begin();
00018
00019
00020 while (it != segments.end())
00021 {
00022
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
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
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
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
00176 if (!initialized)
00177 {
00178 throw std::runtime_error("findDesiredDynamics input not initialized");
00179 return;
00180 }
00181
00182
00183 if (inertia.name.size() != inertia.position.size())
00184 {
00185 throw std::runtime_error("findDesiredDynamics inertia message malformed");
00186 return;
00187 }
00188
00189
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
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
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