00001 //================================================================================================= 00002 // Copyright (c) 2017, 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 00064 StepController(ros::NodeHandle& nh, bool auto_spin = true); 00065 virtual ~StepController(); 00066 00073 template<typename T> 00074 void loadPlugin(const std::string& plugin_name, boost::shared_ptr<T>& plugin) 00075 { 00076 boost::unique_lock<boost::shared_mutex> lock(controller_mutex_); 00077 00078 if (step_controller_plugin_ && step_controller_plugin_->getState() == ACTIVE) 00079 { 00080 ROS_ERROR("[StepController] Cannot replace plugin due to active footstep execution!"); 00081 return; 00082 } 00083 00084 if (!vigir_pluginlib::PluginManager::addPluginByName(plugin_name)) 00085 { 00086 ROS_ERROR("[StepController] Could not load plugin '%s'!", plugin_name.c_str()); 00087 return; 00088 } 00089 else if (!vigir_pluginlib::PluginManager::getPlugin(plugin)) 00090 { 00091 ROS_ERROR("[StepController] Could not obtain plugin '%s' from plugin manager!", plugin_name.c_str()); 00092 return; 00093 } 00094 else 00095 ROS_INFO("[StepController] Loaded plugin '%s'.", plugin_name.c_str()); 00096 } 00097 00103 void executeStepPlan(const msgs::StepPlan& step_plan); 00104 00108 void update(const ros::TimerEvent& event = ros::TimerEvent()); 00109 00110 protected: 00114 void publishFeedback() const; 00115 00116 vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin_; 00117 StepControllerPlugin::Ptr step_controller_plugin_; 00118 00119 // mutex to ensure thread safeness 00120 boost::shared_mutex controller_mutex_; 00121 00123 00124 // subscriber 00125 void loadStepPlanMsgPlugin(const std_msgs::StringConstPtr& plugin_name); 00126 void loadStepControllerPlugin(const std_msgs::StringConstPtr& plugin_name); 00127 void executeStepPlan(const msgs::StepPlanConstPtr& step_plan); 00128 00129 // action server calls 00130 void executeStepPlanAction(ExecuteStepPlanActionServerPtr& as); 00131 void executePreemptionAction(ExecuteStepPlanActionServerPtr& as); 00132 00133 // subscriber 00134 ros::Subscriber load_step_plan_msg_plugin_sub_; 00135 ros::Subscriber load_step_controller_plugin_sub_; 00136 ros::Subscriber execute_step_plan_sub_; 00137 00138 // publisher 00139 ros::Publisher planning_feedback_pub_; 00140 00141 // action servers 00142 boost::shared_ptr<ExecuteStepPlanActionServer> execute_step_plan_as_; 00143 00144 // timer for updating periodically 00145 ros::Timer update_timer_; 00146 }; 00147 } 00148 00149 #endif