1. 项目背景与目标
在机器人自主导航领域,远程规划与车端执行是一种常见架构模式。这次我们要在Scout Mini移动机器人上部署NeuPAN算法,实现基于激光雷达的实时路径规划与避障功能。整个系统采用分布式架构,规划算法运行在远程服务器上,而执行层部署在小车本地。
Scout Mini是一款轻量级差分驱动移动机器人,配备激光雷达和IMU等传感器。我们需要解决的核心问题是:如何让这台小车在复杂环境中实现稳定、可靠的自主导航,同时保证远程规划与本地执行之间的实时通信。
2. 环境准备与安装
2.1 基础环境配置
项目采用Ubuntu 20.04作为基础系统,ROS 2 Foxy版本作为机器人中间件。这个组合的选择基于以下考虑:
- Ubuntu 20.04是长期支持版本,稳定性有保障
- ROS 2 Foxy是首个支持Python 3.8的ROS 2 LTS版本
- Scout Mini的官方驱动已适配Foxy版本
在服务器端,我们使用Docker容器来隔离环境,容器内同样配置Ubuntu 20.04 + ROS 2 Foxy。这种"镜像环境"的配置可以最大程度减少环境差异导致的问题。
2.2 NeuPAN算法安装
NeuPAN是一个基于深度学习的机器人路径规划算法,安装步骤如下:
bash复制# 克隆代码库
git clone https://github.com/hanruihua/NeuPAN
cd NeuPAN
# 安装主程序
pip install -e .
# 安装仿真环境
pip install ir-sim
# 运行示例测试
cd example
python run_exp.py -e corridor -d diff
注意:安装前请确认Python版本为3.8,这是ROS 2 Foxy的官方支持版本。可以使用
python --version检查。
2.3 训练自定义模型
虽然NeuPAN提供了预训练模型,但针对Scout Mini的特殊尺寸和运动特性,建议进行微调训练:
bash复制cd /data/taohongkang/codes/NeuPAN/example/dune_train
python3 dune_train_diff.py
训练过程需要准备足够多的仿真场景数据,建议至少10万组数据样本。训练参数在dune_train_diff.yaml中配置,关键参数包括:
- batch_size: 256
- epoch: 5000
- lr: 5e-5
- data_range: [-25, -25, 25, 25] (训练场景范围)
3. 算法原理与接口分析
3.1 核心算法流程
NeuPAN算法的核心是一个基于深度学习的规划器,其工作流程如下:
-
输入处理:
- 机器人当前状态:
state = [x, y, theta] - 激光雷达扫描数据:
scan - 初始路径/目标点/航点
- 机器人当前状态:
-
障碍物点云提取:
python复制
points = neupan_planner.scan_to_point(robot_state, lidar_scan) -
规划计算:
python复制
action, info = neupan_planner(robot_state, points, point_velocities)
3.2 关键接口解析
在neupan.py中定义了核心接口:
初始化配置:
python复制@classmethod
def init_from_yaml(cls, yaml_file, **kwargs):
# 从YAML文件加载配置
with open(abs_path, "r") as f:
config = yaml.safe_load(f)
return cls(**config)
激光数据处理:
python复制def scan_to_point(self, state, scan, scan_offset=[0,0,0],
angle_range=[-np.pi,np.pi], down_sample=1):
# 将激光数据转换为障碍物点云
路径更新:
python复制def update_initial_path_from_goal(self, start, goal):
# 根据目标点更新初始路径
4. 分阶段实施方案
4.1 阶段0:信息确认
在小车上需要确认以下关键信息:
-
传感器与坐标系:
odom -> base_link的TF变换base_link -> laser的TF变换
-
ROS话题确认:
bash复制ros2 topic list ros2 topic echo /scan ros2 topic echo /odom ros2 topic echo /cmd_vel -
帧名称确认:
- 基座frame:通常是
base_link - 雷达frame:可能是
laser/laser_link/base_scan
- 基座frame:通常是
-
运动学模型:
- Scout Mini使用差分驱动(diff)模型
4.2 阶段1:服务器端测试
先在服务器容器内测试NeuPAN基本功能:
bash复制cd example
python run_exp.py -e corridor -d diff
这个测试验证算法本身是否正常工作,不涉及ROS通信。
4.3 阶段2:ROS 2通信配置
为了实现跨机器通信,需要配置ROS_DOMAIN_ID:
bash复制export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export ROS_DOMAIN_ID=5
然后在两边分别检查话题列表:
bash复制ros2 topic list
注意:两边必须使用相同的DOMAIN_ID才能通信
4.4 阶段3:TCP桥接方案
由于UDP通信存在不稳定性,我们实现了一个TCP桥接方案。小车端运行bridge_sender.py,服务器端运行bridge_receiver.py。
关键实现细节:
- 使用TCP协议保证可靠性
- 自定义消息格式:4字节长度头 + JSON体
- 多线程处理收发,避免阻塞
4.5 阶段4:NeuPAN ROS节点
创建neupan_ros2_node.py实现与ROS 2的集成:
python复制class NeuPANNode(Node):
def __init__(self):
super().__init__('neupan_node')
# 初始化规划器
self.planner = neupan.init_from_yaml('scout_mini_planner.yaml')
# 订阅传感器数据
self.scan_sub = self.create_subscription(LaserScan, '/scan', self.scan_cb, 10)
self.odom_sub = self.create_subscription(Odometry, '/odom', self.odom_cb, 10)
# 发布控制命令
self.cmd_pub = self.create_publisher(Twist, '/neupan_cmd_vel', 10)
# 10Hz控制循环
self.timer = self.create_timer(0.1, self.control_loop)
5. 配置文件详解
5.1 训练配置文件
dune_train_diff.yaml关键参数:
yaml复制robot:
kinematics: 'diff'
length: 0.612 # 小车长度
width: 0.580 # 小车宽度
train:
batch_size: 256
epoch: 5000
lr: 5e-5
data_range: [-25, -25, 25, 25] # 训练场景范围
5.2 规划器配置文件
scout_mini_planner.yaml关键参数:
yaml复制robot:
kinematics: 'diff'
max_speed: [2.78, 1.5] # 最大线速度和角速度(m/s, rad/s)
max_acce: [1.0, 1.0] # 最大加速度
ipath:
arrive_threshold: 0.3 # 到达阈值(米)
close_threshold: 0.2 # 接近阈值
pan:
iter_num: 2 # 迭代次数
dune_checkpoint: 'example/dune_train/model/diff_robot_default/model_5000.pth' # 模型路径
6. 系统集成与测试
6.1 小车端启动顺序
需要按顺序启动以下节点:
- 底盘驱动:
bash复制ros2 launch scout_base scout_mini_base.launch.py
- 激光雷达:
bash复制ros2 launch rslidar_sdk start.py
- TF变换:
bash复制ros2 run tf2_ros static_transform_publisher 0 0 0.23 0 0 0 base_link rslidar
- 点云转换:
bash复制ros2 run pointcloud_to_laserscan pointcloud_to_laserscan_node \
--ros-args -r cloud_in:=/rslidar_points \
-p target_frame:=base_link -p min_height:=-0.1 \
-p max_height:=0.5 -p range_min:=0.3 -p range_max:=25.0
- TCP桥接:
bash复制python3 ~/bridge_sender.py
6.2 服务器端启动顺序
- TCP桥接:
bash复制python3 bridge_receiver.py
- NeuPAN节点:
bash复制python3 neupan_ros2_node.py
- 发送测试目标:
bash复制ros2 topic pub /goal_pose geometry_msgs/msg/PoseStamped \
"{header: {frame_id: 'odom'}, pose: {position: {x: 3.0, y: 0.0, z: 0.0}, orientation: {w: 1.0}}}" --once
7. 常见问题与解决方案
7.1 通信问题排查
如果出现通信失败,按以下步骤排查:
- 检查IP配置:
bash复制ip addr show
ping <对方IP>
- 检查ROS域ID:
bash复制echo $ROS_DOMAIN_ID
- 检查CycloneDDS配置:
bash复制echo $CYCLONEDDS_URI
7.2 雷达数据异常处理
如果雷达数据不正常:
- 检查TF变换:
bash复制ros2 run tf2_tools view_frames
- 检查点云转换参数:
bash复制ros2 param list /pointcloud_to_laserscan
- 检查雷达驱动日志:
bash复制journalctl -u rslidar -f
7.3 规划异常处理
如果规划结果不稳定:
- 检查输入数据:
bash复制ros2 topic hz /scan
ros2 topic hz /odom
- 调整规划器参数:
- 降低最大速度
- 增加安全距离
- 调整迭代次数
- 检查模型路径:
yaml复制pan:
dune_checkpoint: '正确模型路径'
8. 性能优化建议
8.1 通信优化
- 使用有线网络替代无线
- 增加数据压缩
- 实现断线重连机制
8.2 算法优化
- 针对小车特性调整运动学参数
- 增加轨迹预测模块
- 实现动态参数调整
8.3 系统稳定性
- 添加看门狗机制
- 实现异常自动恢复
- 增加日志记录功能
在实际部署中,我发现Scout Mini的最大转向速度需要限制在1.5rad/s以内,否则容易出现打滑现象。同时,线速度建议不超过1m/s以保证安全性。这些参数需要在scout_mini_planner.yaml中相应调整。