double_thread_locomotor.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include <locomotor/locomotor.h>
37 #include <string>
38 
39 namespace locomotor
40 {
42 
56 {
57 public:
58  explicit DoubleThreadLocomotor(const ros::NodeHandle& private_nh)
59  : private_nh_(private_nh), locomotor_(private_nh_),
61  as_(private_nh_, std::bind(&DoubleThreadLocomotor::setGoal, this, std::placeholders::_1))
62  {
66  this, false, false); // one_shot=false(default), auto_start=false
71  this, false, false); // one_shot=false(default), auto_start=false
76  }
77 
78  void setGoal(nav_2d_msgs::Pose2DStamped goal)
79  {
82  }
83 
84 protected:
85  void planLoopCallback(const ros::TimerEvent& event)
86  {
88  }
89 
91  {
93  std::bind(&DoubleThreadLocomotor::onGlobalCostmapUpdate, this, std::placeholders::_1),
94  std::bind(&DoubleThreadLocomotor::onGlobalCostmapException, this, std::placeholders::_1, std::placeholders::_2));
95  }
96 
97  void requestNavigationFailure(const locomotor_msgs::ResultCode& result)
98  {
100  std::bind(&DoubleThreadLocomotor::onNavigationFailure, this, std::placeholders::_1));
101  }
102 
103  // Locomotor Callbacks
104  void onGlobalCostmapUpdate(const ros::Duration& planning_time)
105  {
106  // Run the global planning on the separate executor, but put the result on the main executor
108  std::bind(&DoubleThreadLocomotor::onNewGlobalPlan, this, std::placeholders::_1, std::placeholders::_2),
109  std::bind(&DoubleThreadLocomotor::onGlobalPlanningException, this, std::placeholders::_1, std::placeholders::_2));
110  }
111 
113  {
114  requestNavigationFailure(makeResultCode(locomotor_msgs::ResultCode::GLOBAL_COSTMAP, getResultCode(e_ptr),
115  "Global Costmap failure."));
116  }
117 
118  void onNewGlobalPlan(nav_2d_msgs::Path2D new_global_plan, const ros::Duration& planning_time)
119  {
120  locomotor_.publishPath(new_global_plan);
121  locomotor_.getCurrentLocalPlanner().setPlan(new_global_plan);
122 
123  if (planning_time > desired_plan_duration_)
124  {
125  ROS_WARN_NAMED("locomotor", "Global planning missed its desired rate of %.4fHz... "
126  "the loop actually took %.4f seconds (>%.4f).",
128  }
131  }
132 
134  {
135  ROS_ERROR_NAMED("Locomotor", "Global planning error. Giving up.");
136  requestNavigationFailure(makeResultCode(locomotor_msgs::ResultCode::GLOBAL_PLANNER, getResultCode(e_ptr),
137  "Global Planning Failure."));
138  }
139 
141  {
143  std::bind(&DoubleThreadLocomotor::onLocalCostmapUpdate, this, std::placeholders::_1),
144  std::bind(&DoubleThreadLocomotor::onLocalCostmapException, this, std::placeholders::_1, std::placeholders::_2));
145  }
146 
147  void onLocalCostmapUpdate(const ros::Duration& planning_time)
148  {
150  std::bind(&DoubleThreadLocomotor::onNewLocalPlan, this, std::placeholders::_1, std::placeholders::_2),
151  std::bind(&DoubleThreadLocomotor::onLocalPlanningException, this, std::placeholders::_1, std::placeholders::_2),
153  }
154 
156  {
157  requestNavigationFailure(makeResultCode(locomotor_msgs::ResultCode::LOCAL_COSTMAP, getResultCode(e_ptr),
158  "Local Costmap failure."));
159  }
160 
161  void onNewLocalPlan(nav_2d_msgs::Twist2DStamped new_command, const ros::Duration& planning_time)
162  {
163  locomotor_.publishTwist(new_command);
164  if (planning_time > desired_control_duration_)
165  {
166  ROS_WARN_NAMED("locomotor", "Control loop missed its desired rate of %.4fHz... "
167  "the loop actually took %.4f seconds (>%.4f).",
169  }
171  }
172 
174  {
175  ROS_WARN_NAMED("Locomotor", "Local planning error. Creating new global plan.");
178  }
179 
181  {
182  ROS_INFO_NAMED("Locomotor", "Plan completed! Stopping.");
186  }
187 
188  void onNavigationFailure(const locomotor_msgs::ResultCode result)
189  {
192  as_.failNavigation(result);
193  }
194 
196  // Locomotor Object
198 
199  // Timer Stuff
200  double planner_frequency_ { 10.0 }, controller_frequency_ { 20.0 };
203 
204  // The Two Executors
206 
207  // Action Server
209 };
210 }; // namespace locomotor
211 
212 int main(int argc, char** argv)
213 {
214  ros::init(argc, argv, "locomotor_node");
215  ros::NodeHandle nh("~");
217  ros::spin();
218  return 0;
219 }
locomotor::LocomotorActionServer::failNavigation
void failNavigation(const locomotor_msgs::ResultCode &result_code)
Definition: locomotor_action_server.cpp:80
locomotor::Locomotor::initializeLocalPlanners
void initializeLocalPlanners(Executor &ex)
Definition: locomotor.cpp:103
locomotor::DoubleThreadLocomotor::desired_control_duration_
ros::Duration desired_control_duration_
Definition: double_thread_locomotor.cpp:201
locomotor::DoubleThreadLocomotor::as_
LocomotorActionServer as_
Definition: double_thread_locomotor.cpp:208
main
int main(int argc, char **argv)
Definition: double_thread_locomotor.cpp:212
locomotor::DoubleThreadLocomotor::onGlobalCostmapUpdate
void onGlobalCostmapUpdate(const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:104
locomotor_action_server.h
locomotor::DoubleThreadLocomotor
Connect the callbacks in Locomotor to do global and local planning on two separate timers.
Definition: double_thread_locomotor.cpp:55
locomotor::Executor
Collection of objects used in ROS CallbackQueue threading.
Definition: executor.h:72
ros::init
ROSCPP_DECL void init(const M_string &remappings, const std::string &name, uint32_t options=0)
locomotor::DoubleThreadLocomotor::onLocalCostmapException
void onLocalCostmapException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:155
locomotor::DoubleThreadLocomotor::planner_frequency_
double planner_frequency_
Definition: double_thread_locomotor.cpp:200
locomotor::DoubleThreadLocomotor::requestNavigationFailure
void requestNavigationFailure(const locomotor_msgs::ResultCode &result)
Definition: double_thread_locomotor.cpp:97
locomotor::Locomotor::requestLocalPlan
void requestLocalPlan(Executor &work_ex, Executor &result_ex, LocalPlanCallback cb=nullptr, PlannerExceptionCallback fail_cb=nullptr, NavigationCompleteCallback complete_cb=nullptr)
Request the local planner get run as a new callback.
Definition: locomotor.cpp:146
locomotor::Locomotor::initializeGlobalPlanners
void initializeGlobalPlanners(Executor &ex)
Definition: locomotor.cpp:94
locomotor::LocomotorActionServer::publishFeedback
void publishFeedback(const locomotor_msgs::NavigationState &nav_state)
Definition: locomotor_action_server.cpp:49
locomotor::Locomotor::setGoal
virtual void setGoal(nav_2d_msgs::Pose2DStamped goal)
Starts a new navigation to the given goal.
Definition: locomotor.cpp:112
locomotor
Definition: executor.h:43
locomotor::DoubleThreadLocomotor::local_planning_ex_
Executor local_planning_ex_
Definition: double_thread_locomotor.cpp:205
locomotor::Locomotor::requestLocalCostmapUpdate
void requestLocalCostmapUpdate(Executor &work_ex, Executor &result_ex, CostmapUpdateCallback cb=nullptr, CostmapUpdateExceptionCallback fail_cb=nullptr)
Request the local costmap get updated as a new callback.
Definition: locomotor.cpp:133
ros::Timer::stop
void stop()
locomotor::Locomotor
an extensible path planning coordination engine
Definition: locomotor.h:81
ROS_ERROR_NAMED
#define ROS_ERROR_NAMED(name,...)
locomotor::DoubleThreadLocomotor::control_loop_timer_
ros::Timer control_loop_timer_
Definition: double_thread_locomotor.cpp:202
locomotor::DoubleThreadLocomotor::private_nh_
ros::NodeHandle private_nh_
Definition: double_thread_locomotor.cpp:195
locomotor::Locomotor::initializeLocalCostmap
void initializeLocalCostmap(Executor &ex)
Definition: locomotor.cpp:84
locomotor::Locomotor::initializeGlobalCostmap
void initializeGlobalCostmap(Executor &ex)
Definition: locomotor.cpp:74
nav_core2::NavCore2ExceptionPtr
std::exception_ptr NavCore2ExceptionPtr
locomotor::DoubleThreadLocomotor::setGoal
void setGoal(nav_2d_msgs::Pose2DStamped goal)
Definition: double_thread_locomotor.cpp:78
locomotor::Locomotor::publishTwist
void publishTwist(const nav_2d_msgs::Twist2DStamped &command)
Definition: locomotor.h:191
nav_core2::getResultCode
int getResultCode(const NavCore2ExceptionPtr &e_ptr)
ROS_INFO_NAMED
#define ROS_INFO_NAMED(name,...)
locomotor::LocomotorActionServer::completeNavigation
void completeNavigation()
Definition: locomotor_action_server.cpp:75
locomotor::DoubleThreadLocomotor::desired_plan_duration_
ros::Duration desired_plan_duration_
Definition: double_thread_locomotor.cpp:201
locomotor::Locomotor::publishPath
void publishPath(const nav_2d_msgs::Path2D &global_plan)
Definition: locomotor.h:190
locomotor::DoubleThreadLocomotor::onLocalPlanningException
void onLocalPlanningException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:173
nav_core2::LocalPlanner::setPlan
virtual void setPlan(const nav_2d_msgs::Path2D &path)=0
locomotor::Locomotor::requestNavigationFailure
void requestNavigationFailure(Executor &result_ex, const locomotor_msgs::ResultCode &result, NavigationFailureCallback cb=nullptr)
Request that a onNavigationFailure event be added as a new callback.
Definition: locomotor.cpp:153
locomotor::DoubleThreadLocomotor::onNavigationFailure
void onNavigationFailure(const locomotor_msgs::ResultCode result)
Definition: double_thread_locomotor.cpp:188
locomotor::DoubleThreadLocomotor::onGlobalCostmapException
void onGlobalCostmapException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:112
send_action.goal
goal
Definition: send_action.py:31
ros::TimerEvent
locomotor::DoubleThreadLocomotor::DoubleThreadLocomotor
DoubleThreadLocomotor(const ros::NodeHandle &private_nh)
Definition: double_thread_locomotor.cpp:58
locomotor::DoubleThreadLocomotor::planLoopCallback
void planLoopCallback(const ros::TimerEvent &event)
Definition: double_thread_locomotor.cpp:85
locomotor::DoubleThreadLocomotor::onNewGlobalPlan
void onNewGlobalPlan(nav_2d_msgs::Path2D new_global_plan, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:118
locomotor::Locomotor::getCurrentLocalPlanner
nav_core2::LocalPlanner & getCurrentLocalPlanner()
Definition: locomotor.h:177
locomotor::DoubleThreadLocomotor::onNavigationCompleted
void onNavigationCompleted()
Definition: double_thread_locomotor.cpp:180
locomotor::DoubleThreadLocomotor::plan_loop_timer_
ros::Timer plan_loop_timer_
Definition: double_thread_locomotor.cpp:202
locomotor::DoubleThreadLocomotor::controlLoopCallback
void controlLoopCallback(const ros::TimerEvent &event)
Definition: double_thread_locomotor.cpp:140
locomotor::DoubleThreadLocomotor::controller_frequency_
double controller_frequency_
Definition: double_thread_locomotor.cpp:200
locomotor::DoubleThreadLocomotor::onNewLocalPlan
void onNewLocalPlan(nav_2d_msgs::Twist2DStamped new_command, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:161
std
locomotor::Locomotor::requestGlobalCostmapUpdate
void requestGlobalCostmapUpdate(Executor &work_ex, Executor &result_ex, CostmapUpdateCallback cb=nullptr, CostmapUpdateExceptionCallback fail_cb=nullptr)
Request the global costmap get updated as a new callback.
Definition: locomotor.cpp:126
ROS_WARN_NAMED
#define ROS_WARN_NAMED(name,...)
locomotor::DoubleThreadLocomotor::locomotor_
Locomotor locomotor_
Definition: double_thread_locomotor.cpp:197
ros::NodeHandle::param
T param(const std::string &param_name, const T &default_val) const
locomotor.h
conversions.h
ros::spin
ROSCPP_DECL void spin()
locomotor::DoubleThreadLocomotor::requestGlobalCostmapUpdate
void requestGlobalCostmapUpdate()
Definition: double_thread_locomotor.cpp:90
locomotor::LocomotorActionServer
Definition: locomotor_action_server.h:47
locomotor::DoubleThreadLocomotor::onGlobalPlanningException
void onGlobalPlanningException(nav_core2::NavCore2ExceptionPtr e_ptr, const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:133
DurationBase< Duration >::toSec
double toSec() const
locomotor::Locomotor::getNavigationState
const locomotor_msgs::NavigationState & getNavigationState() const
Definition: locomotor.h:167
ros::Timer::start
void start()
locomotor::DoubleThreadLocomotor::onLocalCostmapUpdate
void onLocalCostmapUpdate(const ros::Duration &planning_time)
Definition: double_thread_locomotor.cpp:147
ros::NodeHandle::createTimer
Timer createTimer(Duration period, const TimerCallback &callback, bool oneshot=false, bool autostart=true) const
locomotor::makeResultCode
locomotor_msgs::ResultCode makeResultCode(int component=-1, int result_code=-1, const std::string &message="")
Definition: locomotor.h:67
ros::Duration
locomotor::Locomotor::requestGlobalPlan
void requestGlobalPlan(Executor &work_ex, Executor &result_ex, GlobalPlanCallback cb=nullptr, PlannerExceptionCallback fail_cb=nullptr)
Request the global planner get run as a new callback.
Definition: locomotor.cpp:140
ros::Timer
locomotor::DoubleThreadLocomotor::global_planning_ex_
Executor global_planning_ex_
Definition: double_thread_locomotor.cpp:205
ros::NodeHandle


locomotor
Author(s):
autogenerated on Sun May 18 2025 02:47:30