00001 #include <robodyn_controllers/MotionLimiter.h>
00002
00003 JointMotionLimitHelper::JointMotionLimitHelper(bool positiveOnly_in)
00004 : positiveOnly(positiveOnly_in)
00005 {
00006 }
00007
00008 JointMotionLimitHelper::JointMotionLimitHelper(const JointMotionLimitHelper& toCopy)
00009 {
00010 positiveOnly = toCopy.getPositiveOnly();
00011 limArray = toCopy.getLimits();
00012 }
00013
00014 JointMotionLimitHelper::~JointMotionLimitHelper()
00015 {
00016 }
00017
00018 void JointMotionLimitHelper::setLimit(double lim)
00019 {
00020 if (positiveOnly && lim < 0.)
00021 {
00022 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointMotionLimitHelper") << log4cpp::Priority::ERROR << "setLimit lim must not be < 0";
00023 throw std::invalid_argument("JointMotionLimitHelper::setLimit lim must not be < 0");
00024 }
00025
00026 for (unsigned int i = 0; i < limArray.size(); ++i)
00027 {
00028 limArray[i] = lim;
00029 }
00030 }
00031
00032 void JointMotionLimitHelper::setLimits(const std::vector<double>& limArray_in)
00033 {
00034 limArray.resize(limArray_in.size());
00035
00036 for (unsigned int i = 0; i < limArray_in.size(); ++i)
00037 {
00038 if (positiveOnly && limArray_in[i] < 0.)
00039 {
00040 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointMotionLimitHelper") << log4cpp::Priority::ERROR << "setLimits lim must not be < 0";
00041 throw std::invalid_argument("JointMotionLimitHelper::setLimits lim must not be < 0");
00042 }
00043
00044 limArray[i] = limArray_in[i];
00045 }
00046 }
00047
00048 double JointMotionLimitHelper::getLimit(unsigned int index) const
00049 {
00050 if (limArray.size() > index)
00051 {
00052 return limArray[index];
00053 }
00054 else
00055 {
00056 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointMotionLimitHelper") << log4cpp::Priority::ERROR << "getLimit index out of range";
00057 throw std::out_of_range("JointMotionLimitHelper::getLimit index out of range");
00058 }
00059 }
00060
00061 JointPositionLimiter::JointPositionLimiter(const JointPositionLimiter& toCopy)
00062 : JointVelocityLimiter()
00063 {
00064 setLimits(toCopy.getMinPositions(), toCopy.getMaxPositions());
00065 }
00066
00067 void JointPositionLimiter::setLimits(const std::vector<double>& minLimits, const std::vector<double>& maxLimits)
00068 {
00069 if (minLimits.size() != maxLimits.size())
00070 {
00071 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointPositionLimiter") << log4cpp::Priority::ERROR << "setPositionLimits min/max length mismatch";
00072 throw std::out_of_range("JointPositionLimiter::setPositionLimits min/max length mismatch");
00073 }
00074
00075 minLimiter.setLimits(minLimits);
00076 maxLimiter.setLimits(maxLimits);
00077 }
00078
00079 JointVelocityLimiter::JointVelocityLimiter(const JointVelocityLimiter& toCopy)
00080 {
00081 setVelocityLimits(toCopy.getVelocityLimits());
00082 }
00083
00084 JointMotionLimiter::JointMotionLimiter(const JointMotionLimiter& toCopy)
00085 : JointVelocityLimiter()
00086 {
00087 setLimits(toCopy.getVelocityLimits(), toCopy.getAccelerationLimits());
00088 }
00089
00090 void JointMotionLimiter::setLimits(const std::vector<double>& velLimits, const std::vector<double>& accLimits)
00091 {
00092 if (velLimits.size() != accLimits.size())
00093 {
00094 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointMotionLimiter") << log4cpp::Priority::ERROR << "setLimits vel/acc length mismatch";
00095 throw std::out_of_range("JointMotionLimiter::setLimits vel/acc length mismatch");
00096 }
00097
00098 setVelocityLimits(velLimits);
00099 accMotionLimiter.setLimits(accLimits);
00100 }
00101
00102 void JointNamePositionLimiter::setLimits(const std::vector<std::string>& jointNames,
00103 const std::vector<double>& minPositionArray_in, const std::vector<double>& maxPositionArray_in, const std::vector<double>& maxVelocityArray_in)
00104 {
00105 if (jointNames.size() != minPositionArray_in.size() || jointNames.size() != maxPositionArray_in.size() || jointNames.size() != maxVelocityArray_in.size())
00106 {
00107
00108 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointNamePositionLimiter") << log4cpp::Priority::DEBUG << "setLimits() - jointNames and limit arrays have different lengths";
00109 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointNamePositionLimiter") << log4cpp::Priority::DEBUG << "minPos: " << minPositionArray_in.size() << ", maxPos: " << maxPositionArray_in.size() << ", maxVel: " << maxVelocityArray_in.size();
00110 }
00111
00112 if (jointNames != joints)
00113 {
00114 jointLimitIndices.clear();
00115
00116 for (unsigned int i = 0; i < jointNames.size(); ++i)
00117 {
00118 jointLimitIndices[jointNames[i]] = i;
00119 }
00120
00121 joints = jointNames;
00122 }
00123
00124 positionLimiter->setLimits(minPositionArray_in, maxPositionArray_in);
00125 positionLimiter->setVelocityLimits(maxVelocityArray_in);
00126
00127 }
00128
00129 void JointNamePositionLimiter::reorderLimits(const std::vector<std::string>& jointNames)
00130 {
00132 if (joints == jointNames)
00133 {
00134 return;
00135 }
00136
00137 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointNamePositionLimiter") << log4cpp::Priority::DEBUG << "reorderLimits- this is happening";
00139 joints.resize(jointLimitIndices.size());
00140 std::vector<double> newMinPositions(jointLimitIndices.size());
00141 std::vector<double> newMaxPositions(jointLimitIndices.size());
00142 std::vector<double> newMaxVelocities(jointLimitIndices.size());
00143 std::map<std::string, unsigned int> oldIndices = jointLimitIndices;
00144 jointLimitIndices.clear();
00145 unsigned int newIndex = 0;
00146
00147 for (unsigned int i = 0; i < jointNames.size(); ++i)
00148 {
00149 std::map<std::string, unsigned int>::iterator it = oldIndices.find(jointNames[i]);
00150
00151 if (it == oldIndices.end())
00152 {
00153
00154 std::stringstream err;
00155 err << "reorderLimits() - no limit available for " << jointNames[i];
00156 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointNamePositionLimiter") << log4cpp::Priority::ERROR << err.str();
00157 throw std::invalid_argument(err.str());
00158 }
00159 else
00160 {
00161 joints[newIndex] = jointNames[i];
00162 jointLimitIndices[jointNames[i]] = newIndex;
00163 newMinPositions[newIndex] = positionLimiter->getMinPosition(it->second);
00164 newMaxPositions[newIndex] = positionLimiter->getMaxPosition(it->second);
00165 newMaxVelocities[newIndex] = positionLimiter->getVelocityLimit(it->second);
00166 oldIndices.erase(it);
00167 ++newIndex;
00168 }
00169 }
00170
00172 for (std::map<std::string, unsigned int>::iterator it = oldIndices.begin(); it != oldIndices.end(); ++it)
00173 {
00174 joints[newIndex] = it->first;
00175 jointLimitIndices[it->first] = newIndex;
00176 newMinPositions[newIndex] = positionLimiter->getMinPosition(it->second);
00177 newMaxPositions[newIndex] = positionLimiter->getMaxPosition(it->second);
00178 newMaxVelocities[newIndex] = positionLimiter->getVelocityLimit(it->second);
00179 ++newIndex;
00180 }
00181
00182 positionLimiter->setLimits(newMinPositions, newMaxPositions);
00183 positionLimiter->setVelocityLimits(newMaxVelocities);
00184 }
00185
00186 double JointNamePositionLimiter::getMinPosition(const std::string& jointName) const
00187 {
00188 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00189
00190 if (mapIt != jointLimitIndices.end())
00191 {
00192 return positionLimiter->getMinPosition(mapIt->second);
00193 }
00194 else
00195 {
00196 throw std::runtime_error((std::string("JointNamePositionLimiter::getMinPosition: no limit available for ") + jointName).c_str());
00197 return 0.;
00198 }
00199 }
00200
00201 double JointNamePositionLimiter::getMaxPosition(const std::string& jointName) const
00202 {
00203 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00204
00205 if (mapIt != jointLimitIndices.end())
00206 {
00207 return positionLimiter->getMaxPosition(mapIt->second);
00208 }
00209 else
00210 {
00211 throw std::runtime_error((std::string("JointNamePositionLimiter::getMaxPosition: no limit available for ") + jointName).c_str());
00212 return 0.;
00213 }
00214 }
00215
00216 bool JointNamePositionLimiter::getMaxVelocity(const std::string& jointName, double& lim) const
00217 {
00218 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00219
00220 if (mapIt != jointLimitIndices.end())
00221 {
00222 lim = positionLimiter->getVelocityLimit(mapIt->second);
00223 return true;
00224 }
00225 else
00226 {
00227 return false;
00228 }
00229 }
00230
00231 bool JointNamePositionLimiter::getLimits(const std::string& jointName, std::pair<double, double>& limits) const
00232 {
00233 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00234
00235 if (mapIt != jointLimitIndices.end())
00236 {
00237 limits.first = positionLimiter->getMinPosition(mapIt->second);
00238 limits.second = positionLimiter->getMaxPosition(mapIt->second);
00239 return true;
00240 }
00241 else
00242 {
00243 return false;
00244 }
00245 }
00246
00247 bool JointNamePositionLimiter::limit(const std::string& jointName, double& value) const
00248 {
00249 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00250
00251 if (mapIt != jointLimitIndices.end())
00252 {
00253 if (value < positionLimiter->getMinPosition(mapIt->second))
00254 {
00255 value = positionLimiter->getMinPosition(mapIt->second);
00256 return true;
00257 }
00258
00259 if (value > positionLimiter->getMaxPosition(mapIt->second))
00260 {
00261 value = positionLimiter->getMaxPosition(mapIt->second);
00262 return true;
00263 }
00264 }
00265 else
00266 {
00267 throw std::runtime_error((std::string("JointNamePositionLimiter::limit: no limits available for ") + jointName).c_str());
00268 return false;
00269 }
00270
00271 return false;
00272 }
00273
00274 bool JointNamePositionLimiter::limitVelocity(const std::string& jointName, double& value) const
00275 {
00276 std::map<std::string, unsigned int>::const_iterator mapIt = jointLimitIndices.find(jointName);
00277
00278 if (mapIt != jointLimitIndices.end())
00279 {
00280 double limitValue = positionLimiter->getVelocityLimit(mapIt->second);
00281
00282 if (value < -limitValue)
00283 {
00284 value = -limitValue;
00285 return true;
00286 }
00287
00288 if (value > limitValue)
00289 {
00290 value = limitValue;
00291 return true;
00292 }
00293 }
00294 else
00295 {
00296 throw std::runtime_error((std::string("JointNamePositionLimiter::limitVelocity: no limits available for ") + jointName).c_str());
00297 return false;
00298 }
00299
00300 return false;
00301 }
00302
00303 void JointNameMotionLimiter::setLimits(const std::vector<std::string>& jointNames,
00304 const std::vector<double>& velLimitArrayIn, const std::vector<double>& accLimitArrayIn)
00305 {
00306 if (jointNames.size() != velLimitArrayIn.size() || jointNames.size() != accLimitArrayIn.size())
00307 {
00308
00309 std::stringstream err;
00310 err << "JointNameMotionLimiter::setLimits() - jointNames and limit arrays have different lengths";
00311 NasaCommonLogging::Logger::log("gov.nasa.controllers.JointNameMotionLimiter", log4cpp::Priority::DEBUG, err.str());
00312 throw std::invalid_argument(err.str());
00313 }
00314
00316 for (unsigned int i = 0; i < jointNames.size(); ++i)
00317 {
00318 jointNameLimitMap[jointNames[i]] = std::make_pair(velLimitArrayIn[i], accLimitArrayIn[i]);
00319 }
00320
00322 joints.resize(jointNameLimitMap.size());
00323 jointLimitIndices.clear();
00324 velLimits.resize(jointNameLimitMap.size());
00325 accLimits.resize(jointNameLimitMap.size());
00326 unsigned int i = 0;
00327
00328 for (std::map<std::string, std::pair<double, double> >::iterator it = jointNameLimitMap.begin(); it != jointNameLimitMap.end(); ++it)
00329 {
00330 jointLimitIndices[it->first] = i;
00331 joints[i] = it->first;
00332 velLimits[i] = it->second.first;
00333 accLimits[i] = it->second.second;
00334 ++i;
00335 }
00336
00337 motionLimiter->setLimits(velLimits, accLimits);
00338 }
00339
00340 void JointNameMotionLimiter::setLimits(const std::vector<std::string>& jointNames, double velLim, double accLim)
00341 {
00342 std::vector<double> velLims(jointNames.size(), velLim);
00343 std::vector<double> accLims(jointNames.size(), accLim);
00344 setLimits(jointNames, velLims, accLims);
00345 }
00346
00347 void JointNameMotionLimiter::reorderLimits(const std::vector<std::string>& jointNames)
00348 {
00350 if (joints == jointNames)
00351 {
00352 return;
00353 }
00354
00356 joints = jointNames;
00357 velLimits.resize(jointNames.size());
00358 accLimits.resize(jointNames.size());
00359
00360 for (unsigned int i = 0; i < jointNames.size(); ++i)
00361 {
00362 std::map<std::string, std::pair<double, double> >::const_iterator mapIt = jointNameLimitMap.find(jointNames[i]);
00363
00364 if (mapIt != jointNameLimitMap.end())
00365 {
00366 velLimits[i] = mapIt->second.first;
00367 accLimits[i] = mapIt->second.second;
00368 }
00369 else
00370 {
00372 std::stringstream err;
00373 err << "reorderLimits() - no limit available for " << jointNames[i];
00374 NasaCommonLogging::Logger::getCategory("gov.nasa.controllers.JointNameMotionLimiter") << log4cpp::Priority::ERROR << err.str();
00375 throw std::invalid_argument(err.str());
00376 }
00377 }
00378
00379 motionLimiter->setLimits(velLimits, accLimits);
00380 }
00381
00382 double JointNameMotionLimiter::getVelocityLimit(const std::string& jointName) const
00383 {
00384 std::map<std::string, std::pair<double, double> >::const_iterator mapIt = jointNameLimitMap.find(jointName);
00385
00386 if (mapIt != jointNameLimitMap.end())
00387 {
00388 return mapIt->second.first;
00389 }
00390 else
00391 {
00392 throw std::runtime_error((std::string("JointNameMotionLimiter::getVelocityLimit: no limit available for ") + jointName).c_str());
00393 return 0.;
00394 }
00395 }
00396
00397 double JointNameMotionLimiter::getAccelerationLimit(const std::string& jointName) const
00398 {
00399 std::map<std::string, std::pair<double, double> >::const_iterator mapIt = jointNameLimitMap.find(jointName);
00400
00401 if (mapIt != jointNameLimitMap.end())
00402 {
00403 return mapIt->second.second;
00404 }
00405 else
00406 {
00407 throw std::runtime_error((std::string("JointNameMotionLimiter::getAccelerationLimit: no limit available for ") + jointName).c_str());
00408 return 0.;
00409 }
00410 }
00411
00412 void JointNameMotionLimiter::getAllLimits(std::vector<std::string>& jointNames_out, std::vector<double>& velLimits_out, std::vector<double>& accLimits_out)
00413 {
00414 jointNames_out.resize(jointNameLimitMap.size());
00415 velLimits_out.resize(jointNameLimitMap.size());
00416 accLimits_out.resize(jointNameLimitMap.size());
00417 unsigned int i = 0;
00418
00419 for (std::map<std::string, std::pair<double, double> >::const_iterator mapIt = jointNameLimitMap.begin(); mapIt != jointNameLimitMap.end(); ++mapIt)
00420 {
00421 jointNames_out[i] = mapIt->first;
00422 velLimits_out[i] = mapIt->second.first;
00423 accLimits_out[i] = mapIt->second.second;
00424 ++i;
00425 }
00426 }
00427
00428 CartesianMotionLimitHelper::CartesianMotionLimitHelper()
00429 {
00430 setLimits();
00431 }
00432
00433 CartesianMotionLimitHelper::CartesianMotionLimitHelper(const CartesianMotionLimitHelper& toCopy)
00434 {
00435 linLimit = toCopy.getLinearLimit();
00436 rotLimit = toCopy.getRotationalLimit();
00437 }
00438
00439 CartesianMotionLimitHelper::~CartesianMotionLimitHelper()
00440 {
00441 }
00442
00443 void CartesianMotionLimitHelper::setLimits(double linLimitIn, double rotLimitIn)
00444 {
00445 if (linLimitIn >= 0 && rotLimitIn >= 0)
00446 {
00447 linLimit = linLimitIn;
00448 rotLimit = rotLimitIn;
00449 }
00450 else
00451 {
00452 std::stringstream err;
00453 err << "CartesianMotionLimitHelper::setLimits() - limits must not be less than 0";
00454 NasaCommonLogging::Logger::log("gov.nasa.controllers.CartesianMotionLimitHelper", log4cpp::Priority::ERROR, err.str());
00455 throw std::invalid_argument(err.str());
00456 }
00457 }
00458
00459 CartesianVelocityLimiter::CartesianVelocityLimiter(const CartesianVelocityLimiter& toCopy)
00460 {
00461 setVelocityLimits(toCopy.getLinearVelocityLimit(), toCopy.getRotationalVelocityLimit());
00462 }
00463
00464 CartesianMotionLimiter::CartesianMotionLimiter(const CartesianMotionLimiter& toCopy)
00465 : CartesianVelocityLimiter(toCopy)
00466 {
00467 setAccelerationLimits(toCopy.getLinearAccelerationLimit(), toCopy.getRotationalAccelerationLimit());
00468 }
00469