controller_manager.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2014-2015, Fetch Robotics Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Fetch Robotics Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL FETCH ROBOTICS INC. BE LIABLE FOR ANY
00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 // Author: Michael Ferguson
00030 
00031 #include <sstream>
00032 #include <robot_controllers_interface/controller_manager.h>
00033 
00034 namespace robot_controllers
00035 {
00036 
00037 ControllerManager::ControllerManager()
00038 {
00039 }
00040 
00041 int ControllerManager::init(ros::NodeHandle& nh)
00042 {
00043   // Find and load default controllers
00044   XmlRpc::XmlRpcValue controller_params;
00045   if (nh.getParam("default_controllers", controller_params))
00046   {
00047     if (controller_params.getType() != XmlRpc::XmlRpcValue::TypeArray)
00048     {
00049       ROS_ERROR_NAMED("ControllerManager", "Parameter 'default_controllers' should be a list.");
00050       return -1;
00051     }
00052     else
00053     {
00054       // Load each controller
00055       for (int c = 0; c < controller_params.size(); c++)
00056       {
00057         // Make sure name is valid
00058         XmlRpc::XmlRpcValue &controller_name = controller_params[c];
00059         if (controller_name.getType() != XmlRpc::XmlRpcValue::TypeString)
00060         {
00061           ROS_WARN_NAMED("ControllerManager", "Controller name is not a string?");
00062           continue;
00063         }
00064 
00065         // Create controller (in a loader)
00066         load(static_cast<std::string>(controller_name));
00067       }
00068     }
00069   }
00070   else
00071   {
00072     ROS_WARN_NAMED("ControllerManager", "No controllers loaded.");
00073     return -1;
00074   }
00075 
00076   // Setup actionlib server
00077   server_.reset(new server_t(nh, "/query_controller_states",
00078                              boost::bind(&ControllerManager::execute, this, _1),
00079                              false));
00080   server_->start();
00081 
00082   return 0;
00083 }
00084 
00085 int ControllerManager::requestStart(const std::string& name)
00086 {
00087   // Find requested controller
00088   ControllerLoaderPtr controller;
00089   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00090   {
00091     if ((*c)->getController()->getName() == name)
00092     {
00093       controller = *c;
00094       break;
00095     }
00096   }
00097 
00098   // Does controller exist?
00099   if (!controller)
00100   {
00101     ROS_ERROR_STREAM_NAMED("ControllerManager", "Unable to start " << name.c_str() << ": no such controller.");
00102     return -1;
00103   }
00104 
00105   // Is controller already running?
00106   if (controller->isActive())
00107   {
00108     ROS_DEBUG_STREAM_NAMED("ControllerManager", "Unable to start " << name.c_str() << ": already running.");
00109     return 0;
00110   }
00111 
00112   // Check for conflicts
00113   std::vector<std::string> names = controller->getController()->getCommandedNames();
00114   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00115   {
00116     // Only care about active controllers
00117     if (!(*c)->isActive())
00118       continue;
00119 
00120     std::vector<std::string> names2 = (*c)->getController()->getClaimedNames();
00121     bool conflict = false;
00122     for (size_t i = 0; i < names.size(); i++)
00123     {
00124       for (size_t i2 = 0; i2 < names2.size(); i2++)
00125       {
00126         if (names[i] == names2[i2])
00127         {
00128           conflict = true;
00129           break;
00130         }
00131       }
00132       if (conflict) break;
00133     }
00134     // Have conflict, try to stop controller (without force)
00135     if (conflict)
00136     {
00137       if ((*c)->stop(false))
00138       {
00139         ROS_INFO_STREAM_NAMED("ControllerManager", "Stopped " << (*c)->getController()->getName().c_str());
00140       }
00141       else
00142       {
00143         // Unable to stop c, cannot start controller
00144         ROS_ERROR_STREAM_NAMED("ControllerManager", "Unable to stop " <<
00145                                                     (*c)->getController()->getName().c_str() <<
00146                                                     " when trying to start " << name.c_str());
00147         return -1;
00148       }
00149     }
00150   }
00151 
00152   // Start controller
00153   if (controller->start())
00154   {
00155     ROS_INFO_STREAM_NAMED("ControllerManager", "Started " << controller->getController()->getName().c_str());
00156     return 0;
00157   }
00158 
00159   return -1;  // Unable to start
00160 }
00161 
00162 int ControllerManager::requestStop(const std::string& name)
00163 {
00164   // Find controller
00165   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00166   {
00167     if ((*c)->getController()->getName() == name)
00168     {
00169       // Stop controller (with force)
00170       if ((*c)->stop(true))
00171       {
00172         ROS_INFO_STREAM_NAMED("ControllerManager", "Stopped " << (*c)->getController()->getName().c_str());
00173         return 0;
00174       }
00175       else
00176       {
00177         return -1;  // controller decided not to stop
00178       }
00179     }
00180   }
00181   return -1;  // no such controller
00182 }
00183 
00184 void ControllerManager::update(const ros::Time& time, const ros::Duration& dt)
00185 {
00186   // Reset handles
00187   for (JointHandleList::iterator j = joints_.begin(); j != joints_.end(); j++)
00188     (*j)->reset();
00189 
00190   // Update controllers
00191   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00192   {
00193     (*c)->update(time, dt);
00194   }
00195 }
00196 
00197 void ControllerManager::reset()
00198 {
00199   // Update controllers
00200   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00201   {
00202     (*c)->reset();
00203   }
00204 }
00205 
00206 bool ControllerManager::addJointHandle(JointHandlePtr& j)
00207 {
00208   // TODO: check for duplicate names?
00209   joints_.push_back(j);
00210   return true;
00211 }
00212 
00213 HandlePtr ControllerManager::getHandle(const std::string& name)
00214 {
00215   // Try joints first
00216   for (JointHandleList::iterator j = joints_.begin(); j != joints_.end(); j++)
00217   {
00218     if ((*j)->getName() == name)
00219       return *j;
00220   }
00221 
00222   // Then controllers
00223   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00224   {
00225     if ((*c)->getController()->getName() == name)
00226       return (*c)->getController();
00227   }
00228 
00229   // Not found
00230   return HandlePtr();
00231 }
00232 
00233 JointHandlePtr ControllerManager::getJointHandle(const std::string& name)
00234 {
00235   // Try joints first
00236   for (JointHandleList::iterator j = joints_.begin(); j != joints_.end(); j++)
00237   {
00238     if ((*j)->getName() == name)
00239       return *j;
00240   }
00241 
00242   // Not found
00243   return JointHandlePtr();
00244 }
00245 
00246 void ControllerManager::execute(const robot_controllers_msgs::QueryControllerStatesGoalConstPtr& goal)
00247 {
00248   robot_controllers_msgs::QueryControllerStatesFeedback feedback;
00249   robot_controllers_msgs::QueryControllerStatesResult result;
00250 
00251   for (size_t i = 0; i < goal->updates.size(); i++)
00252   {
00253     // Update this controller
00254     robot_controllers_msgs::ControllerState state = goal->updates[i];
00255 
00256     // Make sure controller exists
00257     bool in_controller_list = false;
00258     for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00259     {
00260       if ((*c)->getController()->getName() == state.name)
00261       {
00262         if (state.type != "")
00263         {
00264           if (state.type == (*c)->getController()->getType())
00265           {
00266             in_controller_list = true;
00267             break;
00268           }
00269           else
00270           {
00271             std::stringstream ss;
00272             ss << "Controller " << state.name << " is of type " << (*c)->getController()->getType() << " not " << state.type;
00273             getState(result);
00274             server_->setAborted(result, ss.str());
00275             return;
00276           }
00277         }
00278         in_controller_list = true;
00279         break;
00280       }
00281     }
00282     if (!in_controller_list)
00283     {
00284       // Check if controller exists on parameter server
00285       ros::NodeHandle nh;
00286       if (nh.hasParam(state.name))
00287       { 
00288         // Create controller (in a loader)
00289         if (!load(static_cast<std::string>(state.name)))
00290         {
00291           std::stringstream ss;
00292           ss << "Failed to load controller: " << state.name;
00293           getState(result);
00294           server_->setAborted(result, ss.str());
00295           return;
00296         }
00297       }
00298       else
00299       {
00300         std::stringstream ss;
00301         ss << "No such controller to update: " << state.name;
00302         getState(result);
00303         server_->setAborted(result, ss.str());
00304         return;
00305       }
00306     }
00307 
00308     // Update state
00309     if (state.state == state.STOPPED)
00310     {
00311       if (requestStop(state.name) != 0)
00312       {
00313         std::stringstream ss;
00314         ss << "Unable to stop " << state.name;
00315         getState(result);
00316         server_->setAborted(result, ss.str());
00317         return;
00318       }
00319     }
00320     else if (state.state == state.RUNNING)
00321     {
00322       if (requestStart(state.name) != 0)
00323       {
00324         std::stringstream ss;
00325         ss << "Unable to start " << state.name;
00326         getState(result);
00327         server_->setAborted(result, ss.str());
00328         return;
00329       }
00330     }
00331     else
00332     {
00333       std::stringstream ss;
00334       ss << "Invalid state for controller " << state.name << ": " << static_cast<int>(state.state);
00335       getState(result);
00336       server_->setAborted(result, ss.str());
00337       return;
00338     }
00339   }
00340 
00341   // Send result
00342   getState(result);
00343   server_->setSucceeded(result);
00344 }
00345 
00346 void ControllerManager::getState(
00347     robot_controllers_msgs::QueryControllerStatesResult& result)
00348 {
00349   result.state.clear();
00350   for (ControllerList::iterator c = controllers_.begin(); c != controllers_.end(); c++)
00351   {
00352     robot_controllers_msgs::ControllerState state;
00353     state.name = (*c)->getController()->getName();
00354     state.type = (*c)->getController()->getType();
00355     if ((*c)->isActive())
00356     {
00357       state.state = state.RUNNING;
00358     }
00359     else
00360     {
00361       state.state = state.STOPPED;
00362     }
00363     result.state.push_back(state);
00364   }
00365 }
00366 
00367 // NOTE: this function should be called only by one thread
00368 bool ControllerManager::load(const std::string& name)
00369 {
00370   // Create controller (in a loader)
00371   ControllerLoaderPtr controller(new ControllerLoader());
00372   // Push back controller (so that autostart will work)
00373   controllers_.push_back(controller);
00374   // Now initialize controller
00375   if (!controller->init(name, this))
00376   {
00377     // Remove if init fails
00378     controllers_.pop_back();
00379     return false;
00380   }
00381   return true;
00382 }
00383 
00384 }  // namespace robot_controllers


robot_controllers_interface
Author(s): Michael Ferguson
autogenerated on Wed Jun 14 2017 04:09:05