跳转至

阿里云大模型迷宫巡线功能包使用说明

Hint

本文档基于 line_follower_aliyun 工程整理,主要说明该代码包的目录作用、每个包/模块用途、启动流程和常见调试方法。

  • 机器人平台:OriginBot / RDK 系列机器人
  • 系统环境:Ubuntu 22.04 + ROS2 Humble
  • 推理平台:地平线 BPU / DNN Runtime
  • 视觉输入:USB 摄像头图像,经 Hobot Codec 转为 NV12 共享内存图像
  • 大模型接口:阿里云百炼 OpenAI 兼容接口
  • 主要功能:网页端选择迷宫路线 → 阿里云大模型解析 → ROS2 小车巡线并按路口指令转向

一、工程整体说明

该工程是一个“网页端 + ROS2 巡线控制”的组合工程。整体逻辑如下:

网页端选择路口动作
阿里云百炼大模型解析为动作文件 parse_res.txt
点击“发车”启动 ROS2 launch
USB 摄像头发布图像
图像转为 NV12 共享内存话题 /hbmem_img
line_follower_maze 节点调用 BPU 模型预测线中心坐标
根据预测点 x/y 判断循线、岔路口、直行、左转、右转
发布 /cmd_vel 控制底盘运动

动作文件格式示例:

1-0
2-1
3-2

其中:

动作编号 含义
0 左转
1 右转
2 直行

例如 1-0 表示在第一个岔路口左转,2-1 表示在第二个岔路口右转。

二、代码目录结构

工程目录结构如下:

line_follower_aliyun/
├── README.md
├── dev_front/
│   ├── main.py
│   ├── requirements.txt
│   ├── config/
│   │   └── app_config.yaml
│   └── frontend/
│       ├── utils.py
│       └── car.png
└── line_follower_aliyun/
    ├── package.xml
    ├── CMakeLists.txt
    ├── include/
    │   └── line_follower_aliyun/
    │       └── line_follower_aliyun.h
    ├── src/
    │   └── line_follower_maze.cpp
    ├── config/
    │   └── line_follower_maze.yaml
    ├── launch/
    │   ├── line_follower_maze.launch.py
    │   └── usb_cam_web.launch.py
    └── model/
        ├── README.txt
        └── resnet18_224x224_nv12_maze.bin
Attation

dev_front/__pycache__frontend/__pycache__ 是 Python 自动生成的缓存目录,不属于核心代码,可以删除,不影响功能。

三、每个包 / 模块的作用

1. dev_front:网页端与阿里云百炼调用模块

dev_front 不是 ROS2 功能包,它是一个 Python 网页端程序,主要负责让用户通过浏览器选择迷宫路线,并调用阿里云百炼模型把自然语言路线解析成固定格式的动作文件。

主要作用

文件 / 目录 作用
dev_front/main.py Gradio 网页主程序,负责显示页面、验证 API Key、生成迷宫指令、保存解析结果、点击“发车”启动 ROS2 launch
dev_front/config/app_config.yaml 网页端配置文件,配置阿里云接口地址、模型名称、网页端口、动作文件路径、ROS 启动命令
dev_front/frontend/utils.py 阿里云百炼接口调用与解析结果校验逻辑
dev_front/frontend/car.png 网页端点击“发车”后显示的小车图片
dev_front/requirements.txt Python 依赖列表,包括 openaiPyYAMLgradio

工作流程

在网页中选择:第一个路口 / 第二个路口 / 第三个路口
main.py 拼接自然语言提示词
utils.py 调用阿里云百炼 OpenAI 兼容接口
模型输出:1-0、2-1、3-2 这类格式
main.py 保存到 parse_res.txt
点击“发车”后执行 ros2 launch

网页端核心配置 app_config.yaml

llm:
  base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
  model: "qwen-plus"
  api_key_prefix: "sk-"

runtime:
  parse_result_path: "/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt"
  ros_launch_command:
    - "ros2"
    - "launch"
    - "line_follower_aliyun"
    - "line_follower_maze.launch.py"

其中最关键的是 parse_result_path,它必须和 ROS2 参数文件中的 data_path 保持一致。

2. line_follower_aliyun:ROS2 巡线迷宫控制功能包

line_follower_aliyun 是真正的 ROS2 C++ 功能包,负责接收摄像头图像、调用 BPU 模型推理、识别线路坐标、读取动作文件,并发布速度指令控制小车。

主要作用

文件 / 目录 作用
package.xml ROS2 包描述文件,声明包名、版本、构建工具和依赖项
CMakeLists.txt CMake 构建脚本,定义可执行文件 line_follower_maze 的编译、链接和安装规则
include/line_follower_aliyun/line_follower_aliyun.h 节点类、推理结果结构体、后处理解析类声明
src/line_follower_maze.cpp 核心代码,包含图像订阅、模型推理、坐标解析、巡线控制、岔路口动作执行
config/line_follower_maze.yaml ROS2 参数配置文件,配置模型路径、动作文件路径、速度、转向角速度、ROI、话题名等
launch/line_follower_maze.launch.py 总启动文件,同时启动巡线节点、摄像头、底盘驱动
launch/usb_cam_web.launch.py USB 摄像头、Web 显示、JPEG/NV12 编解码、共享内存节点启动文件
model/resnet18_224x224_nv12_maze.bin 已训练并转换好的 BPU 推理模型文件
model/README.txt 模型目录说明,提示可替换为自己的 .bin 模型

四、ROS2 功能包依赖说明

line_follower_aliyun/package.xmlCMakeLists.txt 中涉及的依赖包作用如下。

依赖包 作用
ament_cmake ROS2 C++ 功能包构建工具
rclcpp ROS2 C++ 节点开发基础库,用于创建节点、订阅、发布、参数读取等
dnn_node 地平线 DNN 推理节点基础库,用于加载 .bin 模型并调用 BPU 推理
hbm_img_msgs 地平线共享内存图像消息类型,本工程订阅的是 HbmMsg1080P 类型图像
geometry_msgs 提供 geometry_msgs/msg/Twist,用于向底盘发布速度控制指令
nav_msgs 提供 nav_msgs/msg/Odometry,本工程读取 /odom 获取 yaw 角,用于判断转弯是否完成
tf2 用于把四元数姿态转换为 roll、pitch、yaw 欧拉角
tf2_ros ROS2 TF 支持库,当前工程主要作为姿态相关依赖保留
std_msgs ROS2 标准消息依赖,当前核心控制逻辑中使用较少,属于基础依赖
OpenCV 图像矩阵处理依赖,代码中使用 cv::Mat 管理图像数据
hobot_cv 地平线图像处理库,用于对 NV12 图像进行裁剪、缩放等操作
hbmem 地平线内存管理相关库,用于模型输入输出缓存和共享内存处理
ai_msgs 包描述文件中声明的 AI 消息依赖,当前核心源码中没有直接使用,可能是历史兼容项

五、Launch 中调用的外部功能包说明

line_follower_maze.launch.pyusb_cam_web.launch.py 会调用多个外部 ROS2 包。

外部包 作用
originbot_bringup 启动机器人底盘驱动,提供 /cmd_vel 控制接口和 /odom 里程计数据
hobot_usb_cam 启动 USB 摄像头,发布原始图像话题 /image
websocket 提供网页端图像显示能力,可在浏览器查看摄像头画面
hobot_codec 图像编解码,将 /image 转换为 DNN 推理需要的 NV12 共享内存图像 /hbmem_img
hobot_shm 启动地平线共享内存环境,配合 hbm_img_msgs 使用

整体图像链路如下:

USB 摄像头
    ↓ hobot_usb_cam
/image
    ↓ hobot_codec_decode
/hbmem_img
    ↓ line_follower_maze
BPU 模型推理
/cmd_vel

六、核心节点 line_follower_maze 逻辑说明

1. 订阅与发布的话题

话题 类型 方向 作用
/hbmem_img hbm_img_msgs/msg/HbmMsg1080P 订阅 输入图像,来自 Hobot Codec 转换后的 NV12 图像
/odom nav_msgs/msg/Odometry 订阅 读取小车当前 yaw 角,判断转弯角度是否到位
/cmd_vel geometry_msgs/msg/Twist 发布 控制小车线速度和角速度

实际话题名可以在 config/line_follower_maze.yaml 中修改:

cmd_vel_topic: "cmd_vel"
image_topic: "hbmem_img"
odom_topic: "odom"

2. 模型推理输入输出

节点订阅 /hbmem_img 后,会执行以下处理:

接收 NV12 图像
按 ROI 裁剪图像
缩放到 224 × 224
送入 resnet18_224x224_nv12_maze.bin 模型
模型输出线路目标点坐标 x/y
转换回原图坐标系

代码中的坐标转换逻辑:

result->x = (x * 112 + 112) * 640.0 / 224.0;
result->y = 224 - (y * 112 + 112) + 240;

含义是:模型输出的是归一化坐标,需要转换为原图中用于控制的小车参考坐标。

3. 普通巡线控制

未检测到岔路口、也没有处于直行或转弯状态时,节点执行普通巡线:

float angular_z = -1.0 * (x - line_center_x_) / angular_gain_divisor_;
message.linear.x = line_follow_linear_speed_;
message.angular.z = angular_z;

含义:

参数 作用
x 模型预测的线路中心 x 坐标
line_center_x_ 图像中理想中心点,默认 320
angular_gain_divisor_ 角速度比例分母,越小转向越激进
line_follow_linear_speed_ 普通巡线前进速度

当线在图像中心左侧或右侧时,小车会自动调整角速度,让车头回到线路中心。

4. 岔路口检测逻辑

代码通过预测点 y 判断是否到达岔路口:

if (y < cross_detect_y_threshold_ && IsTurn == false && IsGo == false)

默认参数:

cross_detect_y_threshold: 240.0

当预测点 y 小于阈值,并且当前不在转弯、不在直行状态时,认为检测到岔路口。

检测到岔路口后不会立刻转弯,而是先进入 IsGo 状态,让小车继续前冲一段时间。

5. 岔路口前冲逻辑

检测到岔路口后,小车先直行 go_time 秒:

go_time: 2.3
go_time_per_cycle: 0.035

代码中通过 GoedTime += go_time_per_cycle_ 累加时间。当前逻辑是按每帧约 0.035s 估算,如果实际相机帧率变化较大,需要调整 go_time_per_cycle

Attation

go_time_per_cycle 不是系统真实定时器时间,而是按图像回调次数估算的时间。相机帧率不同,前冲距离会变化。

6. 转向执行逻辑

前冲时间结束后,从动作队列中取出当前路口动作:

current_direction = std::stoi(stringQueue.front());

动作含义:

动作
0 左转
1 右转
2 直行

左转:

rpy[1].yaw = rpy[0].yaw + turning_target_angle_;
message.angular.z = turning_vth_;

右转:

rpy[1].yaw = rpy[0].yaw - turning_target_angle_;
message.angular.z = -turning_vth_;

默认转向目标角度:

turning_target_angle: 1.57
turning_finish_tolerance: 0.1
turning_vth: 1.0

即默认每次左转或右转约 90°。

七、参数文件说明

参数文件路径:

line_follower_aliyun/config/line_follower_maze.yaml

主要参数如下:

参数 默认值 说明
model_path /userdata/dev_ws/src/line_follower_aliyun/line_follower_aliyun/model/resnet18_224x224_nv12_maze.bin .bin 模型绝对路径
model_name resnet18_224x224_nv12 DNN 模型名称
data_path /userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt 网页端输出的动作文件路径
go_time 2.3 到达岔路口后继续直行的时间
turning_vth 1.0 左右转角速度,单位 rad/s
line_follow_linear_speed 0.1 普通循线线速度,单位 m/s
cross_detect_y_threshold 240.0 岔路口检测 y 阈值
turning_target_angle 1.57 转弯目标角度,约等于 90°
turning_finish_tolerance 0.1 转弯完成角度容差
go_time_per_cycle 0.035 图像回调周期估算值
line_center_x 320.0 图像中心线 x 坐标
angular_gain_divisor 200.0 巡线角速度比例分母
roi_left 0 ROI 左边界
roi_top 128 ROI 上边界
roi_right 640 ROI 右边界
roi_bottom 352 ROI 下边界
input_width 224 模型输入宽度
input_height 224 模型输入高度
cmd_vel_topic cmd_vel 速度控制话题
image_topic hbmem_img 图像输入话题
odom_topic odom 里程计话题

八、安装与编译

第一步:安装网页端依赖

cd /userdata/dev_ws/src/line_follower_aliyun/dev_front
pip install -r requirements.txt

如果网络较慢,可以使用清华源:

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

第二步:安装 ROS2 依赖

sudo apt update
sudo apt install ros-humble-tf2 ros-humble-tf2-ros

同时需要确保系统已经安装或工作空间中已经包含以下地平线相关包:

dnn_node
hbm_img_msgs
hobot_cv
hobot_usb_cam
hobot_codec
hobot_shm
websocket
originbot_bringup

这些包 OriginBot / RDK 机器人已经预装。

第三步:编译 ROS2 功能包

cd /userdata/dev_ws
colcon build --symlink-install --packages-select line_follower_aliyun
source install/setup.bash

编译成功后,应能找到可执行节点:

ros2 pkg executables line_follower_aliyun

正常应看到类似输出:

line_follower_aliyun line_follower_maze

九、启动步骤

第一步:确认网页端和 ROS2 参数路径一致

网页端配置:

/userdata/dev_ws/src/line_follower_aliyun/dev_front/config/app_config.yaml

检查:

runtime:
  parse_result_path: "/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt"

ROS2 参数配置:

line_follower_aliyun/config/line_follower_maze.yaml

检查:

data_path: "/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt"

这两个路径必须完全一致。

第二步:启动网页端

cd /userdata/dev_ws/src/line_follower_aliyun/dev_front
python main.py

启动后浏览器访问:

http://机器人IP:7860

在网页中输入阿里云百炼 API Key,然后选择三个岔路口的动作,点击“解析”。

解析成功后,会生成:

/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt

可以查看文件内容:

cat /userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt

示例:

1-0
2-1
3-2

第三步:点击网页“发车”

网页点击“发车”后,会执行配置中的命令:

ros2 launch line_follower_aliyun line_follower_maze.launch.py

也可以不用网页,手动启动:

cd /userdata/dev_ws
source install/setup.bash
ros2 launch line_follower_aliyun line_follower_maze.launch.py

如果需要指定参数文件:

ros2 launch line_follower_aliyun line_follower_maze.launch.py \
  params_file:=/userdata/dev_ws/src/line_follower_aliyun/config/line_follower_maze.yaml

十、USB 摄像头设备号说明

usb_cam_web.launch.py 中默认摄像头设备为:

default_value='/dev/video8'

如果你的摄像头不是 /dev/video8,可以先查看设备:

ls /dev/video*

或:

v4l2-ctl --list-devices

然后修改:

line_follower_aliyun/launch/usb_cam_web.launch.py

把:

default_value='/dev/video8'

改成实际设备,例如:

default_value='/dev/video0'
Attation

当前总启动文件 line_follower_maze.launch.py 没有把 device 参数显式传递给 usb_cam_web.launch.py。如果希望通过命令行直接传 device:=/dev/video0,建议同步修改总 launch 文件,或者直接改 usb_cam_web.launch.py 的默认值。

十一、常用调试命令

1. 查看话题列表

ros2 topic list

重点检查:

/image
/hbmem_img
/cmd_vel
/odom

2. 查看摄像头原始图像频率

ros2 topic hz /image

3. 查看 NV12 图像频率

ros2 topic hz /hbmem_img

如果 /image 有数据但 /hbmem_img 没有数据,优先检查 hobot_codechobot_shm 是否正常启动。

4. 查看底盘速度指令

ros2 topic echo /cmd_vel

正常巡线时应该能看到:

linear:
  x: 0.1
angular:
  z: ...

5. 查看里程计数据

ros2 topic echo /odom

转弯判断依赖 /odom 中的姿态四元数。如果 /odom 没有数据,车辆可能无法正确判断转弯完成。

6. 单独查看摄像头显示

ros2 run rqt_image_view rqt_image_view

选择 /image 话题查看图像。

十二、常见问题

1. 网页解析成功,但小车启动后没有按路线走

重点检查:

cat /userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt

确保文件格式为:

1-0
2-1
3-2

不要出现解释文字、中文说明或多余字符。

2. 网页端路径和 ROS2 路径不一致

必须保证:

# dev_front/config/app_config.yaml
parse_result_path: "/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt"

# line_follower_aliyun/config/line_follower_maze.yaml
data_path: "/userdata/dev_ws/src/line_follower_aliyun/dev_front/parse_res.txt"

如果路径不同,ROS2 节点会读取不到网页端生成的动作文件。

3. 找不到模型文件

检查模型路径:

ls -l /userdata/dev_ws/src/line_follower_aliyun/line_follower_aliyun/model/resnet18_224x224_nv12_maze.bin

如果模型放在其他位置,需要修改:

model_path: "你的模型绝对路径"

4. 摄像头没有图像

检查设备号:

ls /dev/video*
v4l2-ctl --list-devices

如果默认 /dev/video8 不存在,修改 usb_cam_web.launch.py

5. 小车一直转圈或巡线发散

优先调整:

line_center_x: 320.0
angular_gain_divisor: 200.0
line_follow_linear_speed: 0.1

建议:

现象 调整方向
转向太猛 增大 angular_gain_divisor
转向太慢 减小 angular_gain_divisor
速度太快,容易冲出线 减小 line_follow_linear_speed
中心偏一边 调整 line_center_x

6. 岔路口识别过早或过晚

调整:

cross_detect_y_threshold: 240.0
go_time: 2.3
现象 调整方向
过早认为到达岔路口 降低或重新标定 cross_detect_y_threshold
到路口后不触发 提高 cross_detect_y_threshold
转弯前冲太远 减小 go_time
转弯前冲不够 增大 go_time

7. 转弯角度不准

优先检查 /odom

ros2 topic echo /odom

然后调整:

turning_target_angle: 1.57
turning_finish_tolerance: 0.1
turning_vth: 1.0
现象 调整方向
转不到 90° 增大 turning_target_angle 或减小 turning_finish_tolerance
转过头 减小 turning_target_angle 或降低 turning_vth
转弯抖动 增大 turning_finish_tolerance 或降低 turning_vth