00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <ros/ros.h>
00038 #include <moveit/controller_manager/controller_manager.h>
00039 #include <control_msgs/FollowJointTrajectoryAction.h>
00040 #include <actionlib/client/simple_action_client.h>
00041 #include <pluginlib/class_list_macros.h>
00042
00043 #include <pr2_mechanism_msgs/ListControllers.h>
00044 #include <pr2_mechanism_msgs/SwitchController.h>
00045 #include <pr2_mechanism_msgs/LoadController.h>
00046 #include <pr2_controllers_msgs/Pr2GripperCommandAction.h>
00047 #include <algorithm>
00048 #include <map>
00049
00050 namespace pr2_moveit_controller_manager
00051 {
00052
00053 static const double DEFAULT_MAX_GRIPPER_EFFORT = 10000.0;
00054 static const double GRIPPER_OPEN = 0.086;
00055 static const double GRIPPER_CLOSED = 0.0;
00056
00057 template<typename T>
00058 class ActionBasedControllerHandle : public moveit_controller_manager::MoveItControllerHandle
00059 {
00060 public:
00061 ActionBasedControllerHandle(const std::string &name, const std::string &ns) :
00062 moveit_controller_manager::MoveItControllerHandle(name),
00063 namespace_(ns),
00064 done_(true)
00065 {
00066 controller_action_client_.reset(new actionlib::SimpleActionClient<T>(name_ +"/" + namespace_, true));
00067 unsigned int attempts = 0;
00068 while (ros::ok() && !controller_action_client_->waitForServer(ros::Duration(5.0)) && ++attempts < 3)
00069 ROS_INFO_STREAM("Waiting for " << name_ + "/" + namespace_ << " to come up");
00070
00071 if (!controller_action_client_->isServerConnected())
00072 {
00073 ROS_ERROR_STREAM("Action client not connected: " << name_ + "/" + namespace_);
00074 controller_action_client_.reset();
00075 }
00076
00077 last_exec_ = moveit_controller_manager::ExecutionStatus::SUCCEEDED;
00078 }
00079
00080 bool isConnected() const
00081 {
00082 return controller_action_client_;
00083 }
00084
00085 virtual bool cancelExecution()
00086 {
00087 if (!controller_action_client_)
00088 return false;
00089 if (!done_)
00090 {
00091 ROS_INFO_STREAM("Cancelling execution for " << name_);
00092 controller_action_client_->cancelGoal();
00093 last_exec_ = moveit_controller_manager::ExecutionStatus::PREEMPTED;
00094 done_ = true;
00095 }
00096 return true;
00097 }
00098
00099 virtual bool waitForExecution(const ros::Duration &timeout = ros::Duration(0))
00100 {
00101 if (controller_action_client_ && !done_)
00102 return controller_action_client_->waitForResult(timeout);
00103 return true;
00104 }
00105
00106 virtual moveit_controller_manager::ExecutionStatus getLastExecutionStatus()
00107 {
00108 return last_exec_;
00109 }
00110
00111 protected:
00112
00113 void finishControllerExecution(const actionlib::SimpleClientGoalState& state)
00114 {
00115 ROS_DEBUG_STREAM("Controller " << name_ << " is done with state " << state.toString() << ": " << state.getText());
00116 if (state == actionlib::SimpleClientGoalState::SUCCEEDED)
00117 last_exec_ = moveit_controller_manager::ExecutionStatus::SUCCEEDED;
00118 else
00119 if (state == actionlib::SimpleClientGoalState::ABORTED)
00120 last_exec_ = moveit_controller_manager::ExecutionStatus::ABORTED;
00121 else
00122 if (state == actionlib::SimpleClientGoalState::PREEMPTED)
00123 last_exec_ = moveit_controller_manager::ExecutionStatus::PREEMPTED;
00124 else
00125 last_exec_ = moveit_controller_manager::ExecutionStatus::FAILED;
00126 done_ = true;
00127 }
00128
00129 moveit_controller_manager::ExecutionStatus last_exec_;
00130 std::string namespace_;
00131 bool done_;
00132 boost::shared_ptr<actionlib::SimpleActionClient<T> > controller_action_client_;
00133 };
00134
00135 class Pr2GripperControllerHandle : public ActionBasedControllerHandle<pr2_controllers_msgs::Pr2GripperCommandAction>
00136 {
00137 public:
00138 Pr2GripperControllerHandle(const std::string &name, const std::string &ns = "gripper_action") :
00139 ActionBasedControllerHandle<pr2_controllers_msgs::Pr2GripperCommandAction>(name, ns),
00140 closing_(false)
00141 {
00142 }
00143
00144 virtual bool sendTrajectory(const moveit_msgs::RobotTrajectory &trajectory)
00145 {
00146 if (!controller_action_client_)
00147 return false;
00148 if (!trajectory.multi_dof_joint_trajectory.points.empty())
00149 {
00150 ROS_ERROR("The PR2 gripper controller cannot execute multi-dof trajectories.");
00151 return false;
00152 }
00153
00154 if (trajectory.joint_trajectory.points.back().positions.empty())
00155 {
00156 ROS_ERROR("The PR2 gripper controller expects a joint trajectory with one point that specifies at least one position, but 0 positions provided)");
00157 return false;
00158 }
00159
00160 if (trajectory.joint_trajectory.points.size() > 1)
00161 ROS_DEBUG("The PR2 gripper controller expects a joint trajectory with one point only, but %u provided. Using last point only.", (unsigned int)trajectory.joint_trajectory.points.size());
00162
00163 pr2_controllers_msgs::Pr2GripperCommandGoal goal;
00164 goal.command.max_effort = DEFAULT_MAX_GRIPPER_EFFORT;
00165
00166 bool open = false;
00167 for (std::size_t i = 0 ; i < trajectory.joint_trajectory.points.back().positions.size() ; ++i)
00168 if (trajectory.joint_trajectory.points.back().positions[i] > 0.5)
00169 {
00170 open = true;
00171 break;
00172 }
00173
00174 if (open)
00175 {
00176 goal.command.position = GRIPPER_OPEN;
00177 closing_ = false;
00178 ROS_DEBUG_STREAM("Sending gripper open command");
00179 }
00180 else
00181 {
00182 goal.command.position = GRIPPER_CLOSED;
00183 closing_ = true;
00184 ROS_DEBUG_STREAM("Sending gripper close command");
00185 }
00186
00187 controller_action_client_->sendGoal(goal,
00188 boost::bind(&Pr2GripperControllerHandle::controllerDoneCallback, this, _1, _2),
00189 boost::bind(&Pr2GripperControllerHandle::controllerActiveCallback, this),
00190 boost::bind(&Pr2GripperControllerHandle::controllerFeedbackCallback, this, _1));
00191 done_ = false;
00192 last_exec_ = moveit_controller_manager::ExecutionStatus::RUNNING;
00193 return true;
00194 }
00195
00196 private:
00197
00198 void controllerDoneCallback(const actionlib::SimpleClientGoalState& state,
00199 const pr2_controllers_msgs::Pr2GripperCommandResultConstPtr& result)
00200 {
00201
00202 if (state == actionlib::SimpleClientGoalState::ABORTED && closing_)
00203 finishControllerExecution(actionlib::SimpleClientGoalState::SUCCEEDED);
00204 else
00205 finishControllerExecution(state);
00206 }
00207
00208 void controllerActiveCallback()
00209 {
00210 ROS_DEBUG_STREAM("Controller " << name_ << " started execution");
00211 }
00212
00213 void controllerFeedbackCallback(const pr2_controllers_msgs::Pr2GripperCommandFeedbackConstPtr& feedback)
00214 {
00215 }
00216
00217 bool closing_;
00218 };
00219
00220 class Pr2FollowJointTrajectoryControllerHandle : public ActionBasedControllerHandle<control_msgs::FollowJointTrajectoryAction>
00221 {
00222 public:
00223
00224 Pr2FollowJointTrajectoryControllerHandle(const std::string &name, const std::string &ns = "follow_joint_trajectory") :
00225 ActionBasedControllerHandle<control_msgs::FollowJointTrajectoryAction>(name, ns)
00226 {
00227 }
00228
00229 virtual bool sendTrajectory(const moveit_msgs::RobotTrajectory &trajectory)
00230 {
00231 if (!controller_action_client_)
00232 return false;
00233 if (!trajectory.multi_dof_joint_trajectory.points.empty())
00234 {
00235 ROS_ERROR("The PR2 FollowJointTrajectory controller cannot execute multi-dof trajectories.");
00236 return false;
00237 }
00238 if (done_)
00239 ROS_DEBUG_STREAM("Sending trajectory to FollowJointTrajectory action for controller " << name_);
00240 else
00241 ROS_DEBUG_STREAM("Sending continuation for the currently executed trajectory to FollowJointTrajectory action for controller " << name_);
00242 control_msgs::FollowJointTrajectoryGoal goal;
00243 goal.trajectory = trajectory.joint_trajectory;
00244 controller_action_client_->sendGoal(goal,
00245 boost::bind(&Pr2FollowJointTrajectoryControllerHandle::controllerDoneCallback, this, _1, _2),
00246 boost::bind(&Pr2FollowJointTrajectoryControllerHandle::controllerActiveCallback, this),
00247 boost::bind(&Pr2FollowJointTrajectoryControllerHandle::controllerFeedbackCallback, this, _1));
00248 done_ = false;
00249 last_exec_ = moveit_controller_manager::ExecutionStatus::RUNNING;
00250 return true;
00251 }
00252
00253 protected:
00254
00255 void controllerDoneCallback(const actionlib::SimpleClientGoalState& state,
00256 const control_msgs::FollowJointTrajectoryResultConstPtr& result)
00257 {
00258 finishControllerExecution(state);
00259 }
00260
00261 void controllerActiveCallback()
00262 {
00263 ROS_DEBUG_STREAM("Controller " << name_ << " started execution");
00264 }
00265
00266 void controllerFeedbackCallback(const control_msgs::FollowJointTrajectoryFeedbackConstPtr& feedback)
00267 {
00268 }
00269 };
00270
00271 class Pr2MoveItControllerManager : public moveit_controller_manager::MoveItControllerManager
00272 {
00273 public:
00274
00275 Pr2MoveItControllerManager() : node_handle_("~")
00276 {
00277 if (node_handle_.hasParam("controller_manager_name"))
00278 node_handle_.getParam("controller_manager_name", controller_manager_name_);
00279 if (controller_manager_name_.empty())
00280 node_handle_.param("pr2_controller_manager_name", controller_manager_name_, std::string("pr2_controller_manager"));
00281 if (node_handle_.hasParam("use_controller_manager"))
00282 node_handle_.param("use_controller_manager", use_controller_manager_, true);
00283 else
00284 node_handle_.param("use_pr2_controller_manager", use_controller_manager_, true);
00285
00286 XmlRpc::XmlRpcValue controller_list;
00287 if (node_handle_.hasParam("controller_list"))
00288 {
00289 node_handle_.getParam("controller_list", controller_list);
00290 if (controller_list.getType() != XmlRpc::XmlRpcValue::TypeArray)
00291 ROS_WARN("Controller list should be specified as an array");
00292 else
00293 for (int i = 0 ; i < controller_list.size() ; ++i)
00294 if (!controller_list[i].hasMember("name") || !controller_list[i].hasMember("joints"))
00295 ROS_WARN("Name and joints must be specifed for each controller");
00296 else
00297 {
00298 try
00299 {
00300 ControllerInformation ci;
00301 std::string name = std::string(controller_list[i]["name"]);
00302 if (controller_list[i].hasMember("default"))
00303 {
00304 try
00305 {
00306 if (controller_list[i]["default"].getType() == XmlRpc::XmlRpcValue::TypeBoolean)
00307 {
00308 ci.default_ = controller_list[i]["default"];
00309 }
00310 else
00311 {
00312 std::string def = std::string(controller_list[i]["default"]);
00313 std::transform(def.begin(), def.end(), def.begin(), ::tolower);
00314 if (def == "true" || def == "yes")
00315 ci.default_ = true;
00316 }
00317 }
00318 catch (...)
00319 {
00320 }
00321 }
00322
00323 if (controller_list[i].hasMember("ns"))
00324 ci.ns_ = std::string(controller_list[i]["ns"]);
00325 if (controller_list[i].hasMember("action_ns"))
00326 ci.ns_ = std::string(controller_list[i]["action_ns"]);
00327 if (controller_list[i]["joints"].getType() == XmlRpc::XmlRpcValue::TypeArray)
00328 {
00329 int nj = controller_list[i]["joints"].size();
00330 for (int j = 0 ; j < nj ; ++j)
00331 ci.joints_.push_back(std::string(controller_list[i]["joints"][j]));
00332 }
00333 else
00334 ROS_WARN_STREAM("The list of joints for controller " << name << " is not specified as an array");
00335 if (!ci.joints_.empty())
00336 possibly_unloaded_controllers_[name] = ci;
00337 }
00338 catch (...)
00339 {
00340 ROS_ERROR("Unable to parse controller information");
00341 }
00342 }
00343 }
00344 else
00345 {
00346 if (use_controller_manager_)
00347 ROS_DEBUG_STREAM("No controller list specified. Using list obtained from the " << controller_manager_name_);
00348 else
00349 ROS_ERROR_STREAM("Not using a controller manager and no controllers specified. There are no known controllers.");
00350 }
00351
00352 if (use_controller_manager_)
00353 {
00354 static const unsigned int max_attempts = 5;
00355 unsigned int attempts = 0;
00356 while (ros::ok() && !ros::service::waitForService(controller_manager_name_ + "/list_controllers", ros::Duration(5.0)) && ++attempts < max_attempts)
00357 ROS_INFO_STREAM("Waiting for service " << controller_manager_name_ + "/list_controllers" << " to come up");
00358
00359 if (attempts < max_attempts)
00360 while (ros::ok() && !ros::service::waitForService(controller_manager_name_ + "/switch_controller", ros::Duration(5.0)) && ++attempts < max_attempts)
00361 ROS_INFO_STREAM("Waiting for service " << controller_manager_name_ + "/switch_controller" << " to come up");
00362
00363 if (attempts < max_attempts)
00364 while (ros::ok() && !ros::service::waitForService(controller_manager_name_ + "/load_controller", ros::Duration(5.0)) && ++attempts < max_attempts)
00365 ROS_INFO_STREAM("Waiting for service " << controller_manager_name_ + "/load_controller" << " to come up");
00366
00367 if (attempts < max_attempts)
00368 {
00369 lister_service_ = root_node_handle_.serviceClient<pr2_mechanism_msgs::ListControllers>(controller_manager_name_ + "/list_controllers", true);
00370 switcher_service_ = root_node_handle_.serviceClient<pr2_mechanism_msgs::SwitchController>(controller_manager_name_ + "/switch_controller", true);
00371 loader_service_ = root_node_handle_.serviceClient<pr2_mechanism_msgs::LoadController>(controller_manager_name_ + "/load_controller", true);
00372 }
00373 else
00374 ROS_ERROR("Not using the PR2 controller manager");
00375 }
00376 }
00377
00378 virtual ~Pr2MoveItControllerManager()
00379 {
00380 }
00381
00382 virtual moveit_controller_manager::MoveItControllerHandlePtr getControllerHandle(const std::string &name)
00383 {
00384 std::map<std::string, moveit_controller_manager::MoveItControllerHandlePtr>::const_iterator it = handle_cache_.find(name);
00385 if (it != handle_cache_.end())
00386 return it->second;
00387
00388 moveit_controller_manager::MoveItControllerHandlePtr new_handle;
00389 if (possibly_unloaded_controllers_.find(name) != possibly_unloaded_controllers_.end())
00390 {
00391 const std::string &ns = possibly_unloaded_controllers_.at(name).ns_;
00392 new_handle = getControllerHandleHelper(name, ns);
00393 }
00394 else
00395 new_handle = getControllerHandleHelper(name, "");
00396
00397 if (new_handle)
00398 handle_cache_[name] = new_handle;
00399 return new_handle;
00400 }
00401
00402 virtual void getControllersList(std::vector<std::string> &names)
00403 {
00404 const pr2_mechanism_msgs::ListControllers::Response &res = getListControllerServiceResponse();
00405 std::set<std::string> names_set;
00406 names_set.insert(res.controllers.begin(), res.controllers.end());
00407
00408 for (std::map<std::string, ControllerInformation>::const_iterator it = possibly_unloaded_controllers_.begin() ; it != possibly_unloaded_controllers_.end() ; ++it)
00409 names_set.insert(it->first);
00410
00411 names.clear();
00412 names.insert(names.end(), names_set.begin(), names_set.end());
00413 }
00414
00415 virtual void getActiveControllers(std::vector<std::string> &names)
00416 {
00417 names.clear();
00418 if (use_controller_manager_)
00419 {
00420 const pr2_mechanism_msgs::ListControllers::Response &res = getListControllerServiceResponse();
00421 for (std::size_t i = 0; i < res.controllers.size(); ++i)
00422 if (res.state[i] == "running")
00423 names.push_back(res.controllers[i]);
00424 }
00425 else
00426
00427 for (std::map<std::string, ControllerInformation>::const_iterator it = possibly_unloaded_controllers_.begin() ; it != possibly_unloaded_controllers_.end() ; ++it)
00428 names.push_back(it->first);
00429 }
00430
00431 virtual void getControllerJoints(const std::string &name, std::vector<std::string> &joints)
00432 {
00433 std::map<std::string, ControllerInformation>::const_iterator it = possibly_unloaded_controllers_.find(name);
00434 if (it != possibly_unloaded_controllers_.end())
00435 joints = it->second.joints_;
00436 else
00437 {
00438 joints.clear();
00439 std::string param_name;
00440 if (node_handle_.searchParam(name + "/joints", param_name))
00441 {
00442 XmlRpc::XmlRpcValue joints_list;
00443 node_handle_.getParam(param_name, joints_list);
00444 if (joints_list.getType() == XmlRpc::XmlRpcValue::TypeArray)
00445 for (int i = 0 ; i < joints_list.size() ; ++i)
00446 joints.push_back((std::string)joints_list[i]);
00447 }
00448 else
00449 if (node_handle_.searchParam(name + "/joint", param_name))
00450 {
00451 std::string joint_name;
00452 if (node_handle_.getParam(param_name, joint_name))
00453 joints.push_back(joint_name);
00454 }
00455 if (joints.empty())
00456 ROS_INFO("The joints for controller '%s' are not known and were not found on the ROS param server under '%s/joints'or '%s/joint'. "
00457 "Perhaps the controller configuration is not loaded on the param server?", name.c_str(), name.c_str(), name.c_str());
00458 ControllerInformation &ci = possibly_unloaded_controllers_[name];
00459 ci.joints_ = joints;
00460 }
00461 }
00462
00463 virtual moveit_controller_manager::MoveItControllerManager::ControllerState getControllerState(const std::string &name)
00464 {
00465 moveit_controller_manager::MoveItControllerManager::ControllerState state;
00466 if (use_controller_manager_)
00467 {
00468 const pr2_mechanism_msgs::ListControllers::Response &res = getListControllerServiceResponse();
00469 for (std::size_t i = 0; i < res.controllers.size(); ++i)
00470 {
00471 if (res.controllers[i] == name)
00472 {
00473 if (res.state[i] == "running")
00474 state.active_ = true;
00475 break;
00476 }
00477 }
00478 }
00479 else
00480 {
00481
00482 state.active_ = true;
00483 }
00484
00485 std::map<std::string, ControllerInformation>::const_iterator it = possibly_unloaded_controllers_.find(name);
00486 if (it != possibly_unloaded_controllers_.end())
00487 if (it->second.default_)
00488 state.default_ = true;
00489 return state;
00490 }
00491
00492 virtual bool switchControllers(const std::vector<std::string> &activate, const std::vector<std::string> &deactivate)
00493 {
00494 if (!use_controller_manager_)
00495 {
00496 ROS_WARN_STREAM("Cannot switch controllers without using the controller manager");
00497 return false;
00498 }
00499
00500 if (!activate.empty())
00501 {
00502
00503 const std::vector<std::string> &loaded_c = getListControllerServiceResponse().controllers;
00504 std::set<std::string> loaded_c_set(loaded_c.begin(), loaded_c.end());
00505 for (std::size_t i = 0 ; i < activate.size() ; ++i)
00506 if (loaded_c_set.find(activate[i]) == loaded_c_set.end())
00507 {
00508 handle_cache_.erase(activate[i]);
00509 pr2_mechanism_msgs::LoadController::Request req;
00510 pr2_mechanism_msgs::LoadController::Response res;
00511 req.name = activate[i];
00512 if (!loader_service_.call(req, res))
00513 {
00514 ROS_WARN("Something went wrong with loader service while trying to load '%s'", req.name.c_str());
00515 return false;
00516 }
00517 if (!res.ok)
00518 {
00519 ROS_WARN("Loading controller '%s' failed", req.name.c_str());
00520 return false;
00521 }
00522 }
00523 }
00524
00525 last_lister_response_ = ros::Time();
00526 pr2_mechanism_msgs::SwitchController::Request req;
00527 pr2_mechanism_msgs::SwitchController::Response res;
00528
00529 req.strictness = pr2_mechanism_msgs::SwitchController::Request::BEST_EFFORT;
00530 req.start_controllers = activate;
00531 req.stop_controllers = deactivate;
00532 if (!switcher_service_.call(req, res))
00533 {
00534 ROS_WARN_STREAM("Something went wrong with switcher service");
00535 return false;
00536 }
00537 if (!res.ok)
00538 ROS_WARN_STREAM("Switcher service failed");
00539 return res.ok;
00540 }
00541
00542 protected:
00543
00544 const pr2_mechanism_msgs::ListControllers::Response &getListControllerServiceResponse()
00545 {
00546 if (use_controller_manager_)
00547 {
00548 static const ros::Duration max_cache_age(1.0);
00549 if ((ros::Time::now() - last_lister_response_) > max_cache_age)
00550 {
00551 pr2_mechanism_msgs::ListControllers::Request req;
00552 if (!lister_service_.call(req, cached_lister_response_))
00553 ROS_WARN_STREAM("Something went wrong with lister service");
00554 last_lister_response_ = ros::Time::now();
00555 }
00556 }
00557 return cached_lister_response_;
00558 }
00559
00560 moveit_controller_manager::MoveItControllerHandlePtr getControllerHandleHelper(const std::string &name, const std::string &ns)
00561 {
00562 moveit_controller_manager::MoveItControllerHandlePtr new_handle;
00563 if (name == "l_gripper_controller" || name == "r_gripper_controller")
00564 {
00565 new_handle.reset(ns.empty() ? new Pr2GripperControllerHandle(name) : new Pr2GripperControllerHandle(name, ns));
00566 if (!static_cast<Pr2GripperControllerHandle*>(new_handle.get())->isConnected())
00567 new_handle.reset();
00568 }
00569 else
00570 {
00571 new_handle.reset(ns.empty() ? new Pr2FollowJointTrajectoryControllerHandle(name) : new Pr2FollowJointTrajectoryControllerHandle(name, ns));
00572 if (!static_cast<Pr2FollowJointTrajectoryControllerHandle*>(new_handle.get())->isConnected())
00573 new_handle.reset();
00574 }
00575 return new_handle;
00576 }
00577
00578 ros::NodeHandle node_handle_;
00579 ros::NodeHandle root_node_handle_;
00580
00581 std::string controller_manager_name_;
00582 bool use_controller_manager_;
00583 ros::ServiceClient loader_service_;
00584 ros::ServiceClient switcher_service_;
00585 ros::ServiceClient lister_service_;
00586
00587 ros::Time last_lister_response_;
00588 pr2_mechanism_msgs::ListControllers::Response cached_lister_response_;
00589
00590 std::map<std::string, moveit_controller_manager::MoveItControllerHandlePtr> handle_cache_;
00591
00592 struct ControllerInformation
00593 {
00594 ControllerInformation() : default_(false)
00595 {
00596 }
00597
00598 bool default_;
00599 std::string ns_;
00600 std::vector<std::string> joints_;
00601 };
00602 std::map<std::string, ControllerInformation> possibly_unloaded_controllers_;
00603 };
00604
00605 }
00606
00607 PLUGINLIB_EXPORT_CLASS(pr2_moveit_controller_manager::Pr2MoveItControllerManager,
00608 moveit_controller_manager::MoveItControllerManager);