15 #ifndef NAV2_RVIZ_PLUGINS__NAV2_PANEL_HPP_
16 #define NAV2_RVIZ_PLUGINS__NAV2_PANEL_HPP_
19 #include <QBasicTimer>
20 #include <QStateMachine>
21 #include <QSignalTransition>
28 #include "nav2_lifecycle_manager/lifecycle_manager_client.hpp"
29 #include "nav2_msgs/action/navigate_to_pose.hpp"
30 #include "nav2_msgs/action/navigate_through_poses.hpp"
31 #include "nav2_msgs/action/follow_waypoints.hpp"
32 #include "nav2_rviz_plugins/ros_action_qevent.hpp"
33 #include "rclcpp/rclcpp.hpp"
34 #include "rclcpp_action/rclcpp_action.hpp"
35 #include "rviz_common/panel.hpp"
36 #include "rviz_common/ros_integration/ros_node_abstraction_iface.hpp"
37 #include "tf2_geometry_msgs/tf2_geometry_msgs.hpp"
38 #include "visualization_msgs/msg/marker_array.hpp"
39 #include "nav2_util/geometry_utils.hpp"
40 #include "nav2_ros_common/tf2_factories.hpp"
44 namespace nav2_rviz_plugins
50 QLineEdit * frame_id_edit;
51 QDoubleSpinBox * pos_x_spin;
52 QDoubleSpinBox * pos_y_spin;
53 QDoubleSpinBox * yaw_spin;
67 void onInitialize()
override;
70 void load(
const rviz_common::Config & config)
override;
71 void save(rviz_common::Config config)
const override;
82 void onAccumulatedWp();
83 void onAccumulatedNTP();
84 void onAccumulating();
85 void onNewGoal(
double x,
double y,
double theta, QString frame);
86 void handleGoalSaver();
87 void handleGoalLoader();
89 void initialStateHandler();
90 void onSendNavToPose();
91 void onAddNavThroughPose();
92 void onRemoveNavThroughPose();
96 void onCancelButtonPressed();
97 void timerEvent(QTimerEvent * event)
override;
98 bool isLoopValueValid(std::string & loop);
99 void createNavThroughPoseTab(
int index);
100 void syncTabsWithAccumulatedPoses();
101 void updateAccumulatedPosesFromTabs();
102 geometry_msgs::msg::PoseStamped getPoseFromNavThroughTab(
const NavThroughPoseTab & tab);
107 bool store_initial_pose_ =
false;
108 bool initial_pose_stored_ =
false;
109 bool loop_counter_stop_ =
true;
110 std::string loop_no_ =
"0";
111 std::string base_frame_;
114 std::shared_ptr<rviz_common::ros_integration::RosNodeAbstractionIface> node_ptr_;
117 geometry_msgs::msg::PoseStamped convert_to_msg(
118 std::vector<double> pose,
119 std::vector<double> orientation);
120 void startWaypointFollowing(std::vector<geometry_msgs::msg::PoseStamped> poses);
121 void startNavigation(geometry_msgs::msg::PoseStamped);
122 void startNavThroughPoses(nav_msgs::msg::Goals poses);
123 using NavigationGoalHandle =
124 rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>;
125 using WaypointFollowerGoalHandle =
126 rclcpp_action::ClientGoalHandle<nav2_msgs::action::FollowWaypoints>;
127 using NavThroughPosesGoalHandle =
128 rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateThroughPoses>;
131 rclcpp::Node::SharedPtr client_node_;
132 rclcpp::executors::SingleThreadedExecutor::SharedPtr executor_;
134 std::chrono::milliseconds server_timeout_;
140 nav2::ActionClient<nav2_msgs::action::NavigateToPose>::SharedPtr navigation_action_client_;
141 nav2::ActionClient<nav2_msgs::action::FollowWaypoints>::SharedPtr
142 waypoint_follower_action_client_;
143 nav2::ActionClient<nav2_msgs::action::NavigateThroughPoses>::SharedPtr
144 nav_through_poses_action_client_;
147 nav2::Subscription<nav2_msgs::action::NavigateToPose::Impl::FeedbackMessage>::SharedPtr
148 navigation_feedback_sub_;
149 nav2::Subscription<nav2_msgs::action::NavigateThroughPoses::Impl::FeedbackMessage>::SharedPtr
150 nav_through_poses_feedback_sub_;
151 nav2::Subscription<nav2_msgs::action::NavigateToPose::Impl::GoalStatusMessage>::SharedPtr
152 navigation_goal_status_sub_;
153 nav2::Subscription<nav2_msgs::action::NavigateThroughPoses::Impl::GoalStatusMessage>::SharedPtr
154 nav_through_poses_goal_status_sub_;
157 nav2::TransformBuffer::SharedPtr tf2_buffer_;
158 nav2::TransformListener::SharedPtr transform_listener_;
161 nav2_msgs::action::NavigateToPose::Goal navigation_goal_;
162 nav2_msgs::action::FollowWaypoints::Goal waypoint_follower_goal_;
163 nav2_msgs::action::NavigateThroughPoses::Goal nav_through_poses_goal_;
164 NavigationGoalHandle::SharedPtr navigation_goal_handle_;
165 WaypointFollowerGoalHandle::SharedPtr waypoint_follower_goal_handle_;
166 NavThroughPosesGoalHandle::SharedPtr nav_through_poses_goal_handle_;
169 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> client_nav_;
170 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> client_loc_;
172 QCheckBox * store_initial_pose_checkbox_{
nullptr};
174 QPushButton * start_reset_button_{
nullptr};
175 QPushButton * pause_resume_button_{
nullptr};
176 QPushButton * navigation_mode_button_{
nullptr};
177 QPushButton * add_pose_button_{
nullptr};
178 QPushButton * remove_pose_button_{
nullptr};
179 QPushButton * save_waypoints_button_{
nullptr};
180 QPushButton * load_waypoints_button_{
nullptr};
181 QPushButton * pause_waypoint_button_{
nullptr};
182 QPushButton * start_nav_to_pose_button_{
nullptr};
184 QLabel * navigation_status_indicator_{
nullptr};
185 QLabel * localization_status_indicator_{
nullptr};
186 QLabel * navigation_goal_status_indicator_{
nullptr};
187 QLabel * navigation_feedback_indicator_{
nullptr};
188 QLabel * waypoint_status_indicator_{
nullptr};
189 QLabel * number_of_loops_{
nullptr};
191 QLineEdit * nr_of_loops_{
nullptr};
194 QLineEdit * behavior_tree_file_{
nullptr};
197 QTabWidget * tools_tab_widget_{
nullptr};
200 QLineEdit * nav_to_pose_frame_id_{
nullptr};
201 QDoubleSpinBox * nav_to_pose_x_{
nullptr};
202 QDoubleSpinBox * nav_to_pose_y_{
nullptr};
203 QDoubleSpinBox * nav_to_pose_yaw_{
nullptr};
206 QTabWidget * nav_through_poses_tabs_{
nullptr};
208 QStateMachine state_machine_;
211 QState * pre_initial_{
nullptr};
212 QState * initial_{
nullptr};
213 QState * idle_{
nullptr};
214 QState * reset_{
nullptr};
215 QState * paused_{
nullptr};
216 QState * resumed_{
nullptr};
217 QState * paused_wp_{
nullptr};
218 QState * resumed_wp_{
nullptr};
220 QLabel * imgDisplayLabel_{
nullptr};
226 QState * running_{
nullptr};
227 QState * canceled_{
nullptr};
230 QState * accumulating_{
nullptr};
231 QState * accumulated_wp_{
nullptr};
232 QState * accumulated_nav_through_poses_{
nullptr};
234 nav_msgs::msg::Goals acummulated_poses_;
235 nav_msgs::msg::Goals store_poses_;
238 std::vector<NavThroughPoseTab> nav_through_pose_tabs_;
241 void updateWpNavigationMarkers();
246 void resetUniqueId();
249 static inline QString getNavToPoseFeedbackLabel(
250 nav2_msgs::action::NavigateToPose::Feedback msg =
251 nav2_msgs::action::NavigateToPose::Feedback());
252 static inline QString getNavThroughPosesFeedbackLabel(
253 nav2_msgs::action::NavigateThroughPoses::Feedback =
254 nav2_msgs::action::NavigateThroughPoses::Feedback());
256 static inline std::string toLabel(T & msg);
259 static inline std::string toString(
double val,
int precision = 0);
263 rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr wp_navigation_markers_pub_;
271 using SystemStatus = nav2_lifecycle_manager::SystemStatus;
274 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> & client_nav,
275 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> & client_loc)
276 : client_nav_(client_nav), client_loc_(client_loc)
281 SystemStatus status_nav = SystemStatus::TIMEOUT;
282 SystemStatus status_loc = SystemStatus::TIMEOUT;
284 while (status_nav == SystemStatus::TIMEOUT) {
285 if (status_nav == SystemStatus::TIMEOUT) {
286 status_nav = client_nav_->is_active(std::chrono::seconds(1));
291 bool tried_loc_bringup_once =
false;
292 while (status_loc == SystemStatus::TIMEOUT) {
293 status_loc = client_loc_->is_active(std::chrono::seconds(1));
294 if (tried_loc_bringup_once) {
297 tried_loc_bringup_once =
true;
300 if (status_nav == SystemStatus::ACTIVE) {
301 emit navigationActive();
303 emit navigationInactive();
306 if (status_loc == SystemStatus::ACTIVE) {
307 emit localizationActive();
309 emit localizationInactive();
314 void navigationActive();
315 void navigationInactive();
316 void localizationActive();
317 void localizationInactive();
320 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> client_nav_;
321 std::shared_ptr<nav2_lifecycle_manager::LifecycleManagerClient> client_loc_;
Panel to interface to the nav2 stack.
void load(const rviz_common::Config &config) override
Load and save configuration data.