play_motion_server.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Modified BSD License)
00003  *
00004  *  Copyright (c) 2013, PAL Robotics, S.L.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of PAL Robotics, S.L. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
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(); //should not be needed
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(); //XXX: can this fail? should we check it?
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 }


play_motion
Author(s): Paul Mathieu , Adolfo Rodriguez Tsouroukdissian
autogenerated on Sat Jun 8 2019 20:26:22