00001 //================================================================================================= 00002 // Copyright (c) 2018, Alexander Stumpf, TU Darmstadt 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 // * Redistributions of source code must retain the above copyright 00008 // notice, this list of conditions and the following disclaimer. 00009 // * Redistributions in binary form must reproduce the above copyright 00010 // notice, this list of conditions and the following disclaimer in the 00011 // documentation and/or other materials provided with the distribution. 00012 // * Neither the name of the Simulation, Systems Optimization and Robotics 00013 // group, TU Darmstadt nor the names of its contributors may be used to 00014 // endorse or promote products derived from this software without 00015 // specific prior written permission. 00016 00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THIS 00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00027 //================================================================================================= 00028 00029 #ifndef STEP_CONTROLLER_H__ 00030 #define STEP_CONTROLLER_H__ 00031 00032 #include <ros/ros.h> 00033 00034 #include <actionlib/server/simple_action_server.h> 00035 00036 #include <vigir_pluginlib/plugin_manager.h> 00037 00038 #include <vigir_footstep_planning_msgs/footstep_planning_msgs.h> 00039 #include <vigir_footstep_planning_plugins/plugins/step_plan_msg_plugin.h> 00040 00041 #include <vigir_step_control/step_controller_plugin.h> 00042 00043 00044 00045 namespace vigir_step_control 00046 { 00047 using namespace vigir_footstep_planning_msgs; 00048 00049 typedef actionlib::SimpleActionServer<msgs::ExecuteStepPlanAction> ExecuteStepPlanActionServer; 00050 typedef boost::shared_ptr<ExecuteStepPlanActionServer> ExecuteStepPlanActionServerPtr; 00051 00052 class StepController 00053 { 00054 public: 00055 // typedefs 00056 typedef boost::shared_ptr<StepController> Ptr; 00057 typedef boost::shared_ptr<const StepController> ConstPtr; 00058 00063 StepController(ros::NodeHandle& nh); 00064 virtual ~StepController(); 00065 00072 bool initialize(ros::NodeHandle& nh, bool auto_spin = true); 00073 00082 bool initialize(ros::NodeHandle& nh, StepControllerPlugin::Ptr step_controller_plugin, vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin, bool auto_spin = true); 00083 00090 template<typename T> 00091 bool loadPlugin(const std::string& plugin_name, boost::shared_ptr<T>& plugin) 00092 { 00093 UniqueLock lock(controller_mutex_); 00094 00095 if (step_controller_plugin_ && step_controller_plugin_->getState() == ACTIVE) 00096 { 00097 ROS_ERROR("[StepController] Cannot replace plugin due to active footstep execution!"); 00098 return false; 00099 } 00100 00101 if (!vigir_pluginlib::PluginManager::addPluginByName(plugin_name)) 00102 { 00103 ROS_ERROR("[StepController] Could not load plugin '%s'!", plugin_name.c_str()); 00104 return false; 00105 } 00106 else if (!vigir_pluginlib::PluginManager::getPlugin(plugin)) 00107 { 00108 ROS_ERROR("[StepController] Could not obtain plugin '%s' from plugin manager!", plugin_name.c_str()); 00109 return false; 00110 } 00111 else 00112 ROS_INFO("[StepController] Loaded plugin '%s'.", plugin_name.c_str()); 00113 00114 return true; 00115 } 00116 00122 void executeStepPlan(const msgs::StepPlan& step_plan); 00123 00127 void update(const ros::TimerEvent& event = ros::TimerEvent()); 00128 00129 protected: 00133 void publishFeedback() const; 00134 00135 StepControllerPlugin::Ptr step_controller_plugin_; 00136 vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin_; 00137 00138 // mutex to ensure thread safeness 00139 boost::shared_mutex controller_mutex_; 00140 00142 00143 // subscriber 00144 void loadStepPlanMsgPlugin(const std_msgs::StringConstPtr& plugin_name); 00145 void loadStepControllerPlugin(const std_msgs::StringConstPtr& plugin_name); 00146 void executeStepPlan(const msgs::StepPlanConstPtr& step_plan); 00147 00148 // action server calls 00149 void executeStepPlanAction(ExecuteStepPlanActionServerPtr as); 00150 void executePreemptionAction(ExecuteStepPlanActionServerPtr as); 00151 00152 // subscriber 00153 ros::Subscriber load_step_plan_msg_plugin_sub_; 00154 ros::Subscriber load_step_controller_plugin_sub_; 00155 ros::Subscriber execute_step_plan_sub_; 00156 00157 // publisher 00158 ros::Publisher feedback_pub_; 00159 00160 // action servers 00161 boost::shared_ptr<ExecuteStepPlanActionServer> execute_step_plan_as_; 00162 00163 // timer for updating periodically 00164 ros::Timer update_timer_; 00165 }; 00166 } 00167 00168 #endif