TrajectoryManager.cpp
Go to the documentation of this file.
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     // handle followers
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             // get next point failed
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             // kasquish the joints
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                     // check replan
00120                     if (!(replanIt == goalReplanMap.end() || replanIt->second.empty() || replanIt->second.at(i).type != r2_msgs::ReplanType::PAUSE))
00121                     {
00122                         // want to replan...can we?
00123                         if (controllableJoints.at(jntIt->first))
00124                         {
00125                             // we can so set to multiloop step
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                                 // not there, add
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                                 // found it
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                 // only apply on first point so we just delete it after one run
00148                 goalReplanMap.erase(replanIt);
00149             }
00150         }
00151 
00152         followerStatus = followerIt->second->goalManager.getStatus();
00153 
00154         // Store the current goalStatus for this follower
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         // Process completion
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     // the joints in here should have been removed above so we just call kasquish here
00210     // if it fails, they will stop abruptly
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         // clean up
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                 // tell it to reset to smooth next time around
00254                 jointControlOut.data.at(i).commandMode.state = r2_msgs::JointControlCommandMode::MULTILOOPSMOOTH;
00255                 ++i;
00256             }
00257             else
00258             {
00259                 // remove
00260                 jointControlOut.joint.erase(jointControlOut.joint.begin() + i);
00261                 jointControlOut.data.erase(jointControlOut.data.begin() + i);
00262             }
00263         }
00264     }
00265 
00266     // Publish the goalStatuses
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     // Apply the settings
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     // Apply the settings
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     // Apply the settings
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     // Apply the settings
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     //forceController->updateActualVelocity(actualFrameVelMap);
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         // send message and stop
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         // send message and stop
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         // send message and stop
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         // get online trajectory
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                 //        goalReplanMap.insert(goalId);
00524                 sendStatusMessage(goalFollowerMap.at(goalId).goalManager.getStatus(), true);
00525                 goalStatusMap.insert(std::make_pair(goalId, goalFollowerMap.at(goalId).goalManager.getStatus()));
00526                 // Add the new joints to the jointGoalMap
00527                 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00528             }
00529         }
00530         catch (std::exception& e)
00531         {
00532             // send message and stop
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             // report the time to wait to try again
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         // send message and stop
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         // send message and stop
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         // get online trajectory
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                 // Add the new joints to the jointGoalMap
00630                 addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00631             }
00632         }
00633         catch (std::exception& e)
00634         {
00635             // send message and stop
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             // report the time to wait to try again
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     // If no joint names are included in the trajectory, then stop all followers
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         // send message and stop
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         // get online trajectory
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             // remove trajectory joints from kasquish list
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             // Add the new joints to the jointGoalMap
00734             addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00735         }
00736         catch (std::exception& e)
00737         {
00738             // send message and stop
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     // If no joint names are included in the trajectory, then stop all followers
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         // we aren't going to actually kasquish the joints in this case
00783 
00784         // Add the new goalId to the goalFollowerMap
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         // Add the new joints to the jointGoalMap
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         // abort
00829         followerIt->second->abort(msg);
00830 
00831         // send status update
00832         sendStatusMessage(followerIt->second->goalManager.getStatus(), true);
00833 
00834         // Remove the current goal from the goalFollowerIndexMap
00835         goalFollowerMap.erase(followerIt);
00836 
00837         // Remove the joints from the jointGoalMap
00838         removeFromJointGoalMap(goalId);
00839     }
00840 
00841     // remove from goal status map if in there
00842     goalStatusMap.erase(goalId);
00843 
00844     // remove from first point status map if in there
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         // abort
00864         followerIt->second->abort(msg);
00865 
00866         // add status update
00867         addStatus(followerIt->second->goalManager.getStatus());
00868     }
00869 
00870     // cleanup
00871     goalFollowerMap.clear();
00872 
00873     // remove from goal status map if in there
00874     goalStatusMap.clear();
00875 
00876     // remove from first point status map if in there
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     // Ensure that no joints in the jointNames list are already stored in the jointGoalMap, if so preempt those trajectories
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             // get follower
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                 // preempt
00909                 followerIt->second->preempt(msg);
00910 
00911                 // send status update
00912                 sendStatusMessage(followerIt->second->goalManager.getStatus(), true);
00913 
00914                 // Remove the current goal from the goalFollowerIndexMap
00915                 goalFollowerMap.erase(followerIt);
00916             }
00917 
00918             // remove from goal status map if in there
00919             goalStatusMap.erase(conflictIt->second);
00920 
00921             // remove from first point status map if in there
00922             goalReplanMap.erase(conflictIt->second);
00923 
00924             // Remove the joint from the jointGoalMap
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         // get online trajectory
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             // Add the new joints to the jointGoalMap
00987             addToJointGoalMap(onlineTraj->getJointNames(), goalId);
00988         }
00989         catch (std::exception& e)
00990         {
00991             // send message and stop
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 }


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