Navigation2-main 项目中 nav2_behaviors、controller 和 lifecycle_manager 文件夹的源代码详解
在前述章节中,我们已经详细介绍了 constrained_smoother、collision_monitor、mppi_controller、dwb_controller、rotation_shim 和 core 模块。本节将继续介绍 navigation2-main 项目中的三个重要模块:nav2_behaviors、controller 和 lifecycle_manager。我们将深入解析这些模块的目录结构、核心功能、主要类和函数,帮助您全面理解和使用这些组件。
- nav2_behaviors
nav2_behaviors 模块负责实现机器人在导航过程中可能执行的各种行为,如旋转、直行、避障等。这些行为是导航控制器执行复杂动作的基础,为机器人提供了灵活的运动能力。
目录结构概述
nav2_behaviors/
├── include/
│ └── nav2_behaviors/
│ ├── navigate_rotate.hpp
│ ├── navigate_straight.hpp
│ ├── behavior_base.hpp
│ └── …
├── src/
│ ├── navigate_rotate.cpp
│ ├── navigate_straight.cpp
│ ├── behavior_base.cpp
│ └── …
├── CMakeLists.txt
└── package.xml
详细说明
1.1 include/nav2_behaviors/
此目录包含了 nav2_behaviors 模块的头文件,定义了各种导航行为的接口和基类。
● behavior_base.hpp定义了所有导航行为的基类 BehaviorBase,为具体行为类提供统一的接口和基础功能。
● navigate_rotate.hpp定义了 NavigateRotate 类,负责实现机器人的旋转行为。
● navigate_straight.hpp定义了 NavigateStraight 类,负责实现机器人的直行行为。
1.2 src/
此目录包含了 nav2_behaviors 模块的源代码,实现了各类导航行为的具体逻辑。
1.2.1 behavior_base.cpp
功能概述:
BehaviorBase 类是所有导航行为的基类,提供了配置、执行和取消行为的基础接口,确保不同行为之间的一致性和可扩展性。
关键方法:
● configure(): 配置行为,包括加载参数和初始化资源。
● execute(): 执行具体的导航行为。
● cancel(): 取消正在执行的行为。
示例代码:
#pragma once
#include “rclcpp/rclcpp.hpp”
namespace nav2_behaviors
{
class BehaviorBase
{
public:
BehaviorBase();
virtual ~BehaviorBase();
virtual void configure(const rclcpp::Node::SharedPtr & node, const std::string & name) = 0;
virtual void execute() = 0;
virtual void cancel() = 0;
protected:
rclcpp::Node::SharedPtr node_;
std::string name_;
};
} // namespace nav2_behaviors
1.2.2 navigate_rotate.cpp
功能概述:
NavigateRotate 类实现了机器人的旋转行为,通过控制机器人的角速度,使其旋转到指定的角度。
关键方法:
● configure(): 配置旋转行为,加载旋转速度和目标角度参数。
● execute(): 执行旋转动作,发布旋转速度指令直到达到目标角度。
● cancel(): 取消旋转动作,停止发布速度指令。
示例代码:
#include “nav2_behaviors/navigate_rotate.hpp”
#include “geometry_msgs/msg/twist.hpp”
namespace nav2_behaviors
{
-
NavigateRotate::NavigateRotate()
-
target_angle_(0.0), rotation_speed_(0.5), rotating_(false)
{
}
NavigateRotate::~NavigateRotate()
{
}
void NavigateRotate::configure(const rclcpp::Node::SharedPtr & node, const std::string & name)
{
node_ = node;
name_ = name;
node_->declare_parameter(“rotation_speed”, rotation_speed_);
node_->declare_parameter(“target_angle”, target_angle_);
node_->get_parameter(“rotation_speed”, rotation_speed_);
node_->get_parameter(“target_angle”, target_angle_);
cmd_vel_pub_ = node_->create_publisher<geometry_msgs::msg::Twist>(“/cmd_vel”, 10);
}
void NavigateRotate::execute()
{
rotating_ = true;
double current_angle = getCurrentYaw();
double angle_diff = normalizeAngle(target_angle_ - current_angle);
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.angular.z = (angle_diff > 0) ? rotation_speed_ : -rotation_speed_;
RCLCPP_INFO(node_->get_logger(), “开始旋转到目标角度: %.2f rad”, target_angle_);
while (rotating_ && std::abs(angle_diff) > 0.01) { // 0.01弧度容差
cmd_vel_pub_->publish(cmd_vel);
rclcpp::sleep_for(std::chrono::milliseconds(100));
current_angle = getCurrentYaw();
angle_diff = normalizeAngle(target_angle_ - current_angle);
cmd_vel.angular.z = (angle_diff > 0) ? rotation_speed_ : -rotation_speed_;
}
// 停止旋转
cmd_vel.angular.z = 0.0;
cmd_vel_pub_->publish(cmd_vel);
rotating_ = false;
RCLCPP_INFO(node_->get_logger(), “已到达目标角度: %.2f rad”, target_angle_);
}
void NavigateRotate::cancel()
{
rotating_ = false;
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.angular.z = 0.0;
cmd_vel_pub_->publish(cmd_vel);
RCLCPP_WARN(node_->get_logger(), “旋转行为已取消”);
}
double NavigateRotate::getCurrentYaw()
{
// 获取当前机器人的YAW角度,实际实现需订阅/odom或其他位姿主题
// 这里使用示例值
return 0.0;
}
double NavigateRotate::normalizeAngle(double angle)
{
while (angle > M_PI)
angle -= 2.0 * M_PI;
while (angle < -M_PI)
angle += 2.0 * M_PI;
return angle;
}
} // namespace nav2_behaviors
1.2.3 navigate_straight.cpp
功能概述:
NavigateStraight 类实现了机器人的直行行为,通过控制机器人的线速度,使其沿直线前进指定的距离或时间。
关键方法:
● configure(): 配置直行行为,加载线速度和前进时间/距离参数。
● execute(): 执行直行动作,发布线速度指令直到达到目标。
● cancel(): 取消直行动作,停止发布速度指令。
示例代码:
#include “nav2_behaviors/navigate_straight.hpp”
#include “geometry_msgs/msg/twist.hpp”
namespace nav2_behaviors
{
-
NavigateStraight::NavigateStraight()
-
target_distance_(1.0), linear_speed_(0.5), moving_(false), start_time_(0.0)
{
}
NavigateStraight::~NavigateStraight()
{
}
void NavigateStraight::configure(const rclcpp::Node::SharedPtr & node, const std::string & name)
{
node_ = node;
name_ = name;
node_->declare_parameter(“linear_speed”, linear_speed_);
node_->declare_parameter(“target_distance”, target_distance_);
node_->get_parameter(“linear_speed”, linear_speed_);
node_->get_parameter(“target_distance”, target_distance_);
cmd_vel_pub_ = node_->create_publisher<geometry_msgs::msg::Twist>(“/cmd_vel”, 10);
}
void NavigateStraight::execute()
{
moving_ = true;
double current_distance = 0.0;
start_time_ = node_->now().seconds();
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.linear.x = linear_speed_;
RCLCPP_INFO(node_->get_logger(), “开始直行,目标距离: %.2f 米”, target_distance_);
while (moving_ && current_distance < target_distance_) {
cmd_vel_pub_->publish(cmd_vel);
rclcpp::sleep_for(std::chrono::milliseconds(100));
double current_time = node_->now().seconds();
current_distance = linear_speed_ * (current_time - start_time_);
}
// 停止移动
cmd_vel.linear.x = 0.0;
cmd_vel_pub_->publish(cmd_vel);
moving_ = false;
RCLCPP_INFO(node_->get_logger(), “已到达目标距离: %.2f 米”, target_distance_);
}
void NavigateStraight::cancel()
{
moving_ = false;
geometry_msgs::msg::Twist cmd_vel;
cmd_vel.linear.x = 0.0;
cmd_vel_pub_->publish(cmd_vel);
RCLCPP_WARN(node_->get_logger(), “直行行为已取消”);
}
} // namespace nav2_behaviors
1.3 关键类和接口
1.3.1 BehaviorBase
BehaviorBase 类作为所有导航行为的基类,提供了统一的接口和基础功能,确保不同行为类之间的一致性和可扩展性。
主要成员变量:
● node_: 指向ROS节点的共享指针,用于参数获取和日志记录。
● name_: 行为的名称,用于配置和管理。
主要功能:
- 配置:
○ 加载并初始化行为所需的参数。
○ 设置ROS接口,如发布器和订阅器。 - 行为执行:
○ 处理具体行为的执行逻辑,通过继承实现不同的行为。 - 行为取消:
○ 提供取消行为的接口,以便在需要时中断当前执行的行为。
1.3.2 NavigateRotate
NavigateRotate 类实现了机器人旋转的行为,通过控制机器人发布旋转速度指令,使其旋转到指定的目标角度。
主要成员变量:
● target_angle_: 目标旋转角度(弧度)。
● rotation_speed_: 旋转速度(弧度/秒)。
● rotating_: 标志变量,指示是否正在旋转。
● cmd_vel_pub_: ROS发布器,用于发布速度指令。
主要功能: - 初始化与配置:
○ 加载旋转相关参数,如目标角度和旋转速度。
○ 设置ROS发布器,用于发布旋转控制指令。 - 旋转执行:
○ 计算当前角度与目标角度的差值。
○ 发布相应的旋转速度指令,直到达到目标角度。
○ 停止旋转,确保机器人不再继续旋转。 - 行为取消:
○ 停止发布旋转速度指令,停止旋转动作。
1.3.3 NavigateStraight
NavigateStraight 类实现了机器人直行的行为,通过控制机器人发布线速度指令,使其沿直线前进指定的距离或时间。
主要成员变量:
● target_distance_: 目标前进距离(米)。
● linear_speed_: 线速度(米/秒)。
● moving_: 标志变量,指示是否正在直行。
● start_time_: 行为开始的时间点。
● cmd_vel_pub_: ROS发布器,用于发布速度指令。
主要功能: - 初始化与配置:
○ 加载直行相关参数,如目标距离和线速度。
○ 设置ROS发布器,用于发布直行动作的速度指令。 - 直行动作执行:
○ 计算已移动的距离。
○ 发布相应的线速度指令,直到达到目标距离。
○ 停止移动,确保机器人不再继续前进。 - 行为取消:
○ 停止发布线速度指令,停止直行动作。
1.4 使用示例
以下是如何集成和使用 nav2_behaviors 模块的示例,展示如何配置和执行旋转与直行行为:
#include “nav2_behaviors/navigate_rotate.hpp”
#include “nav2_behaviors/navigate_straight.hpp”
#include “rclcpp/rclcpp.hpp”
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
auto node = std::make_sharedrclcpp::Node(“behaviors_example_node”);
// 初始化旋转行为
nav2_behaviors::NavigateRotate rotate_behavior;
rotate_behavior.configure(node, “rotate_behavior”);
// 初始化直行行为
nav2_behaviors::NavigateStraight straight_behavior;
straight_behavior.configure(node, “straight_behavior”);
// 执行旋转行为
double target_angle = M_PI / 2; // 90度
rotate_behavior.execute();
// 执行直行行为
double target_distance = 2.0; // 2米
straight_behavior.execute();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
2. controller
controller 模块负责实现机器人导航过程中的控制逻辑,包括速度指令的生成与执行。该模块通常与局部规划器紧密结合,通过处理来自局部规划器的路径信息,生成实际的运动控制指令,指导机器人沿路径移动。
目录结构概述
controller/
├── include/
│ └── nav2_controller/
│ ├── controller_base.hpp
│ ├── velocity_smoother.hpp
│ ├── controller_server.hpp
│ └── …
├── src/
│ ├── controller_base.cpp
│ ├── velocity_smoother.cpp
│ ├── controller_server.cpp
│ └── …
├── CMakeLists.txt
└── package.xml
详细说明
2.1 include/nav2_controller/
此目录包含了 controller 模块的头文件,定义了控制器的基类、速度平滑器和控制服务器等组件的接口。
● controller_base.hpp定义了 ControllerBase 类,作为所有控制器的基类,提供统一的接口和基础功能。
● velocity_smoother.hpp定义了 VelocitySmoother 类,用于平滑控制指令,确保速度指令的连续性和稳定性。
● controller_server.hpp定义了 ControllerServer 类,负责与ROS系统交互,接收规划器的路径指令并生成控制指令。
2.2 src/
此目录包含了 controller 模块的源代码,实现了各类控制器组件的具体逻辑。
2.2.1 controller_base.cpp
功能概述:
ControllerBase 类作为所有控制器的基类,提供了统一的接口和基础功能,确保不同控制器之间的一致性和可扩展性。
关键方法:
● configure(): 配置控制器,包括加载参数和初始化资源。
● computeControl(): 计算并返回控制指令。
● cancel(): 取消当前控制指令的执行。
示例代码:
#pragma once
#include “rclcpp/rclcpp.hpp”
#include “geometry_msgs/msg/twist.hpp”
namespace nav2_controller
{
class ControllerBase
{
public:
ControllerBase();
virtual ~ControllerBase();
virtual void configure(const rclcpp::Node::SharedPtr & node, const std::string & name) = 0;
virtual geometry_msgs::msg::Twist computeControl() = 0;
virtual void cancel() = 0;
protected:
rclcpp::Node::SharedPtr node_;
std::string name_;
};
} // namespace nav2_controller
2.2.2 velocity_smoother.cpp
功能概述:
VelocitySmoother 类实现了控制指令的平滑处理,通过限制速度变化率和加速度,确保机器人的运动指令平稳且符合物理限制,避免运动过程中的震动和不稳定。
关键方法:
● smooth(): 对输入的速度指令进行平滑处理,返回平滑后的速度指令。
● setParameters(): 设置平滑参数,如最大加速度和速度变化率。
示例代码:
#include “nav2_controller/velocity_smoother.hpp”
namespace nav2_controller
{
-
VelocitySmoother::VelocitySmoother()
-
max_acceleration_(0.5), max_jerk_(1.0), prev_cmd_vel_({0.0, 0.0, 0.0})
{
}
VelocitySmoother::~VelocitySmoother()
{
}
void VelocitySmoother::configure(const rclcpp::Node::SharedPtr & node, const std::string & name)
{
node_ = node;
name_ = name;
node_->declare_parameter(“max_acceleration”, max_acceleration_);
node_->declare_parameter(“max_jerk”, max_jerk_);
node_->get_parameter(“max_acceleration”, max_acceleration_);
node_->get_parameter(“max_jerk”, max_jerk_);
}
geometry_msgs::msg::Twist VelocitySmoother::smooth(const geometry_msgs::msg::Twist & cmd_vel)
{
geometry_msgs::msg::Twist smooth_vel = cmd_vel;
// 计算线速度变化
double delta_vx = cmd_vel.linear.x - prev_cmd_vel_.linear.x;
double delta_vy = cmd_vel.linear.y - prev_cmd_vel_.linear.y;
double delta_wz = cmd_vel.angular.z - prev_cmd_vel_.angular.z;
// 限制加速度
if (std::abs(delta_vx) > max_acceleration_) {
smooth_vel.linear.x = prev_cmd_vel_.linear.x + ((delta_vx > 0) ? max_acceleration_ : -max_acceleration_);
}
if (std::abs(delta_vy) > max_acceleration_) {
smooth_vel.linear.y = prev_cmd_vel_.linear.y + ((delta_vy > 0) ? max_acceleration_ : -max_acceleration_);
}
if (std::abs(delta_wz) > max_acceleration_) {
smooth_vel.angular.z = prev_cmd_vel_.angular.z + ((delta_wz > 0) ? max_acceleration_ : -max_acceleration_);
}
// 更新前一次速度指令
prev_cmd_vel_ = smooth_vel;
return smooth_vel;
}
} // namespace nav2_controller
2.2.3 controller_server.cpp
功能概述:
ControllerServer 类是控制器模块的核心,负责与ROS系统交互,接收来自局部规划器的路径指令,调用控制器计算控制指令,并将其发布到ROS主题以驱动机器人。
关键方法:
● configure(): 配置控制器服务器,初始化发布器和订阅器。
● updateControl(): 处理路径指令,计算控制指令并发布。
● shutdown(): 关闭控制器服务器,清理资源。
示例代码:
#include “nav2_controller/controller_server.hpp”
#include “nav2_controller/velocity_smoother.hpp”
namespace nav2_controller
{
-
ControllerServer::ControllerServer()
-
smoother_(std::make_shared()), active_(false)
{
}
ControllerServer::~ControllerServer()
{
shutdown();
}
void ControllerServer::configure(const rclcpp::Node::SharedPtr & node, const std::string & name)
{
node_ = node;
name_ = name;
// 初始化速度平滑器
smoother_->configure(node_, name_ + “.velocity_smoother”);
// 初始化控制指令发布器
cmd_vel_pub_ = node_->create_publisher<geometry_msgs::msg::Twist>(“/cmd_vel”, 10);
// 订阅局部规划器的路径指令
path_sub_ = node_->create_subscription<nav_msgs::msg::Path>(
“/local_planner/path”, 10,
std::bind(&ControllerServer::pathCallback, this, std::placeholders::_1));
active_ = true;
}
void ControllerServer::pathCallback(const nav_msgs::msg::Path::SharedPtr msg)
{
if (!active_) {
return;
}
// 从路径中提取目标速度,实际实现可能更复杂
geometry_msgs::msg::Twist goal_vel;
if (!msg->poses.empty()) {
// 假设最后一个路径点的速度作为目标速度
// 实际情况需根据全局规划器和局部规划器的实现调整
// 这里使用示例值
goal_vel.linear.x = 0.5;
goal_vel.angular.z = 0.1;
}
// 计算控制指令
geometry_msgs::msg::Twist cmd_vel = smoother_->smooth(goal_vel);
// 发布控制指令
cmd_vel_pub_->publish(cmd_vel);
}
geometry_msgs::msg::Twist ControllerServer::computeControl()
{
// 这里可以实现更复杂的控制逻辑
// 目前通过回调直接发布控制指令
geometry_msgs::msg::Twist cmd_vel;
return cmd_vel;
}
void ControllerServer::shutdown()
{
if (active_) {
path_sub_.reset();
cmd_vel_pub_.reset();
active_ = false;
}
}
} // namespace nav2_controller
2.3 关键类和接口
2.3.1 ControllerBase
ControllerBase 类作为所有控制器的基类,提供了统一的接口和基础功能,确保不同控制器之间的一致性和可扩展性。
主要成员变量:
● node_: 指向ROS节点的共享指针,用于参数获取和日志记录。
● name_: 控制器的名称,用于配置和管理。
主要功能:
- 配置:
○ 加载并初始化控制器所需的参数。
○ 设置ROS接口,如发布器和订阅器。 - 控制指令计算:
○ 根据当前机器人状态和目标状态,计算并返回控制指令。
○ 提供接口以实现不同的控制策略。 - 行为取消:
○ 提供取消控制指令的接口,以便在需要时中断当前执行的控制动作。
2.3.2 VelocitySmoother
VelocitySmoother 类实现了控制指令的平滑处理,通过限制速度变化率和加速度,确保速度指令的连续性和稳定性,避免运动过程中的震动和不稳定。
主要成员变量:
● max_acceleration_: 最大允许的加速度(米/秒²)。
● max_jerk_: 最大允许的加速度变化率(米/秒³)。
● prev_cmd_vel_: 前一次发布的速度指令,用于计算速度变化。
● node_: 指向ROS节点的共享指针,用于参数获取和日志记录。
主要功能: - 初始化与配置:
○ 加载速度平滑相关参数,如最大加速度和速度变化率。
○ 设置ROS接口,如发布器和订阅器。 - 速度指令平滑:
○ 接收目标速度指令,计算与前一次速度指令的差值。
○ 限制速度变化率和加速度,生成平滑后的速度指令。
○ 更新前一次速度指令,以便下一次平滑处理。
2.3.3 ControllerServer
ControllerServer 类是控制器模块的核心,负责与ROS系统交互,接收来自局部规划器的路径指令,调用控制器计算控制指令,并将其发布到ROS主题以驱动机器人。
主要成员变量:
● node_: 指向ROS节点的共享指针,用于参数获取和日志记录。
● name_: 控制器服务器的名称,用于配置和管理。
● smoother_: 指向 VelocitySmoother 类实例的共享指针,负责速度平滑处理。
● cmd_vel_pub_: ROS发布器,用于发布控制指令。
● path_sub_: ROS订阅器,用于接收局部规划器的路径指令。
● active_: 标志变量,指示控制器服务器是否处于活动状态。
主要功能: - 初始化与配置:
○ 加载并初始化控制器参数。
○ 初始化速度平滑器。
○ 设置ROS发布器和订阅器,用于发布控制指令和接收路径指令。 - 控制指令处理:
○ 接收来自局部规划器的路径指令。
○ 调用速度平滑器处理目标速度指令,生成平滑后的控制指令。
○ 发布控制指令至ROS主题,以驱动机器人运动。 - 控制器服务器管理:
○ 管理控制器服务器的生命周期,包括启动、运行和关闭。
○ 提供接口进行资源清理和行为取消。
2.4 使用示例
以下是如何集成和使用 controller 模块的示例,展示如何配置和执行控制指令:
#include “nav2_controller/controller_server.hpp”
#include “nav2_controller/velocity_smoother.hpp”
#include “rclcpp/rclcpp.hpp”
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
auto node = std::make_sharedrclcpp::Node(“controller_example_node”);
// 初始化控制器服务器
nav2_controller::ControllerServer controller_server;
controller_server.configure(node, “controller_server”);
rclcpp::spin(node);
// 关闭控制器服务器
controller_server.shutdown();
rclcpp::shutdown();
return 0;
}
3. lifecycle_manager
lifecycle_manager 模块负责管理ROS节点的生命周期,协调多个ROS节点的启动、运行和关闭,确保整个导航系统的稳定性和一致性。通过管理节点的生命周期,lifecycle_manager 提供了机制来控制节点的初始化、激活、停用和清理过程。
目录结构概述
lifecycle_manager/
├── include/
│ └── lifecycle_manager/
│ ├── lifecycle_manager_client.hpp
│ ├── lifecycle_manager.hpp
│ └── …
├── src/
│ ├── lifecycle_manager_client.cpp
│ ├── lifecycle_manager.cpp
│ └── …
├── CMakeLists.txt
└── package.xml
详细说明
3.1 include/lifecycle_manager/
此目录包含了 lifecycle_manager 模块的头文件,定义了生命周期管理器和客户端的接口。
● lifecycle_manager.hpp定义了 LifecycleManager 类,负责管理多个ROS节点的生命周期状态。
● lifecycle_manager_client.hpp定义了 LifecycleManagerClient 类,作为其他节点与生命周期管理器交互的客户端接口。
3.2 src/
此目录包含了 lifecycle_manager 模块的源代码,实现了生命周期管理器和客户端的具体逻辑。
3.2.1 lifecycle_manager.cpp
功能概述:
LifecycleManager 类负责管理多个ROS节点的生命周期状态,通过协调节点的初始化、激活、停用和清理过程,确保整个系统的稳定运行。
关键方法:
● addNode(): 添加需要管理生命周期的ROS节点。
● activateNodes(): 激活所有管理的节点。
● deactivateNodes(): 停用所有管理的节点。
● shutdownNodes(): 清理并关闭所有管理的节点。
示例代码:
#pragma once
#include “rclcpp/rclcpp.hpp”
#include “nav2_util/lifecycle_service_client.hpp”
#include
#include
namespace lifecycle_manager
{
class LifecycleManager : public rclcpp::Node
{
public:
LifecycleManager();
~LifecycleManager();
void addNode(const std::string & node_name);
void activateNodes();
void deactivateNodes();
void shutdownNodes();
private:
std::vector<nav2_util::LifecycleServiceClient::SharedPtr> managed_nodes_;
};
} // namespace lifecycle_manager
#include “lifecycle_manager/lifecycle_manager.hpp”
#include “rclcpp/rclcpp.hpp”
#include “lifecycle_msgs/msg/state.hpp”
namespace lifecycle_manager
{
-
LifecycleManager::LifecycleManager()
-
Node(“lifecycle_manager”)
{
// 在此可以添加参数加载和其他初始化操作
}
LifecycleManager::~LifecycleManager()
{
shutdownNodes();
}
void LifecycleManager::addNode(const std::string & node_name)
{
auto client = std::make_shared<nav2_util::LifecycleServiceClient>(node_, node_name);
managed_nodes_.push_back(client);
}
void LifecycleManager::activateNodes()
{
for (auto & client : managed_nodes_) {
if (client->getState().id != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
client->activate();
}
}
}
void LifecycleManager::deactivateNodes()
{
for (auto & client : managed_nodes_) {
if (client->getState().id == lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) {
client->deactivate();
}
}
}
void LifecycleManager::shutdownNodes()
{
for (auto & client : managed_nodes_) {
client->shutdown();
}
}
} // namespace lifecycle_manager
3.2.2 lifecycle_manager_client.cpp
功能概述:
LifecycleManagerClient 类作为其他节点与 LifecycleManager 交互的客户端接口,提供了添加节点、激活节点、停用节点和关闭节点的功能。
关键方法:
● initialize(): 初始化生命周期管理客户端,与 LifecycleManager 建立连接。
● addManagedNode(): 向 LifecycleManager 添加需要管理生命周期的节点。
示例代码:
#pragma once
#include “rclcpp/rclcpp.hpp”
namespace lifecycle_manager
{
class LifecycleManagerClient
{
public:
LifecycleManagerClient(const rclcpp::Node::SharedPtr & node);
~LifecycleManagerClient();
void addManagedNode(const std::string & node_name);
void activateAll();
void deactivateAll();
void shutdownAll();
private:
rclcpp::Node::SharedPtr node_;
std::vectorstd::string nodes_to_manage_;
};
} // namespace lifecycle_manager
#include “lifecycle_manager/lifecycle_manager_client.hpp”
#include “lifecycle_manager/lifecycle_manager.hpp”
namespace lifecycle_manager
{
-
LifecycleManagerClient::LifecycleManagerClient(const rclcpp::Node::SharedPtr & node)
-
node_(node)
{
}
LifecycleManagerClient::~LifecycleManagerClient()
{
}
void LifecycleManagerClient::addManagedNode(const std::string & node_name)
{
// 通过服务调用或其他机制,将节点名称添加到LifecycleManager中
// 这里假设LifecycleManager已经在同一进程中运行
// 实际实现可能需要IPC或服务调用
}
void LifecycleManagerClient::activateAll()
{
// 调用LifecycleManager的激活方法
}
void LifecycleManagerClient::deactivateAll()
{
// 调用LifecycleManager的停用方法
}
void LifecycleManagerClient::shutdownAll()
{
// 调用LifecycleManager的关闭方法
}
} // namespace lifecycle_manager
3.3 关键类和接口
3.3.1 LifecycleManager
LifecycleManager 类负责管理多个ROS节点的生命周期状态,通过协调节点的初始化、激活、停用和清理过程,确保整个系统的稳定运行。
主要成员变量:
● managed_nodes_: 存储所有被管理的节点的生命周期服务客户端。
主要功能:
- 节点管理:
○ 添加需要管理生命周期的节点。
○ 启动和关闭节点的生命周期状态。 - 生命周期控制:
○ 激活所有管理的节点,使其进入活动状态。
○ 停用所有管理的节点,使其进入不活动状态。
○ 关闭所有管理的节点,进行清理和资源释放。
3.3.2 LifecycleManagerClient
LifecycleManagerClient 类作为其他节点与 LifecycleManager 交互的客户端接口,提供了添加节点、激活节点、停用节点和关闭节点的功能。
主要成员变量:
● node_: 指向ROS节点的共享指针,用于与 LifecycleManager 交互。
● nodes_to_manage_: 存储需要管理生命周期的节点名称列表。
主要功能: - 初始化与配置:
○ 初始化生命周期管理客户端,与 LifecycleManager 建立连接。 - 节点管理接口:
○ 向 LifecycleManager 添加需要管理生命周期的节点。
○ 提供接口以激活、停用和关闭所有管理的节点。
3.3.3 LifecycleManager
LifecycleManager 类是生命周期管理的核心,负责统一管理多个ROS节点的生命周期状态,通过协调节点的初始化、激活、停用和清理过程,确保整个导航系统的稳定性和一致性。
主要成员变量:
● managed_nodes_: 存储所有被管理的节点的生命周期服务客户端。
主要功能: - 节点添加与管理:
○ 允许动态添加需要管理生命周期的节点。 - 生命周期状态控制:
○ 激活所有管理的节点,使其进入活动状态。
○ 停用所有管理的节点,使其进入不活动状态。
○ 关闭所有管理的节点,进行资源清理和释放。 - 资源管理:
○ 保证在系统关闭或重新配置时,所有管理的节点能够正确地进行生命周期转换,避免资源泄漏和不一致状态。
3.4 使用示例
以下是如何集成和使用 lifecycle_manager 模块的示例,展示如何配置和管理多个ROS节点的生命周期:
#include “lifecycle_manager/lifecycle_manager.hpp”
#include “nav2_core/planner_base.hpp”
#include “nav2_core/controller.hpp”
#include “rclcpp/rclcpp.hpp”
int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
auto node = std::make_sharedrclcpp::Node(“lifecycle_manager_example_node”);
// 初始化生命周期管理器
lifecycle_manager::LifecycleManager lifecycle_manager;
// 添加需要管理生命周期的节点
lifecycle_manager.addNode(“planner_server”);
lifecycle_manager.addNode(“controller_server”);
lifecycle_manager.addNode(“costmap_2d”);
// 激活所有节点
lifecycle_manager.activateNodes();
rclcpp::spin(node);
// 关闭所有节点
lifecycle_manager.shutdownNodes();
rclcpp::shutdown();
return 0;
}
总结
nav2_behaviors、controller 和 lifecycle_manager 是 navigation2-main 项目中至关重要的三个模块,分别负责实现各类导航行为、控制逻辑和生命周期管理。通过详细解析这三个模块的文件夹结构和源代码实现,我们可以更深入地理解Navigation2的工作原理和设计理念。
关键点回顾
- nav2_behaviors 模块:
○ 导航行为实现:提供了多种导航行为,如旋转和直行,帮助机器人执行复杂的运动任务。
○ 基类与继承:通过基类 BehaviorBase 提供统一的接口,确保不同导航行为的一致性和可扩展性。
○ ROS接口集成:与ROS系统紧密结合,通过发布速度指令控制机器人运动。 - controller 模块:
○ 控制逻辑实现:负责生成和执行控制指令,确保机器人沿预定路径平稳移动。
○ 速度平滑处理:通过 VelocitySmoother 类实现控制指令的平滑处理,提升运动的稳定性。
○ ROS接口整合:通过订阅路径指令和发布控制指令,协调局部规划器与机器人运动。 - lifecycle_manager 模块:
○ 生命周期管理:统一管理多个ROS节点的生命周期状态,确保系统的稳定性和一致性。
○ 节点协调:通过 LifecycleManager 类协调节点的初始化、激活、停用和关闭过程。
○ 资源管理:避免资源泄漏和不一致状态,通过生命周期管理确保系统高效运行。
通过对这三个模块的深入理解,开发者可以更有效地定制和优化导航系统,满足不同应用场景下的需求。同时,这种模块化和分层设计也为系统的扩展和维护提供了坚实的基础。
如果需要进一步了解具体的实现细节和高级功能,建议参考各模块的源代码和官方文档,结合实际项目需求进行深入学习和实践。