Skip to content





华为机器人大赛系列课程


基于昇腾310P的

叠衣服任务实验

版本:0.2

时间:2025.11.12









华为技术有限公司



版权所有 © 华为技术有限公司 2024。 保留一切权利。

非经本公司书面许可,任何单位和个人不得擅自摘抄、复制本文档内容的部分或全部,并不得以任何形式传播。


商标声明

和其他华为商标均为华为技术有限公司的商标。

本文档提及的其他所有商标或注册商标,由各自的所有人拥有。


注意

您购买的产品、服务或特性等应受华为公司商业合同和条款的约束,本文档中描述的全部或部分产品、服务或特性可能不在您的购买或使用范围之内。除非合同另有约定,华为公司对本文档内容不做任何明示或暗示的声明或保证。

由于产品版本升级或其他原因,本文档内容会不定期进行更新。除非另有约定,本文档仅作为使用指导,本文档中的所有陈述、信息和建议不构成任何明示或暗示的担保。






华为技术有限公司

地址:

深圳市龙岗区田华为总部办公楼邮编:518129

网址:

http://e.huawei.com



[TOC]


  1. 实验介绍

具身智能叠衣服demo参考样例是基于鼎桥开发板及千寻机器人本体进行的数采、模型增训和推理部署的二次开发。该款样例旨在为用户提供方便快捷的在机器人大赛下的解题思路,用户可快速上手、验证。

1.1. 外观结构

1.1.1. 千寻本体 & 昇腾310P 开发板/拓展坞


  千寻本体

  香橙派AI Studio (昇腾310P)


1.2. 赛题介绍



难度等级

赛题任务

推荐算法

评价(任务成功率)

总体任务

柔性衣物整理,桌面上一种衣服能叠放整齐。挑战初始姿态任意及多种衣服泛化(布料材质、衣服类型))、通过具身大脑的任务规划器和具身小脑的精确抓取和放置等动作执行,完成柔性衣服整理的长序列任务;

不限定算法,例如可参考VLA模型,或基于世界模型的动作生成。

策略:全程保持自主移动和操作,人工不干预

指标:大脑任务规划器的规划成功率和小脑精确执行成功率;

评分:任务成功率和完成时间进行评分

基础

衣服基本摊平,完成叠一种T

进阶

T恤初始姿态任意,完成叠一种T

高阶

衣服初始姿态任意,完成叠三种衣服


1.2.1. 组网架构


以千寻机器人为例,硬件系统框架如下图所示。


本次叠衣服Demo选用昇腾310P EP模式端侧算力,具体介绍参考:开发套件介绍及组网

组网架构如下:




1.2.2. 叠衣服赛题解题流程


基于千寻本体采集人工遥操叠衣服的真机数据(~200-300条轨迹),并通过开源模型Lerobot π0实现模型增训,在昇腾310P上部署π0模型后得到推理结果,最后使用千寻机器人的上肢双臂机械臂进行叠衣服操作。





2. 样例组装


2.1. 准备组件

千寻机器人本体可自行准备,或者由赛事组织方提供(千寻智能轮式双臂机器人),物料如下图所示。

机器人应用样例所需组件及组件关键部位参数见下表。

模块名称

数量/

是否需要单独购买

千寻本体及电源适配器

1

Meta Quest 3S(遥操数采VR头显)

1

USB3.0 头部摄像头Realsense D455

1

USB3.0 手部摄像头Realssense D405

2

急停按钮(有线/无线)

1

遥控pad

1

2.2. 机器人组装


  千寻机器人本体拆箱后,华为会提供如下配件:

    1. MiniPC(GMK K11迷你主机) + 香橙派AI Studio(昇腾310P)

    2. USB3.0延长线公对母延长线 x 2 (接手臂上的相机Intel Realsense R405 x 2)

    3. USB3.0 公转Tpec-C母延长线 x 1 (接手臂上的相机Intel Realsense R455)

    4. 交换机:5口千兆交换机

    5. USB HUB:USB3.2 扩展器拓展坞

    6. 网线:1根

    7. HDMI:外接显示器 x 1,尽量3米以上

    8. 鼠标键盘

    9. 电源插排:6口以上

  

  开箱标定流程参考:

  1. 机器人开箱:请参照千寻提供的《快速开箱手册指南(用户版)》对机器人进行开箱操作。

  2. 熟悉软硬件:待机器人开箱成功后,仔细阅读《千寻智能Moz1用户手册》与《外部控制模式指南及Capture-X软件使用说明》中关于机器人本体、MovaXHelper软件(运控上位机软件)、Capture-X软件(数据采集软件)的相关使用说明,尤其是注意相关安全设置以及急停按钮的使用方法,确保操作使用过程的人员及设备安全。

  3. 零点标定/校准:由于出厂设置及运输振动等原因,机器人开箱后的零点可能发生漂移,需要参照《千寻智能Moz1用户手册》P29-30进行零点标定。

    1. 使用右侧操控面板,分别设置①机械单元:左手、右手、腰腿②JOG步长:连续③选择坐标系:基坐标系④JOG类型:轴空间Jog

    2. 对照“Jog方向示教”选项卡中的示意图,对每个关节进行零点校正,具体使用“JOG”选项卡的“Jog”子选项卡对每个关节进行微调,确保机器人本体上的零点刻度对齐。

    3. 待所有关节的零点校正完成后,进入“设置”选项卡下的“零点标定”,分别针对每个机械单元进行一键标定即可。

  4. 调节头部角度:参照《千寻智能Moz1用户手册》P12-13进行调节,调整至头部摄像头能看全桌面内容即可,注意在实验过程中需要保持该角度不变。

  5. 设置工作点位:非必须。遥操数采过程中默认采用的工作点位为“VRMOV”。若需要额外调整,可进入“工具”选项卡下的“设置工作点位”新增或修改。

  6. 测试VR遥操数采:详见下文5.1节数据采集&处理以及《外部控制模式指南及Capture-X软件使用说明》。



3. 项目准备


3.1. 项目简介

  基于开源π0模型进行叠衣服操作,π0模型的部署参考具身智能典型算法模型昇腾部署参考(VLA π0 模型)

  

3.1.1. 输入与输出配置文件介绍


  输入的数据包括以下内容

  • 头部摄像头

  • 左手摄像头

  • 右手摄像头

  • 机械臂双臂7*2=14个关节信息

  • 机械臂1*2=2个夹爪信息

  • 机器人状态信息


  输出的数据包括以下内容:

  • 机械臂双臂7*2=14个关节信息

  • 机械臂1*2=2个夹爪信息


3.1.2. 概述

千寻提供的MOZRobot SDK 是一个用于控制 MOZ 机器人系统的综合性 Python SDK。基于 ROS2 构建,它为Moz1机器人提供直观的机器人控制、数据采集的API。

3.1.3. 系统要求

操作系统: Ubuntu 22.04 LTS

ROS 版本: ROS2 Humble

Python 版本: 3.10 或更高版本,建议使用系统解释器

硬件要求:

- RealSense 相机:USB 3.0 * 3

- 与机器人控制系统连接:RJ45 * 1

系统资源: 推荐 8GB+ 内存

3.1.4. 网络配置

主机 IP: 必须在 172.16.0.x 子网中(例如:172.16.0.100)

机器人 IP: 172.16.0.20

ROS_DOMAIN_ID: 33(需要与 MovaX 控制系统保持一致)

3.1.5. 环境配置

系统依赖

python
# 安装 ROS2 Humble
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y

sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

sudo apt update
# you can install ros-humble-desktop-full
sudo apt install -y ros-humble-ros-base python3-colcon-common-extensions ros-dev-tools

# 安装系统依赖
sudo apt install -y build-essential cmake git curl wget python3-pip python3-dev
sudo apt install -y libopencv-dev python3-opencv

robot_interface ROS 包构建

robot_interface 是必需的 ROS2 接口包,包含机器人通信消息和服务定义。必须先构建此包才能正常使用 SDK。

python
# 进入依赖包目录
cd /path/to/mozrobot-SDK/deps

# 创建ROS2工作空间并构建robot_interface包
mkdir -p ~/ros_ws/src
cp -r robot_interface ~/ros_ws/src/
cd ~/ros_ws

# 配置ROS2环境
source /opt/ros/humble/setup.bash
# 构建包
colcon build --packages-select mc_core_interface

环境配置

python
# 配置 ROS2 环境
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
echo "export ROS_DOMAIN_ID=33" >> ~/.bashrc
echo "source ~/ros_ws/install/setup.bash" >> ~/.bashrc  # 添加robot_interface包环境
source ~/.bashrc

网络配置

编辑网络配置:

python
sudo nano /etc/netplan/01-netcfg.yaml

添加以下配置:

python
network:
  version: 2
  ethernets:
    eth0:  # 替换为实际网络接口名称
      addresses: [172.16.0.100/24]  # 选择 172.16.0.x 范围内的 IP
      gateway4: 172.16.0.1
      nameservers:
        addresses: [8.8.8.8, 8.8.4.4]

SDK安装

python
# 安装 Python 依赖
cd /path/to/mozrobot-sdk
pip3 install -r packages/requirements.txt

# 安装sdk
pip install packages/mozrobot-*.whl

验证安装

python
python3 -c "from mozrobot import MOZ1Robot, MOZ1RobotConfig; print('✅ MOZRobot SDK 安装成功!')"

3.2. 千寻机器人本体功能快速测试(验证本体能否基于SDK做基础运动)

python
# 设置环境
export ROS_DOMAIN_ID=33

# 运行示例
cd mozrobot
python3 example/example_usage.py

# 启用性能优化的示例
python3 example/example_usage.py --enable-soft-realtime --bind-cpu 5 --no-camera




4. 连接并启动机器人


4.1. 连接千寻机器人和昇腾310P算力套件

4.1.1. 环境搭建

昇腾310P开发套件

环境要求

镜像版本

opiaipro_ubuntu22.04_desktop_aarch64_20240318

操作系统

Ubuntu22.04

具体配置参考链接:具身智能典型算法模型昇腾部署参考(分层模型)


机器人和开发板连接组网图


连接部署组网图




5. 项目运行


5.1. 数据采集&处理

5.1.1. 千寻机器人本体及实验环境

  本指导书以叠衣服赛题及千寻机器人本体为例,对机器人VR遥操数采系统、总体流程、详细步骤进行讲解。其它型号的机器人和不同的赛题任务也可参考。

  在进行遥操数采之前,需要设置机器人实验环境。除了千寻机器人本体之外,还需要软硬程度适中的衣服、高度大小合适的桌子、充足均匀的光照条件、安全可靠的实验场地、适当的支架保护装置。需要注意的是,在本指导书中,固定桌面高度为75 cm(在这里,为了实验设置和训练的方便,并未做不同桌面高度的泛化)。



5.1.2. 千寻机器人遥操数采软硬件系统概述


  遥操数采系统由硬件设备和软件系统组成。其中, 硬件设备包括:Meta Quest 3S头盔及手柄、控制踏板、急停按钮;软件系统包括:机器人遥操数采软件、机器人控制器上位机软件。

  1. 急停按钮:仅供紧急情况使用,正常情况下通过软件进行上下电等机器人控制操作。

  2. 鼠标/键盘:用于遥操数采的数据采集记录功能,包括激活采集、开始/停止采集、标记无效数据。

  3. Meta Quest 3S:用于VR遥操,将手柄映射为机器人的末端位姿,实现遥操数采。

  4. CaptureX(机器人遥操数采软件):用于记录遥操数采过程中的机器人图像、关节角等数据,并包含VR手柄位姿读取转换、IK逆运动学解算、数据存储记录、数据格式转换、数据上传等功能。

  5. MovaXHelper(机器人控制器上位机软件):用于连接Monitor、启动控制器、连接控制器、控制机器人本体关节阻抗、上下电等与机器人运动控制相关的操作。

5.1.3. 机器人遥操数采总体流程


  1. 插上机器人本体的电源。

  2. 将Meta Quest 3S头盔通过USB-C连接线插到机器人本体。

  3. 启动推理主机。

  4. 在推理主机或平板上启动机器人控制器上位机软件MovaXHelper,连接控制器,进行机器人上电。

  5. 在MovaXHelper中启动遥操。

  6. 启动遥操数采软件CaptureX。

  7. 开始机器人VR遥操数采。

  8. 结束遥操数采,拷贝保存在本地的数据集,供后续模型训练及部署使用。

  9. 在机器人控制器上位机软件中操作机器人下电。

  10. 关闭遥操数采软件。

  11. 关闭推理主机,拔下机器人本体的电源,给Meta Quest 3S头盔充电。

5.1.4. 机器人控制器上位机软件操作流程及步骤


  1. 启动机器人控制器上位机软件。

  2. 首先,点击“连接Monitor”按钮。

  3. 随后,点击“启动控制器”按钮,等待下方“mc_core”指示灯由红变绿即可。

  4. 然后,点击“连接控制器”按钮,并在弹出窗口中选择“Yes”。

  5. 点击右上方工具栏的“系统监测”选项卡,进入控制器设置界面。

  6. 先点击“关节阻抗”按钮(建议开启,以防止机器人发生大力碰撞的情形)。

  7. 再点击“上下电”按钮,听到机器人咔嚓声即表示成功上电/下电。

  

5.1.5. 机器人VR遥操数采流程及步骤


参照《外部控制模式指南及Capture-X软件使用说明》

5.2. 模型微调

该步骤用真机实采数据微调优化π0模型,在预训练大模型基础上更精准地实现叠衣服操作,这一部分涉及算力需求较大,为提高训练效率,建议在自己的算力资源上增训。


* <span style="font-size: 10.5pt"><b>获取环境配置及原始模型文件</b></span>

Lerobot/π0模型(建议使用0.3.3版本的lerobot框架,官网链接:github.com)

示例使用git拉取

git clone -b v0.3.3 https://github.com/huggingface/lerobot.git

conda create -n lerobot python=3.10 -y

conda activate lerobot

cd lerobot

pip install -e

pip install pytest transformers


* <span style="font-size: 10.5pt"><b>获取π0模型</b></span>

    * <span style="font-size: 10.5pt;font-weight: normal">可以通过huggingface手动下载π0模型文件,也可以通过指令下载</span>

① 手动下载:https://huggingface.co/lerobot/pi0/tree/main

② 指令下载:

export HF_ENDPOINT = ’https://hf-mirror.com’

pip install huggingface_hub hf-transfer

hf download lerobot/pi0 --local-dir <模型存放路径>


    * <span style="font-size: 10.5pt;font-weight: normal">下载paligemma-3b的tokenzier(只能手动下载)</span>

下载链接:https://www.modelscope.cn/models/google/paligemma-3b-pt-224

下载added_tokens.json,special_tokens_map.json,tokenizer.json,tokenizer.model和tokenizer_config.json至一个文件夹中

  


    * <span style="font-size: 10.5pt;font-weight: normal">修改lerobot中pi0初始化tokenizer的路径为下载的tokenizer的路径</span>

  

    * <span style="font-size: 10.5pt;font-family: Open Sans">修改模型默认配置文件/src/lerobot/config/policy.py中的类PretrainedConfig,将__post_init__方法中的</span>
python
self.pretrained_path = None

  注释掉并修改为

    * <span style="font-size: 10.5pt;font-family: Open Sans">创建并编辑训练配置文件train_config.json,修改dataset中数据集路径,policy中模型权重路径,权重输出路径,batch_size,权重保存频率优化器配置以及学习率调度器配置。可选优化器参见/src/lerobot/optim/optimizer.py,可选调度器参见/src/lerobot/optim/scheduler.py。</span>
json
{
    "dataset": {
        "repo_id": "/no/need/to/fill/this",
        "root":"/path/to/dataset",
        "episodes": null,
        "image_transforms": {
            "enable": false,
            "max_num_transforms": 3,
            "random_order": false,
            "tfs": {
                "brightness": {
                    "weight": 1.0,
                    "type": "ColorJitter",
                    "kwargs": {
                        "brightness": [
                            0.8,
                            1.2
                        ]
                    }
                },
                "contrast": {
                    "weight": 1.0,
                    "type": "ColorJitter",
                    "kwargs": {
                        "contrast": [
                            0.8,
                            1.2
                        ]
                    }
                },
                "saturation": {
                    "weight": 1.0,
                    "type": "ColorJitter",
                    "kwargs": {
                        "saturation": [
                            0.5,
                            1.5
                        ]
                    }
                },
                "hue": {
                    "weight": 1.0,
                    "type": "ColorJitter",
                    "kwargs": {
                        "hue": [
                            -0.05,
                            0.05
                        ]
                    }
                },
                "sharpness": {
                    "weight": 1.0,
                    "type": "SharpnessJitter",
                    "kwargs": {
                        "sharpness": [
                            0.5,
                            1.5
                        ]
                    }
                }
            }
        },
        "use_imagenet_stats": true,
        "video_backend": "pyav"
    },
    "env": null,
    "policy": {
        "pretrained_path": "/path/to/model/weights",
        "push_to_hub": false,
        "repo_id": null,
        "type": "pi0",
        "n_obs_steps": 1,
        "device": "cuda",
        "use_amp": false,
        "normalization_mapping": {
            "VISUAL": "IDENTITY",
            "STATE": "MEAN_STD",
            "ACTION": "MEAN_STD"
        },
        "input_features": {},
        "output_features": {},
        "chunk_size": 50,
        "n_action_steps": 50,
        "max_state_dim": 32,
        "max_action_dim": 32,
        "resize_imgs_with_padding": [
            224,
            224
        ],
        "empty_cameras": 0,
        "adapt_to_pi_aloha": false,
        "use_delta_joint_actions_aloha": false,
        "tokenizer_max_length": 48,
        "proj_width": 1024,
        "num_steps": 50,
        "use_cache": true,
        "attention_implementation": "eager",
        "freeze_vision_encoder": true,
        "train_expert_only": true,
        "train_state_proj": true,
        "optimizer_lr": 2.5e-05,
        "optimizer_betas": [
            0.9,
            0.95
        ],
        "optimizer_eps": 1e-08,
        "optimizer_weight_decay": 1e-10,
        "scheduler_warmup_steps": 1000,
        "scheduler_decay_steps": 30000,
        "scheduler_decay_lr": 2.5e-06
    },
    "output_dir": "/define/outputs/path",
    "job_name": "train",
    "resume": false,
    "seed": 100000,
    "num_workers": 4,
    "batch_size": 1,
    "steps": 200000,
    "eval_freq": 25000,
    "log_freq": 200,
    "save_checkpoint": true,
    "save_freq": 2500,
    "use_policy_training_preset": false,
    "optimizer": {
        "type": "adam",
        "lr": 5e-05,
        "betas": [
            0.9,
            0.95
        ],
        "eps": 1e-08,
        "weight_decay": 1e-10,
        "grad_clip_norm": 10.0
    },
    "scheduler": {
        "type": "cosine_decay_with_warmup",
        "num_warmup_steps": 500,
        "num_decay_steps": 1000,
        "peak_lr": 5e-5,
        "decay_lr": 1e-5
    },
    "eval": {
        "n_episodes": 50,
        "batch_size": 50,
        "use_async_envs": false
    },
    "wandb": {
        "enable": false,
        "disable_artifact": false,
        "project": "lerobot",
        "entity": null,
        "notes": null
    }
}
    * <span style="font-size: 10.5pt;font-family: Open Sans">调用训练指令lerobot-train(训练脚本在/src/lerobot/scripts/train.py,如需调整可在此修改),并添加config_path参数制定train_config.json路径。</span>
shell
lerobot-train --config_path=/.../train_config.json
    * <span style="font-size: 10.5pt;font-family: Open Sans">若想从得到的训练权重继续启动训练,则执行指令并将配置文件路径改为训练出的权重路径,并添加resume参数。</span>
shell
lerobot-train --config_path=/.../path/to/weights/train_config.json --resume=true

5.3. 端侧部署

  

5.3.1. 模型输入输出

  输入数据:

输入数据名(name)

数据类型(dtype)

数据大小(shape)

数据排布格式

observation.images.head

float32

[N,3,240,320]

N,C,H,W

N - batch size

C - channel

H - height

W - width

observation.images.left_hand

float32

[N,3,240,320]

N,C,H,W

observation.images.right_hand

float32

[N,3,240,320]

N - batch size

N,C,H,W

observation.state

float32

[N, 16]

N, state_dim

tasks

string

[N]

N

  输出数据:

输入数据名(name)

数据类型(dtype)

数据大小(shape)

数据排布格式

action

float32

[N, 16]

N, action_dim

以上是模型推理的输入和输出,输出包括左臂关节、左夹爪、右臂关节、右夹爪。

输入源来自3个相机、任务语言指令及机器人状态,经过编码器、LLM及动作模型得到输出。

  

5.3.2. 模型加载

5.3.2.1. 步骤1:获取模型框架

  Lerobot/π0模型(建议使用0.3.3版本的lerobot框架,lerobot 官网链接:github.com

为加速推理,建议优化精度FP32→FP16,开源模型lerobot π0 文件调整如下:


示例使用git拉取

git clone -b v0.3.3 https://github.com/huggingface/lerobot.git

conda create -n lerobot python=3.10 -y

conda activate lerobot

cd lerobot

pip install -e .

pip install pytest transformers==4.52.1 "numpy<2.0"


5.3.2.2. 步骤2:获取lerobot π0模型

  因为π0当前仅openpi和lerobot提供源码,推荐使用昇腾已适配的lerobot π0,可以通过huggingface手动下载lerobot π0 模型文件,也可以通过指令下载。

① 手动下载:https://huggingface.co/lerobot/pi0_base/tree/main

② 指令下载:

export HF_ENDPOINT=’https:///hf-mirror.com

hf download lerobot/pi0_base  --local-dir <模型存放路径>


  1. 下载paligemma-3b的tokenzier(只能手动下载)

下载链接:https://www.modelscope.cn/models/google/paligemma-3b-pt-224

从链接中下载added_tokens.json,special_tokens_map.json,tokenizer.json,tokenizer.model和tokenizer_config.json五个文件至同一个文件夹中


  1. 在开发板系统上修改lerobot中pi0初始化tokenizer的路径为下载的tokenizer的路径

在src/lerobot/policies/pi0文件夹的modeling_pi0.py文件中,源码固定tokenizer的来源为huggingface,使用时自动下载并加载tokenizer。

实际操作中由于网络问题需手动下载前中并修改路径至本地的tokenizer路径。

在PI0Policy类中的__init__()初始化方法中,将AutoTokenizer.from_pretrained("google/paligemma-3b-pt-224")改为

AutoTokenizer.from_pretrained("下载的tokenizer存放路径")

  1. 310P不支持bfloat16数据格式,需将代码中转换bfloat16格式的代码注释掉

bfloat16转换代码在src/lerobot/policies/pi0文件夹下的 modeling_pi0.py 和 paligemma_with_expert.py 两个文件中,CTRL+F 搜索 bfloat16,在对应代码行按CTRL+/ 注释该行代码使其失效,如下是5处需注释掉的代码行

6. 真机验证

  基于MiniPC(Host主机)安装 LeRobot进行在线推理(pytorch在npu上的运行方式 → torch_npu)。使用lerobot框架加载pi0模型,迁移至npu上并推理,基于torch_npu进行在线推理,推理速度预计在430ms。

  • 推理数据来源:① Intelrealsense 相机 x 3;② 本体状态,以千寻机器人双臂+夹爪 16自由度的向量;③ 输入指令,如叠衣服“fold shirt”指令

  • 输出数据:动作指令,如千寻机器人双臂+夹爪16自由度向量

python
import torch
import torch_npu
from torch_npu.contrib import transfer_to_npu
from lerobot.policies.pi0.modeling_pi0 import PI0Policy
from lerobot
.configs.types import FeatureType, PolicyFeature
import time
 
def main():
    model_path = "/path/to/model/weights"
    # 修改model_path为模型权重路径,from_pretrained方法通过读取权重路径下的config.json文件的配置初始化模型架构,并使用model.safetensors赋予模型预训练权重
    policy = PI0Policy.from_pretrained(model_path).to(device="npu")
    policy.eval()
 
    # 设置输出格式
    policy.config.output_features = {
        "action": PolicyFeature(
            type=FeatureType.ACTION,
            shape=(16,)
        )
    }
    # 设置输入格式
    policy.config.input_features = {
        "observation.images.top": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.images.left_hand": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.images.right_hand": PolicyFeature(
            type=FeatureType.VISUAL,
            shape=(1, 3, 224, 224)
        ),
        "observation.state": PolicyFeature(
            type=FeatureType.STATE,
            shape=(1, 16)
        )
    }
    with torch.inference_mode():
    # 验证模型加载与推理效果
        for _ in range(10):
        # pi0模型一次推理输出50个action,selection_action将推理得到的action存储至队列中,
        # 每次调用从队列中取出一个action返回,直至队列为空再进行新一轮推理,
        # 使用reset()方法清空队列使模型每次都进行推理
            policy.reset()
            observation = {
                # 当前输入是随机生成的用于验证的伪数据,
                # 输入三路相机:真机验证时可替换为真实图像,图像像素值需手动归一化至0~1之间再输入至模型中
                "observation.images.head": torch.rand(1, 3, 224, 224).npu(),
                "observation.images.left_hand": torch.rand(1, 3, 224, 224).npu(),
                "observation.images.right_hand": torch.rand(1, 3, 224, 224).npu(),
                # 输入本体状态:以机器人上半身16个自由度本体状态为例,包括双臂(7*2)+夹爪(1*2)
                "observation.state": torch.randn(1, 16).npu(),
                "task": ["Do something."]
            }
            start = time.perf_counter()
            # 输出控制指令:基于observation输入,推理生成16个自由度输出(以千寻机器人上半身16自由度为例)
            action = policy.select_action(observation)
            # 输出速度统计
            duration = time.perf_counter() - start
            print(f"Time cost: {duration * 1000} ms.")
            print(action)
if __name__ == '__main__':
    main()


  若无报错,证明推理功能上没问题。预期输出基于torch_npu推理π0模型(lerobot)单次推理时间 ~ 430ms



7. 实验总结


本实验基于昇腾310P端侧算力,通过数据采集、模型微调、端侧部署、真机验证四步流程,指导学生从零构建叠衣服演示demo。实践过程中完成机器人实现基于VLA(π0)的双臂复杂操作,强化理论与实践融合,提升具身智能综合应用能力。