Digitail · 双摄引导的具身 IP 互动 Demo

商店客流量提升60%

面向 IP 潮玩店、品牌快闪与活动现场的具身互动引流装置——用一台协作机械臂+灵巧手+双摄像头,把工业机器人塑造成会“摇尾卖萌、碰食指交友、举盒猜 IP”的门店角色;对外吸引客流、制造短视频话题、带起领券分享闭环,对内验证“双摄分工感知→灵巧操作→状态机编排→多模态采集”完整实现路径,沉淀可复用的人机肢体接触(HRI)数据集。

尹伊君

2026

参数信息

碰指触发成功率
≥90 %
举盒成功率
≥90 %
流程完整走完率
≥85 %
单轮时长中位数
≤60 s

技术优势

单轮时长中位数 ≤60 s(实机测试验证)

复现文档

物料准备

### **物料清单**

| **物料准备** | **数量** | **备注** |

| --- | --- | --- |

| 飞特C001舵机 | 1个 | 仅用于主臂第2号关节 |

| 飞特C044舵机 | 2个 | 用于主臂第1号和第3号关节 |

| 飞特C046舵机 | 3个 | 用于主臂第4号、第5号关节及灵巧手 |

| 飞特C047舵机 | 6个 | 适用于从臂所有关节 |

| 舵机驱动板 | 3个 | 没有区别主从均可使用 |

| USB-C线缆 | 2条 | 确保有数据传输功能 |

| 电源适配器 | 2个 | 5.5 mm×2.1 mm DC 12 V 2 A(从臂Follower) 5.5 mm×2.1 mm DC 5 V 4 A(主臂Leader) |

| 深度摄像头 | 2个 | 建议使用1米左右的信号线 |

| 手臂以及灵巧手的3D打印部件 | 1套 | 可选择购买、代打或自行打印(看打印清单) |

| 3D打印桌面夹具 | 4个 | 可选择购买、代打或自行打印(看打印清单) |

### **工具清单**

| **设备工具** | **数量** | **备注** |

| --- | --- | --- |

| 电脑 | 1台 | 电脑的操作系统建议为Ubuntu X86,电脑USB-A口越多越好 |

| 螺丝刀套装 | 一套 | 用着舒服的就行 |

| 插线板 | 2个 | 插线板插槽越多越好 |

| 拓展坞 | 1个 | 需要USB-A口多的,注意要拓展坞不要集线器 |

### **打印清单**

如果身边刚好有一台打印机的话,可以使用以下链接,下载对应模型,自行打印物料。

| **3D模型文件** | **模型下载链接** |

| --- | --- |

| SO-ARM101 | [SO-ARM101模型文件-Github](https://github.com/TheRobotStudio/SO-ARM100/tree/main/STL/SO101) |

| 可活动夹具 | [可活动固定夹具](https://makerworld.com.cn/zh/models/1937099-qiang-li-jia-ju-yi-yu-da-yin-20chong-chi-cun?from=search#profileId-2190630) |

### **必看说明**

1. 关于电脑和操作系统

理论上来说,Lerobot环境可以在`Windows10/11`、`Linux` 和 `Mac` 上运行。如果想在本地跑采集本地跑模型,那么可稳定运行的环境建议为`Ubuntu22.04LST`且为台式机。以下是一些参考,但不绝对。

| **配置项** | **基础使用 (连接与操控)** | **进阶使用 (本地 AI 训练)** |

| --- | --- | --- |

| 操作系统 | Windows, macOS, Linux | Ubuntu 22.04+ |

| CPU | 无特殊要求 | 6核以上,推荐8核 |

| 内存 | 无特殊要求 | 16GB以上,推荐32GB |

| 显卡 (GPU) | 无需独立显卡 | 必需 NVIDIA 独显,显存 8GB 以上 |

| 硬盘 | 无特殊要求 | 1TB 以上,推荐 NVMe 固态硬盘 |

| USB 接口 | 一个空闲的 USB 端口 | 4到6个,或准备一个 USB 扩展坞 |

安装软件

### **Lerobot**

LeRobot是一个面向现实世界机器人应用的学习框架,旨在降低机器人技术的入门门槛,让研究者和开发者能够快速使用预训练模型和共享数据集进行机器人学习 。它不仅提供算法实现,还集成了数据集管理、仿真环境接口和物理机器人控制模块,形成完整的端到端训练与部署流程。

要让`SO-ARM101`动起来的话,首先要在电脑上配置好`lerobot`环境。那么请按照下列命令来安装`lerobot`。所有的命令都是在终端上运行的,所以可以先熟悉熟悉命令行终端。

### **初始化环境**

```shell

For Ubuntu X86

1.Ubuntu 22.04

2.CUDA 12+

3.Python 3.12

4.Torch 2.6

```

这里需要保证的只有 `Ubuntu 22.04` 这个 `Linux` 操作系统,其他的只是之后会涉及到的,电脑是否有显卡对机械臂的遥操作和数据集收集没有很大的影响,但最好还是要有。

Ubuntu这个系统优先推荐安装在台式物理机,次之为台式虚拟机,再次为笔记本物理机,再再次为笔记本虚拟机,最次为WSL(如果对这个特别熟悉的话,可以一试,它的配置特别麻烦,主要体现在USB透传上),其他操作系统也是这个排序。

### **搭建环境(Ubuntu 22.04)**

1、安装 `Miniforge`:\

一条命令一条命令复制到终端上运行,下述所有命令行命令都是一样的

```shell

wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh

chmod +x Miniforge3-Linux-x86_64.sh

./Miniforge3-Linux-x86_64.sh

# 按照提示安装完成后:

source ~/.bashrc

# 初始化所有 shell

conda init --all

```

如果下载命令太慢的话可以去镜像站下载`Miniforge3-Linux-x86_64.sh`如:\

[清华源-Miniforge3-Linux-x86_64.sh](https://mirrors.tuna.tsinghua.edu.cn/github-release/conda-forge/miniforge/Release%2026.5.3-0/Miniforge3-Linux-x86_64.sh)通过这种方式下载的文件一般位于 Download(下载)目录下,可以在当前目录下参考上述安装。

2、创建并激活一个新的 `conda` 环境用于 `lerobot`:

```shell

conda create -y -n lerobot python=3.12 && conda activate lerobot

```

3、克隆 `LeRobot` 仓库:(这里需要git,教程:[Git教程 - 廖雪峰](https://liaoxuefeng.com/books/git/introduction/index.html))

```shell

git clone https://github.com/Seeed-Projects/lerobot.git ~/lerobot

# clone 速率差的话可以使用以下加速源

# git clone https://gitclone.com/github.com/Seeed-Projects/lerobot.git

# git clone https://wget.la/https://github.com/Seeed-Projects/lerobot.git

# git clone https://hk.gh-proxy.org/https://github.com/Seeed-Projects/lerobot.git

# git clone https://ghfast.top/https://github.com/Seeed-Projects/lerobot.git

# git clone https://githubfast.com/Seeed-Projects/lerobot.git

```

4、使用 `miniforge` 时,在环境中安装 `ffmpeg`:

```shell

conda install ffmpeg -c conda-forge

```

> 4.5、如果你使用的是新配置的 `Ubuntu 22.04` 的机器,尤其是最小化安装版本,系统可能默认不带 `gcc` 等 `C` 编译工具。此时在安装带有 `feetech` 电机依赖的 `LeRobot` 时,`evdev` `Python` 包可能会因为缺少`C`编译器而构建失败。\

> 可以先安装基本编译工具:

>

> ```bash

> sudo apt update

> sudo apt install build-essential

>

> ```

5、安装带有 `feetech` 电机依赖的 `LeRobot`:

```bash

cd ~/lerobot

pip install -e ".[feetech]"

# 如果安装太慢的话可以使用临时镜像源加速

# pip install -e ".[feetech]" -i https://pypi.tuna.tsinghua.edu.cn/simple

```

6、检查 `PyTorch` 和 `Torchvision`:

由于通过 pip 安装 lerobot 环境时会卸载原有的 PyTorch 和 Torchvision 并安装 CPU 版本,因此需要在 Python 中进行检查。

```python

python

import torch

print(torch.cuda.is_available())

exit() # 退出python

```

如果输出结果显示为 `False`,表示当前环境中的 PyTorch 是 CPU 版本。若你需要使用 GPU 进行训练或推理,请根据[官网教程](https://pytorch.org/index.html)安装与你的 CUDA 版本匹配的 PyTorch 和 Torchvision。对于装有 NVIDIA GPU 并需要使用 GPU 的环境,最终检查结果应为 `True`。

> 6.5 NVIDIA 的 RTX 50 系列显卡需要安装 CUDA 12.8 及以上版本的预览版

>

> ```Shell

> pip install --pre torch Torchvision torchaudio --index-url https://download.PyTorch.org/whl/nightly/cu128

>

> ```

7、验证:

正常安装成功之后可以先输入`lerobot`,然后快速点几下`Tab`键,命令行就会跳出如下匹配上的`CLI`命令即代表安装成功。

```Shell

ember@Ember:~$ lerobot

lerobot-annotate lerobot-find-cameras lerobot-record

lerobot-teleoperate lerobot-calibrate lerobot-find-joint-limits

lerobot-replay lerobot-train-tokenizer lerobot-dataset-viz

lerobot-find-port lerobot-rollout lerobot-train

lerobot-edit-dataset lerobot-imgtransform-viz lerobot-setup-can

lerobot-eval lerobot-info lerobot-setup-motors

```

8、其他:

在这里,我们所使用的是conda隔离环境,因此有一些命令会日常用到,这里我记录几个,也辅助自己记忆。这里的1、2、3、4······等等不是一定要做的步骤,只是一个标识,后方有简易流程。如果要深入学习,请移步互联网。

```bash

1. 查看所有环境

conda env list

# 等价

conda info --envs

2. 进入 / 激活环境

# 进入lerobot环境

conda activate lerobot

# 进入默认base环境

conda activate base

3. 退出当前环境

conda deactivate

执行后提示符前 (xxx) 消失,脱离所有 conda 环境。

4. 切换环境(不用先退出,直接切)

比如当前在 base,直接切 lerobot:

conda activate lerobot

conda 会自动关闭上一个环境,无需手动deactivate。

5. 新建环境(示例)

conda create -n 环境名(如larobot) python=3.10

6. 删除无用环境(谨慎)

conda remove -n 环境名 --all

极简流程示例

# 1. 查看有哪些环境

conda env list

# 2. 进入项目环境

conda activate lerobot

# 3. 用完退出

conda deactivate

# 4. 想切回base

conda activate base

```

配置舵机

### **说明**

这里会有一个小问题,`Ubuntu22.04` 的 `ttyUSB`、`ttyACM` 端口可能会被一个 `brltty` 服务抢占端口,这个时候直接删掉即可。[Ubuntu22.04(无法访问 /dev/ttyUSB /dev/ttyACM: 没有那个文件或目录)问题解决](https://blog.csdn.net/weixin_49513223/article/details/127068065)

- `sudo dmesg | grep brltty`

- 若果出现`[ 7033.078452] usb 1-13: usbfs: interface 0 claimed by ch341 while 'brltty' sets config #1` 这样的结果,则意味着是驱动占用问题;

- 运行 `sudo apt remove brltty` 然后重新插拔一下设备即可解决问题。

```bash

sudo apt remove brltty

```

### **配置舵机**

1. 找到与每个手臂关联的 USB 端口:

要找到每个总线伺服适配器的端口,请通过 USB 和电源将 MotorBus 连接到你的计算机。运行以下脚本并在提示时断开 MotorBus:

```shell

lerobot-find-port

```

在 Linux 上,需要通过运行以下命令来授予对 USB 端口的访问权限:

```shell

sudo chmod 666 /dev/ttyACM0

sudo chmod 666 /dev/ttyACM1

```

示例输出:

```shell

Finding all available ports for the MotorBus.

['/dev/ttyACM0', '/dev/ttyACM1']

Remove the usb cable from your MotorsBus and press Enter when done.

[...断开相应的 leader 或 follower 手臂并按 Enter...]

The port of this MotorsBus is /dev/ttyACM1

Reconnect the USB cable.

```

其中找到的端口是:`/dev/ttyACM1`,对应你的`leader`或 `follower` 手臂。

2. 设置电机 ID 和波特率

每个电机通过总线上的唯一 ID 进行识别。全新的电机通常带有默认 `ID 1`。为了使电机和控制器之间的通信正常工作,我们首先需要为每个电机设置一个唯一的、不同的 ID。此外,总线上数据传输的速度由波特率决定。为了相互通信,控制器和所有电机需要配置相同的波特率。

为此,我们首先需要使用控制器单独连接到每个电机以设置这些参数。由于我们将这些参数写入电机内部存储器`(EEPROM)`的非易失性部分,因此我们只需要执行一次此操作。

如果你正在重新利用来自另一个机器人的电机,你可能也需要执行此步骤,因为 ID 和波特率可能不匹配。

#### Follower

将 USB 电缆从你的计算机和电源连接到 follower 手臂的控制器板。然后,使用你在上一步中获得的端口运行以下命令。你还需要使用 `id` 参数为你的 leader 手臂命名。

```shell

lerobot-setup-motors \

--robot.type=so101_follower \

--robot.port=/dev/ttyACM0 # <- 在此粘贴上一步找到的端口

```

你应该看到以下说明

```shell

Connect the controller board to the 'gripper' motor only and press enter.

```

按照指示,插入夹爪的电机。确保它是连接到板上的唯一电机,并且电机本身尚未菊花链连接到任何其他电机。当你按下 `[Enter]` 时,脚本将自动为该电机设置 ID 和波特率。

然后你应该看到以下消息:

```shell

'gripper' motor id set to 6

```

接着是下一条指令:

```shell

Connect the controller board to the 'wrist_roll' motor only and press enter.

```

你可以从控制器板上断开 3 针电缆,但可以将其连接到另一端的夹爪电机上,因为它已经在正确的位置。现在,将另一根 3 针电缆插入腕部滚动电机并将其连接到控制器板。与之前的电机一样,确保它是连接到板上的唯一电机,并且电机本身未连接到任何其他电机。

按照指示对每个电机重复操作。

在按 Enter 之前检查每一步的接线。例如,当你操作板时,电源电缆可能会断开连接。

完成后,脚本将简单地结束,此时电机已准备好使用。你现在可以将每个电机的 3 针电缆插入下一个电机,并将第一个电机(ID=1 的 'shoulder pan')的电缆插入控制器板,该控制器板现在可以连接到手臂的底座。

#### Leader

对 leader 手臂执行相同的步骤。

```shell

lerobot-setup-motors \

--teleop.type=so101_leader \

--teleop.port=/dev/ttyACM0 # <- 在此粘贴上一步找到的端口

```

组装机械臂

1.

### **组装机械臂**

舵机到手之后按表格顺序排列

| | | |

| --- | --- | --- |

| ID号 | Leader | Follower |

| 1 | ST-3215-C044 | ST-3215-C047 |

| 2 | ST-3215-C001 | ST-3215-C047 |

| 3 | ST-3215-C044 | ST-3215-C047 |

| 4 | ST-3215-C046 | ST-3215-C047 |

| 5 | ST-3215-C046 | ST-3215-C047 |

| 6 | ST-3215-C046 | ST-3215-C047 |

为什么这里的ID号是这样的先按下不表,先以此为顺序,安装机械臂的各个关节。\

安装`ID1`舵机\

安装两个电机角。用 M3x6mm 螺丝固定顶部的角。底部的角不需要螺丝。

- 将第一个电机放入底座。

- 用 4 颗 M2x6mm 螺丝(最小的螺丝)固定电机。顶部两颗,底部两颗。

- 滑过第一个电机支架并使用两颗 M2x6mm 螺丝(每侧一颗)固定。

- 连接肩部零件。

- 用顶部 4 颗 M3x6mm 螺丝和底部 4 颗 M3x6mm 螺丝拧紧肩部零件

- 添加肩部电机支架。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/350cb0c3-4561-49d2-93e0-38c746b49e94/files/video/55d56df905994e98a60623dcba11d2c3.mp4)

安装`ID2`舵机\

安装两个电机角。用 M3x6mm 螺丝固定顶部的角。底部的角不需要螺丝。

- 从顶部滑入第二个电机。

- 用 4 颗 M2x6mm 螺丝固定第二个电机。

- 用每侧 4 颗 M3x6mm 螺丝连接上臂。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/df2085453d634d0ea7fdb0ef1d254a85.mp4)

安装`ID3`舵机\

安装两个电机角。用 M3x6mm 螺丝固定顶部的角。底部的角不需要螺丝。

- 插入电机 3 并使用 4 颗 M2x6mm 螺丝固定。

- 使用每侧 4 颗 M3x6mm 螺丝将前臂连接到电机 3。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/7dcc4b58d2f3436d82b9358e4a5d8845.mp4)

安装`ID4`舵机\

安装两个电机角。用 M3x6mm 螺丝固定顶部的角。底部的角不需要螺丝。

- 滑过电机支架 4。

- 滑入电机 4。

- 用 4 颗 M2x6mm 螺丝固定电机 4。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/b6a0620cb1fa43549cd08bacf5656c6c.mp4)

安装`ID5`舵机\

将电机 5 插入腕部支架并用 2 颗 M2x6mm 前螺丝固定。

- 仅在腕部电机上安装一个电机角,并用 M3x6mm 角螺丝固定。

- 使用两侧各 4 颗 M3x6mm 螺丝将腕部固定到电机 4。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/3c9241cb23b94675b0f8edeb1eea88df.mp4)

安装Leader臂的舵机`(这里对应为ID6-leader的舵机)`\

将 leader 支架安装到腕部并用 4 颗 M3x6mm 螺丝固定。

- 使用 1 颗 M2x6mm 螺丝将手柄连接到电机 5。

- 插入夹爪电机,用每侧 2 颗 M2x6mm 螺丝固定,使用 M3x6mm 角螺丝连接电机角。

- 用 4 颗 M3x6mm 螺丝连接 follower 触发器。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/4b9b2e4b41684342bc217a5ea0316530.mp4)

安装Follower臂的舵机`(这里对应为ID6-Follower的舵机)`\

将夹爪连接到电机 5,使用 4 颗 M3x6mm 螺丝将其连接到腕部的电机角。

- 插入夹爪电机并用每侧 2 颗 M2x6mm 螺丝固定。

- 在夹爪电机上安装两个电机角。用 M3x6mm 螺丝固定顶部的角;底部的角不需要螺丝。

- 安装夹爪爪并用两侧各 4 颗 M3x6mm 螺丝固定。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/67b2473d-7789-43dd-9c90-4a1620fe89ce/files/video/787cf12901f044f38bb392b850122401.mp4)

- 注:安装时灵巧手直接替代六号抓夹的位置即可

校准机械臂

### **校准**

接下来,你需要校准机器人,以确保 leader 和 follower 手臂在相同的物理位置时具有相同的位置值。 校准过程非常重要,因为它允许在一个机器人上训练的神经网络在另一个机器人上工作。

#### Follower

运行以下命令来校准 follower 手臂:

```shell

lerobot-calibrate \

--robot.type=so101_follower \

--robot.port=/dev/ttyACM1 \ # <- 你的机器人端口

--robot.id=follower1 # <- 给机器人一个唯一的名称

```

下面的视频显示了如何执行校准。首先,你需要将机器人移动到所有关节都处于其范围中间的位置。然后在按 Enter 后,你必须将每个关节移动通过其完整的运动范围。

执行相同的步骤来校准 leader 手臂,运行以下命令:

```shell

lerobot-calibrate \

--teleop.type=so101_leader \

--teleop.port=/dev/ttyACM0 \ # <- 你的机器人端口

--teleop.id=leader1 # <- 给机器人一个唯一的名称

```

视觉训练

下面这段可以直接粘贴到“视觉训练”正文里。相机编号、权重路径和训练环境需按实际设备替换;方案文件中未提供的训练集规模、置信度阈值等参数,我标成了建议值或待实测项。

## 视觉训练

### 1. 训练目标与摄像头分工

本方案使用两路摄像头分别完成顾客侧感知和卡盒侧感知,避免两路画面混用同一套检测逻辑:

- **左摄像头(顾客侧)**:使用预训练 YOLOv8s 微调“person”检测模型,用于检测顾客接近。触发条件为顾客进入约 **1.5 m** 范围并停留至少 **0.5 s**;这两个值为方案目标,需现场标定和验证。

- **右摄像头(桌面侧)**:使用独立的“card_box”检测模型定位卡盒。RGB-D 深度信息结合相机到机械臂基座的外参,将卡盒位置换算到机械臂坐标系。

- **碰指事件**:单纯检测到人体不能确认碰指。需单独采集碰指过程并标注“未接触/接触”等事件,结合指尖区域定位和力觉信号验证。具体识别阈值在 5 人内测后确定,未实测前不作为已验证指标。

### 2. 检查摄像头并确认编号

连接摄像头后,先查看当前系统识别到的设备:

```

lerobot-find-cameras opencv

```

根据命令输出记录左、右摄像头的 ID。编号可能因重启或重新插拔而变化;每次接线调整后都应重新检查。方案的采集目标为 RGB 视频 **1920×1080、30 FPS**;右摄像头如使用深度流,目标为 **15 FPS**。实际分辨率和帧率以设备支持情况为准。

在现有 LeRobot 遥操作或录制命令中加入双摄配置。下面的 `0`、`1` 是示例编号,请替换成上一步查到的实际 ID:

```

--robot.cameras='{ front: {type: opencv, index_or_path: 0, width: 1920, height: 1080, fps: 30, fourcc: "MJPG"}, side: {type: opencv, index_or_path: 1, width: 1920, height: 1080, fps: 30, fourcc: "MJPG"}}'

```

其中 `front` 对应顾客侧,`side` 对应桌面卡盒侧。MJPG 可减少视频传输带宽;两路摄像头尽量分别接入电脑接口,不建议共用同一个 USB Hub。预览画面不等于训练数据已保存,需确认录制程序确实将视频或图像写入数据目录。

### 3. 采集、脱敏与整理训练数据

在实际展台光照和安装位置下采集两路画面,覆盖明暗变化、不同身高档、顾客靠近与路过、局部遮挡,以及卡盒不同位置和可见状态。连续视频不要只抽取相邻帧,避免训练集被大量相似画面占满。

采集前告知参与者并使用匿名编号;上传或共享数据前对人脸打码,不记录真实姓名和手机号。数据按摄像头和用途分开保存,例如:

```

datasets/

├── front_person/

│ ├── images/train/

│ ├── images/val/

│ ├── images/test/

│ ├── labels/train/

│ ├── labels/val/

│ └── labels/test/

└── side_card_box/

├── images/train/

├── images/val/

├── images/test/

├── labels/train/

├── labels/val/

└── labels/test/

```

使用支持 YOLO 格式的标注工具标出目标框:顾客侧标注 `person`,卡盒侧标注 `card_box`。训练、验证和测试集建议按**采集场次或 episode**拆分,避免同一段视频的相邻帧同时出现在训练集和测试集。初次试验可按约 **8:1:1** 划分;这是建议比例,不是方案文件已有的实测数据。

YOLO 检测标签每行对应一个目标,格式为:

```

class_id x_center y_center width height

```

坐标使用 0–1 之间的归一化值;类别编号从 0 开始。没有目标的图片可以不创建对应标签文件。

### 4. 配置数据集

在 `datasets/front_person/data.yaml` 中配置顾客检测数据:

```

path: datasets/front_person

train: images/train

val: images/val

test: images/test

names:

0: person

```

在 `datasets/side_card_box/data.yaml` 中配置卡盒检测数据:

```

path: datasets/side_card_box

train: images/train

val: images/val

test: images/test

names:

0: card_box

```

路径以项目根目录为基准。检查图片和标签文件一一对应、类别编号一致,并随机查看一批标注图,确认框没有漏标、错标或越界。

### 5. 安装训练依赖并微调模型

先按训练电脑的 CPU/GPU 和 CUDA 环境安装对应的 PyTorch,再安装 Ultralytics 与 OpenCV:

```

python -m pip install -U ultralytics opencv-python pyyaml

python -c "import torch, ultralytics; print('torch:', torch.__version__); print('ultralytics:', ultralytics.__version__); print('cuda:', torch.cuda.is_available())"

```

左摄像头顾客检测模型:

```

yolo detect train \

model=yolov8s.pt \

data=datasets/front_person/data.yaml \

imgsz=640 \

epochs=100 \

batch=16 \

device=0 \

project=runs/detect \

name=front_person

```

右摄像头卡盒检测模型:

```

yolo detect train \

model=yolov8s.pt \

data=datasets/side_card_box/data.yaml \

imgsz=640 \

epochs=100 \

batch=16 \

device=0 \

project=runs/detect \

name=side_card_box

```

`epochs=100`、`imgsz=640`、`batch=16` 是初始训练配置,不代表本方案已完成训练。显存不足时降低 `batch`;无可用 GPU 时将 `device=0` 改为 `device=cpu`,并相应调小 `batch`。训练结束后,在命令输出的实际运行目录中找到 `weights/best.pt`;如果同名目录已存在,运行目录可能自动编号。

### 6. 验证模型并检查现场画面

分别用未参与训练的测试集验证两个模型:

```

yolo detect val \

model=runs/detect/front_person/weights/best.pt \

data=datasets/front_person/data.yaml \

split=test \

imgsz=640 \

plots=True

```

```

yolo detect val \

model=runs/detect/side_card_box/weights/best.pt \

data=datasets/side_card_box/data.yaml \

split=test \

imgsz=640 \

plots=True

```

检查 Precision、Recall、mAP、混淆矩阵和漏检、误检样例;重点确认明暗变化、路过行人、部分遮挡和卡盒位置变化时的表现。再用真实录制视频查看预测框:

```

yolo detect predict \

model=runs/detect/front_person/weights/best.pt \

source=数据目录/front_test.mp4 \

imgsz=640 \

conf=0.25 \

save=True

```

右摄像头测试时,将模型和视频路径替换为卡盒模型及右摄像头测试视频。`conf=0.25` 仅用于初次查看效果;部署置信度需根据验证结果和现场误触发情况调整。

### 7. 接入交互状态机并实机验收

- 顾客检测结果映射到现场标定的 **1.5 m** 区域;持续满足检测条件 **0.5 s** 后才触发,减少路过误触发。

- 卡盒检测框与深度数据、相机外参结合,换算到机械臂基座坐标;标定精度需现场测量。

- 碰指检测作为独立事件分支测试,与腕部力觉或关节电流估力交叉确认。检测结果不稳定、目标丢失或通信中断时,交由 FSM 超时、安全停止或回退处理。

- 先完成 5 人内测,再进行正式采集。方案中的验收目标为:碰指一次触发成功率 **≥90%**、举盒一次成功率 **≥90%**、流程完整走完率 **≥85%**;这些均需实机测试后记录,不能仅凭离线 mAP 判断通过。

### 8. 保存复现材料

保存左右摄像头 ID、相机分辨率和帧率、标定文件、类别定义、数据集版本、训练命令、Python/PyTorch/Ultralytics 版本、`best.pt`、验证结果和测试视频。每个数据文件生成 MD5 并写入 `manifest.csv`,同时在 README 中记录硬件型号、固件版本、软件依赖及阈值参数,方便后续复现和追溯。

YOLOv8 检测模型支持训练、验证和推理;数据 YAML 与标签格式可参考 [YOLOv8 官方文档](https://docs.ultralytics.com/models/yolov8)、[训练文档](https://docs.ultralytics.com/modes/train)、[检测数据集格式](https://docs.ultralytics.com/datasets/detect)、[验证文档](https://docs.ultralytics.com/modes/val) 和[推理文档](https://docs.ultralytics.com/modes/predict)。

机械臂以及灵巧手控制算法

### 1. 确认硬件、通信和安全条件

确认机械臂、灵巧手、控制板、急停、腕部六维力传感器(或可读取的关节电流)均已连接。机械臂工作在协作模式,指尖和卡盒接触面安装软质保护层;正式运行前确认固定急停和工作人员手持急停均可用。

查看串口设备并赋予访问权限:

```

ls -al /dev/ttyACM*

sudo chmod 666 /dev/ttyACM*

```

如果系统中没有出现对应串口,先检查数据线、供电和控制板连接,再根据实际操作系统确认设备名。不要在未确认机械臂型号、电压和关节范围时直接运行控制命令。

### 2. 标定机械臂与主从臂

以 SO-ARM101 / LeRobot 为例,先将从臂各关节置于安全的中间位置,再启动标定:

```

lerobot-calibrate \

--robot.type=so101_follower \

--robot.port=/dev/ttyACM0 \

--robot.id=follower1

```

主臂单独标定:

```

lerobot-calibrate \

--teleop.type=so101_leader \

--teleop.port=/dev/ttyACM1 \

--teleop.id=leader1

```

按提示记录各关节的中位位置和可运动范围。标定时逐个关节缓慢运动,不要强行越过机械限位。后续控制、录制和回放应继续使用相同的 `robot.id`、`teleop.id` 和设备端口。

如果实际使用的机械臂并非 SO-ARM101,需将 `robot.type`、驱动和串口配置替换为对应型号的配置。

### 3. 建立姿态库并验证关节映射

为机械臂和灵巧手分别建立命名姿态,并记录每个关节的目标值、速度限制和适用状态。建议至少建立以下姿态:

- `home`:安全待机姿态

- `attract`:摇尾、摆肩等吸引动作

- `index_extend`:伸出食指,等待碰指

- `box_pregrasp`:靠近卡盒的预抓取姿态

- `box_pinch`:双指捏住盒边

- `present`:举盒展示姿态

- `celebrate`:答对后的庆祝动作

- `safe_hold`:故障时停止并保持的安全姿态

先逐个调用姿态,确认关节方向、角度范围和灵巧手手指映射正确。未完成映射检查前,不执行碰指、抓盒或面向顾客的动作。

### 4. 进行低速主从遥操作测试

在自动状态机运行前,先以低速验证主臂输入到从臂输出的方向、范围和延迟:

```

lerobot-teleoperate \

--robot.type=so101_follower \

--robot.port=/dev/ttyACM0 \

--robot.id=follower1 \

--teleop.type=so101_leader \

--teleop.port=/dev/ttyACM1 \

--teleop.id=leader1

```

先在无人员、无障碍物的区域检查各关节是否按预期跟随;确认急停有效后,再加入灵巧手控制。灵巧手通过其实际控制板和驱动接口发送姿态指令;具体命令需按灵巧手型号配置。

### 5. 使用平滑轨迹和状态机编排动作

上层使用单一有限状态机(FSM)管理动作顺序:

```

IDLE → ATTRACT → TOUCH → PICK_BOX → PRESENT → QUIZ → REWARD → RESET

```

每个状态只调用已经验证的机械臂或灵巧手姿态;状态切换须由明确事件触发,例如顾客接近、碰指确认、卡盒定位成功、答题结果返回或复位完成。

机械臂从当前姿态移动到目标姿态时,采用平滑插值,并限制速度、加速度和每次关节目标变化量。所有限制值根据实际机械臂说明书、标定结果和现场测试填写,不直接沿用未经验证的默认值。发生急停、通信中断、目标丢失、连续抓取失败或力信号超限时,立即停止当前动作并进入安全保持或经验证的安全回退状态;故障解除前不自动恢复运动。

### 6. 实现碰指时的力觉保护

在 `TOUCH` 状态中,灵巧手先切换到 `index_extend` 姿态,机械臂保持低速、限力,等待用户主动碰触。指尖接触区域使用软硅胶保护套。

腕部六维力传感器目标采样频率为 **500 Hz**,机械臂关节状态目标采样频率为 **100 Hz**。每轮开始前记录无接触基线;运行中持续检查力或电流信号。超过设备安全上限时,立即停止接触动作并进入安全保持状态。安全阈值应以设备厂商限制和现场校准结果为准,不在未实测时填写固定数值。

视觉确认、力觉确认和状态机事件写入同一时间线;以碰指接触事件作为该轮记录的 `t=0`,记录接触峰值、动作结果和异常原因。

### 7. 执行固定姿态卡盒抓取与展示

卡盒放在右摄像头覆盖的固定候选区域。抓取流程如下:

1. 读取右摄像头识别结果和深度值,结合已标定的相机到机械臂基座外参,计算卡盒位置。

2. 检查卡盒是否位于允许抓取区域;定位失败或坐标异常时不执行抓取。

3. 机械臂移动到 `box_pregrasp`,灵巧手切换到 `box_pinch`,按标定姿态夹住盒边。

4. 抬起过程中持续检查碰撞和力信号;出现异常时停止并安全回退。

5. 到达展示位后保持 **1–2 s**,让顾客看清卡盒词条,再等待答题结果。

6. 展示完成后根据答题结果进入 `REWARD` 或 `RESET`,并记录抓取、展示和答题结果。

卡盒采用预先标定的固定姿态库,不进行未经验证的随机抓取。抓取重试次数和超时参数在内测阶段确定。

### 8. 记录数据并进行验收

每轮自动记录机械臂关节角度、速度和电流、腕部力/力矩、状态机切换时间、碰指力峰值、抓盒结果、各阶段耗时和异常原因。所有数据使用匿名 episode ID;统一主机时钟,并通过 NTP 校时。原始记录和处理后的数据都保留版本信息。

先进行 **5 人内测**,排查动作方向、超时、夹取失败、力阈值和急停回退等问题;参数冻结后再正式采集 **30 人 × 3 轮,共 90 个 episode**,其中第 1 轮标记为学习轮。每轮结束即时检查数据完整性,发现缺项当场补采。

方案文件中的验收值是实机测试目标:碰指一次触发成功率 **≥90%**、举盒一次成功率 **≥90%**、流程完整走完率 **≥85%**、单轮时长中位数 **≤60 s**。这些结果须通过实际测试记录确认。

[视频](https://orecord-files.oss-cn-zhangjiakou.aliyuncs.com/sbp/projects/350cb0c3-4561-49d2-93e0-38c746b49e94/files/video/1354845ea58e42338b1551df3be041f5.mp4)