本目录是阶段三独立开发工作区,由阶段二已验证版本复制而来。这里的修改不会影响阶段二实际运行目录。
文档入口:
docs/阶段三命令.md:当前可直接执行的命令。docs/阶段三.md:任务方案、数据、训练、视觉和业务系统。docs/阶段三技术交接_20260720.md:截至2026-07-24的源码参数、安全边界、 模型和未完成项。
- 三层白色金属货架已到,并已用于实物场景采集。
- 首轮数据采集已完成,湿巾补采实际新增 83 组:5 个会话,共 491 组对齐 RGB-D。
session_20260718_184756为 181 组非货架背景;其余 4 个会话为 310 组实物货架数据。- 前 3 个实物货架会话的场景字段仍误记为
white_cloth,最新湿巾会话为real_shelf;训练和数据划分时应按会话目录识别。 - 当前只保留纸箱和湿巾两类货物,YOLO 类别固定为
carton_box、wet_wipes。 - 数据筛选和双类别框标注已完成:353 张 RGB、362 个目标框,类别为
carton_box、wet_wipes。 - 已生成服务器训练包并完成第一版YOLOv8n训练;新
best.pt已部署,纸箱和湿巾 已完成真实货架只识别测试。 - 当前机械流程先使用货架第一层和第二层,第三层暂不执行;两层观测关节位已写入阶段三 ROS 节点。
- 二维码和YOLO已在同一相机进程中完成空间绑定;期望二维码连续3/5帧属于同一目标框后,才发布该框的抓取XYZ。
- 日常任务固定三个终端:机器人基础、视觉、抓取控制,统一使用
stage3_carton.sh和ROS_DOMAIN_ID=31。 - 货物实机调试默认单件、显式类型和层数、
grasp_only,使用T触发、W逐步、空格请求右臂软件急停;E强制跳过已禁用,连续执行锁定。 - 日常运行统一使用
stage3_carton.sh的robot / vision / control三种模式,固定三个终端并按机器人、视觉、控制职责分开。 - 新增独立右臂网页调试台,默认只读监视(急停除外);显式运动模式要求零位解除急停并使能,先用受限关节单轴小步离开全零奇异位,再开放带IK预检查的1/2/5毫米XYZ单轴低速点动。
- 已加入本地驱动/控制器单实例锁、SDK TCP运动保护、右臂状态过滤、末端位姿过滤 和关节状态发布者GID筛选。
- 所有自动MoveL相邻平移目标硬限制为不超过80 mm;每个逻辑动作只在首段等待一次
W,后续内部段必须实际到位后才自动继续;MoveJ/MoveL到位超时会锁存并 请求原生急停。视觉抓取只接受同一消息携带QR、类别、深度和时间戳的5帧中位数; 样本间隔超过300 ms、时间倒退或视觉进程重启都会清空窗口。 - 商品类别与抓取配置已显式写入SQLite,订单按库存件保存执行检查点并设置Action
超时;结果不确定的
executing单件禁止自动重发,名称关键字不再决定机器人动作。 - O6/L6手指话题必须提供恰好6个执行器值;断连或驱动急停锁存后,手指命令也会 在SDK互斥锁内被拒绝。
- 已建立独立O6/Gemini 2整机预览及碰撞几何;该模型尚未替换活动控制URDF, 也未接入MoveIt PlanningScene。
- 当前真实运动终点是抓住货物并退出货架后保持夹持;篮子放置、抓取成功检测和 真实订单Action仍未完成。
stage3/
├── docs/
│ ├── 阶段三.md
│ ├── 阶段三命令.md
│ ├── 阶段三技术交接_20260720.md
│ └── 阶段二参考.md
├── trace_code/
│ ├── generate_trace_labels.py
│ ├── scan_trace_code.py
│ ├── trace_code_common.py
│ └── requirements.txt
├── yolo_box/
│ ├── collect_rgbd_dataset.py
│ ├── review_rgbd_dataset.py
│ ├── prepare_cvat_task.py
│ ├── prepare_yolo_dataset.py
│ ├── yolo_detect_ros.py
│ ├── utils.py
│ ├── best.pt # 阶段三纸箱/湿巾模型
│ └── best_stage2_screw_backup.pt # 原阶段二螺母模型备份
├── tools/
│ ├── carton_teach_observer.py
│ ├── stage3_web_debug.py
│ └── stage3_web/ # 本地网页前端
├── stage3_carton.sh # 三终端与调试入口
└── ros2_ws/src/
├── api_lbot_yolo_take/
├── robot_tf/
├── yolo_msgs/
├── stage3_interfaces/
├── stage3_order_controller/
├── stage3_o6_description/
├── lbot_driver/
├── lbot_arm_interfaces/
└── lkls73_i1_dual_arm_description/
yolo_box/best.pt 当前是服务器训练的阶段三模型,类别固定为:
0: carton_box
1: wet_wipes
原阶段二螺母模型保存在 yolo_box/best_stage2_screw_backup.pt,不参与阶段三运行。阶段二实际目录中的模型没有修改。
yolo_box/yolo_detect_ros.py
箱子检测、二维码空间绑定、像素/深度坐标、目标筛选
ros2_ws/src/robot_tf/src/tf_transform_service.cpp
相机光学轴转换、目标类别筛选、base_link TF
ros2_ws/src/api_lbot_yolo_take/src/api_lbot_yolo_take.cpp
观察、目标计算、纸箱/湿巾实验抓取、实际到位确认、手型和急停
ros2_ws/src/lbot_driver/src/lbot_driver.cpp
SDK调用互斥、非阻塞运动保护、状态过滤、原生急停
ros2_ws/src/stage3_o6_description/
O6、Gemini 2、USB/连接杆和独立RViz碰撞预览
tools/stage3_web_debug.py
右臂状态监视与受限XYZ单轴点动后端;默认禁止运动
只读监视模式:
/home/siyu/WorkSpace/stage3/stage3_carton.sh web打开http://127.0.0.1:8060/。该模式禁止点动,急停是唯一保留的写操作。运动调试必须显式增加--allow-motion,并满足零位、新鲜状态和ZERO确认等限制,详见docs/阶段三命令.md。本工具与官方网页完全独立。
cd /home/siyu/WorkSpace/stage3/ros2_ws
source /opt/ros/jazzy/setup.bash
source /home/siyu/lbot_ws/lbot_ws/install/setup.bash
colcon build --symlink-install --packages-select \
stage3_interfaces stage3_order_controller yolo_msgs lbot_arm_interfaces \
lbot_driver robot_tf api_lbot_yolo_take \
lkls73_i1_dual_arm_description stage3_o6_description \
--cmake-args -DPython3_EXECUTABLE=/usr/bin/python3
source install/setup.bash订单控制器已经按具体追溯码逐件发送 ExecuteItem Action。当前执行器只允许 dry-run,不发送 MoveJ、MoveL 或灵巧手指令:
cd /home/siyu/WorkSpace/stage3/ros2_ws
source /opt/ros/jazzy/setup.bash
source install/setup.bash
ros2 launch stage3_order_controller stage3_order_dry_run.launch.py在网页创建出库单后执行:
ros2 service call /stage3_order_controller/peek_next std_srvs/srv/Trigger '{}'
ros2 service call /stage3_order_controller/claim_next std_srvs/srv/Trigger '{}'
ros2 service call /stage3_order_controller/dispatch_current std_srvs/srv/Trigger '{}'模拟完成后订单自动恢复reserved,不会扣减库存。真实运动仍锁定,必须先示教
货架水平接近/回撤、推车放置位和两类O6抓取角度。当前O6仍通过厂家兼容的
/robot1/right_hand/set_l6_joint六通道接口控制。
api_lbot_yolo_take原始默认值保持运动锁定。当前流程要求操作员在启动前手动
把右臂放到零位,程序不再执行旧的公共安全位、J2=-1.5或其他自动零位逃离MoveJ。
观察位MoveJ、笛卡尔抓取和抓取调姿由脚本的--step --execute显式开放;如只需
观察位运动则增加--no-orientation。MoveJ/MoveL均以block=false下发,通过实际
状态连续3帧确认到位。运动30秒未到位会锁存并请求右臂原生急停;空格可随时
请求急停,E已禁用,不能绕过到位检查。自动MoveL相邻平移目标不超过80 mm,每个逻辑动作只按一次W;网页调试仍仅允许1/2/5 mm单轴点动。
阶段三继续使用Gemini 2 SDK提供的D2C对齐RGB内参,像素偏移保持0 px,不恢复阶段二的+40 px和//量化。TF经验补偿当前值为:光轴深度-85 mm、横向+20 mm、垂直+50 mm。控制端按物品类型和层数使用固定抓取Z。默认只允许检查视觉与TF坐标,坐标公式、检查命令和显式解锁参数见docs/阶段三.md第5节。
采集程序沿用阶段二 Orbbec 的彩色/深度流、硬件对齐和帧同步配置:
conda activate yolo
cd /home/siyu/WorkSpace/stage3/yolo_box
python3 collect_rgbd_dataset.py只读取相机参数、不打开采集窗口:
python3 collect_rgbd_dataset.py --camera-info-only常用按键:
Space 保存一组 RGB-D 数据
Backspace/X 删除最近保存的一组 RGB-D 数据
A 开启/关闭自动采集
+ / - 调整自动采集间隔
D 切换 RGB、深度、叠加和并排显示
R 切换场景标签
H 在终端重新显示帮助
Q/Esc 退出
“删除最近一组”会同时移除对应的RGB、毫米深度、深度预览、单帧JSON,并从 samples.jsonl 删除最后一条记录。自动采集开启时执行删除会先关闭自动采集,避免刚删除就被下一帧重新保存。
右侧面板顶部的“已拍摄 N 张 RGB”是当前session的图片计数器。每次手动或自动保存加一,删除最近一组减一;服务器训练所需的 rgb/ 图片数量与该计数一致。
默认输出到 stage3/datasets/raw/session_时间/:
rgb/ 用于 YOLO 标注和训练的原始彩色图
depth_mm/ 16 位 PNG,像素值单位为毫米
depth_preview/ 便于人工检查的伪彩深度图
metadata/ 每帧深度比例、中心深度和时间戳
session.json 相机型号、序列号、流配置、内参与外参
samples.jsonl 本次采集的完整索引
YOLOv8 第一版只训练 rgb/。深度数据先保留,用于抓取坐标验证、箱体距离分析和后续离线回放,不直接作为 YOLO 输入。
不需要在 CVAT 中把深度图再标一遍,也不要标 depth_preview/ 里的伪彩图片。当前流程是:
CVAT 只给 RGB 图片标 carton_box / wet_wipes 框
-> 通过同一 session 和 sample_id 找到 depth_mm/*.png
-> 把 RGB 框的像素范围同步应用到对齐后的深度图
-> 在框内取有效深度中位数,计算箱体三维位置
当前保存的对齐深度输出为 1280x720,和 RGB 分辨率一致;RGB、深度、预览和 metadata 的文件名共享同一个样本 ID。深度原图中的 0 是无效值,不能把它当作真实距离。完成 RGB 框标注后,再做“框内有效深度率”检查即可。
注意:对齐后的 1280x720 深度不能直接套用原始 1280x800 深度流内参。后续三维解算应使用 SDK 的对齐标定结果;如果深度已经转换到 RGB 像素坐标系,则使用对应 RGB 内参。这个问题属于坐标解算,不需要人工增加一套深度标注。
一组样本由同一个 sample_id 关联四个位置:RGB、毫米深度、深度预览和单帧 JSON。不要手动进入四个目录删除。使用筛选程序逐组查看:
cd /home/siyu/WorkSpace/stage3/yolo_box
python3 review_rgbd_dataset.py窗口左侧显示 RGB,右侧显示深度预览,并显示深度有效率、深度范围和中心区域深度。按键:
K / Enter / Space 保留当前组并前进
X / Backspace 标记当前组为剔除并前进
U 取消当前决定,恢复待检查
N / 右方向键 下一组
P / 左方向键 上一组
S 立即保存筛选清单
Q / Esc 保存并退出
窗口底部会持续显示 总数、已筛选、待筛选、保留、剔除 和进度条;这些数量只统计当前 491 组数据,不会把旧 review 清单中已经不存在的样本算进去。
筛选结果保存在 datasets/curation/rgbd_review.jsonl。正常筛选不会删除原始数据;制作 CVAT 上传包时排除被标记样本:
python3 prepare_cvat_task.py \
--review ../datasets/curation/rgbd_review.jsonl \
--output ../datasets/cvat_filtered_images.zip只有确认不再需要原始文件时,才执行物理删除。程序会要求手动输入 DELETE,并同步删除四处文件、更新对应 samples.jsonl:
python3 review_rgbd_dataset.py --apply-rejected深度预览只是伪彩显示,不能作为训练图。深度原图是 depth_mm/*.png 的 16 位毫米值。当前先用 RGB 训练 YOLO,深度用于目标框内的距离/三维坐标和质量检查;白色货架全画面出现黑色深度空洞是常见现象,不应仅凭背景有效率删除所有图片。完成 CVAT 框标注后,再按箱体框内有效深度率筛选真正影响抓取的样本。
框标注保存在每张 RGB 图片旁边的 X-AnyLabeling JSON 中。不要使用 datasets/cvat_filtered_images/labels/ 里的旧空文件;转换程序以 JSON 为唯一标注源,并自动把 carton _ box、wet _ wipes 等历史写法统一为:
0: carton_box
1: wet_wipes
重新生成训练集时使用一个不存在的新输出目录:
cd /home/siyu/WorkSpace/stage3
python3 yolo_box/prepare_yolo_dataset.py \
--output datasets/yolo_stage3_new \
--archive datasets/yolo_stage3_new.zip程序校验图片、JSON、类别、矩形框和文件名,并按采集时间间隔把相邻帧组成完整片段。同一片段不会同时出现在训练集和验证集,避免连续帧泄漏导致指标虚高。当前正式数据包统计:
总计:353 张图片,362 个目标框
训练:283 张,287 框(纸箱 134,湿巾 153)
验证: 70 张, 75 框(纸箱 37,湿巾 38)
正式训练只使用 datasets/yolo_stage3/ 或解压后的同结构目录,不要直接使用 datasets/cvat_filtered_images/labels/ 中手工导出的临时文件。标准目录必须是:
yolo_stage3/
├── data.yaml
├── dataset_manifest.json
├── images/
│ ├── train/
│ └── val/
└── labels/
├── train/
└── val/
类别编号不可改动:
0 = carton_box
1 = wet_wipes
训练前确认:
cd /home/siyu/WorkSpace/stage3
cat datasets/yolo_stage3/data.yaml
find datasets/yolo_stage3/images/train -type f | wc -l
find datasets/yolo_stage3/labels/train -type f -name '*.txt' | wc -l
find datasets/yolo_stage3/images/val -type f | wc -l
find datasets/yolo_stage3/labels/val -type f -name '*.txt' | wc -l四个数量应分别为 283、283、70、70。空标签只允许用于经过人工确认的无目标负样本;当前正式包中的 353 张图片都应有对应标签。不要把 depth_mm/、depth_preview/、二维码标签图或未审核的自动标注结果放入 YOLO 训练集。
本机已安装 Ultralytics,yolo 环境可识别 RTX 3060 6GB。训练前关闭 X-AnyLabeling、YOLO相机程序和其他占用显存的进程:
conda activate yolo
cd /home/siyu/WorkSpace/stage3
nvidia-smi
yolo checks
yolo detect train \
model=yolov8n.pt \
data=/home/siyu/WorkSpace/stage3/datasets/yolo_stage3/data.yaml \
epochs=100 \
imgsz=640 \
batch=8 \
workers=4 \
device=0 \
patience=20 \
seed=42 \
cache=False \
project=/home/siyu/WorkSpace/stage3/runs/stage3 \
name=box_wipes_v1batch=8 是 6GB 显存的保守起点。出现 CUDA out of memory 时改成 batch=4;仍不足时改成 batch=2,不要降低 imgsz=640 后却忘记在验证和部署时保持相同输入尺寸。首次运行如果本地没有 yolov8n.pt,Ultralytics 会联网下载预训练权重。
当前 AutoDL 服务器为 RTX PRO 6000 Blackwell(Compute Capability sm_120)。服务器原有 torch 2.7.1+cu118 只包含到 sm_90 的 CUDA内核,虽然 torch.cuda.is_available() 返回 True,实际计算会报 no kernel image is available for execution on the device。不能继续使用该环境,也不需要为了 YOLO训练安装 nvcc;应使用支持 Blackwell 的 PyTorch CUDA 12.8 wheel。
先建立独立环境,不要使用服务器当前未激活环境中的 ~/.local 用户包:
conda create -n stage3_yolo python=3.12 -y
conda activate stage3_yolo
python -m pip install -U pip
python -m pip install \
torch==2.7.1 torchvision==0.22.1 \
--index-url https://download.pytorch.org/whl/cu128
python -m pip install ultralytics==8.4.87把配置、缓存和训练结果放在可写且持久化的用户目录,避开只剩 30GB 的容器根分区和不可写的默认 Ultralytics 配置目录:
mkdir -p "$HOME/stage3_yolo" \
"$HOME/stage3_yolo/cache/pip" \
"$HOME/stage3_yolo/cache/torch" \
"$HOME/stage3_yolo/config/ultralytics" \
"$HOME/stage3_yolo/runs"
export PIP_CACHE_DIR="$HOME/stage3_yolo/cache/pip"
export TORCH_HOME="$HOME/stage3_yolo/cache/torch"
export YOLO_CONFIG_DIR="$HOME/stage3_yolo/config/ultralytics"
df -h "$HOME" /root/autodl-tmp 2>/dev/null || df -h "$HOME"每次新开服务器终端后,都要重新执行 conda activate stage3_yolo 和上面三个 export。如需长期生效,可以将三个 export 写入该服务器用户的 shell 启动配置。
安装后不能只检查 CUDA available: True,必须执行一次真实 GPU计算,并确认编译架构包含 sm_120:
python - <<'PY'
import torch
print("torch:", torch.__version__)
print("compiled CUDA:", torch.version.cuda)
print("CUDA available:", torch.cuda.is_available())
print("GPU:", torch.cuda.get_device_name(0))
print("compiled architectures:", torch.cuda.get_arch_list())
assert torch.cuda.is_available(), "CUDA is not available"
assert "sm_120" in torch.cuda.get_arch_list(), "PyTorch wheel has no sm_120 kernel"
a = torch.randn((2048, 2048), device="cuda")
b = a @ a
torch.cuda.synchronize()
print("GPU tensor test: PASS", float(b[0, 0]))
PY期望看到:
torch: 2.7.1+cu128
compiled CUDA: 12.8
GPU: NVIDIA RTX PRO 6000 Blackwell Server Edition
compiled architectures: ... sm_120 ...
GPU tensor test: PASS ...
如果没有 sm_120 或张量测试失败,不要启动训练。确认上面的 cu128 安装命令是在 stage3_yolo 环境中执行,并检查:
which python
python -m pip show torch torchvision ultralytics上传 datasets/yolo_stage3.zip 后,在服务器用户目录解压。ZIP根目录已经直接包含 data.yaml、images、labels,不要额外嵌套两层:
conda activate stage3_yolo
export PIP_CACHE_DIR="$HOME/stage3_yolo/cache/pip"
export TORCH_HOME="$HOME/stage3_yolo/cache/torch"
export YOLO_CONFIG_DIR="$HOME/stage3_yolo/config/ultralytics"
cd "$HOME/stage3_yolo"
unzip /path/to/yolo_stage3.zip -d dataset
yolo detect train \
model=yolov8n.pt \
data=$HOME/stage3_yolo/dataset/data.yaml \
epochs=100 \
imgsz=640 \
batch=64 \
workers=12 \
device=0 \
patience=20 \
seed=42 \
cache=False \
project=$HOME/stage3_yolo/runs \
name=box_wipes_v1该 GPU 有约 96GB 显存,YOLOv8n、imgsz=640 可从 batch=64 起步;训练稳定后可尝试 batch=128。如果数据加载或显存报错,先回退到 batch=32,不要同时改变图像尺寸、模型和 batch,以免无法定位问题。当前数据只有 353 张,过大的 batch 会让每个 epoch 的优化步数过少,因此第一版不建议超过 128。多卡服务器第一版仍固定 device=0。
服务器环境已知结论:
- RTX PRO 6000 Blackwell 硬件、约 96GB 显存和 22 个逻辑 CPU 足够训练本项目。
nvcc缺失不影响 Ultralytics/PyTorch wheel 训练,除非后续编译自定义 CUDA算子。- 原来的
torch 2.7.1+cu118必须弃用,不能靠升级驱动解决sm_120内核缺失。 - 根分区显示约 30GB;数据、环境缓存和 runs 应留在
/root/autodl-tmp对应的持久目录(当前$HOME位于该路径)。 - Ultralytics 的默认配置目录不可写,因此训练前必须设置
YOLO_CONFIG_DIR。
训练中断后使用对应运行目录的 last.pt,不要重新从 yolov8n.pt 开始:
conda activate yolo
yolo detect train resume=True \
model=/home/siyu/WorkSpace/stage3/runs/stage3/box_wipes_v1/weights/last.pt如果同名 box_wipes_v1 已经存在,再次全新训练时换成 box_wipes_v2,不要混用不同数据版本的 last.pt。
训练完成后的主要文件:
runs/stage3/box_wipes_v1/
├── weights/best.pt
├── weights/last.pt
├── results.csv
├── results.png
├── confusion_matrix.png
├── PR_curve.png
└── val_batch*_pred.jpg
重新运行验证集评估:
conda activate yolo
yolo detect val \
model=/home/siyu/WorkSpace/stage3/runs/stage3/box_wipes_v1/weights/best.pt \
data=/home/siyu/WorkSpace/stage3/datasets/yolo_stage3/data.yaml \
imgsz=640 \
device=0 \
split=val \
plots=True检查时不要只看总 mAP50,还要分别查看 carton_box 和 wet_wipes 的 Precision、Recall、mAP50-95、混淆矩阵及预测图片。重点检查:
- 白色货架是否被误识别为纸箱。
- 湿巾远距离、小目标或部分遮挡时是否漏检。
- 二维码、货架横梁和深度黑洞区域是否产生误框。
- 连续相邻帧是否让验证指标看起来虚高。当前准备脚本已经按采集片段分组,重新拆分数据时不要退回简单的逐图随机划分。
先对验证集和真实货架图片做离线推理,不要训练完立即控制机械臂:
conda activate yolo
yolo detect predict \
model=/home/siyu/WorkSpace/stage3/runs/stage3/box_wipes_v1/weights/best.pt \
source=/home/siyu/WorkSpace/stage3/datasets/yolo_stage3/images/val \
imgsz=640 \
conf=0.25 \
device=0 \
save=True \
project=/home/siyu/WorkSpace/stage3/runs/stage3_predict \
name=box_wipes_v1_val预测图保存在 runs/stage3_predict/box_wipes_v1_val/。根据真实误检/漏检再调整部署置信度,训练阶段不要为了提高表面指标随意删除困难样本。
conda activate yolo
yolo export \
model=/home/siyu/WorkSpace/stage3/runs/stage3/box_wipes_v1/weights/best.pt \
format=onnx \
imgsz=640 \
opset=12 \
simplify=True \
dynamic=False \
device=0导出的 best.onnx 可配置到 X-AnyLabeling,用于后续图片预标注。自动结果仍必须人工检查,不能直接再次进入训练集。
服务器训练使用 100 epochs,验证集 70 张图片、75 个目标框,最终结果为:
Precision 0.996
Recall 1.000
mAP50 0.995
mAP50-95 0.985
训练曲线中训练损失持续下降,验证损失总体下降,最后阶段没有明显反弹;该结果可以进入实机只识别测试,但仍需用未参与训练的新货架画面验证。
新模型已经复制到默认路径,直接运行即可:
conda activate yolo
cd /home/siyu/WorkSpace/stage3/yolo_box
source /opt/ros/jazzy/setup.bash
source /home/siyu/WorkSpace/stage3/ros2_ws/install/setup.bash
python3 yolo_detect_ros.py \
--conf_threshold 0.40 \
--display默认 --target_class_id -1,同时显示和发布两个类别。只测试单一类别时可指定:
--target_class_id -1 carton_box + wet_wipes
--target_class_id 0 只检测 carton_box
--target_class_id 1 只检测 wet_wipes
运行中也可以向 /yolo_detect 发布同样的 ID 动态切换类别;发布 -1 恢复全部类别。
也可以显式指定同一个模型:
source /opt/ros/jazzy/setup.bash
source /home/siyu/WorkSpace/stage3/ros2_ws/install/setup.bash
python3 yolo_detect_ros.py \
--yolo_model /home/siyu/WorkSpace/stage3/yolo_box/best.pt \
--conf_threshold 0.40 \
--display确认日志和画面中的模型类别顺序严格为:
0: carton_box
1: wet_wipes
完成离线图片、实时相机、深度框内坐标和空载机械臂路径验证后,才允许把新模型接入自动抓取。切换模型只替换 --yolo_model 的路径,扫码、/yolo_data、/get_yolo_point、MoveJ、MoveL 和灵巧手接口保持不变。
- 训练期间不要运行 X-AnyLabeling GPU自动标注,避免争抢显存。
- Gemini 2 同一时刻只能由一个进程打开;离线训练不需要启动相机。
best.pt用于部署,last.pt主要用于断点续训。- 每次改变标签、划分或增强策略都使用新的运行名称并记录数据版本。
- 不要把训练集预测效果当泛化能力,最终以验证集和现场实拍测试为准。
- 不要直接让未经现场验证的新模型驱动机械臂;先显示检测框,再验证深度和 TF,最后空载执行路径。
安装生成和识别依赖:
conda activate yolo
python3 -m pip install -r /home/siyu/WorkSpace/stage3/trace_code/requirements.txt推荐使用统一的网页系统完成商品入库和出库点单:
conda activate yolo
cd /home/siyu/WorkSpace/stage3/trace_code
python3 trace_label_app.py一个进程提供两个页面并使用同一个 trace_inventory.db:
入库管理:http://127.0.0.1:5050/
出库点单:http://127.0.0.1:5050/orders
入库管理页面包含三种单件入库方式:
自动生成:输入商品名称和货架层,自动生成唯一编号、批号和二维码。手动入库:输入商品名称、20位DEMO追溯编号、有效期、批号和货架层。扫码入库:输入商品信息后启动Gemini 2,按3/5帧确认一个未入库二维码并立即录入这一件;有效期可留空,数据库记为N/A。
商品名称输入框会列出数据库中的已有名称,批号输入框会列出最近使用过的批号;可以直接选择,也可以继续输入新值。同一批号允许对应多件商品,追溯编号仍严格保持单件唯一。
自动生成每次执行:
为新商品自动分配DEMOxxx商品编码
随机生成数据库中不存在的12位单品序列号
随机生成数据库中不存在的批号
生成75x75 mm二维码PNG
立即写入SQLite库存数据库
数据库保存在 trace_code/trace_inventory.db,标签保存在 trace_code/generated/app_labels/。手动和扫码入库也会为输入编号生成本地标签,因此仍可在库存表中打开PNG或选择A4打印。页面下方可按商品、批号、编号或货架搜索,库存表会显示有效期和入库方式。相同商品名称会复用商品编码,每个单品的追溯码始终唯一,同一批号允许对应多件商品。
在入库页面右上角点击 出库点单,或直接打开:
http://127.0.0.1:5050/orders
页面会从同一个 trace_inventory.db 读取已有商品,并显示每种商品的当前可用库存。加入出库单时,前端限制数量不能超过库存,提交时后端还会在 SQLite 事务中再次检查并锁定具体单品;即使多个页面同时点单,也不会超卖。
出库页面支持按商品名称或商品编码检索,输入时会显示匹配商品的联想提示、实拍外观和可用库存;商品目录和当前出库单也会显示对应实拍图。图片来自阶段三采集数据,当前映射 医用湿巾 和 医疗物流演示箱 两种商品。
提交成功后库存单品状态变为 reserved(已预占),出库单会记录商品、数量、追溯码、批号和货架层,供后续机器人执行。尚未执行的订单可以点击 取消并释放,库存会恢复为在库。现阶段这是库存预占,不代表机器人已经完成实际抓取。
扫码入库一次只处理一件,确认后相机自动关闭。扫码前应停止YOLO、数据采集和其他相机程序;30秒内未识别到有效二维码时,本次入库取消且数据库不会写入半条记录。
原命令行批量生成器继续保留,适合一次生成固定数量的测试标签:
cd /home/siyu/WorkSpace/stage3/trace_code
python3 generate_trace_labels.py --count 2 --shelf-levels 1,2 --label-size-mm 75输出位于 trace_code/generated/batch_时间/,其中 labels/ 是300 DPI PNG,labels_print_A4_75x75mm.pdf 是A4纵向批量打印文件,manifest.csv 和 manifest.json 保存编号与物品、层号的映射。默认标签为 75x75 mm,在一张A4上按 2列x3行 排列,最多放6张;超过6张自动增加A4页面。可用 --label-size-mm 在60-120 mm内调整,排版会重新计算。打印PDF时选择“A4、纵向、实际大小/100%”,不要选择“适合页面”。
用 Gemini 2 直接扫描编号,并按最近 5 帧中至少 3 帧一致进行确认:
python3 scan_trace_code.py程序优先读取网页使用的 trace_inventory.db,同时兼容 generated/ 下旧批次的 manifest.json。扫到编号后查询物品名称、批号和货架层,并将完整结果写入 trace_code/result.json。不需要手动输入 --expected。相机同一时刻只能由一个进程占用,因此扫描程序运行时应先停止数据采集程序和 YOLO 相机程序。离线检查标签图片可使用:
python3 scan_trace_code.py --image generated/batch_时间/labels/某编号.png--expected 只保留给后续任务控制器使用:订单或数据库在程序内部提供目标编号,再与扫码结果比较,不作为正常演示的人工输入项。
持续显示测试模式:
python3 scan_trace_code.py --test-display该模式不会在第一次确认后退出。窗口持续刷新识别框,并在每个识别框上方显示编号、物品名称、货架层和多帧确认状态;移走或更换标签后信息会随实时画面更新,按 Q 或 Esc 退出。
新标签只生成二维码,扫码程序也默认只识别二维码:
python3 scan_trace_code.py --test-display --code-type qrall 和 barcode 参数仅用于兼容、检查此前已打印的Code 128旧标签。