step_controller.cpp
Go to the documentation of this file.
00001 #include <vigir_step_control/step_controller.h>
00002 
00003 #include <vigir_generic_params/parameter_manager.h>
00004 
00005 
00006 
00007 namespace vigir_step_control
00008 {
00009 StepController::StepController(ros::NodeHandle& nh)
00010 {
00011   vigir_pluginlib::PluginManager::addPluginClassLoader<StepControllerPlugin>("vigir_step_control", "vigir_step_control::StepControllerPlugin");
00012   vigir_pluginlib::PluginManager::addPluginClassLoader<vigir_footstep_planning::StepPlanMsgPlugin>("vigir_footstep_planning_plugins", "vigir_footstep_planning::StepPlanMsgPlugin");
00013 
00014   // subscribe topics
00015   load_step_plan_msg_plugin_sub_ = nh.subscribe("load_step_plan_msg_plugin", 1, &StepController::loadStepPlanMsgPlugin, this);
00016   load_step_controller_plugin_sub_ = nh.subscribe("load_step_controller_plugin", 1, &StepController::loadStepControllerPlugin, this);
00017   execute_step_plan_sub_ = nh.subscribe("execute_step_plan", 1, &StepController::executeStepPlan, this);
00018 
00019   // publish topics
00020   feedback_pub_ = nh.advertise<msgs::ExecuteStepPlanFeedback>("execute_feedback", 1, true);
00021 
00022   // init action servers
00023   execute_step_plan_as_.reset(new ExecuteStepPlanActionServer(nh, "execute_step_plan", false));
00024   execute_step_plan_as_->registerGoalCallback(boost::bind(&StepController::executeStepPlanAction, this, boost::ref(execute_step_plan_as_)));
00025   execute_step_plan_as_->registerPreemptCallback(boost::bind(&StepController::executePreemptionAction, this, boost::ref(execute_step_plan_as_)));
00026 
00027   // start action servers
00028   execute_step_plan_as_->start();
00029 }
00030 
00031 StepController::~StepController()
00032 {
00033 }
00034 
00035 bool StepController::initialize(ros::NodeHandle& nh, bool auto_spin)
00036 {
00037   // init step controller plugin
00038   if (!loadPlugin(nh.param("step_controller_plugin", std::string("step_controller_plugin")), step_controller_plugin_))
00039     return false;
00040 
00041   // init step plan msg plugin
00042   if (!loadPlugin(nh.param("step_plan_msg_plugin", std::string("step_plan_msg_plugin")), step_plan_msg_plugin_))
00043     return false;
00044 
00045   return initialize(nh, step_controller_plugin_, step_plan_msg_plugin_, auto_spin);
00046 }
00047 
00048 bool StepController::initialize(ros::NodeHandle& nh, StepControllerPlugin::Ptr step_controller_plugin, vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin, bool auto_spin)
00049 {
00050   step_plan_msg_plugin_ = step_plan_msg_plugin;
00051   step_controller_plugin_ = step_controller_plugin;
00052 
00053   if (step_controller_plugin_)
00054     step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
00055 
00056   // schedule main update loop
00057   if (auto_spin)
00058     update_timer_ = nh.createTimer(nh.param("update_rate", 10.0), &StepController::update, this);
00059 
00060   return true;
00061 }
00062 
00063 void StepController::executeStepPlan(const msgs::StepPlan& step_plan)
00064 {
00065   UniqueLock lock(controller_mutex_);
00066 
00067   if (!step_controller_plugin_)
00068   {
00069     ROS_ERROR("[StepController] executeStepPlan: No step_controller_plugin available!");
00070     return;
00071   }
00072 
00073   // An empty step plan will always trigger a soft stop
00074   if (step_plan.steps.empty())
00075     step_controller_plugin_->stop();
00076   else
00077     step_controller_plugin_->updateStepPlan(step_plan);
00078 }
00079 
00080 void StepController::update(const ros::TimerEvent& event)
00081 {
00082   UniqueLock lock(controller_mutex_);
00083 
00084   if (!step_controller_plugin_)
00085   {
00086     ROS_ERROR_THROTTLE(5.0, "[StepController] update: No step_controller_plugin available!");
00087     return;
00088   }
00089 
00090   // Save current state to be able to handle action server correctly;
00091   // We must not send setSucceeded/setAborted state while sending the
00092   // final feedback message in the same update cycle!
00093   StepControllerState state = step_controller_plugin_->getState();
00094 
00095   // pre process
00096   step_controller_plugin_->preProcess(event);
00097 
00098   // process
00099   step_controller_plugin_->process(event);
00100 
00101   // post process
00102   step_controller_plugin_->postProcess(event);
00103 
00104   lock.unlock();
00105 
00106   // publish feedback
00107   publishFeedback();
00108 
00109   // update action server
00110   switch (state)
00111   {
00112     case FINISHED:
00113       if (execute_step_plan_as_->isActive())
00114       {
00115         msgs::ExecuteStepPlanResult result;
00116         result.controller_state = state;
00117         execute_step_plan_as_->setSucceeded(result);
00118       }
00119       break;
00120 
00121     case FAILED:
00122       if (execute_step_plan_as_->isActive())
00123       {
00124         msgs::ExecuteStepPlanResult result;
00125         result.controller_state = state;
00126         execute_step_plan_as_->setAborted(result);
00127       }
00128       break;
00129 
00130     default:
00131       break;
00132   }
00133 }
00134 
00135 void StepController::publishFeedback() const
00136 {
00137   if (step_controller_plugin_->getState() != READY)
00138   {
00139     const msgs::ExecuteStepPlanFeedback& feedback = step_controller_plugin_->getFeedbackState();
00140 
00141     // publish feedback
00142     feedback_pub_.publish(feedback);
00143 
00144     if (execute_step_plan_as_->isActive())
00145       execute_step_plan_as_->publishFeedback(feedback);
00146   }
00147 }
00148 
00149 // --- Subscriber calls ---
00150 
00151 void StepController::loadStepPlanMsgPlugin(const std_msgs::StringConstPtr& plugin_name)
00152 {
00153   loadPlugin(plugin_name->data, step_plan_msg_plugin_);
00154 
00155   if (step_controller_plugin_)
00156     step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
00157 }
00158 
00159 void StepController::loadStepControllerPlugin(const std_msgs::StringConstPtr& plugin_name)
00160 {
00161   loadPlugin(plugin_name->data, step_controller_plugin_);
00162 
00163   if (step_controller_plugin_)
00164     step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
00165 }
00166 
00167 void StepController::executeStepPlan(const msgs::StepPlanConstPtr& step_plan)
00168 {
00169   executeStepPlan(*step_plan);
00170 }
00171 
00172 //--- action server calls ---
00173 
00174 void StepController::executeStepPlanAction(ExecuteStepPlanActionServerPtr as)
00175 {
00176   const msgs::ExecuteStepPlanGoalConstPtr& goal(as->acceptNewGoal());
00177 
00178   // check if new goal was preempted in the meantime
00179   if (as->isPreemptRequested())
00180   {
00181     as->setPreempted();
00182     return;
00183   }
00184 
00185   executeStepPlan(goal->step_plan);
00186 }
00187 
00188 void StepController::executePreemptionAction(ExecuteStepPlanActionServerPtr as)
00189 {
00190   if (as->isActive())
00191     as->setPreempted();
00192 
00193   //step_controller_plugin->stop();
00194 }
00195 } // namespace


vigir_step_control
Author(s): Alexander Stumpf
autogenerated on Thu Jun 6 2019 21:13:33