Go to the documentation of this file.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
00037 #include "play_motion/play_motion_server.h"
00038
00039 #include <boost/foreach.hpp>
00040
00041 #include "play_motion/play_motion.h"
00042 #include "play_motion/play_motion_helpers.h"
00043 #include "play_motion/xmlrpc_helpers.h"
00044
00045 #include <diagnostic_msgs/DiagnosticArray.h>
00046 #include <diagnostic_updater/DiagnosticStatusWrapper.h>
00047
00048 #define foreach BOOST_FOREACH
00049
00050 namespace play_motion
00051 {
00052 PlayMotionServer::PlayMotionServer(const ros::NodeHandle& nh, const PlayMotionPtr& pm) :
00053 nh_(nh),
00054 pm_(pm),
00055 al_server_(nh_, "play_motion", false)
00056 {
00057 al_server_.registerGoalCallback(boost::bind(&PlayMotionServer::alGoalCb, this, _1));
00058 al_server_.registerCancelCallback(boost::bind(&PlayMotionServer::alCancelCb, this, _1));
00059 al_server_.start();
00060
00061 list_motions_srv_ = ros::NodeHandle("~").advertiseService("list_motions",
00062 &PlayMotionServer::listMotions,
00063 this);
00064
00065 diagnostic_pub_ = nh_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1);
00066 diagnostic_timer_ = nh_.createTimer(ros::Duration(1.0), &PlayMotionServer::publishDiagnostics,
00067 this);
00068 }
00069
00070 PlayMotionServer::~PlayMotionServer()
00071 {}
00072
00073 bool PlayMotionServer::findGoalId(AlServer::GoalHandle gh, PlayMotion::GoalHandle& goal_hdl)
00074 {
00075 typedef std::pair<PlayMotion::GoalHandle, AlServer::GoalHandle> goal_pair_t;
00076 foreach (const goal_pair_t& p, al_goals_)
00077 if (goal_hdl = p.first, p.second == gh)
00078 return true;
00079
00080 return false;
00081 }
00082
00083 void PlayMotionServer::playMotionCb(const PlayMotion::GoalHandle& goal_hdl)
00084 {
00085 PMR r;
00086 r.error_code = goal_hdl->error_code;
00087 r.error_string = goal_hdl->error_string;
00088
00089 if (r.error_code == PMR::SUCCEEDED)
00090 {
00091 ROS_INFO("Motion played successfully.");
00092 al_goals_[goal_hdl].setSucceeded(r);
00093 }
00094 else
00095 {
00096 if (r.error_code == 0)
00097 ROS_ERROR("Motion ended with INVALID ERROR code %d and description '%s'", r.error_code, r.error_string.c_str());
00098 else
00099 ROS_WARN("Motion ended with an error code %d and description '%s'", r.error_code, r.error_string.c_str());
00100 al_goals_[goal_hdl].setAborted(r);
00101 }
00102 al_goals_.erase(goal_hdl);
00103 }
00104
00105 void PlayMotionServer::alCancelCb(AlServer::GoalHandle gh)
00106 {
00107 PlayMotion::GoalHandle goal_hdl;
00108 if (findGoalId(gh, goal_hdl))
00109 goal_hdl->cancel();
00110 else
00111 ROS_ERROR("Cancel request could not be fulfilled. Goal not running?.");
00112
00113 al_goals_.erase(goal_hdl);
00114 gh.setCanceled();
00115 }
00116
00117 void PlayMotionServer::alGoalCb(AlServer::GoalHandle gh)
00118 {
00119 AlServer::GoalConstPtr goal = gh.getGoal();
00120 ROS_INFO_STREAM("Received request to play motion '" << goal->motion_name << "'.");
00121 PlayMotion::GoalHandle goal_hdl;
00122 if (!pm_->run(goal->motion_name,
00123 goal->skip_planning,
00124 goal_hdl,
00125 boost::bind(&PlayMotionServer::playMotionCb, this, _1)))
00126 {
00127 PMR r;
00128 r.error_code = goal_hdl->error_code;
00129 r.error_string = goal_hdl->error_string;
00130 if (!r.error_string.empty())
00131 ROS_ERROR_STREAM(r.error_string);
00132 ROS_ERROR_STREAM("Motion '" << goal->motion_name << "' could not be played.");
00133 gh.setRejected(r);
00134 return;
00135 }
00136 gh.setAccepted();
00137 al_goals_[goal_hdl] = gh;
00138 }
00139
00140 bool PlayMotionServer::listMotions(play_motion_msgs::ListMotions::Request& req,
00141 play_motion_msgs::ListMotions::Response& resp)
00142 {
00143 try
00144 {
00145 MotionNames motions;
00146 ros::NodeHandle pnh("~");
00147 getMotionIds(pnh, motions);
00148 foreach (const std::string& motion, motions)
00149 {
00150 play_motion_msgs::MotionInfo info;
00151 info.name = motion;
00152 getMotionJoints(pnh, motion, info.joints);
00153 getMotionDuration(pnh, motion);
00154 resp.motions.push_back(info);
00155 }
00156 }
00157 catch (const xh::XmlrpcHelperException& e)
00158 {
00159 ROS_ERROR_STREAM(e.what());
00160 return false;
00161 }
00162 return true;
00163 }
00164
00165 void PlayMotionServer::publishDiagnostics(const ros::TimerEvent &) const
00166 {
00167 diagnostic_msgs::DiagnosticArray array;
00168 diagnostic_updater::DiagnosticStatusWrapper status;
00169 status.name = "Functionality: Play Motion";
00170 for (std::map<PlayMotion::GoalHandle, AlServer::GoalHandle>::const_iterator it = al_goals_.begin();
00171 it != al_goals_.end(); ++it)
00172 {
00173 const AlServer::GoalHandle &hdl = it->second;
00174 status.add("Executing motion", hdl.getGoal()->motion_name);
00175 }
00176 if (al_goals_.empty())
00177 status.mergeSummary(diagnostic_msgs::DiagnosticStatus::OK, "Not executing any motion");
00178 else
00179 status.mergeSummary(diagnostic_msgs::DiagnosticStatus::OK, "Executing motions");
00180
00181 array.status.push_back(status);
00182 diagnostic_pub_.publish(array);
00183 }
00184 }