如何在ROS2 Foxy中通过Python节点停止或终止Nav2导航?
方法1:通过Action客户端取消当前导航目标
Nav2的核心导航功能(如NavigateToPose、FollowWaypoints)基于ROS2 Action实现,可通过对应Action客户端发送取消请求终止导航。
以下是针对NavigateToPose Action的Python实现示例:
import rclpy from rclpy.action import ActionClient from rclpy.node import Node from nav2_msgs.action import NavigateToPose class Nav2Stopper(Node): def __init__(self): super().__init__('nav2_stopper_node') self._action_client = ActionClient(self, NavigateToPose, 'navigate_to_pose') self.current_goal_handle = None def send_cancel_request(self): if self.current_goal_handle is not None: future = self.current_goal_handle.cancel_goal_async() rclpy.spin_until_future_complete(self, future) if future.result() is not None: self.get_logger().info('导航已成功取消') else: self.get_logger().error('取消导航请求失败') else: self.get_logger().warn('当前没有正在执行的导航目标') # 若需启动导航并记录目标句柄,可添加此方法 def send_nav_goal(self, pose): goal_msg = NavigateToPose.Goal() goal_msg.pose = pose self._action_client.wait_for_server() send_goal_future = self._action_client.send_goal_async(goal_msg) rclpy.spin_until_future_complete(self, send_goal_future) self.current_goal_handle = send_goal_future.result() if not self.current_goal_handle.accepted: self.get_logger().error('导航目标被拒绝') return self.get_logger().info('导航目标已接受') def main(args=None): rclpy.init(args=args) stopper = Nav2Stopper() stopper.send_cancel_request() stopper.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
若使用FollowWaypoints Action,只需将Action类型改为nav2_msgs.action.FollowWaypoints,并将Action话题替换为follow_waypoints即可。
方法2:调用Nav2的cancel_all_goals服务
Nav2提供cancel_all_goals服务(类型为std_srvs/srv/Empty),调用该服务可直接取消所有正在执行的导航任务。
Python实现示例:
import rclpy from rclpy.node import Node from std_srvs.srv import Empty class Nav2CancelService(Node): def __init__(self): super().__init__('nav2_cancel_service_client') self.cli = self.create_client(Empty, 'cancel_all_goals') while not self.cli.wait_for_service(timeout_sec=1.0): self.get_logger().info('服务未启动,等待中...') self.req = Empty.Request() def send_request(self): future = self.cli.call_async(self.req) rclpy.spin_until_future_complete(self, future) if future.result() is not None: self.get_logger().info('所有导航目标已取消') else: self.get_logger().error('调用取消服务失败') def main(args=None): rclpy.init(args=args) cancel_client = Nav2CancelService() cancel_client.send_request() cancel_client.destroy_node() rclpy.shutdown() if __name__ == '__main__': main()
注意事项
- 确保Python节点运行时与Nav2节点处于同一ROS2域,且具备足够权限。
- 使用Action取消方式时,需确保正确记录了
goal_handle,否则无法发起有效取消请求。 - 若Nav2配置中自定义了Action或服务话题名称,需将示例中的话题名替换为实际使用的名称。
内容的提问来源于stack exchange,提问作者Sachmk2
相关产品推荐
相关产品推荐

