
简介这份资源是第二十五届中国机器人及人工智能大赛智慧药房组的参赛作品资料包面向参加机器人大赛的高校学生及指导教师尤其适合需要参考完整赛题方案、搭建仿真与实机调试环境的中高级参赛者。压缩包共150个文件约38.19MB以39个yaml配置、23个Python脚本、11个launch启动文件、10个srv服务定义为主辅以cpp源码、msg消息、pgm地图、jpg/png图像、mp3语音、pdf与md文档等覆盖感知、导航、任务调度与交互各环节。内容包含设计文档与设计源码可帮助读者理解智慧药房场景下的机器人任务流程、坐标点配置、视觉模型部署与节点通信方式并参考其目录组织与参数设置进行二次开发。目前已有822人学习下载适合备赛复盘、方案借鉴与工程实践参考。1. 智慧药房赛项资源包从一堆散件到能跑通的 ROS 抓取链路如果你正在准备中国机器人及人工智能大赛的智慧药房组或者带学生做机器人视觉抓取类的大作业手里大概率会缺一份能直接对照的工程骨架。这个压缩包就是第二十五届该赛项的参赛作品归档里面没有花哨的 PPT 包装全是实打实的工程文件main.cpp、send_goals_node.cpp两个 C 节点reminder_basic.py.bak和launch_watcher.bash两个脚本一个yolox.bin权重文件外加Start_Point1.JPG、Start_Point2.JPG、test_image.jpg三张标定与测试图还有珍贵的顶盖.gcode.3mf这个打印件模型。它解决的不是“从零讲原理”的问题而是“别人已经跑通的节点怎么组织、话题怎么接、权重怎么挂”的问题。适合已经摸过 ROS、知道catkin_make或colcon build是怎么回事但卡在视觉抓取链路拼不起来的参赛者和自学者。下面我按拆包后的真实结构把这份资源从“能看懂”推到“能复现”。2. 拆包先看文件构成哪些是源码、哪些是配置、哪些是打印件拿到压缩包别急着编译先按类型分堆。这个包里的文件大致分四类C 源码、Python/Bash 脚本、模型权重与图像、3D 打印模型。分类清楚了才知道哪些要进工作空间、哪些要单独放。2.1 源码与脚本的职责划分main.cpp和send_goals_node.cpp是典型的 ROS 节点写法。从命名推断send_goals_node.cpp负责向机械臂或移动底盘发送目标位姿main.cpp更可能是视觉处理主循环或状态机入口。reminder_basic.py.bak带.bak后缀说明它是备份版本常见做法是把它当参考实现而不是直接运行——.bak文件往往对应某个被改坏或临时替换的版本直接跑容易踩到旧逻辑。launch_watcher.bash是启动监控脚本通常用来拉起 launch 文件并监视节点是否掉线。提示.bak文件不要直接改后缀当正式脚本用先和现有节点对比话题名和参数确认它对应的是哪一版逻辑。2.2 权重、图像与打印件的用途yolox.bin是 YOLOX 的权重文件说明视觉检测走的是 YOLOX 路线不是 YOLOv5 或 v8。Start_Point1.JPG和Start_Point2.JPG大概率是标定用的起始点参考图用来核对相机坐标系和机械臂基座坐标系的对应关系。test_image.jpg是单帧测试图用来验证检测节点能不能出框。珍贵的顶盖.gcode.3mf是切片后的 3D 打印文件对应药房场景里的某个顶盖结构件说明这套作品有实体机构不是纯仿真。文件类型建议处理方式main.cppC 源码放入 src 包内编译send_goals_node.cppC 源码放入 src 包内编译reminder_basic.py.bakPython 备份参考逻辑不直接运行launch_watcher.bashBash 脚本检查路径后赋执行权限yolox.bin模型权重放入 weights 目录并核对输入尺寸Start_Point1/2.JPG标定图用于坐标核对不参与编译test_image.jpg测试图单帧验证检测节点珍贵的顶盖.gcode.3mf打印文件直接送打印机与代码无关2.3 建立工作空间的目录约定我一般会按下面这个结构把文件归位避免编译时找不到头文件和权重# 建立 ROS 工作空间 mkdir -p ~/smart_pharmacy_ws/src cd ~/smart_pharmacy_ws/src # 假设包名为 smart_pharmacy把源码放进去 mkdir -p smart_pharmacy/src smart_pharmacy/launch smart_pharmacy/weights smart_pharmacy/scripts # 归位示例路径按实际解压目录调整 cp main.cpp send_goals_node.cpp smart_pharmacy/src/ cp yolox.bin smart_pharmacy/weights/ cp launch_watcher.bash smart_pharmacy/scripts/ cp reminder_basic.py.bak smart_pharmacy/scripts/这段命令做三件事建工作空间、建包目录、按类型归位。src放 C 源码weights放权重scripts放脚本。参数上唯一要改的是包名如果你打算和现有工程合并包名必须和package.xml、CMakeLists.txt里的名字一致否则catkin_make会报找不到包。3. 编译与节点启动把 C 节点和 YOLOX 权重接起来文件归位只是第一步真正决定能不能跑的是编译配置和启动顺序。这一章把CMakeLists.txt的关键项、节点启动顺序、权重加载路径讲清楚。3.1 CMakeLists.txt 里必须补的三处ROS1 环境下main.cpp和send_goals_node.cpp要各自生成可执行文件。常见做法是在CMakeLists.txt里加# 生成两个可执行节点 add_executable(main_node src/main.cpp) add_executable(send_goals_node src/send_goals_node.cpp) # 链接 ROS 基础库和 OpenCV target_link_libraries(main_node ${catkin_LIBRARIES} ${OpenCV_LIBS}) target_link_libraries(send_goals_node ${catkin_LIBRARIES}) # 如果 main.cpp 里用了 YOLOX 推理补上推理库 # target_link_libraries(main_node yolox_lib)逻辑说明add_executable把每个 cpp 编成独立节点不要图省事合成一个否则话题冲突时不好排查。target_link_libraries里catkin_LIBRARIES是 ROS 消息和通信的基础OpenCV_LIBS是图像处理用的。参数上如果你的 YOLOX 推理是纯 OpenCV DNN 加载yolox.bin就不需要额外链接推理库如果用了 ONNX Runtime 或 TensorRT才补第三行。3.2 权重加载路径与输入尺寸核对yolox.bin能不能被正确读取取决于代码里的路径和输入尺寸。常见翻车点是路径写死成作者机器上的绝对路径。启动前先确认# 查看权重文件大小确认不是空文件或占位文件 ls -lh ~/smart_pharmacy_ws/src/smart_pharmacy/weights/yolox.bin # 用 file 看下文件类型 file ~/smart_pharmacy_ws/src/smart_pharmacy/weights/yolox.bin如果file输出是 data 或 binary说明是二进制权重正常。如果输出是 ASCII text那可能是下载不完整或本身就是文本占位。参数上YOLOX 常见输入尺寸是 640x640 或 416x416代码里blobFromImage的尺寸必须和训练时一致否则检测框会整体偏移。这个包没给训练配置所以只能从main.cpp里的预处理代码反推找到resize或blobFromImage那一行核对。3.3 启动顺序先起检测再起目标发送节点之间有依赖顺序错了会看到“等待话题”卡死。我一般按这个顺序# 终端 1启动 roscore roscore # 终端 2启动视觉检测主节点 cd ~/smart_pharmacy_ws source devel/setup.bash rosrun smart_pharmacy main_node # 终端 3启动目标发送节点 source devel/setup.bash rosrun smart_pharmacy send_goals_node # 终端 4用测试图验证检测输出 rostopic echo /detection_result逻辑说明roscore是 ROS1 的通信基础必须先起。main_node负责加载权重并发布检测结果send_goals_node订阅结果后换算成目标位姿。rostopic echo用来确认检测话题有没有数据。参数上话题名要和代码里advertise和subscribe的名字完全一致大小写都不能差。如果rostopic echo一直没输出先rostopic list看话题在不在再rosnode info看节点有没有正常注册。4. 避坑与排查标定图、.bak 脚本和权重路径的三个血泪经验这个包里的文件不多但每个都可能让你卡半天。下面三条是我拆类似工程时反复遇到的。4.1 标定图对不上导致抓取偏移现象检测框看着在药盒上但机械臂抓过去总是偏几厘米。原因Start_Point1.JPG和Start_Point2.JPG是标定参考但代码里的手眼矩阵或坐标偏移量是按作者当时的相机高度和角度算的你换了支架或相机型号矩阵就失效。解决不要直接信代码里的偏移常量用这两张图重新核对起始点或者干脆重新做一次手眼标定把新矩阵写回参数文件。4.2 .bak 脚本里的旧话题名现象运行reminder_basic.py.bak后节点报错说找不到某个话题。原因.bak是备份版本里面的话题名可能是上一版命名和当前main.cpp发布的话题对不上。解决打开.bak文件搜索Subscriber和Publisher把话题名和当前节点对比改成一致再运行。更稳妥的做法是只参考它的逻辑不直接运行。4.3 权重路径写死导致加载失败现象main_node启动后立刻退出日志显示failed to load yolox.bin。原因代码里用了作者机器的绝对路径比如/home/xxx/...。解决把路径改成ros::package::getPath动态获取或者用 launch 文件传参。常见做法是在 launch 里加param nameweight_path value$(find smart_pharmacy)/weights/yolox.bin/代码里读这个参数。注意改完路径后记得重新catkin_make因为参数读取代码变了。4.4 打印件与代码版本不匹配现象机构装好了但抓取高度和代码里的目标位姿对不上。原因珍贵的顶盖.gcode.3mf是某个版本的打印件如果代码里的位姿是按另一版机构调的就会差一截。解决先确认打印件是不是当前机构版本再核对send_goals_node.cpp里的目标高度常量必要时手动微调。5. 进阶用法用 test_image 做单帧回归与参数微调最后一章讲一个具体技巧怎么用test_image.jpg把检测和抓取链路拆开验证而不是每次都跑全流程。这个方法我每次调视觉参数都会走一遍。5.1 单帧检测验证先写一个最小验证节点只读test_image.jpg并输出检测框不接机械臂import cv2 import numpy as np # 读取测试图 img cv2.imread(test_image.jpg) # 按 YOLOX 常见输入尺寸预处理 blob cv2.dnn.blobFromImage(img, 1/255.0, (640, 640), swapRBTrue) # 加载权重假设是 OpenCV DNN 可读格式 net cv2.dnn.readNet(yolox.bin) net.setInput(blob) outs net.forward() # 打印输出维度确认模型输出结构 print(output shape:, outs.shape)逻辑说明blobFromImage做归一化和尺寸变换swapRBTrue是因为 OpenCV 默认 BGR而训练常用 RGB。参数上1/255.0是归一化系数(640,640)必须和训练输入一致。outs.shape能告诉你模型输出是[1, N, 85]还是别的结构据此写后处理。5.2 用标定图核对坐标映射把Start_Point1.JPG和Start_Point2.JPG分别跑一遍检测看同一个起始点在两帧里的像素坐标是否一致。如果差得多说明相机位置动了需要重新标定。这一步能提前发现坐标映射问题避免装好机构后才发现抓偏。5.3 参数微调的优先级调参不要一次改一堆。我一般按这个顺序先调检测置信度阈值看框全不全再调 NMS 阈值看有没有重复框最后调目标位姿的偏移量。每次只改一个用test_image.jpg回归一次。这样出问题能定位到具体参数不会变成玄学。参数作用调整方向置信度阈值控制检出框数量漏检多就降低误检多就提高NMS 阈值控制重复框框重叠多就降低坐标偏移量控制抓取点按标定图微调从那以后我每次拿到这类竞赛归档都强制先跑一遍单帧验证再接机构。希望帮到你。本文还有配套的精品资源点击获取