step_controller.cpp
Go to the documentation of this file.
2 
3 #include <vigir_generic_params/parameter_manager.h>
4 
5 
6 
7 namespace vigir_step_control
8 {
10 {
11  vigir_pluginlib::PluginManager::addPluginClassLoader<StepControllerPlugin>("vigir_step_control", "vigir_step_control::StepControllerPlugin");
12  vigir_pluginlib::PluginManager::addPluginClassLoader<vigir_footstep_planning::StepPlanMsgPlugin>("vigir_footstep_planning_plugins", "vigir_footstep_planning::StepPlanMsgPlugin");
13 
14  // subscribe topics
15  load_step_plan_msg_plugin_sub_ = nh.subscribe("load_step_plan_msg_plugin", 1, &StepController::loadStepPlanMsgPlugin, this);
16  load_step_controller_plugin_sub_ = nh.subscribe("load_step_controller_plugin", 1, &StepController::loadStepControllerPlugin, this);
17  execute_step_plan_sub_ = nh.subscribe("execute_step_plan", 1, &StepController::executeStepPlan, this);
18 
19  // publish topics
20  feedback_pub_ = nh.advertise<msgs::ExecuteStepPlanFeedback>("execute_feedback", 1, true);
21 
22  // init action servers
23  execute_step_plan_as_.reset(new ExecuteStepPlanActionServer(nh, "execute_step_plan", false));
24  execute_step_plan_as_->registerGoalCallback(boost::bind(&StepController::executeStepPlanAction, this, boost::ref(execute_step_plan_as_)));
25  execute_step_plan_as_->registerPreemptCallback(boost::bind(&StepController::executePreemptionAction, this, boost::ref(execute_step_plan_as_)));
26 
27  // start action servers
28  execute_step_plan_as_->start();
29 }
30 
32 {
33 }
34 
36 {
37  // init step controller plugin
38  if (!loadPlugin(nh.param("step_controller_plugin", std::string("step_controller_plugin")), step_controller_plugin_))
39  return false;
40 
41  // init step plan msg plugin
42  if (!loadPlugin(nh.param("step_plan_msg_plugin", std::string("step_plan_msg_plugin")), step_plan_msg_plugin_))
43  return false;
44 
46 }
47 
48 bool StepController::initialize(ros::NodeHandle& nh, StepControllerPlugin::Ptr step_controller_plugin, vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin, bool auto_spin)
49 {
50  step_plan_msg_plugin_ = step_plan_msg_plugin;
51  step_controller_plugin_ = step_controller_plugin;
52 
54  step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
55 
56  // schedule main update loop
57  if (auto_spin)
58  update_timer_ = nh.createTimer(nh.param("update_rate", 10.0), &StepController::update, this);
59 
60  return true;
61 }
62 
63 void StepController::executeStepPlan(const msgs::StepPlan& step_plan)
64 {
66 
68  {
69  ROS_ERROR("[StepController] executeStepPlan: No step_controller_plugin available!");
70  return;
71  }
72 
73  // An empty step plan will always trigger a soft stop
74  if (step_plan.steps.empty())
76  else
77  step_controller_plugin_->updateStepPlan(step_plan);
78 }
79 
81 {
83 
85  {
86  ROS_ERROR_THROTTLE(5.0, "[StepController] update: No step_controller_plugin available!");
87  return;
88  }
89 
90  // Save current state to be able to handle action server correctly;
91  // We must not send setSucceeded/setAborted state while sending the
92  // final feedback message in the same update cycle!
93  StepControllerState state = step_controller_plugin_->getState();
94 
95  // pre process
96  step_controller_plugin_->preProcess(event);
97 
98  // process
99  step_controller_plugin_->process(event);
100 
101  // post process
102  step_controller_plugin_->postProcess(event);
103 
104  lock.unlock();
105 
106  // publish feedback
107  publishFeedback();
108 
109  // update action server
110  switch (state)
111  {
112  case FINISHED:
113  if (execute_step_plan_as_->isActive())
114  {
115  msgs::ExecuteStepPlanResult result;
116  result.controller_state = state;
117  execute_step_plan_as_->setSucceeded(result);
118  }
119  break;
120 
121  case FAILED:
122  if (execute_step_plan_as_->isActive())
123  {
124  msgs::ExecuteStepPlanResult result;
125  result.controller_state = state;
126  execute_step_plan_as_->setAborted(result);
127  }
128  break;
129 
130  default:
131  break;
132  }
133 }
134 
136 {
137  if (step_controller_plugin_->getState() != READY)
138  {
139  const msgs::ExecuteStepPlanFeedback& feedback = step_controller_plugin_->getFeedbackState();
140 
141  // publish feedback
142  feedback_pub_.publish(feedback);
143 
144  if (execute_step_plan_as_->isActive())
145  execute_step_plan_as_->publishFeedback(feedback);
146  }
147 }
148 
149 // --- Subscriber calls ---
150 
151 void StepController::loadStepPlanMsgPlugin(const std_msgs::StringConstPtr& plugin_name)
152 {
153  loadPlugin(plugin_name->data, step_plan_msg_plugin_);
154 
156  step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
157 }
158 
159 void StepController::loadStepControllerPlugin(const std_msgs::StringConstPtr& plugin_name)
160 {
161  loadPlugin(plugin_name->data, step_controller_plugin_);
162 
164  step_controller_plugin_->setStepPlanMsgPlugin(step_plan_msg_plugin_);
165 }
166 
167 void StepController::executeStepPlan(const msgs::StepPlanConstPtr& step_plan)
168 {
169  executeStepPlan(*step_plan);
170 }
171 
172 //--- action server calls ---
173 
175 {
176  const msgs::ExecuteStepPlanGoalConstPtr& goal(as->acceptNewGoal());
177 
178  // check if new goal was preempted in the meantime
179  if (as->isPreemptRequested())
180  {
181  as->setPreempted();
182  return;
183  }
184 
185  executeStepPlan(goal->step_plan);
186 }
187 
189 {
190  if (as->isActive())
191  as->setPreempted();
192 
193  //step_controller_plugin->stop();
194 }
195 } // namespace
void executeStepPlanAction(ExecuteStepPlanActionServerPtr as)
void publishFeedback() const
Publishes feedback messages of current state of execution.
ros::Subscriber load_step_controller_plugin_sub_
void publish(const boost::shared_ptr< M > &message) const
boost::shared_ptr< ExecuteStepPlanActionServer > execute_step_plan_as_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void executeStepPlan(const msgs::StepPlan &step_plan)
Instruct the controller to execute the given step plan. If execution is already in progress...
ros::Subscriber load_step_plan_msg_plugin_sub_
bool loadPlugin(const std::string &plugin_name, boost::shared_ptr< T > &plugin)
Loads plugin with specific name to be used by the controller. The name should be configured in the pl...
vigir_footstep_planning::StepPlanMsgPlugin::Ptr step_plan_msg_plugin_
bool initialize(ros::NodeHandle &nh, bool auto_spin=true)
Initializes step controller.
StepControllerPlugin::Ptr step_controller_plugin_
#define ROS_ERROR_THROTTLE(rate,...)
bool param(const std::string &param_name, T &param_val, const T &default_val) const
StepController(ros::NodeHandle &nh)
StepController.
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
boost::unique_lock< Mutex > UniqueLock
Definition: step_queue.h:45
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void executePreemptionAction(ExecuteStepPlanActionServerPtr as)
actionlib::SimpleActionServer< msgs::ExecuteStepPlanAction > ExecuteStepPlanActionServer
void update(const ros::TimerEvent &event=ros::TimerEvent())
Main update loop to be called in regular intervals.
#define ROS_ERROR(...)
void loadStepPlanMsgPlugin(const std_msgs::StringConstPtr &plugin_name)
ROS API.
void loadStepControllerPlugin(const std_msgs::StringConstPtr &plugin_name)


vigir_step_control
Author(s): Alexander Stumpf
autogenerated on Mon Jun 10 2019 15:44:47