一文带你完成20届智能车地瓜赛道备赛
第20届智能车竞赛备赛指南 本文为第20届大学生智能车竞赛提供系统化的备赛指导,涵盖竞赛规则解读、硬件选型建议、ROS环境配置以及三大核心任务(巡线避障、智能扫码、远程控制)的详细技术方案。针对OriginCar系列平台(RDK X3/X5)给出性能对比与选型建议,重点推荐RDK X5的高算力优势。指南包含完整的开发流程:从环境搭建、功能包迁移到系统集成,特别强调巡线算法的优化策略和二维码识别的高
🏆 第20届全国大学生智能车竞赛备赛指南
📅 注意!!!:本文并不能保证帮助完赛,仅提供完赛思路和参考代码,完赛需要个人具备一定工程能力,实际开发过程中基础问题请参考RDK手册、ROS2入门教程 和求助大模型
🎯 目标:帮助参赛团队高效完成备赛,提升竞技水平
📊 版本:v3.0 (最后更新:2025年7月11日)
📋 目录
- 🏆 第20届全国大学生智能车竞赛备赛指南
- 📋 目录
- 🎯 前言
- 📚 适用对象
- 📝 内容概览
- 📖 比赛规则
- 📋 官方资料
- 🤔 个人规则理解
- 📝 规则要点总结
- 🚗 车模要求与硬件平台
- ⚠️ 重要注意事项
- 🔧 硬件配置对比
- 📊 性能评价与选择建议
- OriginCar (RDK X3)
- OriginCar Pro (RDK X5) 🔥 强烈推荐
- ⚙️ ROS包迁移
- 🛠️ 环境准备
- RDK X3 配置
- 🔧 基础环境配置
- 📦 功能包迁移
- RDK X5 配置
- 🔧 基础环境配置
- 📦 功能包迁移
- 🏁 任务一:巡线避障扫码
- 🎯 技术方案选择
- Part 1: 巡线功能实现
- 📚 推荐资源
- 🚀 快速部署
- Step 1: 工作空间创建
- Step 2: 源码下载
- Step 3: 环境配置与编译
- ⚙️ 节点配置优化
- 🔧 摄像头和图像数据流配置
- 🚀 启动与测试
- 🛠️ 常见问题与解决方案
- 🎯 测试验证
- 📈 模型训练与优化
- 📦 获取控制功能包
- 🔧 编译与配置
- 🚦 系统启动流程
- 🎯 比赛用精简配置
- 📈 性能调优指南
- 🚧 Part 2: 避障功能实现
- 🔍 避障系统原理
- 📦 获取避障检测包
- 🧠 模型训练与部署
- 训练资源推荐
- 🔧 模型配置
- 🖥️ 调试环境配置
- 🧪 测试与验证
- 🔗 集成启动配置
- 🧠 智能避障控制算法
- 核心控制逻辑
- 🔧 关键参数配置
- 📊 参数调优指南
- 💡 高级优化策略
- 🚀 系统集成启动
- 📈 性能监控与调试
- 📱 Part3:智能扫码系统
- 🔧 技术实现方案
- 总体思路
- 🎯 核心技术流程
- 📝 控制逻辑修改
- 1. 主控制逻辑
- 2. 二维码跟踪算法
- 📚 二维码解析实现
- 方案一:基于OpenCV + ZBar
- 方案二:ROS节点集成
- ⚙️ 参数配置优化
- 关键参数设定
- 🎯 集成测试流程
- 1. 训练数据准备
- 2. 测试验证步骤
- 3. 性能调优技巧
- 📊 故障排除指南
- 📱 二维码扫描库推荐
- 📚 参考资源
- ⚙️ 参数调优建议
- 🔧 技术实现方案
- 🎮 任务二:远程控制
- 🔧 硬件优化建议
- 网络性能提升
- 📱 远程控制实现
- 方案一:基于摄像头图像的远程控制 📹
- 方案二:ROS2节点级远程控制 🎛️
- 🤖 大模型图生文功能
- 端侧部署方案(RDK X5推荐)
- 云端推理方案(推荐)
- 🖥️ 上位机调试环境
- 🔧 硬件优化建议
- 🅿️ 任务三:智能停车系统
- 复用现有框架
- ⚡ 调度优化
- 🚀 优化目标
- 🔧 实现思路
🎯 前言
欢迎来到第20届全国大学生智能车竞赛!作为第19届的参赛选手,我将在本文中分享实战经验和实用建议,帮助大家高效完成备赛。
📚 适用对象
- 🆕 新手参赛者:建议先阅读官方 第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛规则
- 🎖️ 经验选手:可重点关注优化技巧和新思路
- 🎓 指导老师:可参考整体技术方案和学生培养思路
📝 内容概览
本文涵盖:
- 📖 比赛规则解读与理解
- 🚗 硬件平台选择与配置
- ⚙️ ROS2环境搭建与调试
- 🏁 三大任务详细实现方案
- ⚡ 高级调度优化技巧
💡 使用建议:
- 按需阅读,重点关注感兴趣的部分
- 新手建议按顺序阅读,老手可直接跳转到优化章节
- 每个章节都有对应的参考链接和实用资源
📖 比赛规则
📋 官方资料
- 📄 详细规则:第二十届全国大学生智能车竞赛-地瓜机器人智慧医疗挑战赛规则
- 🎁 资料获取:第二十届全国大学生智能汽车竞赛地瓜机器人创意组智慧医疗挑战赛
- 💬 官方交流群:建议加入官方QQ群获取最新动态
🤔 个人规则理解
⏳ 状态:待补充,将在后续更新中详细展开
📝 规则要点总结
- 🏃 任务流程:巡线 → 避障 → 扫码 → 远程控制 → 停车
- ⏱️ 时间限制:单次任务完成时间有上限要求
- 🏆 评分标准:完成度、用时、稳定性综合评分
- ⚠️ 安全要求:必须确保车辆和人员安全
🚗 车模要求与硬件平台
⚠️ 重要注意事项
- 🚫 禁止改装:请勿擅自更换核心部件(如拆壳、换电机等),违者将被取消资格
- ✅ 允许升级:可加装风扇散热或更换更好的 WiFi 模块
- 📋 检录要求:比赛现场需要进行硬件检录,确保符合规范
🔧 硬件配置对比
| 项目 | OriginCar (RDK X3) | OriginCar Pro (RDK X5) |
|---|---|---|
| 主控制器 | 地瓜机器人 RDK X3 | 地瓜机器人 RDK X5 |
| 核心算力 (BPU) | 5 TOPS | 10 TOPS |
| 内存 | 4GB LPDDR4 | 8GB LPDDR4 |
| 关键传感器 | 单目摄像头 (1080P) | 单目摄像头 (1080P) + 深度相机 |
| 💡 推荐指数 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 💰 价格区间 | 经济型 | 高性能型 |
📊 性能评价与选择建议
OriginCar (RDK X3)
- ✅ 优势:
- 成本相对较低,适合预算有限的团队
- 能完成所有比赛任务
- 社区资源丰富,问题解决方便
- ❌ 劣势:
- 对算法优化要求较高
- 多模型同时运行时可能出现性能瓶颈
- 内存限制可能影响复杂算法部署
OriginCar Pro (RDK X5) 🔥 强烈推荐
- ✅ 优势:
- 算力翻倍,AI模型运行更流畅
- CPU和内存全面升级,多任务处理能力强
- 深度相机提供额外的感知维度
- 更好的散热设计,稳定性更高
- ❌ 劣势:
- 成本相对较高
💡 选择建议:
- 预算充足的团队:优先选择 RDK X5
- 注重性价比的团队:RDK X3 也能很好完成任务
- 首次参赛的团队:推荐 RDK X5,降低技术门槛
⚙️ ROS包迁移
📚 新手提示:如首次接触 ROS2,建议先阅读 ROS2入门教程
🎥 视频资源:推荐观看B站相关ROS2教程视频加深理解
🛠️ 环境准备
在开始之前,请确保:
- ✅ SD卡容量至少32GB,推荐64GB
- ✅ 网络连接稳定,支持SSH访问
- ✅ PC端安装SSH客户端(推荐MobaXterm或VSCode)
- ✅ 准备好官方origincar功能包
RDK X3 配置
🔧 基础环境配置
-
💾 烧录系统镜像
- 按 RDK 手册烧录最新 RDK X3 镜像到 SD 卡
- 插入 OriginCar,上电后:红灯常亮、绿灯闪烁 = 正常状态
💡 优化建议:烧录 server 端镜像以节省计算资源
📥 镜像下载:官方镜像下载地址 -
🌐 网络配置
- 确保 OriginCar 可联网,PC 端可通过 SSH 连接
- 有线连接时,确保 IP 同网段,默认静态 IP:
192.168.127.10 - WiFi配置可通过图形界面或命令行完成
-
ℹ️ 系统信息检查
# 查看系统信息 rdkos_info -
🔄 系统更新
# 更新系统组件 sudo rdk-miniboot-update sudo apt update && sudo apt full-upgrade # 清理缓存(可选) sudo apt autoremove sudo apt autoclean⚠️ 故障排除:截至 2025.7.1,RDK X3 最新镜像为 v3.0.0,若遇 GPG key 错误,使用以下命令修复:
sudo apt install gpg cp /usr/share/keyrings/ros-archive-keyring.gpg /usr/share/keyrings/ros-archive-keyring.gpg.b && rm /usr/share/keyrings/ros-archive-keyring.gpg sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key | sudo gpg --dearmor -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://mirrors4.tuna.tsinghua.edu.cn/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update
📦 功能包迁移
-
🏗️ 创建工作空间并迁移功能包
# 创建ROS2工作空间 mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src # 检查目录结构 ls -la📁 目录结构:上传官方 origincar 功能包,确保目录结构如下:
~/ros2_ws/ └── src/ └── origincar/ ├── 3rdparty/ ├── origincar_base/ # 底盘控制包 ├── origincar_bringup/ # 启动文件包 ├── origincar_description/ # 机器人描述文件 └── origincar_msg/ # 消息定义包 -
📚 安装依赖包
# 安装colcon编译工具 pip3 install colcon-common-extensions # 安装ROS2相关依赖包 sudo apt install \ ros-humble-navigation2 \ ros-humble-nav2-bringup \ ros-humble-robot-localization \ ros-humble-teleop-twist-keyboard \ python3-ament-package \ ros-humble-ament-cmake \ ros-humble-cv-bridge \ ros-humble-image-transport # 验证安装 pip3 show colcon-common-extensions -
🔨 编译功能包
# 进入工作空间根目录 cd ~/ros2_ws # 设置环境变量 source /opt/tros/humble/setup.bash # 编译(首次编译可能较慢) colcon build --symlink-install # 检查编译结果 ls install/✅ 编译成功标志:出现
install/目录且无错误输出
🐛 常见问题:缺少依赖包时会有明确的错误提示,按提示安装即可 -
🧪 验证安装
# 设置环境变量 source ~/ros2_ws/install/setup.bash # 启动底盘节点 ros2 launch origincar_bringup origincar_base.launch.py新开终端测试键盘控制:
# 设置环境变量 source /opt/tros/humble/setup.bash # 启动键盘控制 ros2 run teleop_twist_keyboard teleop_twist_keyboard✅ 验证成功:小车能够响应键盘控制命令即表示环境配置完成
RDK X5 配置
🔧 基础环境配置
-
💾 烧录系统镜像
- 按 RDK 手册烧录最新 RDK X5 镜像到 SD 卡
- 插入 OriginCar Pro,上电后:绿灯常亮、红灯闪烁 = 正常状态
💡 新特性:RDK X5 支持更快的启动速度和更稳定的系统
-
🌐 网络配置
- 确保 OriginCar 可联网,PC 端可通过 SSH 连接
- 支持 RDK Studio 闪连功能,操作更便捷
- 有线连接时,确保 IP 同网段,默认静态 IP:
192.168.127.10
🚀 RDK Studio:图形化连接工具,支持一键连接和文件传输
-
ℹ️ 系统信息检查
# 查看系统版本(X5有专门的版本信息) rdkos_info # 查看BPU状态 hrut_somstatus -
🔄 系统更新
# 更新系统组件 sudo rdk-miniboot-update sudo apt update && sudo apt full-upgrade # 检查更新状态 apt list --upgradable
📦 功能包迁移
-
🏗️ 创建工作空间并迁移功能包
# 创建工作空间 mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src📁 目录结构:上传官方 origincar 功能包,确保目录结构如下:
~/ros2_ws/ └── src/ └── origincar/ ├── 3rdparty/ # 第三方依赖包 ├── origincar_base/ # 底盘控制包 ├── origincar_bringup/ # 启动文件包 ├── origincar_description/ # 机器人描述文件 └── origincar_msg/ # 消息定义包 -
📚 安装依赖包
# 安装colcon编译工具 pip3 install colcon-common-extensions # 安装ROS2相关依赖包(X5版本优化) sudo apt install \ ros-humble-navigation2 \ ros-humble-nav2-bringup \ ros-humble-robot-localization \ ros-humble-teleop-twist-keyboard \ python3-ament-package \ ros-humble-cv-bridge \ ros-humble-image-transport -
🔨 编译功能包
# 进入工作空间 cd ~/ros2_ws # 编译(X5编译速度更快) colcon build --symlink-install # 检查编译结果 echo "编译完成,检查安装目录..." ls -la install/ -
🧪 验证安装
# 启动底盘节点 source ~/ros2_ws/install/setup.bash ros2 launch origincar_bringup origincar_base.launch.py新开终端测试键盘控制:
source /opt/tros/humble/setup.bash ros2 run teleop_twist_keyboard teleop_twist_keyboard✅ 验证成功:小车能够响应键盘控制命令即表示环境配置完成
🏁 任务一:巡线避障扫码
🎯 任务目标:实现自主巡线、智能避障、精准扫码的完整功能链
⏱️ 预期时间:熟练后单次完成时间可控制在10秒以内
任务一包含三个核心功能:🛣️ 巡线 + 🚧 避障 + 📱 扫码
🎯 技术方案选择
我为大家提供两种成熟的实现思路,各有优劣:
| 方案 | 技术栈组合 | 优势分析 | 劣势分析 | 适用场景 |
|---|---|---|---|---|
| 方案一 | ResNet 巡线 + YOLOv5s 避障 + 追踪二维码车库 | ✅ 技术成熟稳定 ✅ 巡线精度高 ✅ 社区支持好 |
❌ 模型切换复杂 ❌ 帧率相对较低 ❌ 调试难度大 |
追求稳定性的团队 |
| 方案二 | YOLOv5s 全功能检测(巡线+避障+扫码+车库) | ✅ 统一模型架构 ✅ 易于维护升级 ✅ RDK X3 可达30fps ✅ 部署简单 |
❌ 单一模型压力大 ❌ 需要大量训练数据 ❌ 精度依赖数据质量 |
注重开发效率的团队 |
🔥 推荐方案二的理由:
- YOLOv5s 巡线效果优秀,可同时检测多种目标
- 统一的模型训练和部署流程,减少维护成本
- 对 RDK X3 算力要求更友好,X5 上性能更佳
- 便于后续功能扩展和优化
💡 经验分享:
- 作者去年使用方案一在决赛中跑出24秒的成绩
- 方案二在维护性和实现难度上更有优势
- 建议新手从方案二入手,有经验后可尝试方案一优化
📝 使用建议:选择方案二的同学可以快速浏览巡线部分,重点关注 避障功能实现 部分
Part 1: 巡线功能实现
🎯 功能目标:实现稳定、精准的赛道中心线检测和跟踪
📊 性能指标:检测精度>95%,处理帧率>20fps
📚 推荐资源
建议使用 Nodehub 中的优质功能包,这些包经过实战验证,稍作修改即可高效完成任务:
- 🌐 Nodehub 平台:地瓜机器人官方算法市场
- 📦 核心功能包:
💡 选择建议:这些包来自社区贡献,经过多次比赛验证,是快速上手的最佳选择
🚀 快速部署
Step 1: 工作空间创建
# 创建比赛专用工作空间
mkdir -p ~/ros2_ws/src/racing_car
cd ~/ros2_ws/src/racing_car
# 验证当前路径
pwd # 应显示: /root/ros2_ws/src/racing_car
Step 2: 源码下载
根据硬件平台选择对应分支:
# 🔧 RDK X5
git clone https://github.com/wunuo1/racing_track_detection_resnet.git -b feature-x5
# 🔧 RDK X3
git clone https://github.com/wunuo1/racing_track_detection_resnet.git -b feature-x3
# 验证下载结果
ls -la racing_track_detection_resnet/
💡 备用方案:
- 若无法使用 git,可从 GitHub 网页下载对应分支的 zip 文件
- 注意选择正确的分支:feature-x5 或 feature-x3
- 下载后需要解压到正确的目录结构
Step 3: 环境配置与编译
# 🔧 配置环境变量(首次必需)
source /opt/tros/humble/setup.bash
# 💡 自动化配置:添加到 ~/.bashrc 避免重复操作
echo "# ROS2 环境配置" >> ~/.bashrc
echo "source /opt/tros/humble/setup.bash" >> ~/.bashrc
echo "source ~/ros2_ws/install/setup.bash" >> ~/.bashrc
# 🔨 编译项目
cd ~/ros2_ws
colcon build --symlink-install
# 🧪 验证编译结果
echo "编译完成状态:"
ls -la install/racing_track_detection_resnet/
✅ 编译状态判断:
- 正常情况:无错误输出,install目录生成成功
- 异常情况:通常为依赖包缺失,按错误提示安装
- 警告信息:多数可以忽略,不影响功能实现
⚙️ 节点配置优化
修改 launch 文件,优化启动配置。编辑赛道检测的 launch.py 文件:
def generate_launch_description():
racing_track_detection_resnet18_node = Node(
package='racing_track_detection_resnet',
executable='racing_track_detection_resnet',
output='screen',
parameters=[
{"sub_img_topic": "/hbmem_img"},
{"model_path": "config/race_track_detection.bin"}
],
arguments=['--ros-args', '--log-level', 'warn']
)
return LaunchDescription([
racing_track_detection_resnet18_node
])
🔧 摄像头和图像数据流配置
数据流分析:
赛道检测节点需要订阅 /hbmem_img 话题,这是摄像头发布的 NV12 格式的高效共享内存图像数据。理解数据流对后续调试至关重要。
创建摄像头启动文件:
在 origincar_bringup 包中创建 camera.launch.py 文件,这是系统的核心入口:
import os
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import IncludeLaunchDescription
from ament_index_python import get_package_share_directory
def generate_launch_description():
# NV12编解码节点 - 将MJPEG转换为共享内存格式
nv12_codec_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('hobot_codec'),
'launch/hobot_codec_decode.launch.py'
)
),
launch_arguments={
'codec_in_mode': 'ros', # 输入模式:ROS话题
'codec_out_mode': 'shared_mem', # 输出模式:共享内存
'codec_sub_topic': '/image', # 订阅原始图像
'codec_pub_topic': '/hbmem_img' # 发布共享内存图像
}.items()
)
# WebSocket调试节点 - 用于实时预览
web_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('websocket'),
'launch/websocket.launch.py'
)
),
launch_arguments={
'websocket_image_topic': '/image',
'websocket_smart_topic': '/racing_track_center_detection'
}.items()
)
# USB摄像头节点配置
usb_cam_node = Node(
package='hobot_usb_cam',
executable='hobot_usb_cam',
name='hobot_usb_cam',
parameters=[
{"camera_calibration_file_path": "/opt/tros/lib/hobot_usb_cam/config/usb_camera_calibration.yaml"},
{"frame_id": "default_usb_cam"},
{"framerate": 30}, # 帧率:30fps
{"image_width": 640}, # 图像宽度
{"image_height": 480}, # 图像高度
{"io_method": "mmap"}, # 内存映射方式
{"pixel_format": "mjpeg"}, # 像素格式
{"video_device": "/dev/video8"}, # 设备节点(需根据实际调整)
{"zero_copy": False}
],
arguments=['--ros-args', '--log-level', 'error']
)
return LaunchDescription([
usb_cam_node,
nv12_codec_node,
web_node,
])
🔍 关键参数说明:
video_device: 通常为/dev/video8,可通过ls /dev/video*查看framerate: 推荐 30fps,过高可能影响处理性能image_width/height: 640x480 是性能与质量的良好平衡点
📊 节点数据流图:
hobot_usb_cam ──(MJPEG)──> nv12_codec_node ──(NV12)──> racing_track_detection_resnet
│ │
└──(MJPEG)──> web_node <──(检测结果)───────────────────────┘
🚀 启动与测试
分步启动命令:
# 1. 启动赛道检测节点
cd ~/ros2_ws/src/racing_car/racing_track_detection_resnet/config
ros2 launch racing_track_detection_resnet racing_track_detection_resnet.launch.py
# 2. 启动摄像头节点(新终端)
ros2 launch origincar_bringup camera.launch.py
🛠️ 常见问题与解决方案
问题1:开发环境推荐
推荐使用 VSCode + Remote-SSH 插件进行远程开发:
- 安装 C/C++、Python、ROS 等插件
- 支持代码补全、语法高亮、调试功能
- 便于多文件编辑和项目管理
问题2:QoS策略不兼容
如遇到以下错误:
[racing_track_detection_resnet-1] [WARN] [1751361111.644720579] [GetLineCoordinate]:
New publisher discovered on topic '/hbmem_img', offering incompatible QoS.
No messages will be sent to it. Last incompatible policy: RELIABILITY_QOS_POLICY
解决方案: 修改订阅者QoS策略
// 在 racing_track_detection_resnet 节点中添加
rclcpp::QoS img_qos(10);
img_qos.reliability(rclcpp::ReliabilityPolicy::BestEffort); // 匹配发布者策略
subscriber_hbmem_ = this->create_subscription<hbm_img_msgs::msg::HbmMsg1080P>(
sub_img_topic_,
img_qos, // 使用兼容的QoS
std::bind(&TrackDetectionNode::subscription_callback, this, std::placeholders::_1)
);
重新编译后问题即可解决。
🎯 测试验证
启动成功后,访问 http://[设备IP]:8000 查看:
- 摄像头实时图像
- 赛道检测结果
- 中心点坐标信息
📈 模型训练与优化
预训练模型效果评估:
默认模型在标准环境下表现一般,建议训练自定义模型以适应具体赛道环境。
训练资源推荐:
模型部署流程:
-
准备模型文件:
- 训练完成后转换为
.bin格式 - 将模型文件放置在
config/目录下
- 训练完成后转换为
-
更新启动配置:
racing_track_detection_resnet18_node = Node(
package='racing_track_detection_resnet',
executable='racing_track_detection_resnet',
output='screen',
parameters=[
{"sub_img_topic": "/hbmem_img"},
{"model_path": "config/your_custom_model.bin"} # 使用自定义模型
],
arguments=['--ros-args', '--log-level', 'warn']
)
- 性能验证:
- 重新启动节点
- 在Web界面观察检测效果
- 记录模型推理时间和精度
📦 获取控制功能包
推荐使用 Nodehub 中的成熟巡线控制包:
cd ~/ros2_ws/src/racing_car
git clone https://github.com/nodehubs/racing_control.git
💡 备用方案:如无法使用 git,可从网页下载 ZIP 包后上传
🔧 编译与配置
cd ~/ros2_ws
colcon build --package-select racing_control --symlink-install
关键参数调整:
修改 racing_control/launch/racing_control.launch.py 中的控制参数:
# 巡线控制参数
parameters=[
{"follow_linear_speed": 0.5}, # 直线速度(m/s)
{"follow_angular_ratio": 1.2}, # 角速度系数
{"max_angular_velocity": 1.0}, # 最大角速度限制
{"center_offset_threshold": 50}, # 中心偏移阈值(像素)
]
🚦 系统启动流程
完整启动序列(4个核心节点):
# Terminal 1: 底盘控制
ros2 launch origincar_base origincar_bringup.launch.py
# Terminal 2: 摄像头与图像处理
ros2 launch origincar_bringup camera.launch.py
# Terminal 3: 赛道检测
ros2 launch racing_track_detection_resnet racing_track_detection_resnet.launch.py
# Terminal 4: 巡线控制
ros2 launch racing_control racing_control.launch.py
🎯 比赛用精简配置
为提高系统稳定性,比赛时建议关闭Web调试功能:
# camera_race.launch.py - 去除webnode的精简版本
import os
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.launch_description_sources import PythonLaunchDescriptionSource
from launch.actions import IncludeLaunchDescription
from ament_index_python import get_package_share_directory
def generate_launch_description():
nv12_codec_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('hobot_codec'),
'launch/hobot_codec_decode.launch.py'
)
),
launch_arguments={
'codec_in_mode': 'ros',
'codec_out_mode': 'shared_mem',
'codec_sub_topic': '/image',
'codec_pub_topic': '/hbmem_img'
}.items()
)
usb_cam_node = Node(
package='hobot_usb_cam',
executable='hobot_usb_cam',
name='hobot_usb_cam',
parameters=[
{"camera_calibration_file_path": "/opt/tros/lib/hobot_usb_cam/config/usb_camera_calibration.yaml"},
{"frame_id": "default_usb_cam"},
{"framerate": 30},
{"image_width": 640},
{"image_height": 480},
{"io_method": "mmap"},
{"pixel_format": "mjpeg"},
{"video_device": "/dev/video8"},
{"zero_copy": False}
],
arguments=['--ros-args', '--log-level', 'error']
)
return LaunchDescription([
usb_cam_node,
nv12_codec_node,
])
📈 性能调优指南
实时监控命令:
# 查看话题发布频率
ros2 topic hz /racing_track_center_detection
# 监控系统资源使用
htop
# 检查消息延迟
ros2 topic echo /racing_track_center_detection --once
关键调优参数:
| 参数名称 | 推荐范围 | 影响说明 |
|---|---|---|
follow_linear_speed |
0.5-1.0 m/s | 基础前进速度,过高影响稳定性 |
follow_angular_ratio |
0.8-1.5 | 转向响应强度,过大易震荡 |
⚠️ 注意事项:此配置仅为基础版本,后续避障和扫码功能需要进一步集成优化。
🚧 Part 2: 避障功能实现
🎯 核心目标:在巡线基础上实现动态障碍物检测与智能避障
📊 技术指标:避障成功率100%,响应时间<50ms,稳定性优先
🔍 避障系统原理
技术方案:
- 检测模块:基于YOLOv5s的实时障碍物检测
- 判断逻辑:结合障碍物位置与赛道中心线进行距离评估
- 控制策略:优先级决策 → 避障机动 → 恢复巡线
决策流程图:
摄像头图像 → YOLOv5检测 → 距离判断 → 控制决策
↓ ↓ ↓
[障碍物位置] [安全距离] [避障/巡线]
📦 获取避障检测包
克隆功能包:
cd ~/ros2_ws/src/racing_car
# RDK X5 版本
git clone https://github.com/wunuo1/racing_obstacle_detection_yolo.git -b feature-x5
# RDK X3 版本
git clone https://github.com/wunuo1/racing_obstacle_detection_yolo.git -b feature-x3
💡 备用方案:从GitHub网页下载对应分支的ZIP包
编译安装:
cd ~/ros2_ws
colcon build --packages-select racing_obstacle_detection_yolo --symlink-install
🧠 模型训练与部署
训练资源推荐
核心教程:
🔧 模型配置
1. 修改配置文件:
编辑 racing_obstacle_detection_yolo/config/yolov5sconfig.json:
{
"model_file": "/root/ros2_ws/src/racing_car/racing_obstacle_detection_yolo/config/your_custom_model.bin",
"class_num": 3,
"cls_names_list": "/root/ros2_ws/src/racing_car/racing_obstacle_detection_yolo/config/obstacles.list"
}
2. 更新类别列表:
编辑 obstacles.list 文件,根据你的训练数据定义:
construction_cone
qr_code
park
3. 修改启动文件:
更新 racing_obstacle_detection_yolo.launch.py:
def generate_launch_description():
# 图像尺寸参数
image_width_launch_arg = DeclareLaunchArgument(
"dnn_sample_image_width", default_value=TextSubstitution(text="640")
)
image_height_launch_arg = DeclareLaunchArgument(
"dnn_sample_image_height", default_value=TextSubstitution(text="480")
)
# 障碍物检测节点
racing_obstacle_detection_yolov5_node = Node(
package='racing_obstacle_detection_yolo',
executable='racing_obstacle_detection_yolo',
output='screen',
parameters=[
{"is_shared_mem_sub": True},
{"sub_img_topic": "/hbmem_img"},
{"config_file": "/root/ros2_ws/src/racing_car/racing_obstacle_detection_yolo/config/yolov5sconfig.json"},
{"confidence_threshold": 0.7}, # 置信度阈值
{"nms_threshold": 0.5}, # NMS阈值
],
arguments=['--ros-args', '--log-level', 'warn']
)
return LaunchDescription([
image_width_launch_arg,
image_height_launch_arg,
racing_obstacle_detection_yolov5_node
])
🖥️ 调试环境配置
创建障碍物调试用摄像头配置:
创建 obstacle_camera.launch.py:
def generate_launch_description():
nv12_codec_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(
get_package_share_directory('hobot_codec'),
'launch/hobot_codec_decode.launch.py'
)
),
launch_arguments={
'codec_in_mode': 'ros',
'codec_out_mode': 'shared_mem',
'codec_sub_topic': '/image',
'codec_pub_topic': '/hbmem_img'
}.items()
)
# WebSocket调试 - 专门用于障碍物检测可视化
web_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
get_package_share_directory('websocket') + '/launch/websocket.launch.py'
),
launch_arguments={
'websocket_image_topic': '/image',
'websocket_image_type': 'mjpeg',
'websocket_smart_topic': '/racing_obstacle_detection' # 障碍物检测话题
}.items()
)
usb_cam_node = Node(
package='hobot_usb_cam',
executable='hobot_usb_cam',
name='hobot_usb_cam',
parameters=[
{"camera_calibration_file_path": "/opt/tros/lib/hobot_usb_cam/config/usb_camera_calibration.yaml"},
{"frame_id": "default_usb_cam"},
{"framerate": 30},
{"image_width": 640},
{"image_height": 480},
{"io_method": "mmap"},
{"pixel_format": "mjpeg"},
{"video_device": "/dev/video8"},
{"zero_copy": False}
],
arguments=['--ros-args', '--log-level', 'error']
)
return LaunchDescription([
usb_cam_node,
nv12_codec_node,
web_node,
])
🧪 测试与验证
启动检测测试:
# Terminal 1: 启动障碍物检测
ros2 launch racing_obstacle_detection_yolo racing_obstacle_detection_yolo.launch.py
# Terminal 2: 启动调试摄像头
ros2 launch origincar_bringup obstacle_camera.launch.py
验证检查项:
- Web界面显示检测框
- 置信度数值合理(>0.7)
- 检测响应时间<100ms
- 无漏检或误检
🔗 集成启动配置
创建统一启动文件 camera_all.launch.py:
def generate_launch_description():
# 图像编解码
nv12_codec_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('hobot_codec'), 'launch/hobot_codec_decode.launch.py')
),
launch_arguments={
'codec_in_mode': 'ros',
'codec_out_mode': 'shared_mem',
'codec_sub_topic': '/image',
'codec_pub_topic': '/hbmem_img'
}.items()
)
# 赛道检测模块
racing_track_detection_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('racing_track_detection_resnet'), 'launch', 'racing_track_detection_resnet.launch.py')
)
)
# 障碍物检测模块
racing_obstacle_detection_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
os.path.join(get_package_share_directory('racing_obstacle_detection_yolo'), 'launch', 'racing_obstacle_detection_yolo.launch.py')
)
)
# 调试WebSocket(可选)
web_node = IncludeLaunchDescription(
PythonLaunchDescriptionSource(
get_package_share_directory('websocket') + '/launch/websocket.launch.py'
),
launch_arguments={
'websocket_image_topic': '/image',
'websocket_image_type': 'mjpeg',
'websocket_smart_topic': '/racing_obstacle_detection'
}.items()
)
# USB摄像头
usb_cam_node = Node(
package='hobot_usb_cam',
executable='hobot_usb_cam',
name='hobot_usb_cam',
parameters=[
{"camera_calibration_file_path": "/opt/tros/lib/hobot_usb_cam/config/usb_camera_calibration.yaml"},
{"frame_id": "default_usb_cam"},
{"framerate": 30},
{"image_width": 640},
{"image_height": 480},
{"io_method": "mmap"},
{"pixel_format": "mjpeg"},
{"video_device": "/dev/video8"},
{"zero_copy": False}
],
arguments=['--ros-args', '--log-level', 'error']
)
return LaunchDescription([
usb_cam_node,
nv12_codec_node,
racing_track_detection_node,
racing_obstacle_detection_node,
# web_node, # 比赛时可注释掉
])
💡 提示:调试时保留
web_node,比赛时注释掉以节省资源
🧠 智能避障控制算法
核心控制逻辑
在启动避障控制前,需要修改 racing_control 包的核心算法。主要修改文件:src/racing_car/racing_control/src/racing_control.cpp
关键决策算法:
// 核心避障决策逻辑
void processObstacleAvoidance(const TargetsMsg::SharedPtr targets_msg,
const PointMsg::SharedPtr point_msg) {
// 无障碍物 - 执行正常巡线
if(targets_msg->targets.size() == 0) {
if(!point_msg->targets.empty()) {
LineFollowing(point_msg->targets[0]);
}
return;
}
// 有障碍物 - 分析威胁等级
for(const auto &target : targets_msg->targets) {
if(target.type == "construction_cone") { // 替换为你的类别名称
// 计算障碍物底部坐标(距离代理指标)
int bottom_y = target.rois[0].rect.y_offset + target.rois[0].rect.height;
float confidence = target.rois[0].confidence;
// 距离判断逻辑
if (bottom_y < bottom_threshold_) {
// 障碍物距离较远,继续巡线
if(!point_msg->targets.empty()) {
LineFollowing(point_msg->targets[0]);
}
} else {
// 障碍物接近,执行避障
if(confidence > confidence_threshold_) {
ObstacleAvoidance(target, point_msg->targets[0]);
}
}
}
}
}
// 避障机动算法
void ObstacleAvoidance(const Target& obstacle, const Point& track_center) {
int obstacle_center_x = obstacle.rois[0].rect.x_offset + obstacle.rois[0].rect.width / 2;
int image_center_x = 320; // 假设图像宽度640
// 根据障碍物位置选择避障方向
if (obstacle_center_x < image_center_x) {
// 障碍物在左侧,向右避障
publishTwist(avoidance_linear_speed_, -avoidance_angular_speed_);
} else {
// 障碍物在右侧,向左避障
publishTwist(avoidance_linear_speed_, avoidance_angular_speed_);
}
}
🔧 关键参数配置
修改参数文件位置: racing_control/launch/racing_control.launch.py
racing_control_node = Node(
package='racing_control',
executable='racing_control',
name='racing_control',
parameters=[
# 巡线控制参数
{"follow_linear_speed": 0.3}, # 正常巡线速度
{"follow_angular_ratio": 1.2}, # 巡线角速度系数
# 避障控制参数
{"obstacle_avoidance_speed": 0.2}, # 避障时的线速度
{"obstacle_avoidance_angular_ratio": 1.8}, # 避障角速度系数
# 检测阈值参数
{"bottom_threshold": 400}, # 距离阈值(像素)
{"confidence_threshold": 0.7}, # 置信度阈值
# 安全参数
{"max_angular_velocity": 1.5}, # 最大角速度限制
{"emergency_stop_distance": 450}, # 紧急停车距离
],
output='screen'
)
📊 参数调优指南
| 参数名称 | 推荐范围 | 作用说明 | 调优技巧 |
|---|---|---|---|
bottom_threshold |
350-450 | 触发避障的距离阈值 | 数值越大越早避障,越小越激进 |
confidence_threshold |
0.6-0.8 | YOLO检测置信度阈值 | 过低易误检,过高易漏检 |
obstacle_avoidance_speed |
0.5-0.8 | 避障时前进速度 | 速度越低越安全,过低影响效率 |
avoidance_angular_ratio |
1.5-2.0 | 避障转向强度 | 需要根据赛道调整 |
💡 高级优化策略
1. 多障碍物处理:
// 选择最近的威胁障碍物
float min_distance = std::numeric_limits<float>::max();
Target nearest_obstacle;
for(const auto &target : targets_msg->targets) {
float distance = calculateDistance(target);
if(distance < min_distance) {
min_distance = distance;
nearest_obstacle = target;
}
}
2. 渐进式避障:
// 根据距离调整避障强度
float distance_ratio = static_cast<float>(bottom_y) / image_height;
float dynamic_angular_speed = base_angular_speed * (1.0 + distance_ratio);
3. 预测性避障:
// 结合赛道中心点预判最佳避障路径
int track_direction = track_center.x - image_center_x;
int obstacle_direction = obstacle_center_x - image_center_x;
// 如果障碍物阻挡预期路径,提前避障
if ((track_direction > 0 && obstacle_direction > 0) ||
(track_direction < 0 && obstacle_direction < 0)) {
early_avoidance = true;
}
🚀 系统集成启动
完整避障系统启动序列:
# Terminal 1: 底盘控制
ros2 launch origincar_base origincar_bringup.launch.py
# Terminal 2: 视觉处理模块(集成版)
ros2 launch origincar_bringup camera_all.launch.py
# Terminal 3: 智能控制
ros2 launch racing_control racing_control.launch.py
📈 性能监控与调试
实时监控命令:
# 监控检测结果
ros2 topic echo /racing_obstacle_detection --once
# 监控控制指令
ros2 topic echo /cmd_vel --once
# 检查系统延迟
ros2 topic hz /racing_track_center_detection
ros2 topic hz /racing_obstacle_detection
调试检查清单:
- 障碍物检测准确率 > 95%
- 避障响应时间 < 50ms
- 无频繁震荡现象
- 能够顺利恢复巡线
- 在不同光照条件下稳定工作
⚠️ 安全提醒:测试时请确保周围环境安全
📱 Part3:智能扫码系统
🎯 功能目标:实现快速、准确的二维码识别与内容解析
📊 性能指标:识别成功率100%,响应时间<1秒,支持多种二维码格式
🔧 技术实现方案
总体思路
扫码功能基于现有的YOLOv5检测框架,通过增加二维码类别实现目标检测,然后结合专业的二维码解析库完成内容识别。
🎯 核心技术流程
A[摄像头图像] --> B[YOLOv5检测] --> C[检测到二维码] --> D[达到阈值] --> E[停车扫码] --> F[二维码解析] --> G[内容输出] --> H[任务完成]
📝 控制逻辑修改
1. 主控制逻辑
修改 racing_control.cpp 中的控制逻辑,添加二维码检测和跟踪功能:
void processQRCodeDetection(const TargetsMsg::SharedPtr targets_msg,
const PointMsg::SharedPtr point_msg) {
bool qr_detected = false;
bool obstacle_detected = false;
Target qr_target, obstacle_target;
// 遍历检测结果,分类处理
for(const auto &target : targets_msg->targets) {
if(target.type == "qr_code") {
qr_detected = true;
qr_target = target;
} else if(target.type == "construction_cone") {
int bottom_y = target.rois[0].rect.y_offset + target.rois[0].rect.height;
if(bottom_y > obstacle_threshold_ && target.rois[0].confidence > confidence_threshold_) {
obstacle_detected = true;
obstacle_target = target;
}
}
}
// 优先级决策逻辑
if(obstacle_detected) {
// 最高优先级:避障
ObstacleAvoidance(obstacle_target, point_msg->targets[0]);
} else if(qr_detected) {
// 中优先级:二维码处理
QRCodeTracking(qr_target);
} else {
// 默认:巡线
if(!point_msg->targets.empty()) {
LineFollowing(point_msg->targets[0]);
}
}
}
2. 二维码跟踪算法
void QRCodeTracking(const Target& qr_target) {
// 计算二维码中心位置
int qr_center_x = qr_target.rois[0].rect.x_offset + qr_target.rois[0].rect.width / 2;
int qr_bottom_y = qr_target.rois[0].rect.y_offset + qr_target.rois[0].rect.height;
int image_center_x = 320; // 图像中心
// 距离判断
if(qr_bottom_y > scan_distance_threshold_) {
// 距离足够近,停车扫码
StopAndScan(qr_target);
} else {
// 距离较远,跟踪接近
TrackTowardsQR(qr_center_x, image_center_x);
}
}
void TrackTowardsQR(int qr_x, int center_x) {
float error = static_cast<float>(qr_x - center_x) / center_x;
float angular_velocity = -qr_tracking_angular_ratio_ * error;
// 限制角速度
angular_velocity = std::max(-max_angular_velocity_,
std::min(max_angular_velocity_, angular_velocity));
publishTwist(qr_tracking_linear_speed_, angular_velocity);
}
void StopAndScan(const Target& qr_target) {
// 停车
publishTwist(0.0, 0.0);
// 触发扫码流程
triggerQRScanning(qr_target);
}
📚 二维码解析实现
方案一:基于OpenCV + ZBar
安装依赖:
# 在RDK系统中安装
sudo apt update
sudo apt install libzbar-dev libzbar0
pip3 install pyzbar opencv-python
Python实现:
import cv2
from pyzbar import pyzbar
import numpy as np
class QRCodeScanner:
def __init__(self):
self.scanner_active = False
def scan_qr_code(self, image_region):
"""
扫描图像区域中的二维码
:param image_region: 裁剪后的图像区域
:return: 解析结果字符串或None
"""
try:
# 预处理图像
gray = cv2.cvtColor(image_region, cv2.COLOR_BGR2GRAY)
# 增强对比度
enhanced = cv2.equalizeHist(gray)
# 使用pyzbar解码
decoded_objects = pyzbar.decode(enhanced)
if decoded_objects:
for obj in decoded_objects:
qr_data = obj.data.decode('utf-8')
print(f"扫码成功: {qr_data}")
return qr_data
except Exception as e:
print(f"扫码错误: {e}")
return None
def crop_qr_region(self, full_image, detection_box):
"""
根据检测框裁剪二维码区域
"""
x = detection_box.x_offset
y = detection_box.y_offset
w = detection_box.width
h = detection_box.height
# 扩大裁剪区域以确保完整性
margin = 20
x_start = max(0, x - margin)
y_start = max(0, y - margin)
x_end = min(full_image.shape[1], x + w + margin)
y_end = min(full_image.shape[0], y + h + margin)
return full_image[y_start:y_end, x_start:x_end]
方案二:ROS节点集成
创建扫码服务节点:
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from std_msgs.msg import String
import cv2
from pyzbar import pyzbar
class QRScannerNode(Node):
def __init__(self):
super().__init__('qr_scanner_node')
# 订阅图像话题
self.image_subscription = self.create_subscription(
Image,
'/image',
self.image_callback,
10
)
# 发布扫码结果
self.qr_result_publisher = self.create_publisher(
String,
'/qr_scan_result',
10
)
self.bridge = CvBridge()
self.scanning_enabled = False
def image_callback(self, msg):
if not self.scanning_enabled:
return
try:
# 转换图像格式
cv_image = self.bridge.imgmsg_to_cv2(msg, "bgr8")
# 扫描二维码
result = self.scan_qr_codes(cv_image)
if result:
# 发布结果
result_msg = String()
result_msg.data = result
self.qr_result_publisher.publish(result_msg)
# 关闭扫描
self.scanning_enabled = False
except Exception as e:
self.get_logger().error(f'扫码处理错误: {e}')
def scan_qr_codes(self, image):
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 解码二维码
decoded_objects = pyzbar.decode(gray)
for obj in decoded_objects:
return obj.data.decode('utf-8')
return None
def enable_scanning(self):
self.scanning_enabled = True
self.get_logger().info('二维码扫描已启用')
def main(args=None):
rclpy.init(args=args)
node = QRScannerNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
⚙️ 参数配置优化
关键参数设定
修改 racing_control.launch.py 添加扫码相关参数:
parameters=[
# 现有参数...
# 扫码控制参数
{"qr_tracking_linear_speed": 1.15}, # 接近二维码时的速度,直接拉满急停
{"qr_tracking_angular_ratio": 1.5}, # 跟踪角速度系数
{"scan_distance_threshold": 420}, # 开始扫码的距离阈值
{"qr_confidence_threshold": 0.8}, # 二维码检测置信度
# 扫码行为参数
{"scan_timeout": 5.0}, # 扫码超时时间(秒)
{"scan_retry_count": 3}, # 扫码重试次数
{"post_scan_delay": 2.0}, # 扫码后等待时间
]
🎯 集成测试流程
1. 训练数据准备
在YOLOv5训练数据中添加二维码类别:
- 收集不同角度、光照的二维码图片
- 标注时类别设为
qr_code - 确保训练数据多样性
2. 测试验证步骤
# 1. 启动完整系统
ros2 launch origincar_base origincar_bringup.launch.py
ros2 launch origincar_bringup camera_all.launch.py
ros2 launch racing_control racing_control.launch.py
# 2. 启动扫码节点(如果使用独立节点)
ros2 run qr_scanner qr_scanner_node
# 3. 监控扫码结果
ros2 topic echo /qr_scan_result
3. 性能调优技巧
提高识别成功率:
- 优化图像预处理:增强对比度、去噪
- 调整检测阈值:平衡误检与漏检
- 多帧融合:连续多帧确认结果
优化响应速度:
- 减小图像处理分辨率
- 限制扫码区域大小
- 使用异步处理
📊 故障排除指南
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无法检测到二维码 | 模型未训练该类别 | 重新训练包含二维码的模型 |
| 检测到但无法解析 | 图像质量差/距离不当 | 调整scan_distance_threshold |
| 扫码成功率低 | 光照条件/角度问题 | 优化图像预处理算法 |
| 系统响应慢 | 图像处理负载过重 | 降低处理频率或分辨率 |
💡 实用技巧:建议在二维码检测时临时提高摄像头亮度,以提高识别成功率。
📱 二维码扫描库推荐
推荐使用OpenCV的WeChat QRCode模块,具有以下优势:
- ✅ 识别率高:对各种角度、光照条件适应性强
- ✅ 性能优秀:针对移动设备优化,速度快
- ✅ 易于集成:Python和C++接口简单
Python实现示例:
import cv2
def scan_qr_code(self, image):
"""优化的二维码扫描函数"""
# 创建检测器(只需初始化一次)
if not hasattr(self, 'qr_detector'):
self.qr_detector = cv2.wechat_qrcode.WeChatQRCode(
"detect.prototxt", "detect.caffemodel",
"sr.prototxt", "sr.caffemodel"
)
# 检测和解码
data, points = self.qr_detector.detectAndDecode(image)
if data:
return {
'content': data[0], # 二维码内容
'position': points[0] if points else None, # 位置信息
'confidence': 1.0 # 置信度
}
return None
📚 参考资源
- 🔗 Python使用示例:OpenCV WeChat QRCode样例
- 📦 模型文件下载:OpenCV第三方模型库
- 📖 技术文档:详细的API文档和配置说明
⚙️ 参数调优建议
关键参数:
scan_threshold:触发扫码的距离阈值follow_speed:跟踪二维码时的移动速度scan_timeout:扫码超时时间retry_count:扫码失败重试次数
调试技巧:
- 先在静态环境下测试二维码识别效果
- 逐步增加移动速度,观察识别稳定性
- 测试不同光照条件下的识别率
- 调整摄像头焦距和曝光参数
🎮 任务二:远程控制
🎯 任务目标:实现流畅的远程控制体验 + 智能的大模型图生文功能
� 核心技术:实时图像传输 + ROS2远程通信 + 云端AI推理
任务二的核心是实现小车的远程控制功能,这是区别于其他参赛队伍的关键优势!
🔧 硬件优化建议
网络性能提升
-
RDK X3 用户:
- 由于板载WiFi模块性能有限,强烈建议外接高性能USB网卡
- 推荐型号:debug
- 提升效果:图像传输稳定性和流畅度显著改善
-
RDK X5 用户:
- 板载WiFi模块性能已经足够强大,可直接使用
- 支持更高带宽的数据传输
- 延迟更低,控制响应更及时
📱 远程控制实现
远程控制分为两大类实现方案:
方案一:基于摄像头图像的远程控制 📹
技术架构:
摄像头采集 → 图像编码 → 网络传输 → PC端显示 → 用户操控 → 指令回传 → 小车执行
实现要点:
-
图像采集发布
- 使用
hobot_usb_cam包采集摄像头图像 - 发布
/image话题,图像格式为MJPEG - 话题类型:
sensor_msgs/msg/CompressedImage
- 使用
-
上位机显示
- 推荐使用 Foxglove 作为上位机程序
- 支持
CompressedImage类型图像显示 - 直接订阅
/image话题即可实现图像传输
-
控制指令传输
- 通过 ROS2 话题机制实现双向通信
- 低延迟的指令响应机制
方案二:ROS2节点级远程控制 🎛️
技术架构:
上位机界面 → ROS2话题发布 → 网络传输 → 下位机话题订阅 → 节点状态切换
实现细节:
-
消息定义
在src/origincar/origincar_msg/msg下创建Sign.msg文件:int32 sign_data # 控制信号数据 -
话题通信
- 上位机发布:
sign4return话题(控制指令) - 消息类型:
std_msgs::msg::Int32或自定义消息 - 下位机发布:
sign_switch话题(状态反馈) - 消息类型:
origincar_msg::msg::Sign
- 上位机发布:
-
状态管理
- 下位机订阅
sign4return实现节点控制 - 根据不同信号切换任务模式(巡线/避障/扫码等)
- 向
sign_switch发布当前状态供上位机显示
- 下位机订阅
🤖 大模型图生文功能
端侧部署方案(RDK X5推荐)
对于 RDK X5 用户,可以直接在端侧部署视觉语言模型:
- 📖 参考文档:视觉语言模型部署指南
- ⚡ 性能优势:本地推理,无网络延迟
云端推理方案(推荐)
技术流程:
- 图像采集:摄像头实时采集前方图像
- 图像预处理:缩放、裁剪、格式转换
- 云端推理:上传至云端大模型进行图像理解
- 结果返回:获取文字描述并展示
推荐服务:火山引擎 Doubao-1.5-vision-lite 模型
- 💰 性价比高:新用户送50万Token
- 🎯 效果优秀:图像理解能力强
- 🚀 响应快速:推理速度快,延迟低
快速部署:
-
环境准备
# 安装火山引擎SDK pip install volcengine-python-sdk[ark] # 验证安装 python3 -c "import volcengine; print('SDK安装成功')" -
配置API密钥
- 在火山引擎控制台获取API密钥
-
功能包获取
cd ~/ros2_ws/src/racing_car git clone https://github.com/Machao615/racing_vision_ai.git # 编译 cd ~/ros2_ws colcon build --packages-select racing_vision_ai --symlink-install -
配置说明
这个ROS2功能包的特点:- 监听
sign4return信号触发 - 当信号值达到配置的目标值时自动执行
- 订阅一帧图像并调用火山引擎API
- 返回图像的文字描述结果
- 监听
📖 详细使用方法:参考 racing_vision_ai 文档
🖥️ 上位机调试环境
环境配置步骤:
-
安装 coStudio 客户端
- 下载安装包并完成安装
- 导入
demo.json配置文件 - 按需配置模块布局
-
日志监控配置
- 添加"日志订阅"模块
- 设置命名空间过滤:仅订阅
ai_vision话题 - 配置实时显示大模型推理结果
界面布局建议:
- 左侧:实时图像显示窗口
- 右侧:AI分析结果文本框
- 底部:控制按钮和状态栏
🅿️ 任务三:智能停车系统
🎯 任务目标:实现精准的停车位识别与自动停车功能
复用现有框架
💡 实现提示:可复用任务一中的 YOLOv5s 检测框架,专门针对停车位进行优化,直接修改任务一逻辑中的追踪二维码->追踪车库即可。
⏳ 更新计划:详细的实现代码和调试技巧将在后续更新中提供
⚡ 调度优化
🎯 核心价值:这是区别于其他参赛队伍的关键优势!
🏆 竞争意义:优秀的调度系统能至少将成绩控制进30s内
🚀 优化目标
优秀的任务调度系统能够实现:
| 优化维度 | 具体目标 | 预期效果 |
|---|---|---|
| 🔄 流畅切换 | 各任务间无缝过渡,减少等待时间 | 节省2-5秒切换时间 |
| ⚡ 性能最大化 | 充分平衡硬件平台算力 | CPU合理分配避免进程互相抢占CPU |
| 🛡️ 稳定可靠 | 提高系统整体鲁棒性 | 异常恢复时间<1秒 |
| 🧠 智能决策 | 根据环境动态调整策略 | 适应性提升100% |
🔧 实现思路
核心思路是通过 ROS2 的节点管理和话题订阅机制,实现任务间的智能调度和资源分配。
具体实现:在每一个任务进行中,保证只运行必要的节点和话题,但是为了快速启动和响应不能关闭节点和话题,可以通过设置参数来控制节点的行为。
更多推荐



所有评论(0)