42 #include <mbf_msgs/ExePathResult.h> 50 const std::string name,
54 const TFPtr &tf_listener_ptr,
55 const MoveBaseFlexConfig &config,
56 boost::function<
void()> setup_fn,
57 boost::function<
void()> cleanup_fn) :
59 controller_(controller_ptr), tf_listener_ptr(tf_listener_ptr), state_(INITIALIZED),
60 moving_(false), max_retries_(0), patience_(0), vel_pub_(vel_pub), current_goal_pub_(goal_pub),
61 calling_duration_(
boost::chrono::microseconds(static_cast<int>(1e6 / DEFAULT_CONTROLLER_FREQUENCY)))
87 ROS_ERROR(
"Controller frequency must be greater than 0.0! No change of the frequency!");
90 calling_duration_ = boost::chrono::microseconds(static_cast<int>(1e6 / frequency));
121 boost::lock_guard<boost::mutex> guard(
state_mtx_);
129 boost::lock_guard<boost::mutex> guard(
state_mtx_);
138 ROS_DEBUG(
"Setting new plan while moving");
140 boost::lock_guard<boost::mutex> guard(
plan_mtx_);
149 boost::lock_guard<boost::mutex> guard(
plan_mtx_);
156 boost::lock_guard<boost::mutex> guard(
plan_mtx_);
170 ROS_ERROR_STREAM(
"Could not get the robot pose in the global frame. - robot frame: \"" 172 message_ =
"Could not get the robot pose";
173 outcome_ = mbf_msgs::ExePathResult::TF_ERROR;
181 const geometry_msgs::TwistStamped& robot_velocity,
182 geometry_msgs::TwistStamped& vel_cmd,
183 std::string& message)
185 return controller_->computeVelocityCommands(robot_pose, robot_velocity, vel_cmd, message);
210 boost::lock_guard<boost::mutex> guard(
lct_mtx_);
217 boost::lock_guard<boost::mutex> guard(
lct_mtx_);
241 ROS_WARN_STREAM(
"Cancel controlling failed or is not supported by the plugin. " 242 <<
"Wait until the current control cycle finished!");
254 std::vector<geometry_msgs::PoseStamped> plan;
259 ROS_ERROR(
"robot navigation moving has no plan!");
270 boost::chrono::thread_clock::time_point loop_start_time = boost::chrono::thread_clock::now();
327 geometry_msgs::TwistStamped cmd_vel_stamped;
328 geometry_msgs::TwistStamped robot_velocity;
362 cmd_vel_stamped.header.seq = seq++;
367 boost::chrono::thread_clock::time_point end_time = boost::chrono::thread_clock::now();
368 boost::chrono::microseconds execution_duration =
369 boost::chrono::duration_cast<boost::chrono::microseconds>(end_time - loop_start_time);
375 if (sleep_time > boost::chrono::microseconds(0))
378 boost::this_thread::sleep_for(sleep_time);
383 boost::this_thread::interruption_point();
384 ROS_WARN_THROTTLE(1.0,
"Calculation needs too much time to stay in the moving frequency! (%f > %f)",
390 catch (
const boost::thread_interrupted &ex)
402 message_ =
"Unknown error occurred: " + boost::current_exception_diagnostic_information();
411 geometry_msgs::Twist cmd_vel;
412 cmd_vel.linear.x = 0;
413 cmd_vel.linear.y = 0;
414 cmd_vel.linear.z = 0;
415 cmd_vel.angular.x = 0;
416 cmd_vel.angular.y = 0;
417 cmd_vel.angular.z = 0;
boost::mutex plan_mtx_
mutex to handle safe thread communication for the current plan
boost::condition_variable condition_
condition variable to wake up control thread
ControllerState
Internal states.
void notify_all() BOOST_NOEXCEPT
bool new_plan_
true, if a new plan is available. See hasNewPlan()!
AbstractControllerExecution(const std::string name, const mbf_abstract_core::AbstractController::Ptr &controller_ptr, const ros::Publisher &vel_pub, const ros::Publisher &goal_pub, const TFPtr &tf_listener_ptr, const MoveBaseFlexConfig &config, boost::function< void()> setup_fn, boost::function< void()> cleanup_fn)
Constructor.
double angle(const geometry_msgs::PoseStamped &pose1, const geometry_msgs::PoseStamped &pose2)
std::string global_frame_
the global frame the robot is controlling in.
virtual ~AbstractControllerExecution()
Destructor.
boost::chrono::microseconds calling_duration_
the duration which corresponds with the controller frequency.
ros::Duration patience_
The time / duration of patience, before changing the state.
#define ROS_DEBUG_STREAM_NAMED(name, args)
boost::mutex configuration_mutex_
dynamic reconfigure config mutex, thread safe param reading and writing
void publish(const boost::shared_ptr< M > &message) const
bool computeRobotPose()
Computes the robot pose;.
boost::mutex vel_cmd_mtx_
mutex to handle safe thread communication for the current velocity command
The controller has been stopped!
Exceeded the maximum number of retries without a valid command.
Received no velocity command by the plugin, in the current cycle.
ros::Publisher current_goal_pub_
publisher for the current goal
Got a valid velocity command from the plugin.
bool hasNewPlan()
Returns true if a new plan is available, false otherwise! A new plan is set by another thread! ...
void setVelocityCmd(const geometry_msgs::TwistStamped &vel_cmd_stamped)
Sets the velocity command, to make it available for another thread.
double dist_tolerance_
distance tolerance to the given goal pose
The controller has been started without a plan.
bool getRobotPose(const TF &tf, const std::string &robot_frame, const std::string &global_frame, const ros::Duration &timeout, geometry_msgs::PoseStamped &robot_pose)
void setState(ControllerState state)
Sets the controller state. This method makes the communication of the state thread safe...
bool cancel_
flag for canceling controlling
ros::Publisher vel_pub_
publisher for the current velocity command
virtual bool cancel()
Cancel the planner execution. This calls the cancel method of the planner plugin. This could be usefu...
std::string message_
the last received plugin execution message
static const double DEFAULT_CONTROLLER_FREQUENCY
virtual void run()
The main run method, a thread will execute this method. It contains the main controller execution loo...
geometry_msgs::TwistStamped vel_cmd_stamped_
the last calculated velocity command
Exceeded the patience time without a valid command.
bool isMoving()
Returns whether the robot should normally move or not. True if the controller seems to work properly...
bool mbf_tolerance_check_
whether move base flex should check for the goal tolerance or not.
AbstractControllerExecution::ControllerState state_
the current controller state
bool moving_
main controller loop variable, true if the controller is running, false otherwise ...
#define ROS_FATAL_STREAM(args)
#define ROS_WARN_THROTTLE(period,...)
bool isPatienceExceeded()
Checks whether the patience duration time has been exceeded, ot not.
double angle_tolerance_
angle tolerance to the given goal pose
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
boost::mutex state_mtx_
mutex to handle safe thread communication for the current value of the state
uint32_t outcome_
the last received plugin execution outcome
The robot arrived the goal.
ros::Time getLastPluginCallTime()
Returns the time of the last plugin call.
An internal error occurred.
ros::Time start_time_
The time the controller has been started.
std::vector< geometry_msgs::PoseStamped > getNewPlan()
Gets the new available plan. This method is thread safe.
virtual uint32_t computeVelocityCmd(const geometry_msgs::PoseStamped &pose, const geometry_msgs::TwistStamped &velocity, geometry_msgs::TwistStamped &vel_cmd, std::string &message)
Request plugin for a new velocity command, given the current position, orientation, and velocity of the robot. We use this virtual method to give concrete implementations as move_base the chance to override it and do additional stuff, for example locking the costmap.
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
Received an invalid plan that the controller plugin rejected.
geometry_msgs::TwistStamped getVelocityCmd()
Returns the last velocity command calculated by the plugin. Set by setVelocityCmd method...
double distance(const geometry_msgs::PoseStamped &pose1, const geometry_msgs::PoseStamped &pose2)
void publishZeroVelocity()
bool reachedGoalCheck()
Checks whether the goal has been reached in the range of tolerance or not.
mbf_abstract_core::AbstractController::Ptr controller_
the local planer to calculate the velocity command
int max_retries_
The maximum number of retries.
ControllerState getState()
Return the current state of the controller execution. Thread communication safe.
boost::mutex lct_mtx_
mutex to handle safe thread communication for the last plugin call time
geometry_msgs::PoseStamped robot_pose_
current robot pose;
std::string robot_frame_
the frame of the robot, which will be used to determine its position.
void reconfigure(const MoveBaseFlexConfig &config)
Is called by the server thread to reconfigure the controller execution, if a user uses dynamic reconf...
virtual bool start()
Starts the controller, a valid plan should be given in advance.
double tf_timeout_
time before a timeout used for tf requests
#define ROS_ERROR_STREAM(args)
bool setControllerFrequency(double frequency)
Sets the controller frequency.
Controller has been started.
std::vector< geometry_msgs::PoseStamped > plan_
the last set plan which is currently processed by the controller
ros::Time last_call_time_
The current cycle start time of the last cycle run. Will by updated each cycle.
void setNewPlan(const std::vector< geometry_msgs::PoseStamped > &plan)
Sets a new plan to the controller execution.
The controller has been canceled.