SMACC2
waypoints_navigator.cpp
Go to the documentation of this file.
1// Copyright 2021 RobosoftAI Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*****************************************************************************************************************
16 *
17 * Authors: Pablo Inigo Blasco, Brett Aldrich
18 *
19 ******************************************************************************************************************/
20
21#include <tf2/transform_datatypes.h>
22#include <yaml-cpp/yaml.h>
23
24#include <fstream>
32#include <rclcpp/rclcpp.hpp>
33
34namespace cl_nav2z
35{
36using namespace std::chrono_literals;
37WaypointNavigator::WaypointNavigator() : currentWaypoint_(0), waypoints_(0) {}
38
40
42{
44
46}
47
49{
51
53}
54
56{
59 RCLCPP_WARN(
60 getLogger(), "[WaypointNavigator] Goal result received, incrementing waypoint index: %ld",
63
65}
66
67void WaypointNavigator::rewind(int /*count*/)
68{
71}
72
74{
75 if (succeddedNav2ZClientConnection_.connected())
76 {
77 this->succeddedNav2ZClientConnection_.disconnect();
78 this->cancelledNav2ZClientConnection_.disconnect();
79 this->abortedNav2ZClientConnection_.disconnect();
80 }
81}
82
84{
85 if (currentWaypoint_ >= 0 && currentWaypoint_ < (int)waypoints_.size())
86 {
87 auto & next = waypoints_[currentWaypoint_];
88
89 ClNav2Z::Goal goal;
91 auto pose = p->toPoseMsg();
92
93 // configuring goal
94 goal.pose.header.frame_id = p->getReferenceFrame();
95 goal.pose.header.stamp = getNode()->now();
96 goal.pose.pose = next;
97
98 RCLCPP_WARN(getLogger(), "[WaypointsNavigator] Configuring default planners");
99 auto plannerSwitcher = client_->getComponent<PlannerSwitcher>();
100 plannerSwitcher->setDefaultPlanners();
101
102 RCLCPP_WARN(getLogger(), "[WaypointsNavigator] Configuring default goal planner");
103 auto goalCheckerSwitcher = client_->getComponent<GoalCheckerSwitcher>();
104 goalCheckerSwitcher->setGoalCheckerId("goal_checker");
105
106 // publish stuff
107 // rclcpp::sleep_for(5s);
108
109 RCLCPP_INFO(getLogger(), "[WaypointsNavigator] Getting odom tracker");
111 if (odomTracker != nullptr)
112 {
113 RCLCPP_INFO(getLogger(), "[WaypointsNavigator] Storing path in odom tracker");
114
115 auto pathname =
116 this->owner_->getStateMachine()->getCurrentState()->getName() + " - " + getName();
117 odomTracker->pushPath(pathname);
118 odomTracker->setStartPoint(pose);
119 odomTracker->setWorkingMode(cl_nav2z::odom_tracker::WorkingMode::RECORD_PATH);
120 }
121
122 // SEND GOAL
123 if (!succeddedNav2ZClientConnection_.connected())
124 {
131 }
132
133 client_->sendGoal(goal);
134 }
135 else
136 {
137 RCLCPP_WARN(
138 getLogger(),
139 "[WaypointsNavigator] All waypoints were consumed. There is no more waypoints available.");
140 }
141}
142
143void WaypointNavigator::insertWaypoint(int index, geometry_msgs::msg::Pose & newpose)
144{
145 if (index >= 0 && index <= (int)waypoints_.size())
146 {
147 waypoints_.insert(waypoints_.begin(), index, newpose);
148 }
149}
150
151void WaypointNavigator::setWaypoints(const std::vector<geometry_msgs::msg::Pose> & waypoints)
152{
153 this->waypoints_ = waypoints;
154}
155
156void WaypointNavigator::setWaypoints(const std::vector<Pose2D> & waypoints)
157{
158 waypoints_.clear();
159 waypointsNames_.clear();
160 int i = 0;
161 for (auto & p : waypoints)
162 {
163 geometry_msgs::msg::Pose pose;
164 pose.position.x = p.x_;
165 pose.position.y = p.y_;
166 pose.position.z = 0.0;
167 tf2::Quaternion q;
168 q.setRPY(0, 0, p.yaw_);
169 pose.orientation = tf2::toMsg(q);
170
171 waypoints_.push_back(pose);
172 waypointsNames_.push_back(std::to_string(i++));
173 }
174}
175
177{
178 if (index >= 0 && index < (int)waypoints_.size())
179 {
180 waypoints_.erase(waypoints_.begin() + index);
181 }
182}
183
184const std::vector<geometry_msgs::msg::Pose> & WaypointNavigator::getWaypoints() const
185{
186 return waypoints_;
187}
188
190
191#define HAVE_NEW_YAMLCPP
193{
194 RCLCPP_INFO_STREAM(getLogger(), "[WaypointNavigator] Loading file:" << filepath);
195 this->waypoints_.clear();
196 std::ifstream ifs(filepath.c_str(), std::ifstream::in);
197 if (ifs.good() == false)
198 {
199 throw std::string("Waypoints file not found");
200 }
201
202 try
203 {
204#ifdef HAVE_NEW_YAMLCPP
205 YAML::Node node = YAML::Load(ifs);
206#else
207 YAML::Parser parser(ifs);
208 parser.GetNextDocument(node);
209#endif
210
211#ifdef HAVE_NEW_YAMLCPP
212 const YAML::Node & wp_node_tmp = node["waypoints"];
213 const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
214#else
215 const YAML::Node * wp_node = node.FindValue("waypoints");
216#endif
217
218 if (wp_node != NULL)
219 {
220 for (unsigned int i = 0; i < wp_node->size(); ++i)
221 {
222 // Parse waypoint entries on YAML
223 geometry_msgs::msg::Pose wp;
224
225 try
226 {
227 // (*wp_node)[i]["name"] >> wp.name;
228 // (*wp_node)[i]["frame_id"] >> wp.header.frame_id;
229 wp.position.x = (*wp_node)[i]["position"]["x"].as<double>();
230 wp.position.y = (*wp_node)[i]["position"]["y"].as<double>();
231 wp.position.z = (*wp_node)[i]["position"]["z"].as<double>();
232 wp.orientation.x = (*wp_node)[i]["orientation"]["x"].as<double>();
233 wp.orientation.y = (*wp_node)[i]["orientation"]["y"].as<double>();
234 wp.orientation.z = (*wp_node)[i]["orientation"]["z"].as<double>();
235 wp.orientation.w = (*wp_node)[i]["orientation"]["w"].as<double>();
236
237 this->waypoints_.push_back(wp);
238 }
239 catch (...)
240 {
241 RCLCPP_ERROR(getLogger(), "parsing waypoint file, syntax error in point %d", i);
242 }
243 }
244 RCLCPP_INFO_STREAM(getLogger(), "Parsed " << this->waypoints_.size() << " waypoints.");
245 }
246 else
247 {
248 RCLCPP_WARN_STREAM(getLogger(), "Couldn't find any waypoints in the provided yaml file.");
249 }
250 }
251 catch (const YAML::ParserException & ex)
252 {
253 RCLCPP_ERROR_STREAM(
254 getLogger(), "Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
255 }
256}
257
259{
260 RCLCPP_INFO_STREAM(getLogger(), "[WaypointNavigator] Loading file:" << filepath);
261 this->waypoints_.clear();
262 std::ifstream ifs(filepath.c_str(), std::ifstream::in);
263 if (ifs.good() == false)
264 {
265 throw std::string("Waypoints file not found");
266 }
267
268 try
269 {
270#ifdef HAVE_NEW_YAMLCPP
271 YAML::Node node = YAML::Load(ifs);
272#else
273 YAML::Parser parser(ifs);
274 parser.GetNextDocument(node);
275#endif
276
277#ifdef HAVE_NEW_YAMLCPP
278 const YAML::Node & wp_node_tmp = node["waypoints"];
279 const YAML::Node * wp_node = wp_node_tmp ? &wp_node_tmp : NULL;
280#else
281 const YAML::Node * wp_node = node.FindValue("waypoints");
282#endif
283
284 if (wp_node != NULL)
285 {
286 for (unsigned int i = 0; i < wp_node->size(); ++i)
287 {
288 // Parse waypoint entries on YAML
289 geometry_msgs::msg::Pose wp;
290
291 try
292 {
293 // (*wp_node)[i]["name"] >> wp.name;
294 // (*wp_node)[i]["frame_id"] >> wp.header.frame_id;
295 wp.position.x = (*wp_node)[i]["x"].as<double>();
296 wp.position.y = (*wp_node)[i]["y"].as<double>();
297 auto name = (*wp_node)[i]["name"].as<std::string>();
298
299 this->waypoints_.push_back(wp);
300 this->waypointsNames_.push_back(name);
301 }
302 catch (...)
303 {
304 RCLCPP_ERROR(getLogger(), "parsing waypoint file, syntax error in point %d", i);
305 }
306 }
307 RCLCPP_INFO_STREAM(getLogger(), "Parsed " << this->waypoints_.size() << " waypoints.");
308 }
309 else
310 {
311 RCLCPP_WARN_STREAM(getLogger(), "Couldn't find any waypoints in the provided yaml file.");
312 }
313 }
314 catch (const YAML::ParserException & ex)
315 {
316 RCLCPP_ERROR_STREAM(
317 getLogger(), "Error loading the Waypoints YAML file. Incorrect syntax: " << ex.what());
318 }
319}
320} // namespace cl_nav2z
void setGoalCheckerId(std::string goal_checker_id)
geometry_msgs::msg::Pose toPoseMsg()
Definition: cp_pose.hpp:58
boost::signals2::connection cancelledNav2ZClientConnection_
void loadWayPointsFromFile2(std::string filepath)
const std::vector< geometry_msgs::msg::Pose > & getWaypoints() const
void onGoalCancelled(ClNav2Z::WrappedResult &)
boost::signals2::connection abortedNav2ZClientConnection_
std::vector< std::string > waypointsNames_
WaypointEventDispatcher waypointsEventDispatcher
boost::signals2::connection succeddedNav2ZClientConnection_
smacc2::SmaccSignal< void()> onNavigationRequestCancelled
void onGoalAborted(ClNav2Z::WrappedResult &)
smacc2::SmaccSignal< void()> onNavigationRequestAborted
std::vector< geometry_msgs::msg::Pose > waypoints_
void loadWayPointsFromFile(std::string filepath)
void onGoalReached(ClNav2Z::WrappedResult &res)
smacc2::SmaccSignal< void()> onNavigationRequestSucceded
void setWaypoints(const std::vector< geometry_msgs::msg::Pose > &waypoints)
void insertWaypoint(int index, geometry_msgs::msg::Pose &newpose)
ISmaccStateMachine * getStateMachine()
TComponent * getComponent()
ISmaccClient * owner_
Definition: component.hpp:77
rclcpp::Logger getLogger()
virtual std::string getName() const
rclcpp::Node::SharedPtr getNode()
virtual std::string getName()=0
boost::signals2::connection onAborted(void(T::*callback)(WrappedResult &), T *object)
std::shared_future< typename GoalHandle::SharedPtr > sendGoal(Goal &goal)
boost::signals2::connection onSucceeded(void(T::*callback)(WrappedResult &), T *object)
boost::signals2::connection onCancelled(void(T::*callback)(WrappedResult &), T *object)