Skip to content
danielomg22212Public

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

阶段三:医疗物流箱入篮任务

本目录是阶段三独立开发工作区,由阶段二已验证版本复制而来。这里的修改不会影响阶段二实际运行目录。

文档入口:

  • docs/阶段三命令.md:当前可直接执行的命令。
  • docs/阶段三.md:任务方案、数据、训练、视觉和业务系统。
  • docs/阶段三技术交接_20260720.md:截至2026-07-24的源码参数、安全边界、 模型和未完成项。

当前状态(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

订单到ROS2 Action安全联调

订单控制器已经按具体追溯码逐件发送 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节。

RGB-D 数据采集

采集程序沿用阶段二 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 内参。这个问题属于坐标解算,不需要人工增加一套深度标注。

RGB-D按组筛选

一组样本由同一个 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 框标注后,再按箱体框内有效深度率筛选真正影响抓取的样本。

YOLO训练数据集

框标注保存在每张 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 训练集。

本机 RTX 3060 训练

本机已安装 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_v1

batch=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/。根据真实误检/漏检再调整部署置信度,训练阶段不要为了提高表面指标随意删除困难样本。

导出 ONNX(供 X-AnyLabeling 自动预标注)

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,用于后续图片预标注。自动结果仍必须人工检查,不能直接再次进入训练集。

接入阶段三 ROS 视觉程序

服务器训练使用 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 qr

all 和 barcode 参数仅用于兼容、检查此前已打印的Code 128旧标签。

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages