00001 #include "robodyn_controllers/TrajectoryManager.h"
00002
00003 TrajectoryManager::TrajectoryManager(const std::string& name)
00004 : JointTrajectoryManager()
00005 , GoalStatusSender(name)
00006 , velocityFactor(1.)
00007 , stopVelocityLimit(0.4)
00008 , stopAccelerationLimit(1.5)
00009 , jointSettingsValid(false)
00010 , poseSettingsValid(false)
00011 , basesValid(false)
00012 , zeroLimit(1e-5)
00013 {
00014 }
00015
00016 TrajectoryManager::~TrajectoryManager()
00017 {
00018 }
00019
00020 void TrajectoryManager::initialize_sim(const std::string& urdfDesc, double timeStepIn)
00021 {
00022 timeStep = timeStepIn;
00023 boost::shared_ptr<JointPositionLimiter> posLimiter(new JointPositionLimiter);
00024 positionLimiter.reset(new JointNamePositionLimiter);
00025 positionLimiter->setJointPositionLimiter(posLimiter);
00026 treeIkPtr.reset(new MobileTreeIk);
00027 forceController.reset(new Cartesian_HybCntrl);
00028 treeIkPtr->loadFromParam(urdfDesc);
00029 treeIkPtr->setPositionLimiter(positionLimiter);
00030 jointTrajFactory.reset(new jointTrajFactory_type);
00031 cartTrajFactory.reset(new cartTrajFactory_type);
00032 rosJointTrajFactory.setFactory(jointTrajFactory);
00033 rosJointTrajFactory.setPositionLimiter(positionLimiter);
00034 rosCartTrajFactory.setFactory(cartTrajFactory);
00035 rosTreeIkTrajFactory.setCartesianFactory(cartTrajFactory);
00036 rosTreeIkTrajFactory.setTreeIk(treeIkPtr);
00037 rosForceTrajFactory.setCartesianFactory(cartTrajFactory);
00038 rosForceTrajFactory.setTreeIk(treeIkPtr);
00039 rosForceTrajFactory.setForceController(forceController);
00040 }
00041
00042
00043 void TrajectoryManager::initialize(const std::string& urdfFile, double timeStepIn)
00044 {
00045 timeStep = timeStepIn;
00046 boost::shared_ptr<JointPositionLimiter> posLimiter(new JointPositionLimiter);
00047 positionLimiter.reset(new JointNamePositionLimiter);
00048 positionLimiter->setJointPositionLimiter(posLimiter);
00049 treeIkPtr.reset(new MobileTreeIk);
00050 forceController.reset(new Cartesian_HybCntrl);
00051 treeIkPtr->loadFromFile(urdfFile);
00052 treeIkPtr->setPositionLimiter(positionLimiter);
00053 treeIkPtr->setTimeStep(timeStep);
00054 treeIkPtr->setMaxJointDecel(stopAccelerationLimit);
00055 jointTrajFactory.reset(new jointTrajFactory_type);
00056 cartTrajFactory.reset(new cartTrajFactory_type);
00057 rosJointTrajFactory.setFactory(jointTrajFactory);
00058 rosJointTrajFactory.setPositionLimiter(positionLimiter);
00059 rosCartTrajFactory.setFactory(cartTrajFactory);
00060 rosTreeIkTrajFactory.setCartesianFactory(cartTrajFactory);
00061 rosTreeIkTrajFactory.setTreeIk(treeIkPtr);
00062 rosForceTrajFactory.setCartesianFactory(cartTrajFactory);
00063 rosForceTrajFactory.setTreeIk(treeIkPtr);
00064 rosForceTrajFactory.setForceController(forceController);
00065 }
00066
00067 void TrajectoryManager::updateTree(const r2_msgs::ToolFrame& toolFrameMsg)
00068 {
00069 toolFrameManager.updateToolFrames(toolFrameMsg, *treeIkPtr);
00070 treeIkPtr->resetSolver();
00071 }
00072
00073 void TrajectoryManager::updateTrajectories(const r2_msgs::JointCommand& defaultCommandMsg, const r2_msgs::JointControlDataArray& defaultControlMsg, const sensor_msgs::JointState& startJointPositions, const sensor_msgs::JointState& startJointVels)
00074 {
00075 setupJointState(defaultCommandMsg);
00076 setupJointControl(defaultControlMsg);
00077
00078
00079 bool sendUpdate = false;
00080 sensor_msgs::JointState nextPoint;
00081 ros::Duration timeFromStart;
00082 actionlib_msgs::GoalStatus followerStatus;
00083 bool success;
00084 std::set<std::string> kasquishJoints;
00085
00086 for (GoalFollowerMap_type::iterator followerIt = goalFollowerMap.begin(); followerIt != goalFollowerMap.end();)
00087 {
00088 success = true;
00089 try
00090 {
00091 followerIt->second->getNextPoint(nextPoint, timeFromStart);
00092 }
00093 catch (std::exception& e)
00094 {
00095
00096 followerIt->second->goalManager.setReadyState(false);
00097 followerIt->second->goalManager.setStatus(actionlib_msgs::GoalStatus::ABORTED);
00098 followerIt->second->goalManager.setText(e.what());
00099 success = false;
00100
00101 const std::vector<std::string>& jointNames = followerIt->second->getJointNames();
00102 kasquishJoints.insert(jointNames.begin(), jointNames.end());
00103 }
00104 if (success)
00105 {
00106 unsigned int i;
00107 GoalReplanMap_type::iterator replanIt = goalReplanMap.find(followerIt->first);
00108
00109 for (i = 0; i < nextPoint.name.size(); ++i)
00110 {
00111 std::map<std::string, unsigned int>::const_iterator jntIt = jointIndexMap.find(nextPoint.name[i]);
00112
00113 if (jntIt != jointIndexMap.end())
00114 {
00115 jointStateOut.position.at(jointIndexMap.at(nextPoint.name[i])) = nextPoint.position.at(i);
00116 jointStateOut.velocity.at(jointIndexMap.at(nextPoint.name[i])) = nextPoint.velocity.at(i);
00117 jointStateOut.effort.at(jointIndexMap.at(nextPoint.name[i])) = nextPoint.effort.at(i);
00118
00119
00120 if (!(replanIt == goalReplanMap.end() || replanIt->second.empty() || replanIt->second.at(i).type != r2_msgs::ReplanType::PAUSE))
00121 {
00122
00123 if (controllableJoints.at(jntIt->first))
00124 {
00125
00126 std::vector<std::string>::iterator controlIt = std::find(jointControlOut.joint.begin(), jointControlOut.joint.end(), jntIt->first);
00127
00128 if (controlIt == jointControlOut.joint.end())
00129 {
00130
00131 jointControlOut.joint.push_back(jntIt->first);
00132 jointControlOut.data.push_back(r2_msgs::JointControlData());
00133 jointControlOut.data.back().commandMode.state = r2_msgs::JointControlCommandMode::MULTILOOPSTEP;
00134 }
00135 else
00136 {
00137
00138 jointControlOut.data.at(controlIt - jointControlOut.joint.begin()).commandMode.state = r2_msgs::JointControlCommandMode::MULTILOOPSTEP;
00139 }
00140 }
00141 }
00142 }
00143 }
00144
00145 if (replanIt != goalReplanMap.end())
00146 {
00147
00148 goalReplanMap.erase(replanIt);
00149 }
00150 }
00151
00152 followerStatus = followerIt->second->goalManager.getStatus();
00153
00154
00155 std::pair<GoalStatusMap_type::iterator, bool> insRet = goalStatusMap.insert(std::make_pair(followerStatus.goal_id, followerStatus));
00156
00157 if (insRet.second)
00158 {
00159 std::stringstream ss;
00160 ss << "First status " << (int)followerStatus.status
00161 << " for " << followerStatus.goal_id.id << ", " << followerStatus.goal_id.stamp;
00162 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00163 addStatus(followerStatus);
00164 sendUpdate = true;
00165 }
00166 else if (insRet.first->second.status != followerStatus.status
00167 || insRet.first->second.text != followerStatus.text)
00168 {
00169 std::stringstream ss;
00170 ss << "Status change to " << (int)followerStatus.status
00171 << " for " << followerStatus.goal_id.id << ", " << followerStatus.goal_id.stamp;
00172 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00173 insRet.first->second = followerStatus;
00174 addStatus(followerStatus);
00175 sendUpdate = true;
00176 }
00177
00178
00179 if (followerStatus.status == actionlib_msgs::GoalStatus::SUCCEEDED
00180 || followerStatus.status == actionlib_msgs::GoalStatus::ABORTED
00181 || followerStatus.status == actionlib_msgs::GoalStatus::PREEMPTED
00182 || followerStatus.status == actionlib_msgs::GoalStatus::REJECTED)
00183 {
00184 std::stringstream ss;
00185 ss << "Goal complete: " << (int)followerStatus.status
00186 << " for " << followerStatus.goal_id.id << ", " << followerStatus.goal_id.stamp;
00187 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00188 goalStatusMap.erase(followerStatus.goal_id);
00189 followerIt = goalFollowerMap.erase(followerIt);
00190 goalReplanMap.erase(followerStatus.goal_id);
00191 removeFromJointGoalMap(followerStatus.goal_id);
00192 }
00193 else
00194 {
00195 ++followerIt;
00196
00197 if (followerStatus.status != actionlib_msgs::GoalStatus::ACTIVE
00198 && followerStatus.status != actionlib_msgs::GoalStatus::PENDING)
00199 {
00200 std::stringstream ss;
00201 ss << "Received uexpected status: " << (int)followerStatus.status
00202 << " for " << followerStatus.goal_id.id << ", " << followerStatus.goal_id.stamp;
00203 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00204 }
00205 }
00206 }
00207
00209
00210
00211 if (!kasquishJoints.empty())
00212 {
00213 std::vector<std::string> kasquishVec(kasquishJoints.size());
00214 std::copy(kasquishJoints.begin(), kasquishJoints.end(), kasquishVec.begin());
00215 kasquish(kasquishVec, startJointPositions, startJointVels);
00216 }
00217
00219 for (unsigned int i = 0; i < jointStateOut.name.size(); ++i)
00220 {
00221 if (positionLimiter->hasLimits(jointStateOut.name[i]) &&
00222 positionLimiter->limit(jointStateOut.name[i], jointStateOut.position[i]))
00223 {
00225 jointStateOut.velocity[i] = 0.;
00226 jointStateOut.effort[i] = 0.;
00227 std::stringstream ss;
00228 ss << "Position out limited for " << jointStateOut.name[i];
00229 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::DEBUG, ss.str());
00230 }
00231
00233 if (fabs(jointStateOut.velocity[i]) < zeroLimit)
00234 {
00235 jointStateOut.velocity[i] = 0;
00236 }
00237 }
00238
00240 jointStateOut.header.stamp = ros::Time::now();
00241 writeJointState(jointStateOut);
00242
00243 if (!jointControlOut.joint.empty())
00244 {
00245 jointControlOut.header.stamp = ros::Time::now();
00246 writeJointControl(jointControlOut);
00247
00248
00249 for (unsigned int i = 0; i < jointControlOut.joint.size();)
00250 {
00251 if (jointControlOut.data.at(i).commandMode.state == r2_msgs::JointControlCommandMode::MULTILOOPSTEP)
00252 {
00253
00254 jointControlOut.data.at(i).commandMode.state = r2_msgs::JointControlCommandMode::MULTILOOPSMOOTH;
00255 ++i;
00256 }
00257 else
00258 {
00259
00260 jointControlOut.joint.erase(jointControlOut.joint.begin() + i);
00261 jointControlOut.data.erase(jointControlOut.data.begin() + i);
00262 }
00263 }
00264 }
00265
00266
00267 if (sendUpdate)
00268 {
00269 sendStatusMessage();
00270 clearStatusMessage();
00271 }
00272 }
00273
00274 void TrajectoryManager::setJointSettings(const r2_msgs::ControllerJointSettings& settingsMsg)
00275 {
00276 std::stringstream ss;
00277 ss << "received new joint settings";
00278 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00279
00280
00281 try
00282 {
00283 rosJointTrajFactory.setSettings(settingsMsg);
00284 rosJointTrajFactory.getSettings(jointSettings);
00285 jointSettingsValid = true;
00286 }
00287 catch (std::exception& e)
00288 {
00289 jointSettingsValid = false;
00290 }
00291 }
00292
00293 void TrajectoryManager::getJointSettings(r2_msgs::ControllerJointSettings& settingsMsg)
00294 {
00295 rosJointTrajFactory.getSettings(settingsMsg);
00296 }
00297
00298 void TrajectoryManager::setPoseSettings(const r2_msgs::ControllerPoseSettings& settingsMsg)
00299 {
00300 std::stringstream ss;
00301 ss << "received new pose settings";
00302 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00303
00304
00305 try
00306 {
00307 rosCartTrajFactory.setSettings(settingsMsg);
00308 forceController->setPoseSettings(settingsMsg.maxLinearVelocity, settingsMsg.maxRotationalVelocity, settingsMsg.maxLinearAcceleration, settingsMsg.maxRotationalAcceleration);
00309 poseSettingsValid = true;
00310 }
00311 catch (std::exception& e)
00312 {
00313 poseSettingsValid = false;
00314 }
00315 }
00316
00317 void TrajectoryManager::setJointCapabilities(const r2_msgs::JointCapability& capabilitiesMsg)
00318 {
00319 positionLimiter->setLimits(capabilitiesMsg.name, capabilitiesMsg.positionLimitMin, capabilitiesMsg.positionLimitMax, capabilitiesMsg.velocityLimit);
00320 }
00321
00322 void TrajectoryManager::setBases(const r2_msgs::StringArray& basesMsg)
00323 {
00324 std::stringstream ss;
00325 ss << "received new bases:";
00326
00327 for (unsigned int i = 0; i < basesMsg.data.size(); ++i)
00328 {
00329 ss << basesMsg.data[i] << " ";
00330 }
00331
00332 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00333
00334
00335 try
00336 {
00337 treeIkPtr->setBases(basesMsg.data);
00338 basesValid = true;
00339 }
00340 catch (std::exception& e)
00341 {
00342 basesValid = false;
00343 }
00344 }
00345
00346 void TrajectoryManager::updateInertia(const sensor_msgs::JointState& inertiaIn)
00347 {
00348 if (inertiaIn.position.size() != inertiaIn.name.size())
00349 {
00350 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, "inertia names and positions are not the same size");
00351 }
00352
00353
00354 try
00355 {
00356 RosMsgConverter::JointStateToJntMap(inertiaIn, jointInertiaMap);
00357 }
00358 catch (std::exception& e)
00359 {
00360 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, e.what());
00361 return;
00362 }
00363
00364 treeIkPtr->setJointInertias(jointInertiaMap);
00365 }
00366
00367 void TrajectoryManager::setPriorityTol(std::vector<double> priorityNum, std::vector<double> priorityLinearTol, std::vector<double> priorityAngularTol)
00368 {
00369 std::map<int, std::pair<double, double> > priorityTolMap;
00370
00371 if (priorityNum.size() != priorityLinearTol.size() || priorityNum.size() != priorityAngularTol.size())
00372 {
00373 std::stringstream err;
00374 err << "priorityNum, priorityLinearTol, and priorityAngularTol must all be the same size!";
00375 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, err.str());
00376 throw std::length_error(err.str());
00377 }
00378
00379 for (unsigned int i = 0; i < priorityNum.size(); ++i)
00380 {
00381 priorityTolMap[(int)priorityNum[i]] = std::make_pair(priorityLinearTol[i], priorityAngularTol[i]);
00382 }
00383
00384 treeIkPtr->setPriorityTol(priorityTolMap);
00385 }
00386
00387 void TrajectoryManager::setIkParameters(double mBar, double kr, unsigned int maxIts, double maxTwist)
00388 {
00389 treeIkPtr->setMBar(mBar);
00390 treeIkPtr->setKr(kr);
00391 treeIkPtr->setMaxCriticalIterations(maxIts);
00392 treeIkPtr->setMaxTwist(maxTwist);
00393 }
00394
00395 void TrajectoryManager::setSensorNameMap(std::vector<std::string> sensorKeys, std::vector<std::string> sensorNames)
00396 {
00397 std::map<std::string, std::string> sensorNameMap;
00398
00399 if (sensorKeys.size() != sensorNames.size())
00400 {
00401 std::stringstream err;
00402 err << "sensor keys and sensor names must be the same size!";
00403 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, err.str());
00404 throw std::length_error(err.str());
00405 }
00406
00407 for (unsigned int i = 0; i < sensorKeys.size(); ++i)
00408 {
00409 sensorNameMap[sensorKeys[i]] = sensorNames[i];
00410 }
00411
00412 forceController->setSensorNameMap(sensorNameMap);
00413 }
00414
00415 void TrajectoryManager::setForceParameters(struct ForceGains new_gains)
00416 {
00417 forceController->setFilter(new_gains.filterAlpha);
00418 forceController->setGain(new_gains.forceGain, new_gains.torqueGain, new_gains.forceIntegral, new_gains.torqueIntegral,
00419 new_gains.forceDamping, new_gains.torqueDamping, new_gains.forceWindupLimit, new_gains.torqueWindupLimit,
00420 new_gains.positionErrorLimit, new_gains.rotationErrorLimit);
00421 forceController->doFeedForward = new_gains.doFeedForward;
00422 }
00423
00424 void TrajectoryManager::updateSensorForces(const r2_msgs::WrenchState& wrenchSensors)
00425 {
00426 if (wrenchSensors.name.size() != wrenchSensors.wrench.size())
00427 {
00428 std::stringstream ss;
00429 ss << "TrajectoryManager::updateForceSensors: sensor names and values do not match!";
00430 NasaCommonLogging::Logger::log("gov.nasa.controller.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00431 throw (std::runtime_error(ss.str()));
00432 }
00433
00434 for (unsigned int i = 0; i < wrenchSensors.name.size(); ++i)
00435 {
00436 forceSensorMap[wrenchSensors.name[i]] = KDL::Wrench(KDL::Vector(wrenchSensors.wrench[i].force.x, wrenchSensors.wrench[i].force.y, wrenchSensors.wrench[i].force.z),
00437 KDL::Vector(wrenchSensors.wrench[i].torque.x, wrenchSensors.wrench[i].torque.y, wrenchSensors.wrench[i].torque.z));
00438 }
00439
00440 forceController->updateSensorForces(forceSensorMap);
00441 }
00442
00443 void TrajectoryManager::updateActualPoseState(const r2_msgs::PoseState& actualPoseState)
00444 {
00445 if (actualPoseState.name.size() != actualPoseState.positions.size() || actualPoseState.name.size() != actualPoseState.velocities.size())
00446 {
00447 std::stringstream ss;
00448 ss << "TrajectoryManager::updateForceSensors: actual pose state names and values do not match!";
00449 NasaCommonLogging::Logger::log("gov.nasa.controller.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00450 throw (std::runtime_error(ss.str()));
00451 }
00452
00453 if (actualPoseState.name != actualFrameNames)
00454 {
00455 actualFrameVelMap.clear();
00456 actualFrameNames = actualPoseState.name;
00457 }
00458
00459 RosMsgConverter::PoseStateToFrameVelMap(actualPoseState, treeIkPtr->getBaseName(), actualFrameVelMap);
00460
00461 }
00462
00463 double TrajectoryManager::addForceWaypoints(const r2_msgs::PoseTrajectory& trajectory,
00464 const sensor_msgs::JointState& startJointPositions,
00465 const sensor_msgs::JointState& startJointVels,
00466 const sensor_msgs::JointState& prevJointVels,
00467 const r2_msgs::PoseState& startPoseState,
00468 const r2_msgs::PoseState& startPoseVels,
00469 const r2_msgs::ForceControlAxisArray& forceAxes)
00470 {
00471 std::stringstream ss;
00472 ss << "TrajectoryManager::" << "received force waypoints: \n" << trajectory;
00473 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00474
00475 if (!poseSettingsValid)
00476 {
00477
00478 std::stringstream ss;
00479 ss << "position settings invalid";
00480 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00481 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00482 }
00483 else if (!basesValid)
00484 {
00485
00486 std::stringstream ss;
00487 ss << "bases invalid";
00488 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00489 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00490 }
00491 else if (forceAxes.axes.size() != forceAxes.nodes.size())
00492 {
00493
00494 std::stringstream ss;
00495 ss << "forces invalid";
00496 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00497 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00498 }
00499 else
00500 {
00501 actionlib_msgs::GoalID goalId;
00502 goalId.stamp = trajectory.header.stamp;
00503 goalId.id = trajectory.header.frame_id;
00504
00505 std::set<std::string> kasquishJoints;
00506 abort(goalId, kasquishJoints);
00507
00508
00509 treeIkPtr->resetMobileJoints();
00510 boost::shared_ptr<RosMsgJointTrajectory> onlineTraj;
00511
00512 try
00513 {
00514 onlineTraj = rosForceTrajFactory.getTrajectory(startJointPositions, startJointVels, prevJointVels, startPoseState, startPoseVels, trajectory, forceAxes);
00515 preempt(onlineTraj->getJointNames(), kasquishJoints);
00516
00517 if (kasquishJoints.empty())
00518 {
00519 std::auto_ptr<OnlineJointTrajectoryFollower> newFollower(new OnlineJointTrajectoryFollower);
00520 newFollower->setTrajectory(onlineTraj, timeStep, velocityFactor);
00521
00522 goalFollowerMap.insert(goalId, newFollower);
00523
00524 sendStatusMessage(goalFollowerMap.at(goalId).goalManager.getStatus(), true);
00525 goalStatusMap.insert(std::make_pair(goalId, goalFollowerMap.at(goalId).goalManager.getStatus()));
00526
00527 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00528 }
00529 }
00530 catch (std::exception& e)
00531 {
00532
00533 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, e.what(), true);
00534 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, e.what());
00535 }
00536
00537 if (!kasquishJoints.empty())
00538 {
00539 std::vector<std::string> kasquishVec(kasquishJoints.size());
00540 std::copy(kasquishJoints.begin(), kasquishJoints.end(), kasquishVec.begin());
00541 kasquish(kasquishVec, startJointPositions, startJointVels);
00542
00543
00544 double maxTime = 0.;
00545
00546 for (std::vector<std::string>::const_iterator jointIt = kasquishVec.begin(); jointIt != kasquishVec.end(); ++jointIt)
00547 {
00548 JointGoalMap_type::const_iterator goalIt = jointGoalMap.find(*jointIt);
00549
00550 if (goalIt != jointGoalMap.end())
00551 {
00552 GoalFollowerMap_type::const_iterator followerIt = goalFollowerMap.find(goalIt->second);
00553
00554 if (followerIt != goalFollowerMap.end())
00555 {
00556 if (followerIt->second->getDuration() > maxTime)
00557 {
00558 maxTime = followerIt->second->getDuration();
00559 }
00560 }
00561 }
00562 }
00563
00564 ss.str("");
00565 ss << "TrajectoryManager:: kaquish not empty, maxTime: " << maxTime;
00566 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00567 return maxTime;
00568 }
00569 }
00570
00571 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, "finished addForceWaypoints");
00572 return 0.;
00573 }
00574
00575 double TrajectoryManager::addCartesianWaypoints(const r2_msgs::PoseTrajectory& trajectory,
00576 const sensor_msgs::JointState& startJointPositions,
00577 const sensor_msgs::JointState& startJointVels,
00578 const sensor_msgs::JointState& prevJointVels,
00579 const r2_msgs::PoseState& startPoseState,
00580 const r2_msgs::PoseState& startPoseVels)
00581 {
00582 std::stringstream ss;
00583 ss << "received cartesian waypoints: \n" << trajectory;
00584 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00585
00586 if (!poseSettingsValid)
00587 {
00588
00589 std::stringstream ss;
00590 ss << "position settings invalid";
00591 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00592 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00593 }
00594 else if (!basesValid)
00595 {
00596
00597 std::stringstream ss;
00598 ss << "bases invalid";
00599 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00600 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00601 }
00602 else
00603 {
00604 actionlib_msgs::GoalID goalId;
00605 goalId.stamp = trajectory.header.stamp;
00606 goalId.id = trajectory.header.frame_id;
00607
00608 std::set<std::string> kasquishJoints;
00609 abort(goalId, kasquishJoints, "duplicate goal");
00610
00611
00612 treeIkPtr->resetMobileJoints();
00613 boost::shared_ptr<RosMsgJointTrajectory> onlineTraj;
00614
00615 try
00616 {
00617 onlineTraj = rosTreeIkTrajFactory.getTrajectory(startJointPositions, startJointVels, prevJointVels, startPoseState, startPoseVels, trajectory);
00618 preempt(onlineTraj->getJointNames(), kasquishJoints, "new Cartesian waypoints");
00619
00620 if (kasquishJoints.empty())
00621 {
00622 std::auto_ptr<OnlineJointTrajectoryFollower> newFollower(new OnlineJointTrajectoryFollower);
00623 newFollower->setTrajectory(onlineTraj, timeStep, velocityFactor);
00624
00625 goalFollowerMap.insert(goalId, newFollower);
00626 sendStatusMessage(goalFollowerMap.at(goalId).goalManager.getStatus(), true);
00627 goalStatusMap.insert(std::make_pair(goalId, goalFollowerMap.at(goalId).goalManager.getStatus()));
00628
00629
00630 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00631 }
00632 }
00633 catch (std::exception& e)
00634 {
00635
00636 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, e.what(), true);
00637 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, "error in addCartesianWaypoints()");
00638 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, e.what());
00639 }
00640
00641 if (!kasquishJoints.empty())
00642 {
00643 std::vector<std::string> kasquishVec(kasquishJoints.size());
00644 std::copy(kasquishJoints.begin(), kasquishJoints.end(), kasquishVec.begin());
00645 kasquish(kasquishVec, startJointPositions, startJointVels);
00646
00647
00648 double maxTime = timeStep;
00649
00650 for (std::vector<std::string>::const_iterator jointIt = kasquishVec.begin(); jointIt != kasquishVec.end(); ++jointIt)
00651 {
00652 JointGoalMap_type::const_iterator goalIt = jointGoalMap.find(*jointIt);
00653
00654 if (goalIt != jointGoalMap.end())
00655 {
00656 GoalFollowerMap_type::const_iterator followerIt = goalFollowerMap.find(goalIt->second);
00657
00658 if (followerIt != goalFollowerMap.end())
00659 {
00660 if (followerIt->second->getDuration() > maxTime)
00661 {
00662 maxTime = followerIt->second->getDuration();
00663 }
00664 }
00665 }
00666 }
00667
00668 return maxTime;
00669 }
00670 }
00671
00672 return 0.;
00673 }
00674
00675 void TrajectoryManager::addJointWaypoints(const trajectory_msgs::JointTrajectory& trajectory,
00676 const sensor_msgs::JointState& startJointPositions,
00677 const sensor_msgs::JointState& startJointVels,
00678 const sensor_msgs::JointState& prevJointVels,
00679 const std::vector<r2_msgs::ReplanType>& replanVec)
00680 {
00681 std::stringstream ss;
00682 ss << "received joint waypoints: \n" << trajectory;
00683 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00684
00685
00686 if (trajectory.joint_names.size() == 0)
00687 {
00688 std::stringstream ss;
00689 ss << "The new joint refs contains no joint names, resetAll";
00690 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::WARN, ss.str());
00691 resetAll("new joint waypoints with no joint names");
00692 }
00693 else if (!jointSettingsValid)
00694 {
00695
00696 std::stringstream ss;
00697 ss << "joint settings invalid";
00698 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, ss.str(), true);
00699 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, ss.str());
00700 }
00701 else
00702 {
00703 actionlib_msgs::GoalID goalId;
00704 goalId.stamp = trajectory.header.stamp;
00705 goalId.id = trajectory.header.frame_id;
00706 std::set<std::string> kasquishJoints;
00707 abort(goalId, kasquishJoints, "duplicate goal");
00708
00709 boost::shared_ptr<RosMsgJointTrajectory> onlineTraj;
00710
00711
00712 try
00713 {
00714 onlineTraj = rosJointTrajFactory.getTrajectory(startJointPositions, startJointVels, prevJointVels, trajectory);
00715
00716 const std::vector<std::string>& trajJoints = onlineTraj->getJointNames();
00717 preempt(trajJoints, kasquishJoints, "new joint waypoints");
00718
00719
00720 for (std::vector<std::string>::const_iterator jointIt = trajJoints.begin(); jointIt != trajJoints.end(); ++jointIt)
00721 {
00722 kasquishJoints.erase(*jointIt);
00723 }
00724
00725 std::auto_ptr<OnlineJointTrajectoryFollower> newFollower(new OnlineJointTrajectoryFollower);
00726 newFollower->setTrajectory(onlineTraj, timeStep, velocityFactor);
00727
00728 goalFollowerMap.insert(goalId, newFollower);
00729 goalReplanMap[goalId] = replanVec;
00730 sendStatusMessage(goalFollowerMap.at(goalId).goalManager.getStatus(), true);
00731 goalStatusMap.insert(std::make_pair(goalId, goalFollowerMap.at(goalId).goalManager.getStatus()));
00732
00733
00734 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00735 }
00736 catch (std::exception& e)
00737 {
00738
00739 sendStatusMessage(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, e.what(), true);
00740 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, "error in addJointWaypoints()");
00741 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, e.what());
00742 }
00743
00744 if (!kasquishJoints.empty())
00745 {
00746 std::vector<std::string> kasquishVec(kasquishJoints.size());
00747 std::copy(kasquishJoints.begin(), kasquishJoints.end(), kasquishVec.begin());
00748 kasquish(kasquishVec, startJointPositions, startJointVels);
00749 }
00750 }
00751 }
00752
00753 void TrajectoryManager::addJointBreadcrumbs(const trajectory_msgs::JointTrajectory& trajectory)
00754 {
00755 std::stringstream ss;
00756 ss << "received trajectory: " << trajectory.header.frame_id << ", " << trajectory.points.size() << " points";
00757
00758 for (unsigned int i = 0; i < trajectory.joint_names.size(); i++)
00759 {
00760 ss << std::endl << " " << trajectory.joint_names[i];
00761 }
00762
00763 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00764
00765
00766 if (trajectory.joint_names.size() == 0)
00767 {
00768 std::stringstream ss;
00769 ss << "The new joint trajectory contains no joint names, resetAll";
00770 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::WARN, ss.str());
00771 resetAll("new joint trajectory with no joint names");
00772 }
00773 else
00774 {
00775 actionlib_msgs::GoalID goalId;
00776 goalId.stamp = trajectory.header.stamp;
00777 goalId.id = trajectory.header.frame_id;
00778
00779 std::set<std::string> kasquishJoints;
00780 abort(goalId, kasquishJoints, "duplicate goal");
00781 preempt(trajectory.joint_names, kasquishJoints, "new joint breadcrumbs");
00782
00783
00784
00785 std::auto_ptr<PreplannedJointTrajectoryFollower> newFollower(new PreplannedJointTrajectoryFollower);
00786 newFollower->setTrajectory(trajectory, timeStep, velocityFactor);
00787
00788 goalFollowerMap.insert(goalId, newFollower);
00789 sendStatusMessage(goalFollowerMap.at(goalId).goalManager.getStatus(), true);
00790 goalStatusMap.insert(std::make_pair(goalId, goalFollowerMap.at(goalId).goalManager.getStatus()));
00791
00792
00793 addToJointGoalMap(trajectory.joint_names, goalId);
00794 }
00795 }
00796
00797 bool TrajectoryManager::isActive(const actionlib_msgs::GoalID& goalId) const
00798 {
00799 return (goalFollowerMap.find(goalId) != goalFollowerMap.end());
00800 }
00801
00802 void TrajectoryManager::abort(const actionlib_msgs::GoalID& goalId, const std::string& msg)
00803 {
00804 std::set<std::string> kasquishJoints;
00805 abort(goalId, kasquishJoints, msg);
00806 }
00807
00808 void TrajectoryManager::abort(const actionlib_msgs::GoalID& goalId, std::set<std::string>& abortedJoints, const std::string& msg)
00809 {
00810 GoalFollowerMap_type::iterator followerIt = goalFollowerMap.find(goalId);
00811
00812 if (followerIt != goalFollowerMap.end())
00813 {
00814 std::stringstream ss;
00815 ss << "aborting goal";
00816
00817 if (!msg.empty())
00818 {
00819 ss << " (" << msg << ")";
00820 }
00821
00822 ss << ": " << goalId;
00823 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::NOTICE, ss.str());
00824
00825 const std::vector<std::string>& jointNames = followerIt->second->getJointNames();
00826 abortedJoints.insert(jointNames.begin(), jointNames.end());
00827
00828
00829 followerIt->second->abort(msg);
00830
00831
00832 sendStatusMessage(followerIt->second->goalManager.getStatus(), true);
00833
00834
00835 goalFollowerMap.erase(followerIt);
00836
00837
00838 removeFromJointGoalMap(goalId);
00839 }
00840
00841
00842 goalStatusMap.erase(goalId);
00843
00844
00845 goalReplanMap.erase(goalId);
00846 }
00847
00848 void TrajectoryManager::kasquishAll(const sensor_msgs::JointState& startJointPositions,
00849 const sensor_msgs::JointState& startJointVels,
00850 const std::string& msg)
00851 {
00852 std::stringstream ss;
00853 ss << "kasquishing all joints";
00854 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::NOTICE, ss.str());
00855
00856 std::set<std::string> abortedJoints;
00857
00858 for (GoalFollowerMap_type::iterator followerIt = goalFollowerMap.begin(); followerIt != goalFollowerMap.end(); ++followerIt)
00859 {
00860 const std::vector<std::string>& jointNames = followerIt->second->getJointNames();
00861 abortedJoints.insert(jointNames.begin(), jointNames.end());
00862
00863
00864 followerIt->second->abort(msg);
00865
00866
00867 addStatus(followerIt->second->goalManager.getStatus());
00868 }
00869
00870
00871 goalFollowerMap.clear();
00872
00873
00874 goalStatusMap.clear();
00875
00876
00877 goalReplanMap.clear();
00878
00879 if (!abortedJoints.empty())
00880 {
00881 std::vector<std::string> kasquishVec(abortedJoints.size());
00882 std::copy(abortedJoints.begin(), abortedJoints.end(), kasquishVec.begin());
00883 kasquish(kasquishVec, startJointPositions, startJointVels);
00884 }
00885 }
00886
00887 void TrajectoryManager::preempt(const std::vector<std::string>& jointNames, std::set<std::string>& preemptedJoints, const std::string& msg)
00888 {
00889
00890 for (std::vector<std::string>::const_iterator jointIt = jointNames.begin(); jointIt != jointNames.end(); ++jointIt)
00891 {
00892 std::map<std::string, actionlib_msgs::GoalID>::const_iterator conflictIt = jointGoalMap.find(*jointIt);
00893
00894 if (conflictIt != jointGoalMap.end())
00895 {
00896
00897 GoalFollowerMap_type::iterator followerIt = goalFollowerMap.find(conflictIt->second);
00898
00899 if (followerIt != goalFollowerMap.end())
00900 {
00901 std::stringstream ss;
00902 ss << "joint conflict, preempting";
00903 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::INFO, ss.str());
00904
00905 const std::vector<std::string>& joints = followerIt->second->getJointNames();
00906 preemptedJoints.insert(joints.begin(), joints.end());
00907
00908
00909 followerIt->second->preempt(msg);
00910
00911
00912 sendStatusMessage(followerIt->second->goalManager.getStatus(), true);
00913
00914
00915 goalFollowerMap.erase(followerIt);
00916 }
00917
00918
00919 goalStatusMap.erase(conflictIt->second);
00920
00921
00922 goalReplanMap.erase(conflictIt->second);
00923
00924
00925 removeFromJointGoalMap(conflictIt->second);
00926 }
00927 }
00928 }
00929
00930 void TrajectoryManager::kasquish(const std::vector<std::string>& jointNames,
00931 const sensor_msgs::JointState& startJointPositions,
00932 const sensor_msgs::JointState& startJointVels)
00933 {
00934 KDL::JntArray startPose;
00935 KDL::JntArrayVel startVel;
00936
00937 try
00938 {
00939 RosMsgConverter::JointStateToJntArray(startJointPositions, jointNames, startPose);
00940 RosMsgConverter::JointStateToJntArrayVel(startJointVels, jointNames, startVel);
00941 }
00942 catch (std::exception& e)
00943 {
00944 sendStatusMessage(ros::Time::now(), "kasquish", actionlib_msgs::GoalStatus::REJECTED, e.what(), true);
00945 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, std::string("kasquish failed: ") + e.what());
00946 return;
00947 }
00948
00949 rosJointTrajFactory.setLimits(jointNames, stopVelocityLimit, stopAccelerationLimit);
00950
00951 for (unsigned int i = 0; i < jointNames.size(); ++i)
00952 {
00953 actionlib_msgs::GoalID goalId;
00954 goalId.id = jointNames[i] + " stop";
00955
00956 trajectory_msgs::JointTrajectory trajectory;
00957 trajectory.header.frame_id = goalId.id;
00958 trajectory.joint_names.push_back(jointNames[i]);
00959 trajectory.points.resize(1);
00960 double dist = 0.5 * startVel.qdot(i) * startVel.qdot(i) / stopAccelerationLimit;
00961
00962 if (startVel.qdot(i) < 0)
00963 {
00964 dist = -dist;
00965 }
00966
00967 trajectory.points[0].positions.push_back(startPose(i) + dist);
00968
00969 boost::shared_ptr<RosMsgJointTrajectory> onlineTraj;
00970
00971
00972 try
00973 {
00974 onlineTraj = rosJointTrajFactory.getTrajectory(startJointPositions, startJointVels, startJointVels, trajectory);
00975
00976 std::auto_ptr<OnlineJointTrajectoryFollower> newFollower(new OnlineJointTrajectoryFollower);
00977 newFollower->setTrajectory(onlineTraj, timeStep, velocityFactor);
00978 newFollower->goalManager.setStatus(actionlib_msgs::GoalStatus::ACTIVE);
00979 newFollower->goalManager.setText(jointNames[i] + " stopping");
00980
00981 std::pair<GoalFollowerMap_type::iterator, bool> retVal = goalFollowerMap.insert(goalId, newFollower);
00982 const JointTrajectoryFollower* follower = retVal.first->second;
00983 addStatus(follower->goalManager.getStatus());
00984 goalStatusMap.insert(std::make_pair(goalId, follower->goalManager.getStatus()));
00985
00986
00987 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00988 }
00989 catch (std::exception& e)
00990 {
00991
00992 addStatus(trajectory.header.stamp, trajectory.header.frame_id, actionlib_msgs::GoalStatus::REJECTED, e.what());
00993 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::ERROR, e.what());
00994 }
00995 }
00996
00997 if (jointSettingsValid)
00998 {
00999 setJointSettings(jointSettings);
01000 }
01001
01002 sendStatusMessage(true);
01003 }
01004
01005 void TrajectoryManager::setupJointState(const r2_msgs::JointCommand& jointCommand)
01006 {
01007 if (jointStateOut.name != jointCommand.name)
01008 {
01009 jointStateOut.name = jointCommand.name;
01010 jointIndexMap.clear();
01011
01012 for (unsigned int i = 0; i < jointCommand.name.size(); ++i)
01013 {
01014 jointIndexMap[jointCommand.name[i]] = i;
01015 }
01016
01017 jointStateOut.position.resize(jointCommand.name.size());
01018 jointStateOut.velocity.resize(jointCommand.name.size());
01019 jointStateOut.effort.resize(jointCommand.name.size());
01020 }
01021
01022 for (unsigned int i = 0; i < jointCommand.name.size(); ++i)
01023 {
01024 jointStateOut.position[i] = jointCommand.desiredPosition[i];
01025 jointStateOut.velocity[i] = 0.;
01026 jointStateOut.effort[i] = 0.;
01027 }
01028 }
01029
01030 void TrajectoryManager::setupJointControl(const r2_msgs::JointControlDataArray& jointControl)
01031 {
01032 for (unsigned int i = 0; i < jointControl.joint.size(); ++i)
01033 {
01034 if (jointControl.data[i].commandMode.state == r2_msgs::JointControlCommandMode::MULTILOOPSMOOTH
01035 || jointControl.data[i].commandMode.state == r2_msgs::JointControlCommandMode::MULTILOOPSTEP)
01036 {
01037 controllableJoints[jointControl.joint[i]] = true;
01038 }
01039 else
01040 {
01041 controllableJoints[jointControl.joint[i]] = false;
01042 }
01043 }
01044 }
01045
01046 void TrajectoryManager::resetAll(const std::string& msg)
01047 {
01048 std::stringstream ss;
01049 ss << "resetAll(): Stopping all followers...";
01050 NasaCommonLogging::Logger::log("gov.nasa.controllers.TrajectoryManager", log4cpp::Priority::NOTICE, ss.str());
01051
01052 goalReplanMap.clear();
01053
01054 if (goalFollowerMap.empty())
01055 {
01056 return;
01057 }
01058
01059 for (GoalFollowerMap_type::iterator followerIt = goalFollowerMap.begin(); followerIt != goalFollowerMap.end(); ++followerIt)
01060 {
01061 followerIt->second->abort(msg);
01062 addStatus(followerIt->second->goalManager.getStatus());
01063 }
01064
01065 goalFollowerMap.clear();
01066
01067 sendStatusMessage(true);
01068 }