21#include <tf2/transform_datatypes.h>
22#include <yaml-cpp/yaml.h>
24#include <ament_index_cpp/get_package_share_directory.hpp>
33#include <rclcpp/rclcpp.hpp>
37using namespace std::chrono_literals;
67 getLogger(),
"[CpWaypointNavigator] Goal result received, incrementing waypoint index: %ld",
99 getLogger(),
"[CpWaypointNavigator] seeking ,%ld/%ld candidate waypoint: %s",
101 if (name == nextName)
105 getLogger(),
"[CpWaypointNavigator] found target waypoint: %s == %s-> found",
106 nextName.c_str(), name.c_str());
111 getLogger(),
"[CpWaypointNavigator] current waypoint: %s != %s -> forward",
112 nextName.c_str(), name.c_str());
129 getLogger(),
"[CpWaypointNavigator] seeking , candidate waypoint: %s", nextName.c_str());
130 if (name == nextName)
134 getLogger(),
"[CpWaypointNavigator] found target waypoint: %s == %s-> found",
135 nextName.c_str(), name.c_str());
140 getLogger(),
"[CpWaypointNavigator] current waypoint: %s != %s -> rewind",
141 nextName.c_str(), name.c_str());
148 getLogger(),
"[CpWaypointNavigator] seekName( %s), previous index: %ld, after index: %ld",
153 std::string parameter_name, std::string yaml_file_package_name)
156 std::string planfilepath;
157 planfilepath =
getNode()->declare_parameter(parameter_name, planfilepath);
158 RCLCPP_INFO(
getLogger(),
"waypoints plan parameter: %s", planfilepath.c_str());
159 if (
getNode()->get_parameter(parameter_name, planfilepath))
161 std::string package_share_directory =
162 ament_index_cpp::get_package_share_directory(yaml_file_package_name);
164 RCLCPP_INFO(
getLogger(),
"file macro path: %s", planfilepath.c_str());
166 boost::replace_all(planfilepath,
"$(pkg_share)", package_share_directory);
168 RCLCPP_INFO(
getLogger(),
"package share path: %s", package_share_directory.c_str());
169 RCLCPP_INFO(
getLogger(),
"waypoints plan file: %s", planfilepath.c_str());
172 RCLCPP_INFO(
getLogger(),
"waypoints plan: %s", planfilepath.c_str());
176 RCLCPP_ERROR(
getLogger(),
"waypoints plan file not found: NONE");
190std::optional<std::shared_future<
191 std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>>>>
193 std::optional<NavigateNextWaypointOptions> options,
200 std::string nextName;
205 getLogger(),
"[CpWaypointNavigator] sending goal, waypoint: %s", nextName.c_str());
218 goal.pose.header.frame_id = p->getReferenceFrame();
220 goal.pose.pose = next;
224 if (options && options->controllerName_)
227 getLogger(),
"[WaypointsNavigator] override controller: %s",
228 options->controllerName_->c_str());
230 plannerSwitcher->setDesiredController(*options->controllerName_);
234 RCLCPP_WARN(
getLogger(),
"[WaypointsNavigator] Configuring default planners");
239 if (options && options->goalCheckerName_)
242 getLogger(),
"[WaypointsNavigator] override goal checker: %s",
243 options->goalCheckerName_->c_str());
245 goalCheckerSwitcher->setGoalCheckerId(*options->goalCheckerName_);
249 RCLCPP_WARN(
getLogger(),
"[WaypointsNavigator] Configuring default goal checker");
250 goalCheckerSwitcher->setGoalCheckerId(
"goal_checker");
253 plannerSwitcher->commitPublish();
258 RCLCPP_INFO(
getLogger(),
"[WaypointsNavigator] Getting odom tracker");
260 if (odomTracker !=
nullptr)
262 RCLCPP_INFO(
getLogger(),
"[WaypointsNavigator] Storing path in odom tracker");
266 odomTracker->pushPath(pathname);
267 odomTracker->setStartPoint(pose);
282 auto callbackptr = resultCallback.lock();
292 "[CpWaypointsNavigator] All waypoints were consumed. There is no more waypoints available.");
303 RCLCPP_WARN(
getLogger(),
"[CpWaypointNavigator] Last waypoint reached, posting EOF event. ");
304 this->postEvent<EvWaypointFinal>();
310 if (r.code == rclcpp_action::ResultCode::SUCCEEDED)
314 else if (r.code == rclcpp_action::ResultCode::ABORTED)
318 else if (r.code == rclcpp_action::ResultCode::CANCELED)
330 if (index >= 0 && index <= (
int)
waypoints_.size())
346 for (
auto & p : waypoints)
348 geometry_msgs::msg::Pose pose;
349 pose.position.x = p.x_;
350 pose.position.y = p.y_;
351 pose.position.z = 0.0;
353 q.setRPY(0, 0, p.yaw_);
354 pose.orientation = tf2::toMsg(q);
363 if (index >= 0 && index < (
int)
waypoints_.size())
376 if (index >= 0 && index < (
int)
waypoints_.size())
382 throw std::out_of_range(
"Waypoint index out of range");
393 throw std::out_of_range(
"Waypoint index out of range");
398 std::string name)
const
430#define HAVE_NEW_YAMLCPP
433 RCLCPP_INFO_STREAM(
getLogger(),
"[CpWaypointNavigatorBase] Loading file:" << filepath);
435 std::ifstream ifs(filepath.c_str(), std::ifstream::in);
436 if (ifs.good() ==
false)
438 throw std::string(
"Waypoints file not found");
443#ifdef HAVE_NEW_YAMLCPP
444 YAML::Node node = YAML::Load(ifs);
446 YAML::Parser parser(ifs);
447 parser.GetNextDocument(node);
450#ifdef HAVE_NEW_YAMLCPP
451 const YAML::Node & wp_node_tmp = node[
"waypoints"];
452 const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
454 const YAML::Node * wp_node = node.FindValue(
"waypoints");
459 for (int64_t i = 0; i < wp_node->size(); ++i)
462 geometry_msgs::msg::Pose wp;
469 auto wpnodei = (*wp_node)[i];
470 wp.position.x = wpnodei[
"position"][
"x"].as<
double>();
471 wp.position.y = wpnodei[
"position"][
"y"].as<
double>();
472 wp.position.z = wpnodei[
"position"][
"z"].as<
double>();
473 wp.orientation.x = wpnodei[
"orientation"][
"x"].as<
double>();
474 wp.orientation.y = wpnodei[
"orientation"][
"y"].as<
double>();
475 wp.orientation.z = wpnodei[
"orientation"][
"z"].as<
double>();
476 wp.orientation.w = wpnodei[
"orientation"][
"w"].as<
double>();
478 if (wpnodei[
"name"].IsDefined())
487 RCLCPP_ERROR(
getLogger(),
"parsing waypoint file, syntax error in point %ld", i);
494 RCLCPP_WARN_STREAM(
getLogger(),
"Couldn't find any waypoints in the provided yaml file.");
497 catch (
const YAML::ParserException & ex)
500 getLogger(),
"Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
506 RCLCPP_INFO_STREAM(
getLogger(),
"[CpWaypointNavigator] Loading file:" << filepath);
508 std::ifstream ifs(filepath.c_str(), std::ifstream::in);
509 if (ifs.good() ==
false)
511 throw std::string(
"Waypoints file not found");
516#ifdef HAVE_NEW_YAMLCPP
517 YAML::Node node = YAML::Load(ifs);
519 YAML::Parser parser(ifs);
520 parser.GetNextDocument(node);
523#ifdef HAVE_NEW_YAMLCPP
524 const YAML::Node & wp_node_tmp = node[
"waypoints"];
525 const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
527 const YAML::Node * wp_node = node.FindValue(
"waypoints");
532 for (int64_t i = 0; i < wp_node->size(); ++i)
535 geometry_msgs::msg::Pose wp;
541 wp.position.x = (*wp_node)[i][
"x"].as<
double>();
542 wp.position.y = (*wp_node)[i][
"y"].as<
double>();
543 auto name = (*wp_node)[i][
"name"].as<std::string>();
550 RCLCPP_ERROR(
getLogger(),
"parsing waypoint file, syntax error in point %ld", i);
557 RCLCPP_WARN_STREAM(
getLogger(),
"Couldn't find any waypoints in the provided yaml file.");
560 catch (
const YAML::ParserException & ex)
563 getLogger(),
"Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
void postWaypointEvent(int index)
void setDefaultPlanners(bool commit=true)
void setWaypoints(const std::vector< geometry_msgs::msg::Pose > &waypoints)
const std::vector< geometry_msgs::msg::Pose > & getWaypoints() const
void loadWayPointsFromFile2(std::string filepath)
void seekName(std::string name)
CpWaypointNavigatorBase()
std::vector< geometry_msgs::msg::Pose > waypoints_
std::vector< std::string > waypointsNames_
geometry_msgs::msg::Pose getCurrentPose() const
void loadWayPointsFromFile(std::string filepath)
virtual ~CpWaypointNavigatorBase()
std::optional< std::string > getCurrentWaypointName() const
std::optional< geometry_msgs::msg::Pose > getNamedPose(std::string name) const
WaypointEventDispatcher waypointsEventDispatcher
geometry_msgs::msg::Pose getPose(int index) const
const std::vector< std::string > & getWaypointNames() const
void loadWaypointsFromYamlParameter(std::string parameter_name, std::string yaml_file_package_name)
void removeWaypoint(int index)
void insertWaypoint(int index, geometry_msgs::msg::Pose &newpose)
long getCurrentWaypointIndex() const
void onInitialize() override
boost::signals2::connection succeddedNav2ZClientConnection_
std::optional< std::shared_future< std::shared_ptr< rclcpp_action::ClientGoalHandle< nav2_msgs::action::NavigateToPose > > > > sendNextGoal(std::optional< NavigateNextWaypointOptions > options=std::nullopt, cl_nav2z::ClNav2Z::SmaccNavigateResultSignal::WeakPtr callback=cl_nav2z::ClNav2Z::SmaccNavigateResultSignal::WeakPtr())
boost::signals2::connection abortedNav2ZClientConnection_
smacc2::SmaccSignal< void()> onNavigationRequestCancelled
boost::signals2::connection cancelledNav2ZClientConnection_
void onInitialize() override
void onGoalAborted(const ClNav2Z::WrappedResult &)
void onGoalCancelled(const ClNav2Z::WrappedResult &)
void onNavigationResult(const ClNav2Z::WrappedResult &r)
smacc2::SmaccSignal< void()> onNavigationRequestAborted
smacc2::SmaccSignal< void()> onNavigationRequestSucceded
void onGoalReached(const ClNav2Z::WrappedResult &res)
geometry_msgs::msg::Pose toPoseMsg()
ISmaccStateMachine * getStateMachine()
TComponent * getComponent()
ISmaccStateMachine * getStateMachine()
virtual std::string getName() const
rclcpp::Logger getLogger() const
rclcpp::Node::SharedPtr getNode()
boost::signals2::connection createSignalConnection(TSmaccSignal &signal, TMemberFunctionPrototype callback, TSmaccObjectType *object)
ISmaccState * getCurrentState() const
virtual std::string getName()=0
std::weak_ptr< SmaccSignal< void(const WrappedResult &), optional_last_value< typename boost::function_traits< void(const WrappedResult &) >::result_type >, int, std::less< int >, function< void(const WrappedResult &) >, typename extended_signature< function_traits< void(const WrappedResult &) >::arity, void(const WrappedResult &) >::function_type, boost::signals2::mutex > > WeakPtr
typename ActionClient::Goal Goal
GoalHandle::WrappedResult WrappedResult
std::shared_future< typename GoalHandle::SharedPtr > sendGoal(Goal &goal, typename SmaccActionResultSignal::WeakPtr resultCallback=typename SmaccActionResultSignal::WeakPtr())