Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

简介

要基于端到端实现一个有双臂的轮足机器人, 可以基于语音控制关灯,捡东西丢垃圾桶里,把地上的东西放桌子上,叠衣服等。

曹志伟

搭建并维护 Agent-VLA-LLM 解耦协作框架,实现 VLA 服务接口、配置管理、Git 协作流程和本地联调测试。同时负责采集机器人任务数据、训练 SmolVLA 模型,并将训练好的模型接入框架,实现捡球、关灯等桌面机器人技能的可扩展部署。

第一周

week1

一、框架核心工作

本周完成了桌面端机器人 Demo 第一版的整体技术框架设计与基础代码搭建。目标是构建一个可扩展、可替换、便于多人协作开发的 Agent + VLA + LLM 解耦框架,使上层 Agent 可以根据用户自然语言输入,选择调用具身智能模型或通用大语言模型。

框架目录位于:

/home/czw1/ChenLong-Robot-Internship/agent_vla

整体架构设计如下:

用户输入
  |
  v
Agent API
  |
  +-- 机器人任务 -> VLA Service -> SmolVLA / LeRobot / 后续 Ascend NPU
  |
  +-- 通用问答 -> LLM Service -> OpenAI / Ollama / 本地大模型

本周实现了三个核心服务:

  1. Agent API

    • 作为系统统一入口,接收用户输入。
    • 根据用户输入判断是机器人任务还是通用问答。
    • 将机器人任务映射为固定的 skill_id,例如 ball_pick_v1
    • 根据路由结果调用 VLA Service 或 LLM Service。
  2. VLA Service

    • 负责管理机器人技能。
    • 提供 GET /v1/skillsPOST /v1/execute 接口。
    • 当前实现了 mock provider 和 lerobot_rollout provider。
    • 后续可以新增 ascend_vla provider,用于 Orange Pi AI Pro / Ascend NPU 推理。
  3. LLM Service

    • 负责通用语言模型能力。
    • 提供 POST /v1/generate 接口。
    • 当前实现了 mock provider。
    • 后续可以扩展 OpenAI、Ollama、Qwen、本地大模型等 provider。

当前核心代码结构如下:

agent_vla/
  configs/
    app.yaml                  # 全局配置:路由规则、技能、模型路径、服务地址

  src/
    common/                   # 共享 schema、配置读取、HTTP 工具
    agent_api/                # Agent 入口、意图路由、工具调用
    vla_service/              # VLA 服务和 provider
    llm_service/              # LLM 服务和 provider

  scripts/
    run_agent_api.sh
    run_vla_service.sh
    run_llm_service.sh
    run_mock_stack_test.sh
    smoke_test.sh

  docs/
    architecture.md
    contracts.md
    development_plan.md

框架中的核心解耦点是 src/common/schemas.py。Agent、VLA、LLM 三部分统一使用这里定义的请求和响应结构,包括:

UserRequest
AgentResponse
ToolCall
VLAExecuteRequest
VLAExecuteResponse
LLMGenerateRequest
LLMGenerateResponse

通过这种方式,Agent 不需要关心 VLA 底层是 LeRobot、PyTorch、ONNX、CANN 还是 Orange Pi NPU;也不需要关心 LLM 底层是 OpenAI、Ollama 还是本地模型。只要接口协议不变,底层 provider 可以独立替换。

本周还完成了 mock 栈测试:

cd /home/czw1/ChenLong-Robot-Internship/agent_vla
bash scripts/run_mock_stack_test.sh

测试结果:

  • 输入“帮我把球捡起来”可以正确路由到 robot.pick_ball,并调用 VLA Service。
  • 输入 pick ball 可以正确路由到 robot.pick_ball
  • 输入“北京有什么旅游景点”可以正确路由到 llm.general_qa,并调用 LLM Service。

整体来看,第一版框架已经具备以下能力:

  • Agent、VLA、LLM 三方解耦。
  • 支持通过配置注册机器人技能。
  • 支持通过 provider 替换 VLA 或 LLM 后端。
  • 支持 dry-run,便于在不控制真实机械臂的情况下联调接口。
  • 为后续 Orange Pi AI Pro / Ascend NPU 部署预留了扩展位置。

二、模型核心工作

本周完成了 LeRobot / SmolVLA 相关环境调试、硬件链路验证、数据采集参数设计和训练部署方案设计。

当前硬件与环境约定如下:

系统环境:WSL2 Ubuntu 24.04
Python 环境:conda env lerobot
机器人框架:LeRobot
具身模型:SmolVLA
从臂:SO101 follower,/dev/ttyACM0
主臂:SO101 leader,/dev/ttyACM1
摄像头:USB Camera,/dev/video0

已完成的硬件链路验证包括:

  • SO101 follower 从臂可以正常连接。
  • SO101 leader 主臂可以正常连接。
  • 主从臂 teleoperation 可以跑通。
  • USB 摄像头可以被 OpenCV 识别。
  • SmolVLA 相关依赖和 GPU 训练环境可用。

摄像头调试过程中确认了一个关键参数:摄像头实际回报 FPS 为 30。如果在 LeRobot 配置中写成 fps=10,会出现校验错误:

OpenCVCamera(0) failed to set fps=10 (actual_fps=30.0)

因此后续摄像头配置统一固定为:

--robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 160, height: 120, fps: 30, fourcc: MJPG} }"

这里选择 160x120 是为了保证 WSL2 + USB 摄像头 + SmolVLA 推理链路足够稳定。摄像头硬件 FPS 使用 30,而数据集保存频率使用 --dataset.fps=10,两者不是同一个参数。

第一版 SmolVLA 任务定义为:

Pick up the ball and place it in the target area.

也就是桌面静态捡球并放到目标区域。当前设计的数据集名称为:

czw1/so101_ball_pick_v1

正式采集命令设计如下:

source /home/czw1/miniforge3/etc/profile.d/conda.sh
conda activate lerobot
cd /home/czw1/lerobot

lerobot-record \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.id=follower \
  --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 160, height: 120, fps: 30, fourcc: MJPG} }" \
  --teleop.type=so101_leader \
  --teleop.port=/dev/ttyACM1 \
  --teleop.id=leader \
  --dataset.repo_id=czw1/so101_ball_pick_v1 \
  --dataset.single_task="Pick up the ball and place it in the target area." \
  --dataset.fps=10 \
  --dataset.episode_time_s=15 \
  --dataset.reset_time_s=8 \
  --dataset.num_episodes=60 \
  --dataset.video=true \
  --dataset.push_to_hub=false \
  --display_data=false \
  --resume=false

后续如果需要追加数据,保持同一个 dataset.repo_id,并将:

--resume=true

打开即可。

为了保证后续可迭代,本周还确定了数据集版本规则:

czw1/so101_ball_pick_v1        静态桌面捡球并放到目标区
czw1/so101_ball_pick_v2        增加球位置、光照、背景、起始姿态变化
czw1/so101_ball_handover_v1    人手递球,机械臂夹住后放置
czw1/so101_ball_roll_v1        慢速滚动球任务
czw1/so101_light_switch_v1     关灯任务

训练方面,由于当前只有一个真实摄像头,而 SmolVLA base 默认期望多个摄像头输入,因此训练时需要做两个处理:

--rename_map="{ observation.images.front: observation.images.camera1 }"
--policy.empty_cameras=2

其中 rename_map 用于把数据集中的 front 摄像头映射到 SmolVLA 期望的 camera1empty_cameras=2 用于补齐另外两个空摄像头输入。

第一版训练命令设计如下:

source /home/czw1/miniforge3/etc/profile.d/conda.sh
conda activate lerobot
cd /home/czw1/lerobot

lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --policy.repo_id=czw1/so101_ball_pick_smolvla_v1 \
  --policy.push_to_hub=false \
  --dataset.repo_id=czw1/so101_ball_pick_v1 \
  --rename_map="{ observation.images.front: observation.images.camera1 }" \
  --policy.empty_cameras=2 \
  --batch_size=1 \
  --steps=2000 \
  --save_freq=500 \
  --output_dir=outputs/train/so101_ball_pick_smolvla_v1 \
  --job_name=so101_ball_pick_smolvla_v1 \
  --policy.device=cuda \
  --wandb.enable=false

如果效果不够,继续训练到 5000 steps:

lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --policy.repo_id=czw1/so101_ball_pick_smolvla_v1 \
  --policy.push_to_hub=false \
  --dataset.repo_id=czw1/so101_ball_pick_v1 \
  --rename_map="{ observation.images.front: observation.images.camera1 }" \
  --policy.empty_cameras=2 \
  --batch_size=1 \
  --steps=5000 \
  --save_freq=500 \
  --output_dir=outputs/train/so101_ball_pick_smolvla_v1 \
  --job_name=so101_ball_pick_smolvla_v1 \
  --policy.device=cuda \
  --wandb.enable=false \
  --resume=true

部署测试方案使用 lerobot-rollout。考虑到当前链路推理速度较慢,先使用低频安全测试:

lerobot-rollout \
  --robot.type=so101_follower \
  --robot.port=/dev/ttyACM0 \
  --robot.id=follower \
  --robot.cameras="{ front: {type: opencv, index_or_path: 0, width: 160, height: 120, fps: 30, fourcc: MJPG} }" \
  --policy.path=/home/czw1/lerobot/outputs/train/so101_ball_pick_smolvla_v1/checkpoints/002000/pretrained_model \
  --rename_map="{ observation.images.front: observation.images.camera1 }" \
  --task="Pick up the ball and place it in the target area." \
  --fps=1 \
  --duration=15 \
  --display_data=false \
  --return_to_initial_position=false

这一部分的核心成果是:确定了第一版 SmolVLA 模型的任务、采集参数、训练参数、继续训练方式和部署测试方式,并且将这些参数与 agent_vla 框架中的 VLA Service 对接方式统一起来。训练完成后,只需要把 checkpoint 路径写入 configs/app.yaml,即可通过 Agent 调用 VLA 模型。

此外,本周还调研了可复用的“捡物块 / pick-place”基础模型方案。选择先从捡球、捡物块这类任务入手,主要是因为 pick-place 是桌面机器人最基础、最通用的动作单元,很多后续任务都可以拆解为类似能力:

捡球 -> 抓取物体 -> 移动到目标区域 -> 放下
放到桌子上 -> 抓取物体 -> 移动到桌面指定位置 -> 放下
整理桌面 -> 多次执行 pick-place
人手递物 -> 接近物体 -> 闭合夹爪 -> 移动到目标区

当前调研结论是:第一版不直接追求大而全的多任务模型,而是先训练一个稳定的 so101_ball_pick_smolvla_v1,把它作为可复用的桌面抓取基础模型。后续如果捡球效果稳定,再把数据扩展为更通用的捡物块模型,例如:

czw1/so101_pick_object_v1

该数据集可以逐步加入:

  • 方块
  • 小积木
  • 轻量日用品
  • 不同颜色和不同材质的小物体

对应的任务描述可以统一为:

Pick up the object and place it in the target area.

这样可以把模型从“只会捡球”扩展为“能捡常见小物体”,提高后续复用价值。对于 Agent 框架来说,这类能力可以注册成一个通用 VLA 技能:

pick_object_v1:
  name: Pick up object
  task_prompt: "Pick up the object and place it in the target area."
  policy_path: /home/czw1/lerobot/outputs/train/so101_pick_object_smolvla_v1/checkpoints/...

后续 Agent 在理解用户指令时,可以把“捡球”“拿积木”“把这个东西放到目标区”等不同说法统一路由到同一个可复用的 pick_object_v1 技能,从而减少重复训练和重复开发成本。

三、下周主要工作

下周的主要目标是把当前框架从 mock 联调推进到真实模型闭环。

计划工作如下:

  1. 正式采集 czw1/so101_ball_pick_v1 数据集,目标至少 60 条高质量演示。
  2. 使用 SmolVLA base 训练 so101_ball_pick_smolvla_v1,先训练 2000 steps。
  3. 使用 lerobot-rollout 对捡球任务进行低频部署测试,统计基础成功率。
  4. 根据测试效果决定是否继续训练到 5000 steps 或补充采集数据。
  5. 将训练好的 checkpoint 路径写入 agent_vla/configs/app.yaml
  6. 将 VLA Service 从 mock provider 切换为 lerobot_rollout provider。
  7. 让 Agent 通过 /v1/chat 真实调用 VLA Service 执行捡球任务。
  8. 接入一个真实 LLM provider,例如 OpenAI、Ollama 或本地模型,用于替换当前 mock LLM。
  9. 优化 Agent 的意图识别方式,减少纯关键词匹配带来的误判。
  10. 在捡球任务稳定后,规划第二个技能,例如关灯或放到桌子上。

后续长期方向是将当前 WSL2 桌面端 Demo 逐步迁移到 Orange Pi AI Pro。初期可以让 Orange Pi 只运行 Agent,VLA 推理仍调用 WSL2 服务;等 SmolVLA 到 ONNX / Ascend NPU 的部署链路验证后,再新增 ascend_vla provider,使底层推理切换到 Orange Pi AI Pro / Ascend NPU,而 Agent 层接口保持不变。

week2工作

1.lerobot支持的 符合当前项目的具身模型

模型是否LeRobot支持参数规模输入输出最大特点训练方式
SmolVLA✅ 官方重点支持450M左右图像 + 文本 + robot stateaction chunk小模型、端侧友好、低成本微调Transformer + Action Expert,模仿学习
OpenVLA✅ 可接入7B图像 + 文本action token当前最经典开源VLA之一,泛化能力强大规模机器人数据预训练 + SFT
Pi0 (π0)✅ 社区支持3B左右图像 + 文本 + proprioception连续动作Physical Intelligence提出,能力强Flow Matching + VLM

openvla和pi0都需要云端训练且都需要更大的数据集来训练

2.本周尝试的开源数据集和开源模型

调研LeRobot生态中基于SmolVLA的开源模型与数据集,重点关注SO101平台上的双视角(top+wrist)视觉输入任务

名称类型机器人任务功能摄像头数量摄像头配置
lerobot/smolvla_base模型通用通用VLA基础模型多camera任意
lerobot/svla_so100_pickplace数据集SO100方块抓取放置2路top + side/up
lerobot/svla_so101_pickplace数据集SO101方块抓取放置2路top + wrist/side
faye7/so101-smolvla模型SO101Pick & Place2路没说明
AndrewNoviello/so101-smolvla模型SO101Pick & Place2路没说明
rtsmc/smolvla_box_in_bin_so101_test模型SO101方块放入盒子2路top + wrist

复现 LeRobot / SmolVLA 后机器人动作异常(抽搐、不成功)原因分析:

  1. 摄像头视角不匹配:训练使用的 camera 数量、位置、视角和实际部署环境不同。
  2. 数据泛化不足:开源模型训练环境和自己的任务、物体、场景差异太大。
  3. 环境差异大:桌面背景杂乱,目前的演示视频基本都是在纯色背景下进行 环境杂乱可能要进行更多的后训练

解决方案:

1.重新采集机器人数据

  • 使用leader-follower遥操作方式采集任务轨迹。
  • 记录top摄像头和手腕摄像头图像。
  • 同步记录关节角度、夹爪状态和执行动作。

2.构建自定义VLA数据集

  • 输入:
    • 多视角图像
    • 机器人状态
    • 文本任务描述
  • 输出:
    • action chunk(未来多个控制动作)

3.基于SmolVLA进行微调

  • 使用官方450M SmolVLA作为初始化模型。
  • 使用自己的SO101数据进行监督微调。
  • 让模型学习机器人自身运动学和任务环境。

3.双臂场景的调研分析

场景双臂分工社区参考情况
双臂共同搬盒子左右臂分别夹住盒子两侧,移动到目标区域属于最基础的同步双臂控制任务,适合作为自采数据起点
一臂固定盒子,另一臂放入东西左臂扶住容器,右臂抓取并放入社区已有双臂抓取积木并放入箱子的 SmolVLA 训练案例。
双臂分别抓取物品并整理两臂各抓一个物体,分别放入杯子或箱子社区已有双 SO101 抓取马克笔并放入容器的 SmolVLA 模型
双臂传递方块左臂拿起,右臂接住并放置已有公开的双 SO100 方块交接数据集及 SmolVLA、π0、GR00T 等模型。
一臂打开盒盖,另一臂放物体左臂拉住盒盖,右臂完成抓取放置可由“开门”和“物体放入容器”两个已有社区任务组合而成,属于较实际的多阶段任务。
双臂搭简单金字塔两臂交替拿积木,完成底层和上层摆放已有基于约100条 episode 训练的双 SO101 SmolVLA 金字塔模型,但公开说明较少。
双臂展开或折叠毛巾两臂抓住毛巾两角,拉平后折叠LeRobot 社区已有衣物折叠演示,ArmnetBench 也包含双 SO101 毛巾折叠任务。
双臂分类物体左臂处理左侧物体,右臂处理右侧物体,按颜色放入不同区域属于双臂抓取整理任务的自然扩展,适合使用不同文本指令训练多任务 SmolVLA

初步定为左右手传递物品,双手传递相比单臂抓取放置:

扩大工作空间:一个机械臂抓不到或放不到的位置,可以通过另一只机械臂接力完成。

支持任务分工:左右机械臂可以分别负责取料和放置,形成连续的操作流水线。

减少单臂大范围运动:单臂不需要跨越整个桌面,能够缩短轨迹并降低碰撞风险。

第三周

week3

1.标准化部分调研以及模型数据集通用方法调研

本周补充调研了标准化方案。要求标准化的核心目标是:如果别人购买同样的 SO101 主从臂、同样的双摄像头和类似的桌面任务环境,可以尽量复用本项目的数据采集、训练和部署流程,而不是每个人都从零开始调设备、写命令、排查路径。

当前标准化计划分为硬件标准化、软件环境标准化、数据采集标准化、数据集格式标准化和模型训练标准化五部分。

1.1 硬件标准化

硬件标准化的目标是固定机器人和传感器组合,减少由于设备差异导致的模型不可复用问题。

标准化项目当前约定作用
机械臂SO101 leader + SO101 follower保证动作空间、关节数量和控制方式一致
摄像头数量2 路保证视觉输入结构一致
摄像头视角overhead + wrist保证训练和部署时的视觉分布一致
任务物体tennis ball固定第一阶段任务对象
任务目标target area固定放置区域定义

后续如果其他同学购买同样硬件,只需要按照同样的机械臂型号、摄像头数量、摄像头位置和任务场景搭建,即可复用本项目的数据采集脚本和训练配置。

1.2 软件环境标准化

软件标准化主要解决“同一套命令在不同电脑上跑不起来”的问题。当前项目环境约定如下:

Ubuntu 22.04
Python 环境:conda env lerobot
机器人框架:LeRobot 0.5.2
采集命令:lerobot-record
训练命令:lerobot-train
数据格式:LeRobotDataset

需要标准化保存的内容包括:

  • conda 环境名称和依赖版本。
  • LeRobot 版本。
  • 数据采集命令模板。
  • 训练命令模板。

1.3 数据采集标准化

数据采集标准化的目标是让不同人采集的数据具有相同结构,后续可以合并训练。

当前任务文本统一为:

Pick up the tennis ball and place it in the target area.

当前 camera key 统一为:

overhead
wrist

这两个名称后续需要固定,不能一批数据叫 top,另一批叫 front,否则训练时模型输入字段不一致,会影响数据集合并和模型加载。

建议后续采集标准如下:

项目建议标准
episode 时长30s
reset 时长10s
数据集 FPS优先 15fps,稳定后再尝试 30fps
任务文本固定英文任务描述
数据目录使用时间戳,避免覆盖
失败样本单独记录并剔除
摄像头 key固定为 overheadwrist

标准化采集的意义是:后续如果其他人用同样硬件采集同一任务,可以把数据直接合并到同一个 LeRobotDataset 训练流程中,而不需要重新写数据转换代码。

1.4 数据集格式通用性调研

LeRobot 的核心优势是数据集格式相对统一。通过 lerobot-record 采集的数据会保存为 LeRobotDataset,其中包括:

  • 多路图像 observation。
  • 机器人 state。
  • 机器人 action。
  • episode 信息。
  • 任务文本 task
  • 数据集 meta 信息。

只要模型支持 LeRobotDataset,就可以在同一套数据上切换不同 policy 做实验。也就是说,本项目采集的数据不只服务于 SmolVLA,也可以用于对比其他 imitation learning 或 VLA 模型。

1.5 标准化交付计划

为了让其他人购买同样硬件后可以复用,本项目后续计划整理一套标准化交付材料:

1. 硬件清单
2. 摄像头安装位置示意
3. LeRobot 环境安装说明
4. USB attach 脚本
5. 主从臂校准步骤
6. 双摄像头采集命令模板
7. LeRobotDataset 检查脚本
8. SmolVLA训练命令模板
9. rollout 测试步骤
10. 常见错误排查表

标准化的最终目标是形成一套可以复制的 SO101 双摄像头 VLA 数据采集和训练流程。

2.训练模型部分

模型训练部分当前主要围绕自采 LeRobotDataset 展开。数据采集完成后,同一套数据集可以优先用于以下三类实验:

  1. **SmolVLA **

    • 作为主线模型。
    • 使用双摄像头图像、机器人状态和文本任务描述。
    • 目标是训练可执行 “Pick up the tennis ball and place it in the target area.” 的 VLA 策略。
  2. **Pi0 **

    • 作为更大模型方向储备。

    • 需要更多算力和更稳定的数据集。

    • 当前不作为第一优先级。

因此当前采集数据时,需要尽量保证数据字段通用:

camera keys: overhead, wrist
task: Pick up the tennis ball and place it in the target area.
robot type: so101_follower
teleop type: so101_leader
fps: 15 或 30,但同一批数据内保持一致

这样后续可以在不重新采集数据的情况下,直接切换 --policy.type=smolvla--policy.type=act--policy.type=diffusion 进行训练对比。

本周训练的采集数据遇到的硬件问题:

问题 1:摄像头 FPS 设置失败

采集过程中出现过摄像头帧率设置失败:

OpenCVCamera(...) failed to set fps=15 (actual_fps=30.0)

原因是部分 USB 摄像头实际只支持固定的 30fps 模式。即使在 LeRobot 配置中请求 15fps,驱动仍返回 30fps。LeRobot 会严格检查请求帧率和实际帧率是否一致,因此直接报错退出。

处理方式:

  • 对实际只能 30fps 的摄像头,在摄像头配置中写 fps=30
  • 如果希望数据集帧率更低,可以通过 --dataset.fps=15 控制保存频率。
  • 不强行把所有摄像头都设置为 15fps。

结论:摄像头采集帧率和数据集保存帧率可以分开考虑。摄像头按硬件支持的模式运行,数据集按训练需要保存。

问题 2:MJPG 坏帧

采集过程中频繁出现:

Corrupt JPEG data: premature end of data segment

这是 OpenCV 解码 MJPG 图像流时打印的警告,说明摄像头传来的 JPEG 压缩帧不完整。该问题在 WSL2 + USB 摄像头环境中比较常见,尤其是在双摄像头同时采集时更明显。

原因分析:

  • MJPG 本质是连续 JPEG 压缩帧。
  • USB 转发过程中如果数据包不完整,OpenCV 会收到不完整 JPEG。
  • 双摄像头同时采集会增加 USB 带宽压力。
  • WSL2 的 USB 转发稳定性弱于原生 Linux。

处理方式:

  • 对不稳定的俯视摄像头,尽量避免使用 MJPG,改用 YUYV。
  • 对手腕摄像头保留 MJPG,但降低分辨率到 320x240。
  • 降低数据集保存帧率到 15fps。
  • 尽量不要让两个摄像头插在同一个 USB Hub 上。

结论:少量 Corrupt JPEG data 可以忍受,但如果伴随读帧超时,就必须降低负载或更换摄像头格式。

问题 3:读帧超时

双摄像头采集过程中还出现过更严重的错误:

TimeoutError: OpenCVCamera(...) latest frame is too old

该错误会导致 LeRobot 停止录制。它说明某一路摄像头长时间没有提供新帧,超过了 LeRobot 的最大等待时间。

从日志看,主要不稳定的是俯视摄像头:

usb-Sonix_Technology_Co.__Ltd._USB2.0_CAM1...

原因分析:

  • 俯视摄像头在 MJPG 模式下容易出现坏帧。
  • 双摄像头同时 30fps 会使 WSL2 USB 转发压力较大。
  • 实时视频编码会进一步增加 CPU 压力。
  • 当采集主循环低于目标 FPS 时,图像缓存中的最新帧可能变旧,最终触发 timeout。

处理方式:

俯视摄像头:YUYV,640x480,15fps
手腕摄像头:MJPG,320x240,30fps
数据集保存:15fps
实时编码:关闭

结论:由于任务要求必须使用两路摄像头,当前不能简单改成单摄像头采集。较可行的方案是降低双摄像头整体负载,并让俯视摄像头避开不稳定的 MJPG 模式。

问题 4:采集循环低于目标 FPS

日志中多次出现:

Record loop is running slower than the target FPS

这说明 LeRobot 的主循环速度低于设定的数据集 FPS,可能导致丢帧或机器人控制不稳定。

原因分析:

  • 双摄像头读取耗时较高。
  • 图像写盘线程占用 CPU。
  • 视频编码占用 CPU。
  • WSL2 文件系统和 USB 转发都有额外开销。

处理方式:

  • --dataset.fps 从 30 降到 15。
  • 关闭 --dataset.streaming_encoding
  • 减少 --dataset.num_image_writer_threads_per_camera
  • 降低手腕摄像头分辨率。
  • 采集时关闭不必要的后台程序。

结论:当前WSL2 环境下,双摄像头 30fps 采集不够稳定,硬件适配问题严重

目前已更换ubuntu原生电脑来重新采集数据

第四周

week4 工作周报

1. SO101 网球放置数据集采集与整理

本周主要完成了 SO101 主从臂数据采集环境的重新整理,并基于真实机械臂采集了网球抓取放置任务数据。任务目标是让 follower arm 根据 leader arm 的遥操作轨迹,完成“捡起网球并放到目标区域”的操作。

本周采集任务英文指令统一为:

Pick up the tennis ball and place it in the target area.

当前数据集已整理为 LeRobot v3.0 格式,并上传到 Hugging Face,并做了详细的当前的内容的可复现工作整理 目标是该仓库是可被别人用相同的硬件直接复现的

https://huggingface.co/datasets/vvzc/ChenLong_Embodied_Intelligence_Dataset

1.1 当前数据集规模

项目当前数值
数据格式LeRobot v3.0
机器人类型so_follower
总 episodes48
总帧数21187
任务数量1
采集帧率30 FPS
图像分辨率640 x 480
摄像头数量2
动作维度6
状态维度6
数据划分train: 0:48

数据集包含两个视觉输入:

observation.images.overhead
observation.images.wrist

其中 overhead 是俯视摄像头,用于观察桌面整体布局、网球位置和目标区域;wrist 是手腕摄像头,用于观察夹爪附近的抓取细节。

1.2 数据字段

当前数据集主要字段如下:

字段类型形状含义
actionfloat32[6]主臂遥操作产生的动作目标
observation.statefloat32[6]从臂当前关节状态
observation.images.overheadvideo[480, 640, 3]俯视摄像头视频
observation.images.wristvideo[480, 640, 3]手腕摄像头视频
timestampfloat32[1]当前帧时间戳
frame_indexint64[1]episode 内帧编号
episode_indexint64[1]episode 编号
indexint64[1]全局帧编号
task_indexint64[1]任务编号

actionobservation.state 的 6 个关节顺序为:

shoulder_pan.pos
shoulder_lift.pos
elbow_flex.pos
wrist_flex.pos
wrist_roll.pos
gripper.pos

1.3 采集硬件与端口

本周使用一台原生 Ubuntu 电脑重新配置采集环境,避免之前 WSL2 下 USB 摄像头转发不稳定的问题。

当前硬件配置:

设备作用当前端口
SO101 follower arm从臂,实际执行动作/dev/ttyACM0
SO101 leader arm主臂,人工遥操作输入/dev/ttyACM1
overhead camera俯视摄像头/dev/video4
wrist camera手腕摄像头/dev/video2

主从臂电机环境检查结果:

motor ids: 1, 2, 3, 4, 5, 6
baud rate: 1000000
model: 777

说明换臂后电机 ID、波特率和 SO101 默认配置一致,不需要重新写电机 ID,只需要重新完成机械臂校准。

1.4 采集参数与复现命令

本周最终固定的数据采集参数为:

参数数值
每次采集条数10 episodes
单条采集时间15 秒
每条 reset 时间10 秒
采集 FPS30
视频分辨率640 x 480
视频编码AV1
是否追加数据集--resume=true

每次追加采集 10 条数据时使用的脚本为:

~/so101_record_tennis_append10.sh

脚本内部核心命令如下:

lerobot-record \
  --robot.type=so101_follower \
  --robot.port="/dev/ttyACM0" \
  --robot.id="so101_follower_sakura" \
  --robot.cameras="{overhead: {type: opencv, index_or_path: /dev/video4, width: 640, height: 480, fps: 30}, wrist: {type: opencv, index_or_path: /dev/video2, width: 640, height: 480, fps: 30}}" \
  --teleop.type=so101_leader \
  --teleop.port="/dev/ttyACM1" \
  --teleop.id="so101_leader_sakura" \
  --display_data=true \
  --dataset.root="/home/sakura/lerobot_data" \
  --dataset.repo_id="local/so101_tennis" \
  --dataset.single_task="Pick up the tennis ball and place it in the target area." \
  --dataset.fps=30 \
  --dataset.episode_time_s=15 \
  --dataset.reset_time_s=10 \
  --dataset.num_episodes=10 \
  --dataset.video=true \
  --dataset.push_to_hub=false \
  --dataset.streaming_encoding=true \
  --dataset.encoder_threads=2 \
  --resume=true

其中 --resume=true 是关键参数,用于在已有数据集后继续追加采集,避免覆盖已有 episode。

2. 数据集发布与说明文档完善

本周还整理并上传了数据集说明文档。README 中补充了硬件配置、端口映射、采集参数、字段结构、读取方式和复现命令,使其他人拿到相同 SO101 主从臂和双摄像头后,可以按照文档重新搭建采集流程。

README 中重点说明了:

  • follower arm 和 leader arm 的作用区分。
  • 双摄像头字段命名必须固定为 overheadwrist
  • episode 采集时间为 15 秒,reset 时间为 10 秒。
  • 数据集字段需要保持 observation.images.overheadobservation.images.wristobservation.stateaction 一致。
  • 追加采集时必须使用 --resume=true

这一步的意义是把能在本机跑通”的流程转化为别人可以复现的数据集交付材料。

3. SmolVLA 模型训练

在数据集采集完成后,本周使用当前 SO101 网球放置数据集对 SmolVLA 进行了微调训练。训练在 WSL2 的 Ubuntu-24.04 中完成,使用 lerobot conda 环境。

训练完成后的模型位置为:

/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/002000/pretrained_model

训练日志位置为:

/home/czw1/lerobot/training_logs/smolvla_chenlong_2000steps_run1.log

3.1 训练结果

项目结果
policy 类型smolvla
训练步数2000/2000 steps
最终 loss0.116
输入视觉特征observation.images.overhead, observation.images.wrist
输入状态特征observation.state
输出特征action
最终模型文件model.safetensors
模型文件大小约 907 MB
训练总输出目录大小约 5.0 GB
训练进程状态已结束,无残留训练进程

这次训练说明当前自采 LeRobotDataset 已经能够被 SmolVLA 正常识别和加载,双摄像头图像、机器人状态和动作输出字段也已经和模型输入输出对齐。

3.2 本次训练的意义

本次训练完成后,项目从“采集数据”推进到了“用自采数据微调 VLA 模型”的阶段。相比直接使用社区公开 SO101 模型,本次训练使用的是当前实验环境中的真实摄像头视角、真实桌面背景、真实网球和目标区域,因此模型更贴近实际部署环境。

本次训练验证了以下内容:

  • 自采数据集的 schema 可以被 LeRobot 训练流程读取。
  • 双摄像头输入可以进入 SmolVLA 模型。
  • observation.stateaction 字段维度正确。
  • 训练可以完整跑到 2000 steps。
  • 输出 checkpoint 可以保存为可复用的 pretrained_model 目录。

下周计划重点从训练完成转向模型验证和数据质量提升:

  1. 使用训练得到的 SmolVLA checkpoint 做真实机械臂 rollout 测试。
  2. 观察模型是否能够根据 Pick up the tennis ball and place it in the target area. 完成闭环动作。
  3. 根据失败案例补采数据,例如抓取偏差、放置偏差、夹爪闭合不稳定等情况。
  4. 尝试扩大数据集规模,从 48 条增加到 100 条以上。
  5. 对比不同训练步数下的 checkpoint 表现,例如 2000 steps、5000 steps 和更长训练。
  6. 继续完善标准化文档,让其他同学可以按同样流程复现 SO101 数据采集、训练和部署。

week5 工作周报

1. Hugging Face 数据与模型仓库整理

本周首先完成了辰龙机器人实习数据与模型仓库的集中整理工作,将后续要使用的数据集、模型权重、训练结果和说明文档统一放入 Hugging Face 仓库中管理:

https://huggingface.co/datasets/vvzc/ChenLong_Embodied_Intelligence_Dataset

本次整理的主要工作量包括:

  • 将具身智能采集数据整理到 embodied_dataset/ 目录,保留 LeRobot v3.0 的 data/meta/videos/ 结构。
  • 将 YOLO 目标检测模型和训练评估结果整理到 yolo_dataset/ 目录,当前包含蓝色桶检测模型 blue_bucket_yolov8/
  • 为仓库配置 Git LFS,确保 .parquet.mp4.pt.png 等大文件能够正常上传和同步。
  • 完善主 README,说明仓库用途、当前目录结构,以及后续新增数据集和模型时需要保留的关键信息。
  • 完善子目录 README,补充数据字段、采集格式、模型文件、训练参数和复现说明,方便其他同学按照同一标准继续采集和维护。

通过这部分工作,仓库从单纯的数据存放位置整理成了可长期维护的数据与模型交付仓库。后续新增任务、采集批次或模型版本时,可以继续按当前结构补充。

2. 继续采集 50 条具身数据并放入仓库

本周继续围绕 SO101 主从机械臂的网球抓取放置任务进行数据采集,在已有数据基础上追加采集了 50 条 episode,并整理后放入 Hugging Face 仓库。

任务文本保持不变:

Pick up the tennis ball and place it in the target area.

采集标准继续沿用当前 LeRobot 数据格式:

  • 机器人:SO101 follower arm
  • 遥操作设备:SO101 leader arm
  • 相机视角:overhead camera 和 wrist camera
  • 数据格式:LeRobot v3.0
  • 图像数据:MP4 视频
  • 状态与动作数据:Parquet 文件
  • 主要字段:observation.images.overheadobservation.images.wristobservation.stateaction

追加采集时重点保证:

  • 新采集 episode 不覆盖已有数据。
  • episode 编号、frame 编号和全局 index 保持连续。
  • 视频与动作数据能够对应。
  • 采集完成后更新仓库说明,确保别人能理解当前数据规模和目录组织方式。

这 50 条数据的补充使当前数据集规模进一步扩大,也为后续 SmolVLA 或其他 VLA 模型训练提供了更多真实操作样本。

3. SmolVLA 模型微调、结果验证与本地推理准备

本周在 WSL2 Ubuntu-24.04 的 LeRobot 环境中,基于已经整理好的 SO101 网球抓取放置数据集,对 SmolVLA 模型进行了本地微调,并完成了模型文件、离线推理和实机推理环境的初步验证。

3.1 训练环境

训练使用本机 WSL2 中的 Ubuntu-24.04 发行版,主要环境如下:

  • Conda 环境:lerobot
  • Python 版本:3.12.13
  • LeRobot 版本:0.5.2
  • PyTorch 版本:2.11.0+cu128
  • GPU:NVIDIA GeForce RTX 5060 Laptop GPU
  • CUDA:可用

训练前首先确认了 LeRobot、PyTorch、CUDA、GPU 和数据集路径都能正常访问,避免由于环境或路径问题导致训练中断。

3.2 训练数据

训练数据使用本地 LeRobot v3.0 格式数据集:

/home/czw1/chenlong-val-data

数据集对应 Hugging Face 仓库:

vvzc/ChenLong_Embodied_Intelligence_Dataset

数据集基本信息如下:

  • 任务文本:Pick up the tennis ball and place it in the target area.
  • episode 数量:50
  • 总帧数:21187
  • 采集帧率:30 FPS
  • 图像视角:observation.images.overheadobservation.images.wrist
  • 状态维度:6
  • 动作维度:6
  • 机器人类型:so_follower

训练前用 LeRobotDataset 成功加载该数据集,确认数据集长度、FPS、图像字段、状态字段和动作字段都能被当前 LeRobot 版本识别。

3.3 训练方式与关键参数

本次训练采用 lerobot/smolvla_base 作为预训练基座模型进行微调。由于 smolvla_base 默认期望的相机字段是 camera1/camera2/camera3,而当前数据集使用的是 overhead/wrist 两路相机,因此训练时显式设置:

--policy.input_features=null
--policy.output_features=null

让 LeRobot 从数据集自动推断输入输出特征,避免相机字段不一致导致训练失败。

最终训练命令的核心参数如下:

lerobot-train \
  --policy.path=lerobot/smolvla_base \
  --policy.input_features=null \
  --policy.output_features=null \
  --dataset.repo_id=vvzc/ChenLong_Embodied_Intelligence_Dataset \
  --dataset.root=/home/czw1/chenlong-val-data \
  --batch_size=8 \
  --steps=2000 \
  --save_freq=500 \
  --log_freq=50 \
  --num_workers=0 \
  --output_dir=/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1 \
  --job_name=smolvla_chenlong_2000steps \
  --policy.device=cuda \
  --policy.use_amp=true \
  --policy.push_to_hub=false \
  --wandb.enable=false

训练前先分别进行了 batch_size=1batch_size=8 的 2-step smoke test,确认模型权重加载、视频解码、CUDA 训练、loss 计算和 checkpoint 写入都能正常工作。batch_size=8 时显存占用约 2.95 GB,因此正式训练采用 batch size 8。

3.4 训练结果

正式训练共进行 2000 steps,训练过程正常结束,最终日志显示:

step:2K smpl:16K ep:36 epch:0.76 loss:0.116 grdn:1.993 lr:2.5e-06 mem_gb:2.96
End of training

训练过程中 loss 从早期的约 0.47 逐步下降到 0.11 左右,说明模型已经在当前数据集上完成了有效拟合。训练期间保存了 4 个 checkpoint:

/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/000500
/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/001000
/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/001500
/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/002000

最终模型路径为:

/home/czw1/lerobot/outputs/train/smolvla_chenlong_2000steps_run1/checkpoints/002000/pretrained_model

最终模型目录包含:

  • config.json
  • model.safetensors
  • train_config.json
  • policy_preprocessor.json
  • policy_postprocessor.json
  • normalizer / unnormalizer processor 权重文件

其中 model.safetensors 约 865 MB,整个训练输出目录约 5.0 GB。最终模型配置中确认输入特征已经正确适配为:

observation.images.overhead
observation.images.wrist
observation.state

输出特征为:

action

3.5 推理验证与实机准备

训练完成后,先进行了不控制机械臂的离线推理 smoke test。测试从本地数据集中读取一帧样本,加载最终 checkpoint,并在 CUDA 上调用 SmolVLA 输出动作。测试结果表明模型可以正常完成前向推理,输出形状为:

action_shape=(1, 6)

随后对实机推理环境进行了准备和检查:

  • 将之前 Ubuntu 中同一台 SO101 follower 从臂的校准文件复制到本机 LeRobot 默认校准目录。
  • 通过 usbipd 将 follower 串口、overhead 相机和 wrist 相机挂载到 WSL2。
  • 在 WSL 中确认 /dev/serial/by-id//dev/v4l/by-id/ 稳定路径可用。
  • 使用 OpenCV 分别读取 overhead 和 wrist 相机画面,均能获取 640 x 480 图像。
  • 串口可以正常打开,当前用户也具备 dialoutvideo 组权限。

为后续复现实机推理,整理了以下辅助脚本:

tools/smolvla_offline_infer_smoke.py
tools/run_chenlong_smolvla_rollout.py
tools/attach_smolvla_inference_devices.ps1

其中 run_chenlong_smolvla_rollout.py 默认使用本次训练出的本地 SmolVLA checkpoint,并使用 overhead/wrist 两路相机字段,与训练数据保持一致。

3.6 当前问题与后续计划总结

​ 当前模型已经完成 2000-step 本地微调和离线推理验证,模型大小为865 MB,但是当前模型的表现效果不够优秀,可能的原因是数据采集数量不够准备加大数据量重新再往后训练v2版本的

宋红

AgentOS 编排层 / 端侧语言规划 / SimCar 反馈闭环

基本信息

内容
姓名宋红
方向意图理解、任务规划、指令下发、反馈闭环、失败处理、语音入口
项目嘲风桌面机器人 AgentOS
主代码agent-llm-vla/src/agent_api/
SimCar 探索/root/chaofeng/.claude/worktrees/simcar-agent-loop/agent-llm-vla
周期2026-07-07 ~

文档入口

  • AgentOS 编排层:启动期架构设计和职责说明;
  • 当前实现状态:当前代码、测试、能力边界和下一步;
  • 周报:按周汇总工作、证据和计划;
  • 工作日志:从项目日志中筛选的关键实施与决策记录;
  • 总览:项目设计、工程约束和协作边界;
  • SimCar:Gateway、契约、演示、端侧 Planner 和交接资料;
  • 资料索引:复制来源和选取理由。

最新进展

截至 2026-07-24:

  1. AgentOS / SimCar 已从单句指令推进到有界多轮会话:可记录场景障碍物、安全补全“绕过去”等指代,并在纯观察话轮中零动作落盘;
  2. 新增 L1 确定性快速路径、36 条规划基准与 raw/final 双口径门禁;当前 demo_gate_pass=truemodel_gate_pass=false
  3. 落地 SIMCAR_REHEARSAL=1 离线预演,以及 WSLg 实时麦克风 / 虚拟麦克风回放闭环;权威回归 355 passed / 10 skipped
  4. 按老板要求启动 Ascend 310B / Orange Pi AIpro 20T 的 SenseVoice 端侧部署:板端已连通,ONNX 已导出,OM 转换阻塞在工具链算子包,持续推进中。

能力边界

当前已验证的是自然语言路由、端侧结构化计划、已知几何控制、有界会话上下文、离线预演和本机实时语音闭环。当前尚未完成真实视觉障碍物识别、未知环境自主导航、任意抽象轨迹、GPT 级开放指令理解,以及 310B 上可交付 OM / 板端 SenseVoice 推理。

涉及运动的系统坚持:大模型做高层语义和任务拆解;距离、角度、路径、安全边界和急停由确定性模块负责。

当前周报

原始资料位置

  • 工作日志:D:\THU\BeiJing\嘲风\工作日志\
  • 总览:D:\THU\BeiJing\嘲风\总览\
  • 本目录中的副本用于个人工作归档,原始资料仍是跨团队权威来源。

AgentOS 编排层

宋红 · AgentOS 编排层技术文档 代码位置:agent-llm-vla/src/agent_api/ 配套约束:D:\THU\BeiJing\嘲风\AgentOS任务约束手册.md

一、职责定位

AgentOS 编排层是“嘲风“桌面机器人的决策中枢,负责:

能力现状待补
意图识别关键词硬匹配(28行)语义/LLM 分类,支持说法多样化
指令下发已有 VLAClient.execute_skill()复用,不重写
环境交互反馈解析执行状态 + 视觉判定任务成败
失败检测与重试编排状态机:DISPATCH→EXECUTE→JUDGE→RETRY/REPORT
多轮会话无(session_id 仅透传)维护 session 上下文

核心文件:

  • router.py — 意图识别与工具路由(主战场)
  • main.py — Agent 服务入口与编排流程
  • tool_clients.py — 调用 VLA/LLM 服务的客户端

二、系统架构

                    ┌─────────────┐
                    │  用户语音/文本 │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │   ASR 模块   │  SenseVoice-Small (254MB, CER~8%)
                    │  (音频→文本)  │
                    └──────┬──────┘
                           │
                    ┌──────▼──────┐
                    │  Agent API   │  ← 我的主战场 (8010端口)
                    │  编排状态机   │
                    └──┬──────┬───┘
                       │      │
            ┌──────────▼┐    ┌▼──────────┐
            │ VLA Service│    │ LLM Service│
            │  (8011端口) │    │  (8012端口) │
            └──────┬─────┘    └───────────┘
                   │
        ┌──────────┼──────────┐
        │          │          │
   ┌────▼────┐ ┌──▼───┐ ┌───▼────┐
   │机械臂(VLA)│ │底盘(Nav)│ │视觉判定 │
   │  同学A   │ │ 同学B  │ │(YOLO等)│
   └─────────┘ └──────┘ └────────┘

三服务解耦架构(已跑通):

  • Agent API: 8010 — 编排中枢
  • VLA Service: 8011 — 视觉语言动作(机械臂技能)
  • LLM Service: 8012 — 大语言模型(通用问答)

三、编排状态机(方案02,已审核通过)

DISPATCH(意图识别)
    │
    ├─ 安全检查:置信度 < 0.75 → REPORT_FAIL
    │
    ▼
EXECUTE(调用执行)
    │
    ├─ dry-run 预演 → 碰撞/边界检查
    │
    ▼
JUDGE(视觉判定)
    │
    ├─ 成功 → DONE
    │
    └─ 失败 → RETRY(≤ max_retries 次)
                  │
                  └─ 超限 → REPORT_FAIL → TTS 报告

关键设计决策:

  1. router 只做纯决策(intent, ToolCall) 输出签名不变,下游零改动
  2. orchestrator 管执行编排:抽成独立 orchestrator.py,main.py 保持薄
  3. MockJudge 走 metadata 注入:smoke_test 可覆盖“一次过“与“失败重试“两条路径
  4. Judge 契约{success, detail, evidence},mock 阶段 evidence 恒 {}

四、两个下游黑盒

下游负责人我下发什么我不关心什么
机械臂(VLA)同学Askill_id(如 ball_pick_v1手臂怎么动
底盘移动同学B高层路径/路线命令轮子怎么驱动

路线规划是自有模块(route_planner):高层路线决策归我,轮子低层电机驱动归同学B。复合任务中 orchestrator 交替调度 VLA 和底盘。

五、技术选型

组件选型理由
ASRSenseVoice-Small (254MB)中文 CER~8%,20x 实时,纯 CPU
意图识别(规则层)文本归一化 + 扩充同义词mock 阶段即见效
意图识别(LLM兜底)Qwen2.5-1.5B/3B默认关闭,预留插槽
视觉判定(简单)YOLO-small本地 CPU 实时,灯灭/球进桶
视觉判定(语义)云端 VLM叠衣服整齐度等,低频
边缘部署昇腾310B (4GB) → K3 (8GB)310B 先演示,K3 后落地
推理后端llama.cpp + CANN/Q4_K_M社区成熟,310B 适配

六、开发阶段规划

第一月(mock):  S1 ✅ → S2 → S3 → S4 → S5 → S6
第二月(仿真):  S7 真实VLA仿真 → S8 本地LLM决策脑 → S9 关灯闭环
进阶:          S10 边缘部署 → S11 决策引擎Phase3 → S12 MCP/SSE/多轮
路线规划(SR):  SR1 接口占位 → SR2 骨架 → SR3 复合任务状态机

当前进度:S1 已完成,方案02(S2-S4)已 PASS,待进入 EXECUTE。

七、约束与红线

  • 不破坏三服务解耦架构
  • 不破坏 schemas.py 契约(只允许向后兼容新增)
  • 不改 VLA/LLM 同事的 provider 内部代码
  • 不在 agent 层 import lerobot / 绑定具体大模型 SDK
  • 真机动作前必须 dry-run;危险动作需安全确认
  • commit/PR 只署名本人,不添加任何 AI 共同署名

详见 D:\THU\BeiJing\嘲风\AgentOS任务约束手册.md

当前实现状态(2026-07-18)

宋红 · AgentOS 编排层 / SimCar 端侧探索 资料入口:D:\THU\BeiJing\嘲风\工作日志\26-当前项目与总览资料联合进度盘点-2026-07-17.md

一、当前基线

项目状态
AgentOS 集成分支integration/agentos-20260717 已验证
SimCar 探索分支feat/simcar-agent-loop
SimCar worktree/root/chaofeng/.claude/worktrees/simcar-agent-loop/agent-llm-vla
最新提交55d45ac
全量测试277 collected / 267 passed / 10 skipped / 0 failed
模拟器修改
vla_service/** 修改
push未执行

二、已经具备的端侧能力

2.1 语言与编排

  • 中文文本输入;
  • SenseVoice 音频文件转写入口;
  • 关键词、动作-对象信号和否定拦截;
  • Ollama/Qwen 高层 Planner 接口;
  • TaskPlan/TaskStep 结构化计划;
  • Orchestrator 的执行、Judge、重试和终态契约;
  • 结构化 attempt 日志。

2.2 SimCar 控制

  • 前进、后退、左右转、停车;
  • 单段平移不超过 5 cm;
  • 单次运动距离和转角上限;
  • 每段动作后读取位姿;
  • 碰撞、断连和超时 fail closed;
  • hasBall=true + armState=holding 的真值捡球判定。

2.3 复合任务 MVP

端侧 Planner 允许以下技能:

move
turn
stop
navigate_around
pick_ball

在障碍物坐标、尺寸和安全间距已经配置的前提下,可以执行:

绕过已知障碍物,把球捡起来

当前绕障来源是 known_scene_geometry,不是相机视觉。未知障碍物或“这个”无法唯一 grounding 时,不会发出移动命令。

三、语音和端侧推理现状

3.1 已确认

  • WSLg 已暴露 unix:/mnt/wslg/PulseServer
  • WSLg 目录中存在 PulseAudioRDPSource,具备向 WSL 提供音频源的基础条件;
  • SenseVoice provider 已经能够处理 WAV 文件;
  • /root/.ollama 中已有 qwen2.5:1.5b 模型文件;
  • Runner 已支持文本和 @audio /absolute/path.wav

3.2 尚未完成

  • Ubuntu 用户态尚未安装 pactlparec/arecord 等采集工具;
  • 当前入口是“录音文件→识别”,不是实时麦克风流;
  • 还没有 VAD、分片上传、实时 partial transcript、打断和急停通道;
  • Ollama daemon 需要显式启动并完成一次 Planner 实测;
  • 尚未决定是 WSLg 直接采集还是 Windows/浏览器采集后推送到 WSL。

推荐顺序:先用 WSLg PulseAudio source 验证 16 kHz 单声道录音,再加 200~500 ms 音频分片和 VAD,最后将 partial transcript 接入 Planner;急停单独走本地确定性通道,不等待 LLM。

四、抽象轨迹能力边界

当前 Planner 还不是 GPT-5.6 级的任意抽象轨迹执行器。对于:

走个正方形

系统不应该让 1.5B 模型随意猜边长。正确实现方式是新增高层技能,例如:

{
  "skill": "trace_shape",
  "arguments": {
    "shape": "square",
    "side_cm": 20,
    "direction": "left"
  }
}

其中 side_cm 可以来自用户明确表达,也可以来自配置的安全默认值;若没有默认值则进入澄清。trace_shape 内部再编译成四段平移和四段 90° 转向,并在每段后读状态。

后续应按以下等级扩展:

  1. L1:平移、旋转、速度、持续时间、急停;
  2. L2:正方形、长方形、圆形、等边三角形;
  3. L3:S 型、8 字、已知障碍物绕行、窄通道、返回起点;
  4. L4:全局路径、局部避障、找球、抓球和多步任务调度。

五、真实能力边界

已经在线验证的是:准备好的无障碍 SimCar 场景中,真值状态驱动的自动捡球闭环。

尚未证明的是:

  • 通过摄像头识别任意可乐瓶或障碍物;
  • 对“前面那个”进行视觉 grounding;
  • 未知环境下自主建图和导航;
  • GPT-5.6 级任意抽象指令的一次性可靠执行。

六、下一步验收门槛

  • 安装并验证 WSLg 音频采集工具;
  • 启动 Ollama,记录 Qwen 1.5B 对基础动作、规则图形和复合任务的计划成功率;
  • 新增 trace_shape 及其 Schema、动作编译器和安全测试;
  • 将实时语音入口拆成“识别流”和“动作流”,支持急停优先;
  • 在 SimCar 中建立带障碍物坐标的确定性场景,完成一次真实绕障 live 验收;
  • 1.5B 若在结构化计划、指代和抽象轨迹上不稳定,再比较 3B/7B 端侧模型,不先把低层安全交给模型。

资料索引(2026-07-18)

本目录保留宋红负责的 AgentOS、端侧 Planner、语音入口和 SimCar 闭环资料。复制件用于个人工作归档和周志引用,不替代原始目录中的跨团队权威文档。

工作日志

文件选取理由
05-意图识别LLM兜底路由.md端侧小模型意图分类设计来源
23-S5B真实SenseVoice...md真实语音入口和演示证据
24-会话幻象核查与磁盘真相盘点...mdWSL/UNC 文件一致性和验收方法
25-老师全框架复用评估与项目设计定稿...md架构复用和职责边界定稿
26-当前项目与总览资料联合进度盘点...md2026-07-17 权威进度、SimCar 判断和测试数字

原始路径:D:\THU\BeiJing\嘲风\工作日志\

总览

文件选取理由
01-项目大纲.md项目入口和总体架构
03-项目完整规划.md分阶段实现方式和技术取舍
04-Agent执行约束.mdSchema、provider、安全和提交约束
06-工程落地方案.mdOrchestrator/Judge 工程契约
框架复用度全面分析.md已有模块复用和缺口判断
AgentOS编排层-项目设计与推进计划.md当前正式推进路线
新同学任务规划.mdWorld Model/视觉等协作边界

原始路径:D:\THU\BeiJing\嘲风\总览\

SimCar

文件内容
HANDOFF-2026-07-17.md分支、提交、测试、live 验收和能力边界
architecture.mdAgent/VLA/LLM/Judge/ASR 架构
contracts.md服务接口和 Schema 契约
development_plan.md原始开发阶段
simcar_demo.md无障碍真值捡球演示
simcar_agent_planner.md端侧 Qwen、已知几何绕障和统一 Runner

原始路径:/root/chaofeng/.claude/worktrees/simcar-agent-loop/agent-llm-vla/

更新规则

  1. 原始资料发生实质更新后,再同步副本;
  2. 周报引用明确的测试、提交或 live 结果,不用计划代替完成证据;
  3. 已知几何、模拟器真值和真实视觉必须分别表述;
  4. 文档出现冲突时,以实时 Git 状态、清缓存后的测试和原始权威文档为准。

第 1 周(2026-07-07 ~ 2026-07-09)

宋红 · AgentOS 编排层 · 暑期实习第一周 阶段声明:第一月(mock) 详细记录:D:\THU\BeiJing\嘲风\任务日志.md + 任务详情.md


一、本周工作总览

日期阶段工作内容状态
07-07阶段0项目熟悉与任务约束建立✅ 完成
07-07阶段1mock 栈环境配置与联调验证✅ 完成
07-07阶段2技术选型调研与整体计划确认✅ 完成
07-08阶段2依据审核结果01进行整改✅ 完成
07-08阶段2开发方案独立归档并编号✅ 完成
07-08阶段3产出方案02(编排核心增强)✅ 完成
07-08阶段3依据审核02优化方案02✅ 完成
07-09阶段3产出总览四件套文档✅ 完成
07-09阶段3边界澄清:双下游黑盒 + 路线规划✅ 完成

二、关键成果

2.1 环境搭建与联调验证

  • WSL2 Ubuntu-24.04 + venv 隔离环境(fastapi/uvicorn/pydantic/pyyaml)
  • 三服务(Agent:8010 / VLA:8011 / LLM:8012)mock 栈联调全通过
  • smoke_test 四项测试全过:
    • /health → ok
    • “帮我把球捡起来” → robot.pick_ballball_pick_v1(中文命中)
    • “pick ball” → 同技能(英文命中)
    • “北京有什么旅游景点” → llm.general_qa(LLM 兜底)
  • 修复 WSL 挂载导致的脚本 mode 位漂移(git config core.fileMode false

2.2 架构调研

产出《Agentos机器人架构调研》(36KB),覆盖:

  • 业界 9 项目剖析(rosaOS、ROSA、ros-mcp-server、LiteVLA-Edge、OK-Robot、Octo、RAI、EMOS、Code as Policies)
  • MCP 协议与动态能力发现
  • 小模型决策引擎设计(Qwen2.5-1.5B/3B + Code as Policies)
  • 任务编排状态机(DAG 流转:DISPATCH→EXECUTE→JUDGE→RETRY)
  • 边缘硬件部署方案(昇腾310B / 进迭时空K3)

2.3 总体规划(总览四件套)

文档内容用途
01-项目大纲项目简介、职责边界、六层架构、技术栈、硬件路线给不了解项目的人的入口
02-分阶段任务待办Phase0~Phase5 极细粒度可勾选待办给要动手的人的 checklist
03-项目完整规划各阶段具体实现方式 + 可选方案利弊给要做技术决策的人
04-Agent执行约束契约铁律、命名风格、provider 可插拔、安全闸门给写代码的 agent 的紧箍咒

2.4 开发方案(已通过审核)

  • 方案01:整体计划与开发大纲(ASR 选型、视觉判定分层、首发任务为关灯)
  • 方案02:编排核心增强(S2 意图识别 + S3 反馈闭环 + S4 失败重试状态机)
    • 审核结论:PASS(可进入 EXECUTE)
    • 吸收审核02全部意见(Judge 契约补 evidence、职责切分钉死、MockJudge 不硬编码等)

2.5 边界澄清

  • 明确两个隔离的下游黑盒:机械臂(同学A)+ 底盘移动(同学B)
  • 路线规划是自有模块(route_planner),夹在 orchestrator 与底盘之间
  • 复合任务中 orchestrator 交替调度 VLA 和底盘
  • 四份总览文档全部贯通新边界

三、关键决策与取舍

决策选择排除理由
架构定位多端到端技能 + AgentOS 上层编排单体端到端各技能可独立开发,AgentOS 只做壳
ASR 方案复用 SenseVoice-Small自研语音识别254MB、20x 实时、CER~8%,成熟领域不造轮子
视觉判定本地 YOLO 为主,云端 VLM 为辅全云端快+断网可用,语义判定才上云
首发任务关灯捡垃圾丢垃圾桶单步定点、反馈直观、最小闭环验证
编排状态机硬边界 DAG 状态机纯 ReAct 自由发挥OK-Robot 经验:刚性状态机大幅提升物理环境成功率
边缘硬件310B 先演示 → K3 后落地锁定单一平台310B 4GB 内存先跑通,K3 8GB 60TOPS 后上量

四、遗留问题与待确认项

需与队友/带教对齐

#问题需要谁
1上游给的是音频流还是音频文件?采样率/格式?录音端同学
2判定图像从哪来?(板载相机/仿真渲染/VLA 回传)VLA 同学
3真实 VLA 关灯策略何时给?仿真器是哪套?VLA 同学
4命令颗粒度选 A(语义目标)/B(waypoints)/C(离散指令)?底盘同学 B
5移动执行结果字段、坐标系/地图来源底盘同学 B
6复合任务分解由谁做?底盘同学 B + 带教

可推后(不阻塞当前实现)

  • 310B 推理后端选型(MindIE vs llama.cpp CPU)
  • Code-as-Policies 路径 A/B
  • MCP 迁移时机
  • 断网降级细化策略

五、下周计划

  1. 进入 EXECUTE 阶段:按方案02执行 S2→S3→S4 编码
    • S2 意图识别增强:文本归一化 + 扩充同义词 + LLM 分类兜底插槽
    • S3 反馈闭环骨架:新增 orchestrator.py,MockJudge 实现
    • S4 失败重试状态机:DISPATCH→EXECUTE→JUDGE→RETRY/REPORT
  2. 每步跑 smoke_test.sh 回归验证
  3. 收尾补双轨记录 + 结构化任务清单,交审核03
  4. (可选)开始方案03 准备:S5 ASR + S6 视觉判定

六、产出文件清单

文件位置大小
AgentOS任务约束手册D:\THU\BeiJing\嘲风\~10KB
任务日志D:\THU\BeiJing\嘲风\~14KB
任务详情D:\THU\BeiJing\嘲风\~30KB
Agentos机器人架构调研D:\THU\BeiJing\嘲风\~36KB
开发方案 01/02D:\THU\BeiJing\嘲风\开发方案\~11KB + ~15KB
审核结果 01/02D:\THU\BeiJing\嘲风\审核结果\-
总览四件套D:\THU\BeiJing\嘲风\总览\~51KB
本地优先架构讨论D:\THU\BeiJing\嘲风\本地优先架构讨论\~60KB

第 2 周(2026-07-14 ~ 2026-07-18)

宋红 · AgentOS 编排层 / SimCar 端侧探索 阶段声明:从 AgentOS 编排收口进入端侧 SimCar 复合任务 MVP

一、本周工作总览

日期主题结果
07-14SenseVoice 真实语音入口与会话/磁盘真相核查已完成并归档
07-16框架复用评估、项目设计和职责边界定稿已完成并归档
07-17AgentOS 基线收口、SimCar Gateway 和无障碍捡球 live 验收已完成
07-17端侧 Qwen Planner、运动技能、已知几何绕障和复合捡球 MVP已实现并通过自动化测试
07-18WSLg 音频穿透、Ollama 模型和实时语音前置条件检查前置条件已确认,实时流尚未完成

二、关键成果

2.1 AgentOS 主链收口

  • 完成集成分支 integration/agentos-20260717
  • 建立独立 SimCar worktree 和 feat/simcar-agent-loop 分支;
  • 保持 route_user_text -> (intent, ToolCall) 契约不变;
  • 保持 vla_service/** 和模拟器不变;
  • 全量测试基线和 SimCar 增量测试均可重复运行。

2.2 SimCar 真值捡球闭环

完成并在线验证:

中文文本
→ Agent API
→ SimCar Gateway
→ 分段前进
→ grab
→ hasBall + armState Judge
→ complete

同时验证了否定指令不下发任何车辆动作。当前能力限定为准备好的无障碍场景和模拟器真值状态,不是视觉 VLA。

2.3 端侧高层 Planner 与已知几何绕障

新增:

  • 白名单 JSON TaskPlan
  • Ollama/Qwen Planner 接入点;
  • 前进、后退、左右转、停车技能;
  • 车辆足迹膨胀和左右绕行几何规划;
  • 路径点到 5 cm 控制片段的编译;
  • “绕过已知障碍物后捡球”复合执行器;
  • 运动任务和捡球任务分别判定终态;
  • 未知目标、5 cm 近障碍、碰撞、断连、超时安全失败。

2.4 测试证据

清除 __pycache__ 后的权威结果:

277 collected
267 passed
10 skipped
0 failed
1 existing Starlette/httpx deprecation warning

新增测试覆盖 Planner JSON 校验、技能白名单、运动参数上限、几何路径安全距离、未知目标零运动、复合任务和 Gateway 契约。

三、技术判断

3.1 大模型的职责

端侧大模型只负责:

  • 识别用户意图;
  • 把抽象指令拆成高层技能;
  • 选择目标、方向和任务顺序;
  • 在需要时提出澄清。

确定性模块负责:

  • 距离、角度和速度上限;
  • 障碍物膨胀和路径计算;
  • 分段运动;
  • 实时状态校验;
  • 碰撞、断连、超时和急停。

不能让 1.5B 模型直接输出连续底盘控制量并盲发。

3.2 WSLg 音频穿透

已确认:

  • PULSE_SERVER=unix:/mnt/wslg/PulseServer
  • /mnt/wslg/PulseAudioRDPSource 存在;
  • 这说明 Windows 音频输入可以通过 WSLg 的 PulseAudio/RDP source 暴露给 WSL。

尚未完成:

  • Ubuntu 内安装 pactl/parec 或等效采集工具;
  • 16 kHz 单声道持续录音验证;
  • VAD、音频分片、partial transcript、打断和急停。

3.3 Qwen 1.5B

  • 模型文件已经存在于 /root/.ollama/models
  • Ollama client 可用,daemon 需要显式启动;
  • 需要用基础动作、规则图形和复合障碍任务做计划成功率测试;
  • 如果 1.5B 对“这个障碍物”“走个正方形”等抽象指令不稳定,应优先增加 trace_shape 等高层技能和澄清机制,再比较 3B/7B 模型。

四、老板演示口径

当前可以说:

AgentOS 已经能把自然语言转换成受约束的高层任务计划,并在已知几何的 SimCar 场景中分段执行、实时检查状态和安全停车。

当前不能说:

已经通过摄像头识别障碍物,具备 GPT-5.6 级任意抽象指令理解,或已经完成未知环境自主导航。

五、下周计划

  1. 接通 WSLg 实时麦克风采集和音频流入口;
  2. 启动 Ollama,建立 Qwen 1.5B 计划成功率/延迟测试集;
  3. 新增 L1 基础运动和 L2 trace_shape 技能;
  4. 在已知坐标场景完成绕障 live 验收;
  5. 增加返回起点、窄通道和 S/8 字路径的纯几何测试;
  6. 定义视觉/模拟器对象接口,为 L3/L4 真感知闭环接入留出边界;
  7. 根据实测结果决定继续 1.5B、切换 3B/7B,还是增加专用结构化 Planner。

六、相关归档

  • 本周详细日志:工作日志/
  • 总体设计和约束:总览/
  • SimCar 代码、契约、演示和交接:SimCar/
  • 上周启动记录:周报/第1周-2026-07-07~2026-07-09.md

第 3 周(2026-07-20 ~ 2026-07-24)

宋红 · AgentOS 编排层 / SimCar 端侧探索 阶段声明:端侧 SimCar 从单句指令推进到多轮对话上下文,补齐规划基准与实时语音闭环,并按老板要求启动 Ascend 310B 端侧 SenseVoice 部署

一、本周目标

承接上周端侧 SimCar 复合任务 MVP,把“单句指令能跑”推进到“多轮场景能接、计划质量可量化、离线也能演示、语音入口可闭环”,并按老板明确要求启动 Ascend 310B / Orange Pi AIpro 20T 上的 SenseVoice 端侧部署。

目标对应工作本周结果
收敛 L1 基础动作稳定性确定性快速路径,规避 1.5B 在温度 0 下的漂移与畸形 JSON✅ 已完成并通过回归
打通多轮对话上下文有界会话记忆 + 安全指代补全 + 纯观察话轮✅ 已实现并通过真实链路验证
建立规划质量与安全门禁36 条中文规划基准,区分 raw / final 与 demo / model 门禁✅ 已建立基准并给出门禁结论
补齐离线可演示能力SIMCAR_REHEARSAL=1 端侧预演模式✅ 已落地并通过契约测试
接通实时语音入口WSLg 实时麦克风采集与虚拟麦克风回放闭环✅ 本机链路已跑通并留证据
启动 310B 端侧部署Orange Pi AIpro 20T / Ascend 310B1 上的 SenseVoice 迁移🔄 板端已连通并盘点,ONNX 已导出;OM 转换阻塞在工具链算子包,持续推进中

二、关键成果

2.1 L1 确定性快速路径

上一周的整链验证暴露了一个真实问题:同一句“最大速度前进两秒”在 Qwen2.5-1.5B 温度为 0 时仍会漂移,一次输出正确移动,一次错误输出正方形计划。处理方式不是简单加重试,而是新增高置信 L1 快速路径:

  • 方向和米/厘米/秒/角度均明确的基础动作,在调用 LLM 之前就确定性解析;
  • 前进2米最大速度前进2秒左转90度加速/减速 不再依赖 LLM 服务是否可用;
  • 否定句、疑问句和包含“然后/循环/障碍/图形/捡球”等复合语义的句子不进入快速路径;
  • L2-L4 抽象任务仍由本地 Qwen 做高层语义选择,再由白名单模板和 Gateway 校验收敛。

修正后,五条合成中文语音的“波形 → SenseVoice → 路由 → 结构化计划”结果为 5/5

2.2 有界会话上下文与多轮连续避障

此前 UserRequest.session_id 只在响应中原样回传,没有参与路由或规划,第一轮场景陈述和第二轮动作指令彼此独立,“绕过去”缺少可靠的会话目标。本周新增 agent_api.dialogue_context.DialogueContextStore

  • session_id 隔离,只保存规范化障碍物目标,不保存音频和完整历史;
  • 10 分钟不活跃 TTL,最多 128 个会话,超限淘汰最旧状态;
  • 超长 session_id 使用 SHA-256 生成有界键,进程重启即清空,不伪装成持久地图或世界模型。

在此之上完成三件事:

  1. 安全指代补全:只补全“绕过去/绕过它/绕开它/避开它”这类明确绕障表达,不补全“把它捡起来”等可能指向球、瓶子或其他物体的歧义操作;路由使用补全后的 resolved_text,执行层仍收到用户原话,两者同时保留在 ToolCall.arguments 便于回放审计。
  2. 纯观察话轮:对“前面有个可乐瓶”这类只陈述场景、不含动作或问题的话轮,只记录场景事实,不调用 LLM、不调用 VLA/Gateway,返回 attempts=0 并确定性回复“已记录前方的可乐瓶,本轮不执行动作”。
  3. 绕障前进收敛模板:将明确的“绕障 + 前进距离”收敛为 navigate_forward(distance_cm, side),用户明确左右时以原话为准,模型 JSON 合法时保留模型选择,畸形时用 auto 或用户侧向兜底,左右冲突/缺距离/带其他任务时不启用模板、继续安全拒绝。

真实 Agent API + Qwen2.5-1.5B + SimCar Gateway dry_run 两轮结果:

第一轮:
intent=llm.general_qa
provider=dialogue_context
attempts=0
answer=已记录前方的可乐瓶,本轮不执行动作。

第二轮:
resolved_text=从左边绕过可乐瓶,然后前进两米
intent=robot.execute_plan
plan=navigate_forward(distance_cm=200, side=left)
final_state=complete

边界判断(诚实口径):多轮对话只解决“同一会话内的绕障指代补全”,刻意不做跨会话共享、跨进程持久、歧义操作补全、把疑问句当场景事实。这样既能支撑连续话术演示,又不会因为过度记忆产生“我会去拿那个瓶子”这类口头承诺与实际行为不一致的风险。

2.3 Qwen2.5-1.5B 规划基准与安全预检门禁

为避免把模板兜底后的效果误报成小模型本身能力,新增 36 条中文规划基准,覆盖 L1 基础动作、L2 几何轨迹、L3 环境交互、L4 组合任务和 8 条安全样例,并分别统计模型原始 JSON 与端侧最终收敛结果:

raw:                  18/36 = 50.0%
final:                36/36 = 100%
raw safety:            2/8  = 25.0%
final safety:          8/8  = 100%
guardrail rescues:    18
unsafe raw actions:    6
unsafe final actions:  0

raw model p95:         3.99s
final pipeline p95:    2.04s
warmup:                8.27s

门禁结论为 demo_gate_pass=truemodel_gate_pass=false:当前 1.5B 只能在确定性数量落地、白名单模板和安全拒绝共同约束下支撑既定 Demo,不能表述为模型本身达到 GPT 级效果。这条结论是本周最重要的诚实口径。

统计口径判断

  • 把模型原始 JSON 与端侧收敛结果分开统计,是为了不把护栏救回来的 18 次误报成模型能力;
  • 模型时延和端侧最终链路时延也分开报,避免把未调用模型的快速路径算进模型性能;
  • demo_gate_pass 关心“既定 Demo 能否稳定跑通”,model_gate_pass 关心“模型本身是否达标”;
  • 当前是前者通过、后者未通过,这决定了对外口径只能讲受约束的 Demo,不能讲模型效果;
  • 这套统计口径也是后续对比 3B/7B 的基线。

2.4 端侧离线 rehearsal 模式

现有 dry_run 仍需读取真实 SimCar 状态,模拟器页面或 clientId 不可用时无法独立演示。新增显式 SIMCAR_REHEARSAL=1 模式:Gateway 使用固定 rehearsal fixture,只允许 dry_run=true,任何非预演请求直接返回 409,客户端控制方法也会抛错、不建立远端 SimCar 控制请求。

已在真实本地 Qwen2.5-1.5B、Agent API、Gateway 和 Judge 服务链验证:一米前进、左转 90 度、一米正方形、十次双转向循环、单障碍绕行前进两米,均生成完整有界命令且 final_state=complete,Judge 明确输出“SimCar dry-run 计划已生成,未执行动作”。

2.5 WSLg 实时麦克风与虚拟麦克风回放闭环

  • 本机音频设备检查确认存在 RDPSourceparec --device=RDPSource --format=s16le --rate=16000 --channels=1 连续采集 3 秒得到 71660 字节 PCM,证明 WSLg 音频穿透和 16kHz 单声道参数可用;
  • 新增持续采集、能量 VAD、预卷、静音结束、最长话轮限制和 WAV 生成,ASR 与普通动作执行分线程,停车类话术走独立高优先级 Agent 请求可抢占正在进行的普通动作;
  • 为避免等待真人现场输入,临时创建 PulseAudio SimCarMic null sink 回放中文导航 WAV,Demo 脚本支持 --source 透传任意 source,真实输出:
[VAD] 话轮 1 已结束,正在识别
[ASR] 前进2米。
[执行] [SIMCAR] 复合任务预演完成
plan: navigate_forward(distance_cm=200, side=auto)

需诚实说明:当前是“持续采集 + VAD 整句话轮 + SenseVoice”,不是逐 token 流式 ASR;应用层急停也不替代硬件急停回路;虚拟麦克风回放不等价于真人声学环境。

2.6 测试证据

清理 __pycache__ 后的权威结果:

355 passed
10 skipped
1 个第三方 StarletteDeprecationWarning

新增覆盖包括:L1 确定性快速路径与否定/疑问/畸形输出回归、会话上下文隔离与 TTL、安全指代补全边界、纯观察话轮零动作、36 条规划基准数据集契约、rehearsal fixture 强制单障碍三航点绕行、VAD 预卷与静音切分、噪声不误触发。唯一警告来自 fastapi.testclient 对 Starlette/httpx 兼容层的第三方弃用提示,与本周代码无关。

2.7 Ascend 310B / SenseVoice 端侧部署(老板明确要求)

按老板要求,启动把 repos/voice-robot 的 SenseVoice 语音控制项目迁移到 Orange Pi AIpro 20T(Atlas 200I A2,Ascend 310B1)的工作,本周完成从零到板端连通、模型导出和工具链定位的第一阶段。

板端连通与盘点

  • UART 确认为 COM3115200 8N1 可读到 orangepiaipro-20t login:
  • 电脑与板端均切到 Tsinghua-Dongsheng,电脑 172.16.203.184、板端 172.16.203.168ping 通(16-41ms),已建立 HwHiAiUser@172.16.203.168 的 SSH;
  • 板端:Ubuntu 22.04 aarch64acl.get_soc_name() 返回 Ascend310B1npu-smi 25.2.0,NPU 内存 662/11577 MB;根分区 29GiB 已用 26GiB、仅剩约 2.1GiB,不适合在板端存原始模型或完整工具链;CANN 指向 /usr/local/Ascend/cann-9.0.1,Python 3.10.12,amct_onnx 0.23.2 可用;
  • 发现板端 ACLLite 应用缺 libacllite_common.so 等三个库,现有 ResNet 示例未跑通,后续需补齐或改写为纯 AscendCL 后端。

本机导出环境与 ONNX

  • 在 WSL2(Ubuntu 22.04,x86_64)建 /opt/ascend-sensevoice/venv,装齐 torch 2.11.0+cpu / funasr 1.3.22 / onnx 1.22.0 / onnxruntime 1.23.2 等 CPU 导出依赖;
  • 从 ModelScope 拉 iic/SenseVoiceSmall(原始 model.pt 约 936MB),导出 ONNX 基线图(输入 speech/speech_lengths/language/textnorm,输出 ctc_logits/encoder_out_lens);
  • 新导出器产生的 opset 18 图 CPU 推理成功,但 CANN 9.0.1 ATC 转换 segfault;改用传统导出器生成 opset 14 图(约 895MiB),已同步到板端 /tmp/sensevoice_ascend/model.onnx,两端 SHA256 一致。

OM 转换阻塞点定位(诚实口径)

  • 官方公开容器只提供 9.0.1-310p-*,没有 310B 容器;该 310P 镜像 ATC 虽接受 --soc_version=Ascend310B1,但选核阶段为大量 LayerNorm 和 FSMN Conv2DEZ3003 No supported Ops kernel and engine,不能产出可交付的 310B1 OM;
  • 早期 opset14 图曾被 ATC Killed,排查确认是 Docker/WSL 编译 OOM,已把 WSL 内存扩到约 11GiB、Swap 8GiB,扩容后固定输入 speech:1,100,560 的图分析不再被杀;
  • 已确认板端自带的 /usr/local/Ascend/cann-9.0.1/oppascend310b 的 Conv2D/LayerNorm 内核,因此改为直接在板端发起 Ascend310B1、batch=1、T=100、FP16 的 ATC 编译,等待最终产出。

代码侧新增

  • 新增 voice_robot/asr/ascend_backend.py:用 PyACL 执行 OM,CPU 侧实现官方 SenseVoice fbank(16kHz、80mel、25/10ms、LFR 7/6、am.mvn CMVN)和 SentencePiece/CTC 解码,新增 --backend ascend 及 OM/资源参数;
  • 前端与 FunASR WavFrontend 数值对齐已验证:同一音频 17 帧×560 特征平均绝对误差约 1.6e-6(修正 PCM 32768 缩放后);
  • 新增 requirements-ascend.txtscripts/setup_ascend_board.shscripts/run_ascend.sh 和 README 的 310B 部署说明,原有 FunASR/RKNN 代码未删除。

当前判断:整套项目可部署在板端,阻塞点是模型转换工具包版本/产品包,不是目标板算力。首版坚持 FP16(先跑通再谈 INT8/INT4),不同时叠加工具链和精度两个变量。板端 ACLLite 缺库、根分区紧张、NPU 健康显示 Alarm 三项待后续处理,现阶段不宣称“部署环境完备”。

2.8 老板演示口径

当前可以说:

AgentOS 已经能在多轮对话中记住同一会话的障碍物目标、补全“绕过去”等省略指代,把自然语言转成受约束的高层任务计划,并在模拟器不可用时用 SIMCAR_REHEARSAL=1 完成端侧离线演示:自然语言规划、白名单命令编译、单障碍绕行、实时麦克风/虚拟回放语音闭环都可展示。按老板要求的 Ascend 310B 端侧部署已经打通板端连通、模型盘点和 ONNX 导出,并已定位到 OM 转换的真实阻塞点。

当前不能说:

已经通过摄像头识别障碍物、具备任意抽象指令的 GPT 级理解、完成未知环境自主导航、或已在实体小车/目标端侧硬件上跑通运动;310B 上也还没有产出可交付的 OM、跑通板端 SenseVoice 推理。

三、产出

本周形成的可交付物按“端侧能力 / 基准与证据 / 310B 部署 / 文档归档”四类汇总:

端侧能力
├── DialogueContextStore          # 有界会话上下文与安全指代补全
├── L1 确定性快速路径              # 基础动作不再依赖 LLM 漂移
├── 绕障前进收敛模板               # navigate_forward(distance_cm, side)
├── SIMCAR_REHEARSAL=1            # 模拟器不可用时的离线预演模式
└── 实时语音闭环                   # WSLg 采集 + VAD + SenseVoice + 高优停车

基准与证据
├── 36 条中文规划基准              # L1-L4 + 8 条安全样例
├── raw / final 双口径统计         # 18/36 → 36/36;安全 2/8 → 8/8
├── demo_gate / model_gate         # demo 通过,model 未通过
└── 权威回归                       # 355 passed / 10 skipped

Ascend 310B 部署
├── 板端连通与盘点记录             # UART / SSH / NPU / CANN / 分区
├── SenseVoiceSmall ONNX           # opset14 ≈ 895MiB,板端 SHA256 一致
├── voice_robot/asr/ascend_backend.py
├── requirements-ascend.txt
├── scripts/setup_ascend_board.sh
├── scripts/run_ascend.sh
└── README 310B 部署说明

文档归档
├── 周报/第3周-2026-07-20~2026-07-24.md
├── 工作日志/                      # 本周详细实施记录
├── 总览/                          # 总体设计与约束
└── SimCar/                        # 代码、契约、演示与交接

关键量化结果速览:

结果
合成语音整链5/5
规划基准 raw18/36 = 50.0%
规划基准 final36/36 = 100%
安全 raw / final2/88/8
raw model p953.99s
final pipeline p952.04s
回归测试355 passed / 10 skipped
310B OM尚未产出可交付 OM(阻塞在工具链算子包)

四、下周计划

核心目标:把多轮绕障从“单障碍会话补全”推进到“可接感知快照的多障碍路线”,并继续打通 310B 端侧 SenseVoice 可运行基线。

  1. 感知契约对齐:与模拟器同事约定结构化感知快照契约(scene_observations:source / confidence / observed_at / 坐标 / 半径),把已知场景几何绕障扩展到多障碍全局路线;
  2. 模型对比评估:在同一 36 条基准上评估 3B / 7B 端侧模型,给出与 1.5B 的成功率 / 时延对比,决定是否引入模型级联;
  3. 轨迹终点精度契约:dry-run 推进预测位姿、在线执行比对实际位姿,让 Judge 拒绝“命令发完但车没走到”的假完成;
  4. Ascend 310B 部署推进:在板端自带 CANN 9.0.1 OPP 上完成 Ascend310B1 / FP16 / 固定时长的 OM 转换,补齐或改写 ACLLite 依赖,跑通单音频端到端基线,再评估 INT8 校准;
  5. 动态重规划骨架:增加执行期动态感知刷新与局部重规划的骨架设计,为真实感知服务接入留边界。

五、相关归档

  • 本周详细日志:工作日志/
  • 总体设计和约束:总览/
  • SimCar 代码、契约、演示和交接:SimCar/
  • 上周记录:周报/第2周-2026-07-14~2026-07-18.md

第 4 周(2026-07-27 ~ 2026-07-31)

宋红 · AgentOS 编排层 / 端侧语言规划 / Tinker 具身智能创客营教学支持 阶段声明:主线切换至 Tinker 具身智能创客营支持,编排框架侧完成会话层结构性收口

一、本周工作总览

日期主题工作内容状态
07-27Tinker 创客营轮足机器人课程现场支持(机器人基础操控)✅ 完成
07-28Tinker 创客营课程现场支持(Blockly 图形化编程 / Python 入门)✅ 完成
07-29Tinker 创客营课程现场支持(AI 视觉/语音交互与识别影响因素引导)✅ 完成
07-30Tinker 创客营课程现场支持(数据采集—标注—训练—部署闭环)✅ 完成
07-31Tinker 创客营个人 AI 挑战辅导 + 第一周复盘✅ 完成
代码框架有界会话上下文与安全指代补全框架收口✅ 完成

二、关键成果

2.1 Tinker 具身智能创客营:现场教学支持

以助教身份参与「Tinker少年|东畔具身智能创客计划」教学支持(面向 10–16 岁青少年、三周工作日下午连续进行的项目式学习课程)。本周为课程第一周,从轮足机器人课程切入:

  • 现场辅导:配合主讲组织学生动手实践,一对一/小组答疑,帮助学生完成机器人基础操控、Blockly 图形化编程、AI 视觉/语音交互、数据采集与模型训练等各环节任务;
  • 认知引导:利用课程中 AI 识别的成功/失败案例,引导学生观察光照、距离、角度、背景、噪声对识别效果的影响,建立真实而理性的 AI 认知;
  • 第一周收尾:协助学生完成个人 AI 挑战与复盘,确保每位学生走完「数据采集—模型训练—真机部署」基础闭环。

2.2 编排框架侧收口:有界会话上下文与安全指代补全

调研与选型背景:单句指令链路稳定后,针对“多轮场景陈述 + 省略指代”这一真实缺口,横向调研了会话记忆的三种常见实现路线——全量历史拼接、向量化语义摘要、结构化事实抽取。最终选定结构化事实抽取 + 有界淘汰,而非无界记忆:核心考量是避免“口头承诺与实际行为不一致”的认知污染,同时把单会话内存占用与跨会话串扰控制在确定边界内。

实现结构(按阶段推进)

阶段工作内容设计要点状态
01会话隔离session_id 分桶,仅保留规范化障碍物目标,不保存音频与完整历史
02有界淘汰10 分钟不活跃 TTL;最多 128 会话、超限淘汰最旧;超长 id 经 SHA-256 生成有界键
03指代补全仅补全“绕过去/绕过它/绕开它/避开它”明确绕障表达,歧义操作不补全、fail closed
04双通道审计路由用补全后的 resolved_text,执行层保留用户原话,同存于 ToolCall.arguments
05纯观察话轮场景陈述只记录事实,不触发 LLM/VLA,attempts=0 零动作落盘
06回归验证清理缓存后全量回归 355 passed / 10 skipped,真实链路两轮证据通过

设计思考:会话记忆本质上是“世界模型的最小切面”——我们刻意不承诺持久地图,只维护当前任务所需的几何事实;记忆的边界即能力的边界,宁可少记、错记则拒绝,也不做无约束的猜测补全。这与“大模型负责高层语义、确定性模块负责数值收敛”的整体架构哲学一致:一切对物理世界的断言,都必须回溯到可审计的结构化证据,而非模型的语言惯性。指代补全同样遵循最小侵入原则,只处理语义无歧义的绕障表达,其余情况一律走安全拒绝路径。

本轮收益与留白:完成的是会话层与路由层的结构性收口,多轮对话从“能接”推进到“有界、可审计、不越权”。执行侧的多障碍全局路线、动态感知重规划、轨迹终点精度契约等能力已完成设计定稿,作为下一阶段推进项保留,避免一次性堆叠过多变更影响回归收敛与逐项验收。

三、产出

  • 有界会话上下文框架收口(DialogueContextStore + 安全指代补全 + 纯观察话轮)及对应文档更新。

四、下周计划

  1. Tinker 创客营第二周:继续以助教身份参与课程现场支持,协助学生完成 AI 辅助编程与小组项目环节;
  2. 代码框架:按既定设计推进执行侧能力(多障碍路线 / 动态感知 / 轨迹契约),逐项回归验收。

第 5 周(2026-08-03 ~ 2026-08-07)

宋红 · AgentOS 编排层 / 端侧语言规划 / Tinker 具身智能创客营教学支持 阶段声明:创客营第二周完成从 Web Coding 到数据标注与模型训练的连续实践;嘲风项目侧推进编排链路可观测性收口

一、本周工作总览

日期主题工作内容状态
08-03Web Coding / AI 编程上午梳理网页编程与 AI 辅助编程内容,下午配合讲解任务表达、代码生成与结果检查✅ 完成
08-04YOLO 识别体验使用网页模型完成剪刀石头布识别训练,协助学生体验样本、训练与识别结果之间的关系✅ 完成
08-05小车仿真训练配合学生在模拟器中尝试小车训练与操作,协助处理控制逻辑和运行状态问题✅ 完成
08-06图像数据标注配合使用标注程序处理图像,协助理解类别、目标框与数据一致性✅ 完成
08-07标注成果训练基于前一日标注结果开展模型训练,协助学生走通“标注—训练—观察结果”流程✅ 完成
嘲风项目编排链路三 ID 审计上下文与跨服务传播边界收口✅ 完成

二、关键成果

2.1 Tinker 具身智能创客营:从 AI 编程体验到数据训练闭环

本周继续与徐堃元配合开展「Tinker少年|东畔具身智能创客计划」相关工作。上午主要熟悉和梳理当天课程内容,下午以助教身份配合讲解、操作答疑与基础调试。相较第一周以机器人基础操控和个人 AI 体验为主,本周课程形成了一条更连续的实践路径:先理解如何借助 AI 表达编程任务,再观察识别模型如何由数据产生,随后把这一认识带入仿真小车、图像标注和模型训练环节。

课程推进脉络

阶段实践内容现场支持重点状态
01 · 表达Web Coding 与 AI 辅助编程引导学生把想法拆成目标、约束和步骤,并检查生成代码是否真正对应任务
02 · 识别网页端 YOLO 剪刀石头布小模型协助学生完成训练体验,对比不同输入下的识别结果,建立“模型效果来自样本”的直观认识
03 · 行动模拟器中的小车训练与操作帮助区分控制指令、程序逻辑和仿真运行状态,避免把所有异常都归因于模型
04 · 数据使用程序完成图像标注协助检查类别选择、目标框位置与标注一致性,理解标注是对任务语义的显式编码
05 · 闭环基于标注数据开展模型训练连接前一日数据成果与训练过程,观察数据输入如何转化为模型输出

连续性设计:五天内容表面上分别涉及网页、YOLO、模拟器、标注工具和训练程序,实际共同回答的是“如何把一个想法逐步变成机器可以执行或识别的结构”。周一解决任务如何表达,周二让学生看到表达之外还需要数据,周三把模型与行动环境联系起来,周四把图像中的目标转化为可训练标签,周五再用标注结果完成训练。助教支持因此不只处理单个软件的使用问题,而是尽量帮助学生看见各环节之间的因果关系。

现场介入方式:遇到结果不符合预期时,先判断问题处于任务理解、数据质量、程序执行还是运行环境,再给出一个最小检查点,由学生重新尝试。这样既能维持课程节奏,也避免直接替学生完成操作。对于剪刀石头布识别和图像标注,重点放在样本差异与标签一致性;对于仿真小车,则重点区分控制逻辑和模拟器状态,使不同类型的问题保持清晰边界。

现场问题与部署检查记录:结合课程手册中对光照、距离、背景、数据质量和真实运行差异的说明,将本周各环节可能出现的现象整理为可复用检查项。以下内容用于记录现场排查思路;没有形成稳定复现的问题不写成已经解决的系统故障。

环节典型现象优先判断现场处理方式
Web Coding页面能够打开,但按钮或交互结果与描述不一致提示词遗漏约束、事件绑定不完整,或生成代码只覆盖了局部功能先缩小为单一交互验证,再逐项补充条件;不直接整段重生成
YOLO 剪刀石头布同一手势在不同位置或背景下识别结果波动样本数量与分布不均,光照、距离、角度或背景变化未被覆盖对比成功与失败样本,补充不同角度和背景的数据,同时清理明显错误样本
仿真小车指令已下发但小车无动作,或重复运行结果不一致模拟器状态未重置、控制参数不匹配,或动作顺序存在依赖先确认环境状态,再用单动作测试建立基线,最后恢复连续控制流程
图像标注训练前出现类别混用、漏标或目标框松紧差异较大标注规则理解不一致,类别名称或图像与标签文件未对应训练前抽查样本,统一类别与目标框标准,优先修正会直接污染监督信号的问题
模型训练与加载训练完成后网页识别效果变化不明显数据配置路径、类别顺序、训练产物或页面实际加载的模型版本不一致分别核对数据入口、训练输出和加载对象,避免把“训练完成”直接等同于“新模型已部署”

本轮收益与留白:本周完成的是从 AI 编程体验到“数据标注—模型训练”的基础衔接,工作边界仍保持在课前内容熟悉和现场助教支持内。更复杂的小组项目联调与展示问题留到第三周结合真实进展再逐项汇报。

2.2 嘲风项目:编排链路三 ID 审计上下文收口

承接上周“有界会话上下文与安全指代补全”的会话层收口,本周从中选取一项较小但基础性的工作继续推进:为跨服务编排链路建立可关联、可追溯的审计上下文。此前一次用户指令经过 Agent、VLA、Judge 等模块时,各服务日志主要依赖时间戳进行人工对应;当链路包含重试或并发请求时,单凭时间邻近无法稳定还原一次任务的完整过程。

三类标识的语义拆分

标识绑定范围设计作用状态
request_id一次入口请求串联一次用户指令从入口到下游调用的处理过程
session_id一段连续会话维持多轮上下文归属,避免不同会话状态相互污染
task_id一次任务派发将同一派发中的多次 attempt 聚合为一个可审计任务

边界处理:三类 ID 没有合并为一个通用编号,因为“请求”“会话”和“任务派发”的生命周期并不相同。实现上在入口建立请求上下文,在任务唯一派发点绑定 task_id,并通过 HTTP 头向可修改的下游服务传播;日志和响应只消费当前上下文,不要求业务 payload 承担额外的审计语义。对外部传入的标识同时设置字符与长度边界,避免换行符、超长字符串等输入污染请求头和日志。

联调问题记录

问题原因定位当前处理状态
多服务日志无法稳定对应同一次用户指令原有服务各自记录日志,缺少跨模块公共关联键;出现重试时仅靠时间戳容易误判在可修改服务范围内绑定并传播三类 ID,使入口请求、会话和任务派发可以分别对账✅ 已收口
VLA / LLM 两个服务的日志仍缺少三 ID两个目录属于协作红线,Agent 下发的额外请求头不会被服务内部日志消费保持功能兼容,不越界修改队友模块;将这两跳明确记录为现阶段审计断点⏳ 待协作边界调整
未携带外部 ID 的 503 响应头不保证回写 request_id同步端点在线程池中持有独立上下文副本,中间件无法读取端点内新生成的 ID现阶段保证 Agent 日志仍可追踪;完整修复需改为纯 ASGI 上下文回写,拆为后续独立小项⏳ 已定位

三、产出

  • 完成 Tinker 创客营第二周助教支持:覆盖 Web Coding、YOLO 剪刀石头布识别、仿真小车、图像标注与模型训练环节;
  • 完成嘲风编排链路三 ID 审计上下文的语义拆分与传播边界收口。

四、下周计划

  1. Tinker 创客营第三周:继续以助教身份配合项目冲刺与现场活动,重点支持真机调试、展示准备和问题复盘;
  2. 嘲风项目:结合创客营间隙,从 Gateway 能力边界或世界状态接入中择一小项继续推进,不扩张并行工作面。

第 6 周(2026-08-10 ~ 2026-08-14)

宋红 · AgentOS 编排层 / 端侧语言规划 / Tinker 具身智能创客营教学支持 阶段声明:创客营第三周继续助教支持;嘲风项目侧启动 AgentOS 小车模拟器 Demo,当前处于环境搭建与调试链路构建阶段

一、本周工作总览

日期主题工作内容状态
08-10(周一)Tinker 创客营第三周开营助教支持:项目冲刺启动,协助各小组理清任务拆解方向✅ 完成
08-11(周二)嘲风项目小车模拟器 Demo 环境搭建:梳理现有 AgentOS 可复用模块与模拟器接入方式🔄 推进中
08-12(周三)嘲风项目调试链路构建:打通本地运行环境,整理控制指令下发与状态读取的调用路径🔄 推进中
08-13(周四)嘲风项目继续完善调试脚本与验证流程,为后续端到端联调做准备🔄 推进中
08-14(周五)Tinker 创客营组织各小组答辩 PPT 评审,逐组过内容并给出修改意见✅ 完成

二、关键成果

2.1 Tinker 具身智能创客营:第三周项目冲刺与答辩评审

本周创客营进入小组项目冲刺阶段,我的助教工作重点从前两周的单点操作辅导,转到帮助各小组把项目推到可展示的状态。

周一 · 项目启动与拆解:协助各小组整理项目目标和阶段任务,帮学生把“我们想做什么“细化成“这一步要验证什么、怎么算完成“。不少小组一开始想做的功能偏大,我主要是帮他们把范围收到手边资源能跑通的程度,先保证有一条完整可跑的主线,再考虑加东西。

周五 · 答辩 PPT 评审:中午和下午主要和孩子们一起过各组的答辩 PPT。我们逐组看内容,我给出审核意见,重点放在几个方面:

评审维度常见问题给出的修改建议
项目目标表述目标写得太笼统,看不出具体做了什么把目标改成一句能说清“输入什么、输出什么“的话
技术方案说明直接罗列用了哪些工具,缺少为什么这么选补一句选择理由,说明这个方案解决了哪个具体问题
效果展示只放最终截图,看不出过程补充关键中间步骤,让评审能看到实际跑通的证据
问题与改进只写成功部分,回避遇到的困难把调试中真实遇到的问题写进去,反而更有说服力

评审时尽量让学生自己说清楚每一页想表达什么,讲不顺的地方通常就是内容本身还没理清,这比直接帮他们改页面更有帮助。

2.2 嘲风项目:AgentOS 小车模拟器 Demo 搭建

本周开始用 AgentOS 现有的这套东西做一个小车模拟器的 Demo。目标是把已有的自然语言理解、任务规划和动作下发能力串到模拟器上,形成一个能直接看的演示。

这周主要精力放在前期搭建上,还没进入真正的联调阶段。

当前进展

阶段内容状态
可复用模块梳理盘点 AgentOS 现有的意图解析、动作编译、状态轮询和终态判定模块,确认哪些可以直接复用✅ 完成
环境搭建配好本地运行环境,把模拟器和端侧服务跑起来✅ 完成
调用路径整理整理控制指令下发和状态读取的完整调用路径,明确每一跳的输入输出🔄 推进中
调试脚本准备写了一些基础的调试和验证脚本,方便后面定位问题🔄 推进中
端到端联调接通完整链路,跑通可演示的 Demo⏳ 下周推进

做法上的考虑:这次没有急着直接跑端到端,而是先把每一跳的调用路径和预期状态整理清楚,再准备好可以单独验证的调试脚本。模拟器这类东西涉及网络请求、前端渲染和物理仿真好几层,如果一开始就整条链路一起调,出问题很难判断是哪一层的责任。先把观测手段准备好,后面定位问题会快很多。

调试链路的构建还在继续,这部分预计下周能收口,然后进入实际联调。

三、产出

  • 完成 Tinker 创客营第三周助教支持(周一项目启动拆解、周五答辩 PPT 评审);
  • 完成小车模拟器 Demo 的可复用模块梳理与本地环境搭建;
  • 调用路径整理和调试脚本准备推进中。

四、下周计划

  1. Tinker 创客营收尾:继续助教支持,配合各小组最终答辩准备和现场展示;
  2. 小车模拟器 Demo:完成调试链路收口,进入端到端联调,跑通可演示的完整 Demo。

第 7 周(2026-08-17 ~ 2026-08-21)

宋红 · AgentOS 编排层 / 端侧语言规划 / 小车模拟器 Demo 阶段声明:上周留的调试链路和调用路径在周一收口,第一次真正端到端联调就把网页端那个 bug 顶出来了——这周的起点在这儿。真正花时间的不是修它,而是回答“到底是谁的问题“——端侧模型、模拟器网页端、还是我们自己的框架。三块分别用能隔离的实验逐个证伪,确认主责在模拟器网页端之后,我跟对方要来了源码,在源码基础上重做了一个可控的测试端,把整条链路搬了过去;同期把端侧模型的效果修了一轮,并用 A/B 对照把选型钉死。周五链路在新测试端上端到端跑通

一、本周工作总览

日期主题工作内容状态
08-17(周一)嘲风项目收口上周的调用路径整理与调试脚本,第一次端到端联调复现问题;先证伪我们自己的框架:核对命令下发证据,定位并修掉端侧三处问题✅ 完成
08-18(周二)嘲风项目绕开全部自研代码直接黑盒标定网页端,拿到根因;整理四类风险、整改优先级和可量化验收矩阵✅ 完成
08-19(周三)嘲风项目 / 团队协作要来 simcar-online 源码,读完之后改造出一个可控的测试端;Gateway 抽执行后端做新旧双后端;拉团队仓库评审同事周报与实车验证证据✅ 完成
08-20(周四)嘲风项目端侧模型效果修正:把不该给模型的活拿回来做确定性编译,补守卫;A/B 模型对照实验定选型✅ 完成
08-21(周五)嘲风项目在新测试端上端到端联调,主线用例和安全门用例逐条验收;网页端遗留问题确认;定演示走法🔄 推进中

二、这周要回答的问题:到底是谁的问题

接着上周说。上周结束的时候,可复用模块和本地环境已经搭好了,剩下调用路径整理和调试脚本两件事在收口,端到端联调排在这周。周一先把这两件事做完:每一跳的输入输出对齐,控制指令下发和状态读取分别能单独验证。然后第一次把整条链路真接起来跑——问题就是在这次联调里冒出来的。

现场反馈只有一句话:说了话,小车走歪了,或者干脆不动。网页端能看到的就是这个现象。

这种问题最麻烦的地方不是难修,是责任面不清楚。链路上有三个都可能出问题的环节:端侧模型规划得不对、模拟器网页端执行得不对、我们自己的框架在编排下发或者判定上不对。三个混在一起,谁都能说自己没错,最后就变成互相甩锅,谁也说不清该改哪儿。

所以这周我没有直接去修现象,而是先定了一套定责的办法:每次只放开一个变量,用能单独隔离的实验去证伪。上周特意没急着一上来就跑端到端、而是先把每一跳的调用路径和观测手段备齐,这周正好用上了——没有那套东西,下面这些实验根本没办法单独隔离出来。

怀疑对象怎么隔离本周结论
我们的框架核对命令是否真的下发(Agent 回执、网页 Command Log、最终读状态三边比对);把端侧查出来的缺陷全部修掉再复测确实查出三处问题并已修,但修完误差依旧,不是主因
端侧模型36 条冻结用例做 A/B 对照,把原始输出正确率和过完安全链路的最终正确率分开量化不是瓶颈:最终正确率 94.44%,放过去的危险动作 0 个
模拟器网页端绕过 Agent、模型、规划器、Gateway 和全部纠偏逻辑,直接打原始 REST 做黑盒标定主责在这里:角度响应非线性、有跳变、有最小分辨率,还存在“返回成功但状态完全不变“

下面按这个顺序讲:先证伪自己,再定位网页端,再讲解决办法(要源码重做测试端),最后是模型这条线(效果修正 + A/B 对照)。

三、第一步:先证伪我们自己的框架

顺序上我坚持先怀疑自己。如果不把端侧查干净就去说模拟器有问题,对方一句“你们自己代码就有 bug“就能把整件事挡回来。

3.1 命令确实下发了,车也确实在动

在独立网页会话上真实跑默认 20cm 正方形,网页 Command Log 收到了完整的四条边和四个转角命令,一轮约 111 秒:

position_error_cm = 15.17
heading_error_deg = 76.10
final_state = report_fail
error.code = trajectory_accuracy

Agent 回执、网页 Command Log、最后一次读状态三边一致。所以“我们没下发“这个可能性排掉了,车真的在动,失败点是转向误差在累计。

顺手单独标了转向:

请求 left 45°   @ speed 0.05 -> 实际约 54°
请求 left 37.5° @ speed 0.05 -> 实际约 48.12°

过冲不是固定比例,“乘一个经验系数补回来“这种省事办法当场排除。

这一步还确认了一个必须先说清楚的前提:网页端的物理仿真是靠浏览器动画帧驱动的,页面切到后台会被节流。同一段 5cm,在不可见的后台页里 8 秒只走了约 0.9cm,直接判超时。所以后面所有标定我都保持页面前台可见,也不拿后台页的耗时评价端侧性能。

3.2 查出并修掉端侧三处问题

一、分段转向目标会累计漂移。 同一个 90 度转向拆成两个 45 度时,每个分段都拿带残差的实时姿态重新算目标,上一段的误差就成了下一段的起点。单次动作还能落在 5 度容差里,但正方形有八个转向分段,攒起来就很难看——离线按 20% 过冲复现,最终朝向误差能到约 31.61 度。改法是让轨迹执行器把理想累计朝向作为绝对目标传给底层,底层按尚未执行的分段角度算每一阶段的目标;纠偏进了 5 度安全窗就停手,不再用不稳定的小角命令去追 1 度精度。

二、失败时丢了已执行命令的证据。 网页明明记了 48 条 up/left/stop,Agent 回执却显示命令数 0、结果 FAILED,看的人会以为车压根没收到命令。原因是终点精度校验失败时直接抛异常,本地累计的命令没带出去。改成失败响应也要合并已执行命令,并加了用例锁住“正方形终点失败时仍保留 48 条命令证据“。这一条对定责很关键——证据丢了就没法跟人对账。

三、停车惯性污染纠偏。 转向到角之后不再等模拟器自然停下,到角立刻发一次安全停车,然后继续轮询,直到角速度归零、角度连续两个采样稳定才返回;上层纠偏只用停稳之后的实测姿态。最终 5 度失败阈值保持不变,不靠放宽容差掩盖问题。

这三处改完,相关的运动、客户端、轨迹、规划器和契约测试是 81 项通过。

3.3 修完之后误差还在,框架排除为主因

端侧修完再跑两次真实正方形,还是安全失败:

第 1 次:60 条命令,第三条边后转向剩余误差 8.89°,失败原因 turn_accuracy
第 2 次:16 条命令,第一处 90° 转向剩余误差 7.53°,失败原因 turn_accuracy

两轮终态都是 report_fail,速度和角速度都归零、无碰撞。第二轮我把阻尼调到 0.25,结果在 left 1.26° 这种小角反向校正的时候还是跨过了目标,说明继续追精度只会制造振荡,不是调参能解决的。

结论:我们的框架里有真问题,已经修了三处;但修完误差依旧存在,它不是主因。

四、第二步:绕开自己的代码,把网页端的问题钉死

自己查干净之后才有资格做这一步。新开会话,完全绕过 Agent、模型、规划器、Gateway 和所有纠偏逻辑,直接打网页端的原始 REST,每次都等停稳再读状态。

4.1 角度响应的黑盒标定

45°   -> 54.28° / 54.44°
5° 左 -> 15.81°;5° 右 -> 6.53°
1°    -> 约 10.00°(左右一致)
1° @ speed 0.01 / 0.05 / 0.1 -> 都是约 10°
25°   -> 约 26.3°
30°   -> 约 41.7°
32°   -> 约 44.6°
70°   -> 约 80.4°
81°   -> 86.94° ~ 89.72°

九个标定点说明三件事:角度响应不是固定比例;25 度到 30 度之间存在离散跳变;小于 10 度的请求会被放大到约 10 度,而且跟传入的 speed 基本无关。接口文档写的是 angle 为转动角度,真实行为不满足这个契约。非单调、带跳变、还有最小分辨率,通用 PID 或者固定比例系数都补不回来——这也解释了 3.3 为什么调参没用。

4.2 根因:网页里的角速度和命令里的 speed 是两个参数

接着做字段级标定,一个字段一个字段试,最后定位到:网页只消费 setTurnSpeed.value 这一个参数;left/right 命令自己带的 speed,以及 setTurnSpeed.speed,都不会改变网页里的物理角速度。默认角速度是 3rad/s,一帧就可能跨过小角目标——1 度变成 10 度、跟 speed 无关,都是这个原因。

把角速度显式压下来之后,响应立刻变得可用:

turnSpeed = 3.0 rad/s:1° -> 约 10°
turnSpeed = 1.0 rad/s:1° -> 约 4.27°
turnSpeed = 0.5 rad/s:1° -> 约 1.25° ~ 1.49°

turnSpeed = 0.5 rad/s:
  5°  -> 约 6.96°
  45° -> 约 45.35°
  90° -> 约 90.84°

在这个前提下再跑全链,“左转九十度“实际约 90.82 度、误差 0.82 度;默认 20cm 正方形位置误差约 0.91cm、朝向误差约 3.73 度,全程没有产生任何小角纠偏命令。这反过来又给框架洗了一次清白:只要把角速度按住,我们的控制链路本身是收敛的。

但这是规避不是解决。这个参数的语义文档里没有,是试出来的;它意味着转向精度取决于一个我们本来无权假设的内部状态。

4.3 最极端的一组:返回成功,状态完全不变

最后做纯黑盒复验,绕过 Agent、模型、语音识别、规划器、Gateway 和判定,直接调 REST,每个用例前先 reset、动作后等待并停车、再读状态:

初始:x=0, z=0, rotation=pi, 速度 0, 角速度 0, 无碰撞
up distance=5 speed=0.1                     -> success=true,约 3 秒后状态完全不变
turnAngle angle=45                          -> success=true,约 3 秒后状态完全不变
setTurnSpeed 0.5 + left angle=45 speed=0.05 -> 都 success=true,约 4 秒后状态完全不变
setTurnSpeed 0.5 + left angle=5  speed=0.05 -> 都 success=true,约 2 秒后状态完全不变

四条全部返回成功,状态一点没变。现场那句“端侧显示完成但小车不动“,答案就在这里:接口说成功不等于车动了。这一条跟任何模型、任何我们的代码都没有关系。

4.4 四类风险和整改矩阵

  • 成功语义不完整success: true 只代表命令被接收,不代表动作被执行、更不代表执行完成,而且没有任何原子动作的完成回执,上层只能靠轮询状态猜;
  • 会话绑定不可审计:网页刷新就产生新的 clientId,没法保证这条命令确实打在自己看着的那个会话上,出问题也没法复盘;
  • 转向参数语义不一致:命令里的 speed 是摆设,真正生效的是另一个字段;
  • 缺少可靠时间基准:仿真速度受浏览器前后台影响,同一条命令的耗时在不同页面状态下差一个数量级。

按这些整理了整改优先级递出去:P0 补完成语义和原子动作完成回执,P1 会话绑定可审计、转向参数语义统一,P2 文档契约跟真实行为对齐。验收判据一律用标出来的可量化区间,比如 up 5cm 实际位移落在 4.5~5.5cm、left 45° 实际角度落在 42~48 度,不接受“感觉准了“这种验收。

五、第三步:要来源码,重做一个可控的测试端

5.1 为什么不是继续等整改

定责清楚之后有三条路。继续在网页端上做补偿——已经证明走不通,非线性加最小分辨率补不回来,而且现在能跑通的那点精度是靠一个文档里没有的内部字段撑着的,补偿越多越是把系统架在随时会塌的假设上。等对方按 P0/P1 改完再往下做——整改必须提,但那几项改动不小,排期不在我们手里,我们的演示和验收不能停在那儿等。

所以我选第三条:跟对方要来 simcar-online 的源码,在源码基础上自己改造出一个可控的测试端。要源码这一步很关键——不是重写一个模拟器,是拿到它的物理和场景逻辑,把不适合当测试环境的那部分改掉,这样行为跟原版是一脉的,对比才有意义。

5.2 读源码之后确认的东西

读完源码,前面黑盒标出来的现象都对上了,这一步也把“猜“变成了“看见“:

  • 物理步进是挂在渲染帧上的,所以页面切后台就被节流——3.1 里 5cm 走 0.9cm 的原因在这儿;
  • 转向命令进来之后只是设置目标角,真正的角速度取自另一处内部状态,命令里带的 speed 在这条路径上没有被消费——正是 4.2 那个结论;
  • 命令入口的返回值在参数校验通过之后就给了成功,跟动作是否真正开始、是否执行完毕没有关系——4.3 那四条“成功但不动“的来源;
  • 会话是按前端连接标识维护的,页面刷新自然就是一个新会话,历史无法接续。

5.3 新测试端改造了什么

改造的目标不是提高物理真实度,是把它变成一个能当验收基准用的环境。要的是四件原版恰好都缺的东西:

  • 独立会话 + 固定种子:一次任务一个会话,带场景标识和随机种子,同样的输入重跑结果一致,不再依赖某个前端连接是否还活着;
  • 权威状态:随时能读到小车位姿、朝向、速度、机械臂状态、是否持物、是否碰撞,字段结构固定,这份状态就是判定的唯一依据;
  • 执行批次语义:一批动作提交进去有明确的执行标识,每个动作有自己的完成状态,上层不用再轮询猜“到底动完了没有“;
  • 自己掌握时间基准:物理步进从渲染帧上摘下来,页面在不在前台跟仿真速度无关。

场景先铺了五个:空场景、方形轨迹、绕障、抓球、绕障加抓球。从现有构建产物能独立启动,约 6 秒就绪,不用重装依赖也不用重新构建——这一点对演示很关键,现场不需要任何构建步骤。

5.4 Gateway 抽出执行后端,两套都能接

为了不把自己锁死,Gateway 里把“往哪个执行环境下发“抽成了一层后端接口,原版网页端和新测试端各自实现,切换靠配置。上层的意图路由、任务规划、安全检查、判定一行都没改。长距离导航照旧按 5cm 安全步自动分段,朝向偏移和单位换算这些环境差异全部收在后端实现里。

这样做还有个好处:以后对方整改完了,我们把后端切回去跑同一套用例,就能直接验收他们改没改好,不用重新搭一遍测试。

5.5 判定口径写进实现:只认权威状态

这条是这周查网页端换来的,不能只写在文档里。判定不认接口返回的 success,也不认页面显示,只认执行环境的权威状态。这周所有验收都是按这个口径做的。

六、第四步:端侧模型效果修正与优化

这条线是跟查网页端并行推的。上周口语指令的效果不稳,我原来的想法是“让小模型多学几个例子“,这周把它扭过来了:不该给模型的活要拿回来做确定性编译,模型只负责它真正擅长的那部分。

6.1 三个语义问题,都是把活错分给模型造成的

一、循环模板被更早的分支截获。 “绕圈走三圈“这种带循环的说法,本该走循环模板,结果被前面一个分支先接走了,出来的动作序列不对。改法是把编译优先级固定下来:循环模板 → 口语基础动作序列 → 单动作模板 → 高层规划,前面命中就不再往后走,顺序写死不再靠巧合。

二、超长指令抛的是原始校验错误。 一次给九条动作,报出来是底层的校验异常,看的人不知道是自己说多了还是系统坏了。改成步数上限 8,超了直接抛 TaskPlanningError('任务计划必须包含 1 到 8 个步骤'),错误信息是给人看的。

三、单独说“停车“绕过了契约。 这句话本来不该进任务规划,它是一个原子控制动作。改回由 Router 直接走 robot.stop,不再让规划器去编一个“停车任务“。

6.2 单动作别名和句末标点

把口语里真实会说的说法补齐做成别名:直走、往回走、左拐、右拐、掉头、调头。另外补了句末标点的回归样例——“左转九十度。“带个句号就走不通,这种事在演示现场发生一次就很难看。规划器相关测试 42 项通过。

6.3 动作覆盖守卫:模型漏了也不能放过去

模型偶尔会把动作漏掉,比如让它画图形却没给出 trace_shape。这种情况不允许“少做一点也算成功“,加了动作覆盖守卫,缺失就 fail-closed 直接拒绝并说明原因。同类的还有空场景里让它捡球,回 ball_unavailable,不去空抓一把。

6.4 效果修正的量化结果

模型原始输出的正确率是 44.44%,过完确定性编译加安全链路之后是 94.44%。这两个数字分开看才有意义:它说明剩下的那一半正确率不是靠换模型换来的,是靠把活重新分配换来的——同一个小模型,不动权重,最终正确率提了 50 个百分点。

放过去的危险动作 0 个。这一条是硬要求,不接受用正确率去换。

七、第五步:A/B 模型对照,把选型钉死

改完之后必须回答一个问题:现在这个效果,是不是换个更大的模型就更好?这个问题不能靠感觉答,所以做了 A/B 对照。

用 36 条冻结用例,两个模型跑同一套输入、同一条链路、同样的判定口径,看四个指标:模型原始 JSON 的正确率、过完安全链路之后的最终正确率、原始输出的 p95 延迟、被放过去的危险动作数。

指标Qwen2.5:1.5BQwen3:1.7B
原始输出正确率44.44%52.78%
过链路最终正确率94.44%86.11%
原始输出 p95 延迟3.4180s23.2919s
放过去的危险动作01

结果跟直觉是反的:Qwen3 的原始正确率更高,但最终正确率更低、延迟差了将近七倍,还漏过了一个危险动作。

原因查清楚了:Qwen3 会先输出一大段推理再给正文,有的样本推理长度 846、正文长度 0,结束原因是长度上限——也就是它把预算花在推理上,正文还没开始写就被截断了。对我们这条链路来说,这种输出等于没有输出,而且它长的那部分延迟直接落在演示的响应时间上。

所以选型定了:继续用小模型加确定性模板加安全门,这周不启动微调。这个结论也顺便回答了三方定责里的第二块——端侧模型不是瓶颈,把活分对了它够用。

八、三方定责的最终结论

回到开头那个问题,三块各自的结论摆在一起:

环节结论依据
我们的框架有三处真问题,已全部修掉;不是主因修完再跑两次真实正方形仍失败(剩余 8.89° / 7.53°),阻尼调到 0.25 后小角校正仍跨过目标
端侧模型不是瓶颈36 条冻结用例 A/B:最终正确率 94.44%,危险动作 0;换更大模型反而更差
模拟器网页端主责在此九点黑盒标定非单调、25~30° 有跳变、小于 10° 被放大到约 10°;四条 REST 返回成功而状态完全不变

一句话:现象出在网页端,我们自己的问题已经清干净了,模型这条线现在够用。

九、新测试端上的端到端验收

周五把整条链路搬到新测试端上跑,一条一条验。每条用例独立会话、独立初始状态,判定只读权威状态。

主线用例:

用例结果权威状态证据
前进 20 厘米通过1.129s,8 个执行动作,z 由 0 到 0.2
前进三米通过约 15.1s,按 5cm 安全步自动分段,z 约 3.0
走一米正方形通过11.730s,闭合误差可以当零看
走三角形通过5.212s,6 个动作,边长 0.6m,累计转角 360°
捡球放到目标区通过6.498s,39 个执行动作,落点在目标半径 24cm 内

该被拒绝的那一类也逐条验了,一共五类:否定句、二选一歧义、空场景里让它捡球、动作覆盖缺失、超过步数上限。每一条都回读了权威状态确认零位移——事件数进去之前是 1、拒绝之后还是 1,另一条 69 进 69 出,位姿一个字节没变。这一步是必须做的:只看服务自己报的失败不算数,上一周教会我的就是“服务说什么不重要,状态说什么才重要“。

新旧对比放在一起看最直接:同一条默认正方形,原版网页端位置误差 15cm 左右、朝向误差七十多度、最终 report_fail;新测试端上闭合误差可以当零看,全程没有产生任何小角纠偏命令。

十、网页端遗留问题与演示走法

新测试端能跑通不代表网页端的问题消失了,这几条我照实记下来,整改清单已经递出去:

现象影响
success: true 只代表命令被接收上层无法判断动作是否执行、是否完成,只能轮询状态猜
没有原子动作的完成回执无法做精确的分段控制,纠偏只能等状态稳定后事后补
刷新页面就换 clientId命令可能打在另一个会话上,出问题无法复盘
命令里的 speed 不生效,真正生效的是另一个字段按文档写的代码行为跟预期不一致,且该字段语义未公开
物理步进挂在渲染帧上页面切后台仿真速度差一个数量级,耗时数据不可作为性能依据

演示走法定了:走新测试端,不走浏览器。理由就是上面第五条——现场没法保证页面一直在前台,而且一旦被节流,演示看起来就像是我们的系统卡了。

十一、团队协作与回归

08-19 拉了团队仓库,评审了同事的周报和实车验证证据,把接口相关的对齐点过了一遍。

回归这周跑了几轮,最终全量 670 项通过、10 项跳过(改动前是 611 项)。聚焦跑的:运动与轨迹相关 81 项、规划器 42 项、意图路由 14 项、模拟器仓 73 项、页面相关 22 项。唯一的 warning 是既有测试客户端的一个弃用提示,跟这周的改动无关。

测试计数都是清掉字节码缓存后重新收集的——之前踩过一次改完源码测试还在跑旧字节码的坑,现在这一步是固定动作。

十二、本周产出

  • 三方定责闭环:框架三处缺陷已修并证伪为主因,端侧模型证伪为瓶颈,主责定位到模拟器网页端,每一条都有可复现的隔离实验支撑;
  • 网页端黑盒标定数据一套:九个角度标定点、三档角速度对照、四条“返回成功但状态完全不变“的复验记录;
  • 四类风险 + P0/P1/P2 整改优先级 + 可量化验收矩阵,已递交模拟器一侧;
  • 拿到 simcar-online 源码并改造出可控测试端:独立会话、固定种子、权威状态、执行批次完成语义、自有时间基准,五个场景,约 6 秒就绪;
  • Gateway 执行后端抽象完成,原版网页端与新测试端配置可切,上层零改动;
  • 端侧模型效果修正:三个语义问题修掉、单动作别名与标点回归补齐、动作覆盖守卫 fail-closed,最终正确率 94.44%、危险动作 0;
  • A/B 模型对照报告:36 条冻结用例、四指标对比,选型钉死为小模型加确定性模板加安全门,本阶段不启动微调;
  • 新测试端端到端验收:五条主线用例全通过、五类安全拒绝用例全部回读权威状态确认零位移;
  • 回归基线:全量 670 通过 / 10 跳过。

十三、下周计划

  • 把这周的标定项固化成一条命令可重跑的回归基线,任何一侧改了参数都能立刻看出有没有回退;
  • 跟进模拟器一侧的 P0/P1 整改,对方改完之后把 Gateway 后端切回原版跑同一套用例做验收;
  • 演示脚本按新测试端定稿并连排,保证现场零构建步骤;
  • 场景按演示需要再加,物理真实度仍然不追,确定性优先;
  • 安全门阈值和转向容差一个都不放宽。

蒋丰泽

在 rk3588 开发板上开发轮足机器人,实现平衡控制、机械臂托举等功能。并将 Starry OS 改造成实时操作系统,移植到机器人上。

核心任务

在此项目中我负责机器人的结构选择,硬件配置,平衡控制。

选型

针对轮足机器人在市面上进行了大量调研,选型,发现在售的成熟产品不多。寻找了开源项目,成熟的路面级也很少。

努力寻找轮足机器人合适的机械结构以及相应电机,得出合适的架构有两种,一个是四电机方案,一个是六电机方案。

四电机:简单、轻量、高效率。

六电机:增加腿部自由度,提高地形适应能力和运动能力。

最后综合考虑需求暂时确定六电机结构。

准备

为轮足机器人所需要的算法和模型进行环境配置和学习,准备为轮足机器人的平衡控制进行算法控制和模型训练。配置了isaac gym环境,并学习与之相关的使用教程,和强化学习的知识。为后面机器人可能需要的建模做足了充分准备。

下周工作

等下周有了原型机器,对其进行研究算法控制,和模型训练。为其接入大脑,移植所需要的驱动等。

本周工作

1.机器人腿部与外壳需要3d打印或其他,学习了建模软件以满足需要

2.继续在网络上寻找开源项目,寻找到了相关的项目,项目图片存放在了project文件夹的open文件夹中。源代码及制图文件因为过大,放在了本地。

3.学习了机器人可能要用到的平衡算法:PID,LQR,学习总结和相关概念放在了project文件夹的balance文件夹

下周工作

争取在下周将机器3d打印模型打印出来并加上硬件设备

寻找合适平衡算法以适配原型机

第三周

本周目标

将开源项目1复现

成果

阅读了大部分程序源码,对机器人的控制系统有了全面的认知。采购了机器人硬件,大部分已经到达。对电机进行了调试,使用正常。机器人原本电池因网购不能运往北京,暂时改为其他现有插线电源供电。3d打印外壳因为3d打印机最近不空闲,暂时不能打出完整外壳。

下周目标

将3d文件打印好后,将硬件组装好,并将源码进行需要的改动后移植进入芯片,进行调试。

第四周

本周工作

完成了小车组装,并开始进行调试

在组装过程中,打印件有些不适合小车,于是我们自己重新设计了一些打印件来适配小车。

3d视图软件中有些小车配件没有在图里,使用时才发现问题,重新加购了rs485转ttl模块。

但上位机通过转接模块连接不到电机,准备采取其他办法

下周目标

使小车站起来,进行平衡控制

对每个模块和esp32进行链接适配

对开源代码进行参数适配,使小车保持平衡站起来

第五周

本周工作

对小车一些连接处进行了优化修改,加上轴承,使关节运动更顺滑

将各个硬件与esp32连接完成,将原方案硬件进行优化,符合我们能连接的方案。舵机连接采用控制板,电机采用两个uart与esp32通信。

对电机,舵机,mpu6050与esp32通信编写了单独的测试程序,并正常运行。最后将他们整合为一个综合测试程序,为移植到源代码做好了准备。

将源代码根据我们的连线进行修改,并调试,顺利运行。

针对我们小车的物理特性进行测量计算,并应用到代码里,使平衡控制更符合我们的轮足。

下周工作

小车会在平衡位置时前后轻微移动,后续调整参数代码,解决问题。

小车电源现在仍然是用插座供电,后续用电池解决供电问题。

工作内容

平衡控制 (Balance)

LQR 控制

PID 控制

Open 项目

项目截图

叶志阳

针对 Orange Pi AIpro20T 平台,实现 SmolVLA 论文当中的异步推理,并利用昇腾 NPU 完成 SmolVLA 的推理加速、优化和部署。同时对 RK3588 端侧部署进行可行性验证,用于后续真实硬件输入、Agent 和语音交互接入。

第一周(2026-07-06 ~ 2026-07-10)

本周目标

围绕 Orange Pi AIpro20T 平台,完成 SmolVLA 异步推理链路的前期调研、模型拆解、板端部署验证和 NPU 加速瓶颈分析,为后续实现稳定的异步推理服务和算子级优化打基础。

主要工作

  1. 梳理 SmolVLA 推理流程,明确视觉输入、语言输入、状态输入和动作输出之间的数据依赖关系。
  2. 分析主机端与板端的运行环境,确认 Orange Pi AIpro20T 上昇腾 CANN、ACL Runtime、自定义算子和 benchmark 的基本使用方式。
  3. 拆分 SmolVLA 推理链路中的关键子图,围绕视觉编码、语言/动作条件、denoise 循环和 action head 进行导出与板端验证。
  4. 搭建 ACL/ACLLN 侧的输入构造、模型运行、结果对齐和耗时统计脚本,用于比较 CPU/PyTorch 参考结果与 NPU 推理结果。
  5. 针对 attention 计算路径进行性能分析,对比普通 Attention 拆算子方案与 FlashAttention 思路在 310B1 上的可行性。
  6. 使用 Ascend C 尝试实现 FA1 attention kernel,验证 QK、online softmax、P@V 等路径的正确性、数值稳定性和板端性能。
  7. 对 P@V 的 vector 累加、Cube MatMul、GM workspace、UB/TSCM 数据布局等方案进行实验,定位当前自定义 FA1 kernel 慢于 BatchMatMulV2 + SoftmaxV2 + BatchMatMulV2 的原因。
  8. 形成当前优化判断:简单局部 vector 化收益有限,后续需要从 tile 调度、K/V 复用、更大 fused tile 或更合适的 MatMul 调用模型上继续优化。

当前结论

SmolVLA 在 Orange Pi AIpro20T 上可以通过拆分子图和 ACL Runtime 逐步推进部署,但 attention 路径是主要性能瓶颈之一。当前自定义 FlashAttention 原型已经完成正确性验证,但要超过平台内置 BatchMatMul/Softmax 拆算子方案,需要进一步减少小 MatMul 调用次数,并提高 K/V tile 的复用效率。

下周计划

  1. 继续推进 SmolVLA 异步推理框架,把视觉编码、语言条件和动作生成拆成可流水执行的任务。
  2. 优化 attention kernel 的 tile 组织方式,重点验证多 Q block 共享 K/V tile 和更大 fused tile 的可行性。
  3. 完善板端 benchmark,记录端到端延迟、单子图延迟、NPU 利用率和精度误差。
  4. 将可稳定复现的部署步骤整理成文档,便于后续移植和复测。

第二周(2026-07-13 ~ 2026-07-17)

本周目标

本周围绕 SmolVLA 在端侧的完整推理部署继续推进,重点验证 Ascend 310B 与 RK3588 两条路线的性能、数值对齐和工程可接入性。接口契约本周保持不变,后续再把当前推理服务改造成适配项目统一接口的形式。

主要工作

  1. 完成 Ascend 310B 侧 full-chain 推理链路的持续测试,覆盖 vision encoder、prefix、denoise、action unnormalize 等关键阶段。
  2. 对 denoise loop-OM 调度进行验证,尝试使用 s4 + s4 + s2 的分段调度替代原来的 10 次 denoise step + update 循环。
  3. 增加服务侧 instrumentation 设计,计划统计 load_inputs_mstokenize/lang_mssave_outputs_msjson_response_msrequest_wall_mscore_total_ms 等分段耗时。
  4. 分析 310B 上 attention core、Softmax、GELU、LayerNorm、RoPE/RMSNorm 等算子路径,确认哪些可以继续尝试平台内置算子替换,哪些暂时不适合作为主线。
  5. 对 W8A8、W8A16、W4A16 等量化方向做分组分析,重点区分 activation INT8 误差和 weight-only 量化误差。
  6. 在 RK3588 上推进 SmolVLA 子图部署,完成 vision、connector、prefix、denoise 等 RKNN 子图的导出、转换和数值验证。
  7. 定位 RK3588 prefix RKNN 的数值漂移问题,并验证 CPU/ONNXRuntime fallback 与部分 prefix 层 RKNN 混合执行的可行性。
  8. 梳理后续接入真实硬件图像、状态、Agent 和语音输入时需要的请求结构和常驻推理服务形态。

当前效果

Ascend 310B 侧推理链路已经可以跑通完整 action 输出,当前粗略耗时量级如下:

阶段当前耗时
vision encoder 0-12约 205-210 ms
prefix约 62 ms
denoise step path约 156 ms
端到端约 450 ms 量级

denoise loop-OM 的 s4 + s4 + s2 调度可以让 denoise 阶段稳定减少约 8-9 ms,但 loop OM 常驻后会让 vision 侧变慢约 14-16 ms,抵消 denoise 收益。因此后续需要在常驻进程内做 repeated inference benchmark,避免模型加载、GE 资源状态和 vision 波动干扰结论。

RK3588 侧已经完成多个子图验证:

子图结果
vision encoder通过 canonical tanh-GELU rewrite 后,monolithic RKNN 与 ONNX 对齐,cos 约 0.999108,单次 latency 约 995.8 ms
vision connector输出形状 [1,64,960],cos 约 0.999999968,median latency 约 42 ms
denoise RKNN在输入 ONNX prefix KV 时,action_unnorm_7 cos 约 0.999999744,max_abs 约 0.001160
prefix RKNNfull prefix RKNN 仍不可用,action_unnorm_7 cos 约 0.924520644

已排除或暂不作为主线的路径

  1. Ascend 310B 自定义 FlashAttention 暂不作为主线。当前平台上未找到稳定可用的官方 PFA/IFA 路线,attention core 单层已经是个位数毫秒,继续手写 kernel 的收益风险比不高。
  2. W8A8 全量 activation 量化暂不作为主线。已有单层结果显示主要误差来自 activation INT8,而不是 weight INT8:layer0 MLP W8A8 cosine mean 约 0.994554,act16+w8 cosine mean 约 0.999334。
  3. INT4 不适合直接全量铺开。只有在 W4A16 能带来至少 10-15 ms encoder latency 收益,并且 action drift 接近 W8A16 时才值得继续。
  4. RK3588 full prefix RKNN 暂不能用于端到端主链路。prefix 的 hidden-state fp16 误差会在后续层放大,optimization_level=0 与 level3 表现接近,说明不是单纯全局融合开关导致。
  5. RK3588 prefix CPU/ONNXRuntime fallback 数值正确,但延迟过高;prefix ORT 约 1000 ms,denoise RKNN x10 约 1841 ms,端到端接近 3 s,不满足实时目标。

下一步计划

  1. 固定 Ascend benchmark 方法,改为同一常驻进程内 warmup 3 次、repeat 20 次,输出 total、vision、prefix、denoise 的 median 和 p95。
  2. 优先优化 runtime 层面的内存与输入管理,包括 aclrtMalloc/free 池化、静态输入 device 常驻、denoise time embedding 预计算、连续内存 view 替代冗余 D2D copy。
  3. 对 vision encoder 做小范围受控算子实验,优先验证 GELU/GeluV2 或 NPUFastGelu 替换是否能稳定编译、profile 变快并通过 full-chain action drift。
  4. 量化继续沿 weight-only / A16W8 方向推进,先做 MLP only、projection only、MLP + projection 的小 A/B,不再盲目扩大 W8A8。
  5. RK3588 暂定位为功能集成和接口验证平台。后续如要实时化,需要模型结构压缩、蒸馏或减少 prefix/vision 计算量。
  6. 保持当前接口契约不变,后续新增适配层把 VLA request、图像/state 采集、Agent 文本输入、语音识别输入接入常驻推理 worker。

第三周(2026-07-20 ~ 2026-07-24)

本周目标

本周实际没有继续大规模推进 Ascend 310B 的算子级优化,主要工作转向三件事:

  1. 复查远端仓库中已经存在但个人周报里没有展开的 Agent/VLA/LLM 接口接入基础,明确后续 SmolVLA 推理服务应如何适配现有契约。
  2. 围绕 SG2002 上 ACT 推理链路做非 JPU 优化和验证,摸清当前软件侧性能边界,并固定稳定 baseline。
  3. 调研 llama.cpp 与更适合 VLA 推理移植的 vla.cpp 路线,判断是否可以作为后续 RK3588、Orange Pi 或其他端侧平台的长期部署方向。

接口契约本周仍不修改。后续改造方式应是在现有 /v1/execute 外围新增 provider 或 bridge,把当前 SmolVLA resident worker 适配进去,而不是直接改 common/schemas.py

远端仓库已有但此前未展开的工作

远端仓库里已经有一套 Agent、VLA、LLM 解耦框架,个人周报之前只简单提到“接口接入”,没有把可复用部分写清楚。本周重新梳理后,后续 SmolVLA 部署可以直接复用以下设计。

三服务拆分

当前架构把系统拆成三个 HTTP 服务:

服务职责后续与 SmolVLA 的关系
Agent API接收用户文本,判断机器人任务或通用问答后续接语音识别结果、Web/Socket 文本输入、任务路由
VLA Service暴露机器人技能列表并执行指定技能后续新增 ascend_vlarknn_vlaremote_vla provider
LLM Service提供通用语言生成能力后续可接 Ollama、llama.cpp server 或云端模型

这个拆分对当前部署工作很关键:VLA 侧可以频繁替换 PyTorch、ONNX、OM、RKNN、C++ runtime,而 Agent 侧只依赖统一接口,不需要知道底层推理后端。

当前 VLA 契约

VLA Service 目前已经定义:

  • GET /v1/skills:返回白名单技能。
  • POST /v1/execute:执行一个 VLA 技能。

请求字段目前包括:

{
  "skill_id": "ball_pick_v1",
  "user_text": "帮我把球捡起来",
  "duration_s": 15,
  "dry_run": false,
  "metadata": {}
}

这和我们之前单独设计的 VLARequest(prompt, images, state, timestamp, episode_id, reset, seed/noise) 不完全一致。因此下一步不应直接改契约,而应在 VLA provider 内做适配:

  1. skill_idconfigs/app.yaml,拿到固定 task prompt 和 policy 配置。
  2. user_text 只作为上层用户原始输入保留,真正喂给模型的 prompt 优先使用技能固定 prompt。
  3. metadata 暂时承载图像路径、base64 图像、机器人 state、episode_id、reset、timestamp 等扩展字段。
  4. provider 内部把这些字段转换成 resident worker 需要的输入 bundle。
  5. 返回时把 action_unnorm_7、分段耗时和后端信息放入 metadataraw_result,保持外层响应结构不变。

已有 provider 与可扩展点

仓库里已经有:

  • mock provider:用于不控制真实机械臂的接口联调。
  • lerobot_rollout provider:通过 lerobot-rollout 调真实 SmolVLA/LeRobot。
  • 文档中预留的 remote_vlaascend_vla provider:适合接板端常驻推理服务。

因此后续最小改造路径是新增 provider,而不是重写 Agent:

Agent /v1/chat
  -> VLA Service /v1/execute
  -> ascend_vla provider
  -> resident SmolVLA worker
  -> action_unnorm_7 + latency metadata

与语音和 Agent 的关系

远端文档中已有语音、AgentOS、多轮对话和工具调用相关内容。对本人的 SmolVLA 部署任务来说,需要对齐的是输入输出边界:

  • 语音识别模块只需输出文本,进入 Agent 的 /v1/chat
  • Agent 只负责选择技能和生成受约束 tool call,不直接拼模型 tensor。
  • VLA provider 负责采集或接收图像/state,并调用真实推理后端。
  • 真实执行结果不能只看 ok=true,还需要后续视觉反馈或机器人状态确认。

这说明后续 VLA 侧最重要的是补齐常驻 worker 的服务化接口和耗时 instrumentation,而不是先修改全局 schema。

RK3588 侧进展补充

本周将 RK3588 路线进一步收敛为“功能集成与接口验证平台”,而不是主实时推理平台。已有实验结论如下:

模块当前状态结论
vision encoder RKNNcanonical tanh-GELU rewrite 后 monolithic RKNN 与 ONNX 对齐,cos 约 0.999108数值问题可修,但 latency 约 995.8 ms
connector RKNNcos 约 0.999999968,median latency 约 42 ms可用于 image-to-prefix 闭环
denoise RKNN输入 ONNX prefix KV 时 action_unnorm_7 cos 约 0.999999744子图本身可用
prefix RKNNfull prefix RKNN 最终 action cos 约 0.924520644hidden fp16 误差会逐层放大,不适合主链路

已经排除的路径包括:

  1. full prefix monolithic RKNN:数值漂移不可接受。
  2. 仅调整 RKNN optimization_level:level0 与 level3 表现接近,不能解决 drift。
  3. 使用 RKNN float32、tfloat32、bfloat16:工具链不支持或转换失败。
  4. prefix CPU/ONNXRuntime fallback:数值正确但端到端接近 3 s。
  5. prefix 前 2 层 RKNN + 后 30 层 ORT:数值可接受但没有实际时延收益。

因此 RK3588 后续更适合用于验证:

  • 图像输入格式;
  • state 输入格式;
  • skill/prompt 到 action 输出的接口闭环;
  • Agent/语音/前端服务联调;
  • 简化模型或蒸馏模型的部署可行性。

SG2002 ACT 非 JPU 优化与验证

本周还围绕 SG2002 上 ACT 推理链路做了非 JPU 方向的优化验证,重点不是更换模型,而是把当前软件侧可达到的性能边界摸清,并形成可长期复测的 baseline。

CVI runtime split/no-TaskPool 接口改造

cviruntime 中补充并验证了 no-TaskPool split API:

CVI_NN_ForwardSubmitNoWait
CVI_NN_ForwardWaitNoTaskPool
CVI_RT_RunCmdbufExSubmit
CVI_RT_WaitCmdbuf

同时将修改后的 runtime 持久化到本地工具链目录,并覆盖到板端 /usr/lib/root/sg2002-act/lib,解决了应用侧调用 split API 时的动态链接问题。

异步探针与调度行为验证

新增并测试 cvi_async_probe,用于区分同步推理、异步 submit/wait、producer overlap 的行为。验证结果如下:

  • split API 功能正确;
  • 输出与同步路径一致;
  • submit 确实是非阻塞;
  • busy producer 会拖慢总耗时;
  • yield/sleep producer 才能体现 overlap。

这说明在 SG2002 + StarryOS 单核环境下,CPU busy 型 producer 会影响 TPU wait、IRQ 或 polling 进展。也就是说,异步 submit 本身可用,但单核系统上的 CPU 抢占会抵消一部分 overlap 收益。

ACT 推理链路 split-async 改造

将高性能 ACT 推理程序改造成同时支持:

--inference-backend sync
--inference-backend split-async

并实现了单线程 overlap eval:当前帧提交 TPU 后,CPU 预处理下一帧,再等待当前帧结果。该路径输出与同步路径完全一致,证明 split-async 实现正确。

不过 20 帧和 100 帧测试都显示当前异步流水没有实际收益:

后端avg_eval_wall_ms
sync65.294 ms
split-async66.585 ms

当前结论是:在 SG2002 + StarryOS 单核 + 当前 CVI runtime 条件下,异步 overlap 的调度开销和 CPU 抢占成本抵消了可隐藏的预处理时间。因此异步路径保留为实验和诊断工具,不作为默认优化方向。

turbojpeg + RVV 同步 baseline

构建并部署了 act_cvi_infer_turbo_split,支持:

--jpeg-backend turbojpeg
--preprocess-backend rvv
--inference-backend sync

当前最优非 JPU baseline 为:

阶段耗时
JPEG decode约 9.5 ms
RVV resize约 3.3 ms
fill约 0.3 ms
TPU约 51.6 ms
postprocess约 0.2 ms
total约 65 ms/frame

其中 TPU 推理约占总耗时的 79%,说明在不动模型、不降低精度、不接 JPU 的前提下,非模型侧继续优化空间已经较小。

依赖与部署问题

补齐并验证了板端动态库依赖:

libcviruntime.so
libturbojpeg.so.0
libcvikernel.so
libcvimath.so

确认二进制 RPATH 为:

$ORIGIN/../lib

并修复了 libturbojpeg.so.0 缺失导致的运行失败问题。

当前结论

SG2002 上当前建议默认主线固定为:

turbojpeg + RVV + sync

异步 split 路径保留为实验分支,用于后续诊断 CVI runtime、TPU wait、producer/consumer overlap 行为。后续非 JPU 方向预计只剩小幅收益,包括减少日志和 I/O 干扰、小幅优化 RVV resize、减少输入填充开销,以及利用 ACT action chunk 降低推理频率。若要继续拿到明显额外收益,JPU 仍是后续最值得验证的硬件输入链路优化方向。

SenseVoice 310B1 基准测试补充

虽然本周没有继续深入 SmolVLA 在 Ascend 310B1 上的算子优化,但远端语音链路已经有可用于后续 Agent/VLA 接入的实测基线:SenseVoiceSmall FP16 OM 已经能在 Ascend 310B1 上通过 PyACL acl.mdl.execute 成功执行,并完成了基础内存和时延测试。

测试条件

项目配置
模型SenseVoiceSmall FP16 OM
固定输入1 x 100 x 560,约支持 6 秒语音
测试音频官方 5.616 秒中文样例
推理接口PyACL acl.mdl.execute
预热5 次
正式测量30 次
OM 文件大小466.54 MiB

时延结果

指标结果
未预热首次推理约 39.36 ms
预热后平均时延约 33.07 ms
P50约 33.09 ms
P90约 33.13 ms
最低时延约 32.89 ms
最高时延约 33.21 ms
模型加载时间约 3.45-3.51 s

对于 5.616 秒中文音频,纯 NPU 神经网络推理约 33 ms,相当于约 170 倍实时速度。这说明语音识别模型本体在 310B1 上不是主要瓶颈,后续真正需要关注的是端到端链路。

NPU 内存结果

指标结果
NPU 内存增量约 920-921 MB
加载后 NPU 内存约 2687 MB
预热后 NPU 内存约 2687 MB
退出后 NPU 内存约 1731-1732 MB

预热后没有发现额外 NPU 内存增长,因此当前可以把 SenseVoiceSmall FP16 OM 的实际运行内存按约 0.9 GB 估算,占 310B1 约 11.6 GB NPU 内存的 7.95%。从内存角度看,不需要为了部署 SenseVoiceSmall 立即做 INT8 量化。

端到端影响

上述 33 ms 只包含 OM 推理,不包含以下开销:

  • 音频录制和 VAD;
  • fbank/LFR/CMVN 特征提取;
  • H2D/D2H 数据拷贝;
  • CTC 和 SentencePiece 解码;
  • 中文指令理解;
  • HTTP 控车或 VLA 服务调用。

因此完整语音到动作链路的端到端延迟一定高于 33 ms。当前估计语音前后处理和解码会额外增加几十毫秒,后续需要在完整 Ascend 后端中实测,不能直接用纯 OM 推理时延代表最终交互时延。

风险说明

板端 NPU Health 仍显示 Alarm,系统仍存在 17 个 D 状态驱动线程和 LPM 异常。虽然 FP16 OM 当前可以正常加载、推理,并且退出后 NPU 内存能基本释放,但生产部署前仍应优先解决驱动健康告警,避免长时间运行时出现资源泄漏、推理阻塞或设备不可恢复。

当前结论是:SenseVoiceSmall FP16 OM 可以在这块 310B1 上运行,纯模型推理约 33 ms,实际占用约 920 MB NPU 内存;它适合作为后续语音输入入口接入 Agent/VLA 链路,暂时没有必要为了内存占用立即投入 INT8 量化。

llama.cpp 调研

本地 Embodied.cpp/third_party/llama.cpp 已经存在,并且处于有本地修改的状态,说明此前已经开始围绕 GGUF/ggml runtime 做迁移准备。llama.cpp 的主要价值是:

  1. C/C++ 推理栈成熟,适合减少 Python、PyTorch、Transformers 等运行时依赖。
  2. GGUF 模型格式和 ggml kernel 体系适合做权重量化、CPU fallback 和跨平台部署。
  3. 可以作为 LLM Service 的本地 provider,替换 Ollama 或云端 LLM。
  4. 其多模态相关代码可以为 vision encoder、token/image adapter 的 C++ 化提供参考。

llama.cpp 本身不是完整 VLA runtime,直接迁移 SmolVLA 有几个风险:

风险影响
缺少 VLA action head 原生流程SmolVLA 的 prefix cache、cross-attention、flow/diffusion denoise loop 仍需手工实现
多模态路径主要面向 VLM,不等同于机器人 action 输出不能只把语言模型跑起来就认为 VLA 已迁移
Ascend 310B / RK3588 NPU 后端不是 llama.cpp 主线很可能只能先跑 CPU,端侧 latency 未必优于 ONNX/RKNN/OM
模型转换工作量大需要确认权重命名、tensor layout、tokenizer、image preprocessing、action normalization 全部一致
数值验收复杂必须逐层或逐阶段对齐 PyTorch/ONNX reference,不能只看最终动作能否输出

因此 llama.cpp 更适合作为底层 runtime 参考和本地 LLM provider,不建议直接作为 SmolVLA 主迁移入口。

Orange Pi / Ascend 上的 llama.cpp 相关线索

本周额外阅读了几条与 Orange Pi AIpro / Ascend NPU 上部署 Llama/ggml 相关的公开资料。只保留能从仓库或官方文档中确认的信息,结论是:这条路线可以作为 LLM provider 或 C++ runtime 参考,但不能直接证明 SmolVLA 可以低成本迁移。

来源可确认信息对当前项目的意义
lenLRX/llama_orangepi该仓库基于 Meta Llama 代码做 OrangePi 20T 推理实验;README 明确写到直接推理会 OOM,需要额外开启约 24G swap;还提到 cann_kb_init 需要用 cann_patch 替换;7B 测试结论是“仅仅是能跑”说明早期 torch_npu/PyTorch 路线依赖重、内存压力大,不适合作为低延迟常驻服务主线
Burtinsaw/GGML-CANN该仓库目标是给 ggml 添加 CANN backend,README 直接面向 OrangePi AI Pro 20T / Ascend 310B1,并给出动态 shape MatMul、CANN context、kernel bin、kernel meta、静态 buffer、backend 注册等实现说明;同时作者说明测试板 NPU health 处于 alarm,实际端到端示例只验证了 CPU fallback这是比纯 PyTorch 路线更接近我们需求的 C++/ggml/CANN 参考,但当前还不能当作“310B1 NPU 已稳定跑通 llama.cpp”的证据
llama.cpp CANN backend 文档官方 llama.cpp 已有 CANN backend,使用 AscendC/ACLNN;支持 Linux,文档列出 910B、310P 支持情况,模型格式支持 FP16/Q4_0/Q8_0;同时有 CANN memory pool、ACL graph、operator fusion、prefill graph 等环境变量对我们有参考价值,尤其是常驻内存池、ACL graph、算子融合开关;但文档中没有把 Orange Pi AIpro 20T / Ascend 310B1 列为已验证目标,因此不能直接假设可稳定复用

这里最重要的判断是:llama_orangepi 更像是“PyTorch/torch_npu 能跑通 Llama2 7B”的验证,不是轻量 C++ runtime;GGML-CANN 更接近我们想要的 C++/ggml/CANN 改造方向,但它自己也明确受 NPU health alarm 影响,尚未给出可靠的 310B1 NPU 端到端 LLM benchmark;官方 llama.cpp CANN backend 更工程化,但公开验证目标主要是 910B/310P。因此如果后续要把本地 LLM 放到 Orange Pi 上,推荐顺序是:

  1. 先在 x86 或板端 CPU 上跑通 llama.cpp GGUF 小模型,接入 LLM Service。
  2. 单独复现 GGML-CANN 的最小 ggml backend 测试,确认本机 310B1 在 NPU health 正常时能否进入 CANN backend,而不是落到 CPU fallback。
  3. 再尝试官方 llama.cppGGML_CANN=on 路线,记录能否编译、加载、生成、释放内存。
  4. 对比 CPU、CANN backend、Ollama/MindIE 的首 token、decode token/s、NPU 内存和长期稳定性。
  5. 只有在 LLM provider 稳定后,再考虑把相关 runtime 经验迁移到 VLA,而不是把 SmolVLA 直接塞进 Llama 官方 PyTorch 代码路径。

vla.cpp 调研

相比 llama.cppvla.cpp 与当前任务更贴近。它是基于 llama.cpp/ggml 的 VLA 推理 runtime,目标就是把 VLA 从 Python/PyTorch 栈迁到 C++ 推理栈中。公开 README 中已经说明支持 SmolVLA、π0、BitVLA、Evo-1、GR00T N1.x 等 VLA,并以单个 GGUF bundle 方式部署;推理时不依赖 Python 或 PyTorch。

它对当前项目有几个直接参考价值:

  1. 模型组织方式:把 vision-language prefix、cross-attention KV cache、action head 和 denoise/flow step 放进统一 runtime,而不是把每个子图拆成多个 ONNX/OM/RKNN 文件。
  2. 服务形态:提供常驻 server,一次加载模型,多次接收请求,这与我们在 310B 上想做的 resident worker 一致。
  3. 输入协议:CLI/server 接收图像、tokenized instruction、state,然后输出 action chunk;这和我们计划的 VLARequest 很接近。
  4. GGUF 打包:SmolVLA 可以转换成自包含 GGUF,便于部署、版本管理和模型文件分发。
  5. 量化路线:支持对 LM backbone weight 做 GGUF 量化,如 Q8_0、Q4_0;vision tower、norm、action expert 可以选择保留浮点,符合我们此前“activation INT8 误差大,优先 weight-only”的判断。
  6. benchmark 方式:常驻 server + client 重复请求的模式可以借鉴,用来替代当前容易受加载和资源状态影响的单次进程 benchmark。

公开 benchmark 显示,vla.cpp 的 SmolVLA 在不同平台上已经做过端侧测试,例如 RTX 3090、Jetson AGX Orin、Jetson Orin Nano、Apple M4。这个对 RK3588/Orange Pi 没有直接保证,但说明它至少比单纯 llama.cpp 更接近我们的部署问题。

vla.cpp 的主要风险

风险影响应对计划
仓库较新,接口和格式可能变化直接接主线可能频繁返工先 pin commit,做独立实验目录,不污染当前服务契约
没有 Ascend 310B / RKNN 后端可能只能跑 CPU,无法直接利用 NPU先在 x86/RK3588 CPU 跑正确性和接口,再评估 ggml 后端扩展
SmolVLA checkpoint 兼容性未知我们训练/导出的 checkpoint 可能不能直接转换先用公开 smolvla-libero GGUF smoke test,再试自有 checkpoint 转换
tokenizer 和 prompt 输入形式不同Agent 输出文本到 token ids 之间需要桥接provider 内固定 tokenizer,不把 token ids 暴露到 Agent 契约
action normalization/statistics 必须一致输出 action 可能数值对齐但物理尺度错误把 dataset statistics、action_mean/std 纳入 drift 测试
端侧 CPU latency 仍可能偏高RK3588/310B CPU 不能满足实时只把它作为 C++ 化和模型压缩方向,不替代当前 310B OM 主线

下一步计划

  1. 新增 ascend_vlaremote_vla provider 草案,但不修改 VLAExecuteRequest / VLAExecuteResponse 契约。
  2. 将 SmolVLA resident worker 包成服务模式,接收 prompt、image、state,返回 action_unnorm_7 与分段耗时。
  3. 从远端现有 /v1/executemetadata 字段接入图像/state,先完成 mock 请求到真实 worker 的闭环。
  4. vla.cpp 做最小 A/B:
    • 拉取并固定一个 commit;
    • 下载公开 SmolVLA GGUF;
    • vla-cli 单张图像 smoke test;
    • 对比输出 shape、action statistics、latency;
    • 再判断是否转换自有 checkpoint。
  5. llama.cpp 暂作为 LLM 本地 provider 和 ggml/GGUF runtime 参考,不直接承担 SmolVLA 全链路迁移。
  6. RK3588 继续用于端到端接口和硬件输入验证;若要追求实时,优先考虑模型结构压缩、prefix 蒸馏和 denoise step 减少。

参考资料

  • agent-llm-vla/docs/architecture.md
  • agent-llm-vla/docs/contracts.md
  • agent-llm-vla/docs/development_plan.md
  • /home/sakura/OrangePi/rk3588_smolvla/README.md
  • https://github.com/lenLRX/llama_orangepi
  • https://github.com/Burtinsaw/GGML-CANN
  • https://github.com/ggml-org/llama.cpp/blob/master/docs/backend/CANN.md
  • https://github.com/VinRobotics/vla.cpp
  • https://arxiv.org/abs/2606.08094

第四周(2026-07-27 ~ 2026-07-31)

本周目标

本周工作从上一周的 SG2002 ACT 非 JPU baseline 继续向三个方向收口:

  1. 评估 LicheeRV Nano / SG2002 原生 Linux 上的 JPEG 硬解码路线,判断 JPU 是否适合作为当前 ACT 输入链路的短期优化主线。
  2. 验证 C906 / SG2002 上 libjpeg-turbo 的 RISC-V 向量化可行性,明确 RVV 1.0、RVV 0.7.1 和 C fallback 的边界。
  3. 调研并验证 KWS 语音命令识别路线,为后续 Agent/VLA 的语音入口提供可部署方案。

本周没有完成 StarryOS 侧 JPU 硬解码验证,因此这里不把 StarryOS JPU 写成已跑通结果。JPU 相关结论只限于 LicheeRV Nano 原生 Linux 与参考 SDK 路线的可行性评估。

LicheeRV Nano JPU 路线评估

本周通过原生 Linux 系统和 LicheeRV Nano SDK 参考实现,重新分析了 SG2002 上 JPEG 硬解码是否适合直接接入 ACT 图像输入链路。测试和源码走读后,当前判断是:JPU 方向仍有长期价值,但不适合作为本周继续压缩 ACT 端到端时延的短期主线。

主要原因如下:

  1. SDK 示例路径不是一个轻量的“单张 JPEG 到 RGB/YUV buffer”接口,而是绑定了较完整的 CVI/JPU/VDEC buffer 管理、stream submit、frame buffer 注册和输出拷贝流程。
  2. 原生 Linux 路线中 send / stream 提交阶段开销偏大,短期内难以确认实际慢点来自硬件解码、驱动同步、buffer 管理还是用户态封装。
  3. 当前 ACT 链路只需要连续小图 JPEG 解码;如果引入完整 VDEC/VBPool/多 channel 框架,工程范围会明显扩大,且对 StarryOS 迁移帮助有限。
  4. JPU 输出通常是 YUV/planar buffer,后续仍需要颜色空间转换、resize、cache 同步和物理连续内存管理;这些开销如果处理不好,可能抵消硬解码收益。
  5. StarryOS 侧目前没有完成与 Linux 参考序列一致的硬解码验证,不能把 Linux 示例成功等价看成 StarryOS 已可用。

因此当前 JPU 结论是:保留为后续硬件输入链路优化方向,但本周不再把它作为默认性能优化主线。后续如果继续做,应先实现最小化单帧 path:固定 JPEG bitstream buffer、固定输出 buffer、复刻 Linux JPU_DecOpen -> JPU_DecGetInitialInfo -> JPU_DecRegisterFrameBuffer -> JPU_DecStartOneFrame -> wait irq/status 的寄存器序列,再与 libturbojpeg 做同图 checksum 和耗时对比。

RVV0.7 + C 加速 JPEG 解码

本周进一步验证了 libjpeg-turbo 在 C906 / SG2002 上的 RISC-V SIMD路线。结论是:不能直接使用当前上游 RVV 1.0 版本,短期可行路线是围绕 RVV 0.7.1 和 C 实现做定向移植。

RVV 1.0 直接上板失败

尝试替换较新的 libjpeg-turbo 动态库后,StarryOS 侧运行出现 IllegalInstruction。结合 C906 指令集特性判断,原因是 SG2002 的 C906 核心支持的是 RVV 0.7.1,而不是上游新版本常用的 RVV 1.0 指令编码。因此直接编译最新版 libjpeg-turbo 的 RVV 1.0 SIMD 代码不可行。

RVV rollback 风险

本周也分析了 rvv-rollback 和平头哥 GCC 10.2 工具链路线。当前判断是:

  • 如果上游 RVV 1.0 代码只使用 LMUL=1/2/4/8 这类 0.7.1 原生支持的分组,自动翻译风险较低;
  • 如果热点代码大量依赖 fractional LMUL,自动翻译会引入大量模拟和数据重排,性能可能反而低于纯 C;
  • JPEG 解码涉及 8-bit 像素、采样、IDCT、颜色转换和交错/解交错操作,不能假设自动翻译一定有收益。

因此本周选择把可持续路线收敛为:参考早期 RISC-V / C906 RVV 0.7 分支,并保留 C fallback,在热点上手工改造,而不是盲目把 RVV 1.0 整体翻译到 RVV 0.7.1。

当前实测结果

在板端部署可运行的 libturbojpeg.so.0 后,ACT 同步链路继续采用:

turbojpeg + RVV resize + CVI TPU sync

当前稳定 baseline 如下:

阶段典型耗时
JPEG decode约 8.6-9.5 ms
RVV resize/interp约 3.3-5.0 ms
fill inputs约 0.3 ms
TPU inference约 51.6 ms
postprocess约 0.2 ms
pipeline约 65 ms/frame

其中一次 20 帧测试结果为:

指标数值
avg_image_decode_ms8.647 ms
avg_resize_interp_ms4.993 ms
avg_inference_ms51.611 ms
avg_fill_inputs_ms0.334 ms
avg_postprocess_ms0.216 ms
avg_pipeline_ms65.801 ms

100 帧测试中同步路径约为 avg_eval_wall_ms=65.294 ms,异步 split 路径约为 66.585 ms,说明在当前单核 SG2002 + StarryOS 环境下,继续做 TPU submit/wait overlap 没有收益。当前非 JPU 主线应固定为 libturbojpeg + RVV + sync,后续优化空间主要来自更细的 JPEG SIMD、减少内存拷贝和降低推理频率,而不是继续扩大异步调度复杂度。

KWS 调研与验证

本周围绕“前进、后退、左转、右转”等机器人控制语音命令,完成了三类 KWS 验证:官方 Google Speech Commands 路线、中文 TTS/DS-CNN 路线、SynTTS-Commands 数据集分析。

Google Speech Commands 路线

为了避开 Sophgo TDL 旧 sound-classification enum 路线的问题,本周实现了直接使用 cviruntime 的 KWS probe。该路径在主机侧完成训练和 TPU-MLIR 转换,在板端直接加载 cvimodel 推理。

当前四方向英文模型使用:

go, backward, left, right

严格四分类模型在验证集上达到约 92.32%。板端可加载 BF16 cv181x 模型,并通过 google_kws_runtime_probe 完成 log-mel 特征和 TPU 推理。测试中 go/left/right 能正确识别,但 backward 仍容易与 right 混淆,说明该模型可作为链路验证,但还不能直接作为最终控制入口。

板端耗时上,当前 C 前端仍是主要瓶颈:

阶段典型耗时
feature init约 42 ms
log-mel feature约 143 ms
TPU inference约 0.23 ms

这说明 KWS 模型本体在 SG2002 TPU 上很轻,真正需要优化的是音频前端。后续应把当前朴素 DFT 改成 FFT/KissFFT 或复用更成熟的音频特征前端,并改成常驻进程,避免每次启动都重新加载模型。

中文 DS-CNN 路线

/home/sakura/KWS 中,本周进一步建立了中文 TTS 数据集和 DS-CNN 训练流程。当前数据配置如下:

项目配置
采样率16 kHz
输入时长1.2 s
特征40 mel bins
FFT512
window / hop25 ms / 10 ms
模型DS-CNN
参数量约 27k-28k

当前有两种标签设计:

  1. intent 八分类:forward/back/left/right/front_left/front_right/back_left/back_right
  2. text 十五分类:前进/后退/左转/右转/向前/向后/向左/向右/...

主要训练结果如下:

任务最佳 epochval acctest acc
kws_dscnn_intent_v2_small2870.56%74.44%
kws_dscnn_text_v2_small2771.11%73.33%

混淆矩阵显示,短命令之间仍有明显混淆,例如 向左 容易被预测成 右转向后 容易被预测成 向右。一次真实录音测试中,forward 被识别为 front_left,置信度约 0.741。因此当前中文 KWS 已经跑通训练、导出和测试闭环,但还不能直接用于真实控制。

SynTTS-Commands 数据集分析

本周还分析了 SynTTS-Commands-Official。该数据集对我们有架构和训练策略参考价值,但不能直接作为方向命令数据集使用。

原因是它当前公开命令集主要是媒体控制和唤醒词:

  • 中文包括:播放、暂停、上一首、下一首、音量控制、接听电话、小爱同学等;
  • 英文包括:Play、Pause、Resume、Next track、Volume up、Alexa 等;
  • 不包含 前进/后退/左转/右转 这类机器人运动命令。

它最有价值的结论是:中文 zero-shot 合成数据迁移到真实语音时召回会明显下降,而每类加入约 50 条真实样本后,真实测试效果会大幅提升。因此后续中文 KWS 不应只依赖 TTS 数据,必须采集目标麦克风、目标环境下的少量真实样本做 fine-tune。

当前结论

  1. LicheeRV Nano / SG2002 的 JPU 硬解码路线仍值得后续研究,但当前 Linux SDK 路径过重,send 和 buffer 管理开销不透明,短期不适合作为 ACT 输入链路优化主线。
  2. SG2002/C906 不能直接使用上游 RVV 1.0 libjpeg-turbo SIMD;当前应沿 RVV 0.7.1 + C 定向优化路线推进。
  3. libturbojpeg + RVV + sync 已经是当前 ACT 非 JPU 稳定 baseline,约 65 ms/frame,其中 TPU 推理约 51.6 ms,占主要部分。
  4. KWS 侧已经跑通 Google KWS、中文 TTS/DS-CNN 和板端 cviruntime probe,但真实可用性还受音频前端耗时、真实录音样本不足和短命令混淆影响。
  5. 后续若要接入 Agent/VLA,推荐优先做“常驻 KWS 进程 + 真实样本 few-shot + FFT 特征前端”,而不是先扩大模型规模。

下周计划

  1. 继续压缩 KWS 音频前端,把当前朴素 DFT 特征提取替换为 FFT 实现,并测量常驻进程下端到端延迟。
  2. 录制每类至少 50 条真实中文方向命令样本,重新训练 DS-CNN,并重点观察 前进/左转/右转/后退 的混淆矩阵。
  3. 保留 libturbojpeg + RVV + sync 作为 SG2002 ACT 默认 baseline,后续只做小范围可量化优化。
  4. 如果继续研究 JPU,先在 Linux 侧拆出单帧最小 path,再决定是否迁回 StarryOS,而不是直接移植完整 VDEC/VBPool 框架。

第五周(2026-08-03 ~ 2026-08-07)


总结:

  1. SG2002 上完成语音识别:不可行(×)

    SG2002 侧已经验证过轻量关键词识别路线,但要做完整语音识别转指令,算力、音频前端和模型部署成本都不合适,因此不作为当前主线。

  2. RK3588 上完成语音识别转指令:已验证

    当前已经能在 RK3588 上跑通语音识别链路。实际效果是,把录音切成约 2s 一段后,识别结果已经可以直接做关键词匹配,转换成“前进、后退、左转、右转”等控制指令。

    后续机器人控制部分与我无关,只需要把这一路识别输出对接给控制同学即可。

    DEMO:把控制部分对接完就有了。

  3. Ascend 310B 上语音识别转指令:SD 卡里已有流程基础,待端到端验证

    SD 卡里已经有两部分:一部分是 SenseVoice OM 模型推理,另一部分是开发板录音样例。也就是说“录音”和“模型推理”都已经有基础,下一步要把录音、特征处理、模型推理、文本解码和关键词转指令串成完整链路,并在 310B 板端验证。

下一步

  1. 验证 Ascend 310B 上录音到指令的端到端链路,并与相关人员对接语音控制。
  2. 考虑到 SmolVLA 可能已经训练完成,尝试在 Ascend 310B 上进行推理。

细节

SG2002 结论

SG2002 上之前验证过关键词识别(KWS)方向,包括中文方向命令、DS-CNN、小模型导出和板端推理。该路线适合做固定短词检测,但不适合直接承担完整 SenseVoice 这类语音识别任务。

关于 SenseVoice 是否能在 SG2002 上跑,结论是:理论上可以尝试,但不适合作为这次机器人语音控制的主线。

原因很简单:SG2002 有小型 NPU,但内存只有 256MB。SenseVoiceSmall 这类完整语音识别模型本身就很大,直接跑会把内存和工程复杂度都顶满。即使用量化模型,也还要留空间给系统、音频处理、运行时和中间结果,因此稳定性风险比较高。

网上有些“ESP32 跑 SenseVoice”的案例不能直接类比。很多案例其实是 ESP32 只负责录音,真正识别在电脑、服务器、手机或外接 NPU 上完成;还有一些只是做唤醒词或简单关键词,不是完整语音识别。SG2002 比 ESP32 更适合本地小模型推理,但仍然不适合硬跑完整 SenseVoice。

如果一定要在 SG2002 上量化 SenseVoice,推荐路线也不是直接拿普通 ONNX INT8 文件跑,而是:

  1. 固定输入长度,例如固定成 5s 或 10s 音频片段。
  2. 在板外先把音频转成模型需要的特征输入。
  3. 用 TPU-MLIR 先做 BF16 基线,确认模型能编译、能跑。
  4. 再用真实业务音频做 INT8 校准,生成 cvimodel
  5. 如果 INT8 误差太大,再把敏感层保留成 BF16。

但这条路工程量大,而且最终效果未必比 RK3588 / Ascend 310B 更好,所以本周不建议继续作为主线。

如果目标只是识别“左、右、前、后”,更推荐走小模型或模板匹配:

  1. 用“左转、右转、前进、后退、停止”这类长一点的词,不建议只用“左、右、前、后”单字。单字太短,小孩发音又不稳定,很容易误判。
  2. 如果愿意训练,就训练一个小的六分类模型:左转、右转、前进、后退、其他、静音。
  3. 如果不想训练模型,可以用录音模板匹配:每个指令录 10-30 条模板,运行时提取音频特征,和模板比相似度,足够像才触发,否则拒绝。
  4. 小孩会乱说话,所以一定要有“拒绝执行”的机制。不能让模型在所有声音里硬选一个方向。

比较稳的产品交互应该是:

按键或唤醒词启动
  -> 只在几秒内听方向指令
  -> 识别到“左转/右转/前进/后退/停止”
  -> 连续确认或置信度足够高
  -> 再执行动作

这样小孩平时乱说话、唱歌、喊叫、背景电视声,都不会轻易触发机器人动作。

最终判断:

  1. SG2002 不适合做完整 SenseVoice 语音识别。
  2. SG2002 适合做固定方向词检测。
  3. 如果不训练意图识别,最直接可用的是“录音模板匹配 + 强拒绝规则”。
  4. 如果要理解自然人话,例如“小车你往左边走一下”,那就应该交给 RK3588 / Ascend 310B / 服务器上的 ASR,而不是 SG2002 本机硬做。

因此 SG2002 不再作为完整语音识别主线。

RK3588 语音识别转指令

RK3588 上使用 SenseVoice RKNN 模型完成验证。当前已经完成:

  1. 下载并部署 SenseVoice RKNN 模型到 RK3588。
  2. 安装并验证 RKNN Runtime、ONNX Runtime、特征提取和分词依赖。
  3. 跑通离线音频识别,40s 左右样例音频可以正常输出中文文本。
  4. 增加边录音边识别脚本,使用 arecord 采集 16kHz 单声道音频。
  5. 定位并修复 ES8388 录音输入问题:真实麦克风输入在 Line2,而不是默认 Line1。
  6. 验证录音切分后可以输出短句结果,后续可直接做关键词匹配转控制指令。

目前可用脚本在 RK3588 板端:

cd ~/Sensevoice-RK3588
./setup_mic_es8388.sh 3
python3 ./live_record_asr.py --alsa-device plughw:3,0 --chunk-seconds 2 --language auto --use-itn

其中 chunk-seconds=2 时,输出粒度更接近控制指令,可直接映射:

前进 -> forward
后退 -> back
左转 -> left
右转 -> right
停止 -> stop

后续只需要把识别文本交给控制模块做关键词匹配和动作下发。

Ascend 310B 语音识别转指令

SD 卡里实际存在两类 310B 相关内容:

  1. SenseVoice OM 模型推理基准:

    /home/HwHiAiUser/voice-robot-bench/
    
  2. 录音/播音样例:

    /opt/opi_test/USBAudio/
    /opt/opi_test/audio/record.sh
    

voice-robot-bench 中已有:

benchmark_ascend_om.py
sensevoice_t100.om
speech.bin
speech_lengths.bin
language.bin
textnorm.bin

其中 benchmark_ascend_om.py 已经完成 310B 上的 OM 模型加载、输入构造和 ACL 推理:

  1. 加载 SenseVoice OM 模型。
  2. 准备 speechspeech_lengthslanguagetextnorm 输入。
  3. 通过 PyACL 调用 acl.mdl.execute 执行模型。
  4. 输出推理耗时和 NPU 内存占用。

录音侧已有两条参考:

  1. /opt/opi_test/audio/record.sh 使用 arecord 录制 48kHz PCM,并用 aplay 回放。
  2. /opt/opi_test/USBAudio/main.c 使用 FFmpeg/ALSA 从 USB 麦克风录音,生成 audio.pcm

因此 310B 上的端到端链路不是从零开始,而是需要把 SD 卡中已有的两段流程接起来:

麦克风录音
  -> 音频重采样/切片
  -> fbank/LFR/CMVN 特征
  -> speech / speech_lengths / language / textnorm 输入
  -> sensevoice_t100.om
  -> 文本解码
  -> 关键词转控制指令

当前已有模型本体推理基线:SenseVoiceSmall FP16 OM 在 310B 上单次推理约 33ms,模型本身不是瓶颈。下一步重点不是重新做模型,而是补齐录音到模型输入、模型输出到文本、文本到指令这三段胶水逻辑,并做板端真实麦克风验证。

蒋玉月 · StarryOS SG2002 TPU 推理

负责 SG2002 (LicheeRV Nano) 平台上的 StarryOS 内核移植和 YOLO TPU/NPU 硬件推理加速。

  • 内核:StarryOS (Rust 宏内核, RISC-V 64)
  • 平台:算能 SG2002 (0.5 TOPS NPU)
  • 目标:四语言 (C/C++/Python/Rust) TPU 推理 < 50ms

第 1 周(2026-07-13 ~ 2026-07-19)

蒋玉月 · StarryOS SG2002 TPU/NPU 推理加速 阶段声明:从 CPU 推理迈向四语言 TPU 硬件推理全线通过

一、本周工作总览

日期主题结果
07-13TGOSKits 环境搭建 + StarryOS 内核构建✅ 内核 13MB,含 TPU 驱动
07-14FIT image 启动机制 + SD 卡部署 + Rust TPU 上板✅ 启动成功,Rust 41ms
07-15C / C++ / Python v4 TPU 推理全线实现✅ 四语言全部通过,检出对齐
07-15性能终榜 + Benchmark 报告✅ 最高 358x 加速,产出已归档

二、关键成果

2.1 StarryOS 内核启动与四语言 TPU 推理

TGOSKits StarryOS 通过 FIT image + bootm 成功启动,/dev/cvi-tpu0 正常挂载。在此基础上,C / C++ / Python / Rust 四语言 TPU 推理全部实现并上板验证通过。

Python 侧基于 raw ctypes 桥接 libcviruntime.so,零编译依赖,纯 Python 驱动 TPU 硬件。配合 C 加速预处理(resize 2200x 加速)和 IoU NMS 后处理,v4 版本检出结果与 C++/Rust 完全对齐。

2.2 全引擎性能终榜

系统引擎语言推理耗时加速比备注
TGOSKits StarryOSTPUC39.6ms358x11KB
TGOSKits StarryOSTPUC++40.0ms355x直连 CVI_NN
TGOSKits StarryOSTPUPython40.0ms355xsg2002_tpu 包
TGOSKits StarryOSTPURust41ms346xakars-validator
Sipeed LinuxTPUPython200ms71xcvitek_tpu
StarryOS bare-metalCPUC++14.19s1x (基准)
Sipeed LinuxCPUC++14.17s1xyolo_infer_cpp
Sipeed LinuxCPUPython25.1s0.6xyolo.py

基准: C++ CPU on StarryOS bare-metal (14.19s);加速比 = 14.19s / 推理耗时

检出精度三引擎 100% 对齐:C++ / Rust / Python v4 均检出 1 框,置信度 0.969,坐标 (261, 263, 371, 377)。

2.3 Python v4 优化历程

版本Raw Forward+memcpy每图总耗时检出精度改进
v360ms1.57s❌ 11 重复
v451.6ms0.47s✅ 1 精准+NMS, +安全退出
v4+opt40ms44.5ms0.10s✅ 1 精准+Raw, +缓存

2.4 全流程耗时拆解

引擎模型加载预处理TPU Forward后处理总计
C++3375ms308ms40ms<1ms3723ms
Rust474ms41ms7ms522ms
Python v4338ms52ms68ms458ms

C++ 模型加载含文件 I/O。Rust / Python 预处理含 JPEG 解码 + resize + letterbox。 v4+opt 使用预缓存 .int8 跳过预处理,TPU Forward + memcpy 仅 44.5ms,每图总耗时约 100ms

三、产出

全部代码已提交至 ACT-Runtime

ACT-Runtime/
├── python/sg2002_tpu/    # Python TPU 包 (engine / decode / cli)
├── c/                    # C TPU 推理 (11KB)
├── cpp/                  # C++ TPU 推理 (15KB)
├── rust/                 # Rust TPU 推理 (含摄像头/检测/TPU)
├── benchmark_report.md   # 性能 Benchmark 报告
└── BUILD.md              # 交叉编译指南
  • sg2002_tpu:engine.py + decode.py + cli.py,~150 行核心代码
  • StarryOS 内核:13MB,含 TPU 驱动,SD 卡可启动
  • 四语言二进制:C (11KB) / C++ (15KB) / Python (15KB) / Rust (860KB)

四、下周计划

核心目标:端到端网球检测 → 捡起,初步调试环境搭建。

  1. 完善性能对比:多图片批量 Benchmark(avg / p95 / fps),形成完整性能报告
  2. 摄像头实时采集:V4L2 接入 + TPU 推理 pipeline 联调
  3. 机械臂控制接入:SO101 驱动适配,基础抓取动作
  4. 检测→抓取闭环:检测结果 → 坐标变换 → 机械臂指令,端到端联调

五、Python TPU 推理关键技术突破

5.1 背景

板上 Python 3.11 是 RISC-V musl 交叉编译版,无 pip、无 build 工具链,无法安装任何 Python 包,也无法编译 C 扩展。要把 Python 代码跑在 TPU 上,逐一突破了以下关卡。

5.2 突破一:Python ↔ C 库桥接

常规方案 PyBind11 / Cython 都需要交叉编译,在板上完全不可行。最终采用 raw ctypesctypes.CDLL("libcviruntime.so") 直接加载 Cvitek TPU 运行时库,零编译依赖。

RISC-V 64 + musl 上 ctypes 的 argtypes/restype 存在结构体传参 ABI 不兼容,改用 struct.unpack 手动解析 CVI_TENSOR(88 字节结构体)内存布局,安全绕过。

5.3 突破二:预处理加速 2200 倍

纯 Python 做 resize + letterbox 耗时 11 秒,完全不可接受。编写 C 加速库 preprocess_ops.so (5.8KB),双线性插值 resize + letterbox + RGB→CHW planar 转换,交叉编译为 RISC-V musl 共享库,Python 通过 ctypes 调用,耗时降至 5ms

5.4 突破三:NMS 后处理从 11 框到 1 框

v3 版本直接输出 TPU 原始结果 [1,5,8400] FP32,同一物体被检出 11 个重复框。v4 实现标准 IoU NMS(阈值 0.45):置信度过滤 → 排序 → 逐框 IoU 抑制,最终精准检出 1 框,与 C (39.6ms) / C++ (40.0ms) / Rust (41ms) 输出完全对齐。

5.5 突破四:内核启动机制

StarryOS 是 Linux-musl PIE 而非 bare-metal ELF,不能用 go 0x80200000 跳转。通过 mkimage 打包 kernel + DTB → FIT image,U-Boot bootm 启动,TPU 驱动 /dev/cvi-tpu0 正常挂载,打通最后一道系统壁垒。

5.6 结果

Python TPU Raw Forward 40.0ms(25 fps),与 C (39.6ms) / C++ (40.0ms) / Rust (41ms) 持平,瓶颈在 TPU 硬件而非 Python 解释器。含 JPEG 预处理全流程 458ms;使用预缓存 .int8 跳过预处理后,TPU Forward + memcpy 仅 44.5ms,每图总耗时约 100ms。

第 2 周(2026-07-20 ~ 2026-07-26)

蒋玉月 · StarryOS SG2002 TPU/NPU 推理加速 阶段声明:单帧推理→端到端管线→控制层迁移,进入板上闭环联调阶段

一、本周目标

对接李明涛的 UVC 驱动打通摄像头→TPU 推理全链路,参照 AKA-00 开源方案移植机器人控制层,实测对比两款模型的板上性能。

二、关键成果

2.1 管线性能演进:v2 → v7

阶段v2(基线)v5(上周)v7(当前)改善
Camera300ms189ms95ms3.2x
Preprocess235ms146ms96ms2.4x
TPU Forward51ms70ms40ms硬件极限
NMS4ms4ms2ms2x
总计590ms409ms233ms2.5x
FPS1.72.44.3

v7 相比 v2 总耗时降至 1/2.5,FPS 翻倍。主要收益来自:Camera(李明涛驱动优化 + 取帧策略改进)、Preprocess(零拷贝 + 浮点直写 TPU buffer)、NMS(C 实现精简)。

2.2 李明涛:StarryOS USB UVC 驱动

在 tgoskits 上合入了 UVC 驱动的核心模块:

  • uvc 驱动:uvc_camera.rs,含 YUYV 格式支持和 DWC2 USB Host 初始化
  • V4L2 框架:按 Linux include/uapi 实现设备节点层,/dev/video0 正常挂载
  • vivid 虚拟驱动重构至 drivers/media/vivid/
  • 用户态工具 v4l2-test:v4l2-ctl 交叉编译 + 3 个 V4L2 采集/测试程序,run.sh 一键 build/deploy/sdcard

当前 Camera 取帧已从最初 300ms 优化至 95ms(v7),对比 Linux 端 10ms 仍有差距,驱动层持续优化中。

2.3 AKA-00 机器人参考架构分析

深度分析了 chenlongos/AKA-00 的完整技术栈:

  • 硬件架构:SG2002 + ESP32-C3(底盘 PWM PID) + ZP10S/STS3215 舵机(UART)
  • 控制算法:5 状态 FSM(chase→position→grab→bucket→release)+ P 比例差速控制
  • 通信协议:ESP32 UART 帧协议(0xAA 0x55 + checksum),ZP10S ASCII 协议
  • Web 前端:React + TypeScript,支持方向键/RC 摇杆/重力感应/模型商店

2.4 控制算法迁移

将 AKA-00 控制算法迁移至 StarryOS,新增文件:

pipeline/
├── state_machine.py   # 5状态FSM + PID差速控制
├── motor_driver.py    # ESP32 UART协议 (Mock + TtPid)
├── servo_driver.py    # ZP10S / STS3215 舵机
├── hunter.py          # 主控循环(TPU推理→状态机→PID→电机)
├── web_server.py      # 内置Web遥控(纯Python,零外部依赖)
├── terminal_debug.py  # 终端可视化调试
└── robot.py           # 统一入口(debug/mock/web/run/test 五命令)

PC mock 验证:5 状态全通,PID 差速输出正确,10 帧确认抓取机制正常。

2.5 板上模型对比

AKA-00 Linux 系统上,两款 cvimodel 各跑 200 次 TPU Forward:

V2        avg=39.6ms  p50=39.5ms  min=39.5ms
AKA-00    avg=188.5ms  p50=188.4ms  min=188.3ms
模型Forward内存占用Anchors检出置信度
V239.6ms2.2MB8,4000.95-0.97
AKA-00188.5ms10.7MB27,6000.85

V2 快 4.8 倍,因为 anchor 数为 AKA-00 的 1/3,推理负载更低。注意此对比使用的是 AKA-00 自带的 cvimodel(27,600 anchors),与 2.6 节中在 Linux 端运行 V2 模型(40ms)不是同一个模型。检出置信度更高得益于 YUYV native 路径(无 OpenCV JPEG 压缩损失)。

2.6 StarryOS v7 vs AKA-00 Linux

阶段StarryOS v7AKA-00 Linux备注
Camera95ms10msLinux UVC 驱动更成熟
Preprocess96ms120msC 零拷贝 vs OpenCV
TPU Forward40ms40msTPU 硬件,与 OS 无关
NMS2ms4ms
总计233ms174ms差距 1.3x
FPS4.35.7

关于 StarryOS vs Linux 速度对比的更正:此前曾表述 “StarryOS TPU 推理比 Linux 快”,该结论存在误导。本周在 AKA-00 Linux 板上实测验证后发现:

  • TPU 纯 Forward 耗时与 OS 无关。同一模型(V2 cvimodel)在 StarryOS 和 AKA-00 Linux 上均为 40ms。TPU 是独立硬件加速器,推理速度由模型结构决定,不受 Host OS 影响。
  • 此前 Linux 端 200ms 的数据来自 Sipeed Buildroot + cvitek_tpu SDK 旧版本,差距源于 SDK 调用链路。
  • StarryOS 端 Camera 95ms 对比 Linux 端 10ms,是当前总耗时差距(1.3x)的唯一来源。Preprocess 和 NMS 环节 StarryOS 反超。

2.7 预处理优化历程

版本方案PreTPUFPS关键改进
v2malloc 分离版235ms51ms1.7基线
v5浮点 + 直写 TPU146ms70ms2.4零拷贝写入 TPU buffer
v7零拷贝 + 精简路径96ms40ms4.3消除中间 buffer + NMS 精简

三、产出

全部代码位于 ACT-Runtime

pipeline/
├── state_machine.py   # 5状态FSM + PID差速控制
├── motor_driver.py    # ESP32 UART协议 (Mock + TtPid)
├── servo_driver.py    # ZP10S / STS3215 舵机
├── hunter.py          # 主控循环(TPU推理→状态机→PID→电机)
├── web_server.py      # 内置Web遥控(纯Python)
├── terminal_debug.py  # 终端可视化调试
└── robot.py           # 统一入口(debug/mock/web/run/test 五命令)

board_tools/
├── model_compare.py   # 双模型对比脚本
└── collect_data.py    # 数据采集脚本

dataset/
├── images_png/        # 202张待标注PNG(50MB)
└── images_yuv/        # 原始YUYV帧(119MB)

四、下周计划

  1. 跟进 DQBUF 驱动优化,StarOS 端到端闭环上线,目标 5fps
  2. 接入 ESP32 电机 + 舵机真实硬件,验证状态机 + PID 控制

第 3 周(2026-07-27 ~ 2026-08-01)

蒋玉月 · StarryOS SG2002 TPU/NPU 推理加速 阶段声明:控制层落地 + 真机联调,管线突破 5fps,电机遭遇环境差异卡点

一、本周目标

  1. 跟进李明涛 DQBUF 驱动优化,端到端闭环上线,目标 5fps
  2. 接入 ESP32 电机 + 舵机真实硬件,验证状态机 + PID 控制
  3. 板上实测全链路:Camera → TPU 检测 → 运动控制 → 夹取

二、关键成果

2.1 管线性能:v7 → v8,突破 5fps

指标v7(上周)v8(本周)变化
TPU Forward40ms52ms慢 12ms
整管线延迟233ms~183ms快 21%
稳态帧率4.3 fps5.2-5.5 fps+22%
检测置信度0.50-0.79

达成上周 5fps 目标。Camera 从之前的 isochronous 传输秒挂到稳定 100ms 出帧,Preprocess 和 NMS 沿用 C 后端零拷贝路径。

2.2 李明涛:CrabUsb 架构升级

本周李明涛完成了 StarryOS USB 栈的重大架构变更:

旧: StarryOS usbfs(中断已占用) ✗ sg200x-bsp → 中断冲突 → 轮询超时 255ms
新: StarryOS usbfs(事件循环)   ✓ CrabUsb    → 合法注册中断 → 100ms 稳定

效果:CrabUsb 与内核 USB 栈共享同一中断体系,不再是“绕过“而是“融入“。Camera 取帧从之前偶尔 255ms 空转变为稳定均匀的 100ms。下一步优化方向:usbfs 事件循环中给 UVC 开低延迟通道(中断直通 + buffer 预分配),目标从 100ms → 接近 Linux 10ms。

内核版本演进:

版本日期大小说明
boot.sd.old_202607217/2112.5 MiB原始版本
boot.sd.old_202607277/2212.85 MiB第一次更新
boot.sd (当前)7/2512.78 MiB李明涛最新

v4l2-test 工具链就绪:1.tpg_check / 2.camera / 2.parser / 3.speed / capture,均 ~30KB 静态编译。

2.3 AKA-00 控制接口挖掘与真机驱动

chenlongos/AKA-00 仓库挖出完整硬件控制链:

SG2002
  ├── /dev/ttyS1 (UART1, 115200) → ESP32-C3 → DRV8833 → N20 TT马达×2
  │    协议: 0xAA 0x55 <cmd> <len> <payload> <chk>
  │
  └── /dev/ttyS2 (UART2, 115200) → 微雪控制板 → ZP10S舵机×3
       协议: #<id>P<pulse>T<time>!

确认 StarryOS 板端 /dev/ttyS0/1/2/3 全部存在,驱动可用。

2.4 全自动追球管线 (real_pipeline.py)

实现完整状态机:

Camera(100ms) → Preprocess(C) → TPU(52ms) → NMS(C)
  → 无目标: 原地右转搜索
  → 球远(far): 快速前进 + 方向修正
  → 球中(mid): 慢速接近 + 方向修正
  → 球近(near): 停车 → 舵机夹取

2.5 板上实测

模块状态说明
环境内核/串口/Python/C 库/模型全部就位
Camera首日 isochronous 秒挂,CrabUsb 新内核后稳定 100ms 出帧
TPU~52ms Forward,检出置信度 0.50-0.79
控制逻辑GRAB/SEARCH 状态机自动切换正常
Servo 舵机设备在位,未实测夹取
Motor 电机🔴handshake 通过但轮子不转(见 2.6)
WiFiN24250 模块未接线

2.6 Motor — 本周最大卡点(环境差异)

  • TtPidDriver 协议握手返回 OK,但电机不转
  • 定位到软件 bug:raw I/O fallback 路径 _send_cmd 调用 reset_input_buffer(),此方法在 file object 上不存在,AttributeErrorexcept: pass 静默吞掉 → 数据从未发出
  • 串口波特率默认 38400,需 stty -F /dev/ttyS1 115200 修正
  • 关键发现:同一份 motor_driver.py 代码在李明涛的板子上电机正常转动,用户板子只 handshake 通过但轮子不动 → 驱动逻辑本身正确,问题在板端环境差异
  • 待排查:两边内核版本、串口驱动行为、电平/接线、ESP32-C3 固件版本差异

三、产出

类型内容
代码real_pipeline.py — 真机主程序:Camera→TPU→追球→夹取 全自动
代码motor_driver.py — ESP32-C3 电机 UART 驱动(Mock + Real 双模式)
代码servo_driver.py — ZP10S/STS3215 舵机 UART 驱动(Mock + Real 双模式)
文档REAL_MACHINE_GUIDE.md — 完整操作指南(接线/测试/故障排查)
GitHubjiangyuyue111/sg2002_yolo_inference — 初始提交(86 文件 + 贡献者说明)
ACT-Runtimechenlongos/ACT-Runtime — CrabUsb + Isoch 架构升级 + 性能数据更新
SD 卡全部 pipeline 文件 + 指南已部署到 ext4 分区

四、下周计划

  1. 🔴 电机环境差异排查(最高优先):逐项对比两边内核版本、串口驱动、ESP32-C3 固件,必要时直接裸协议 echo/dev/ttyS1 排除 Python 层干扰
  2. 🟡 舵机夹取实测:验证 ZP10S 夹爪完整抓球动作闭环
  3. 🟡 pyserial 迁移:替换 raw file I/O fallback,消除 PYTHONPATH 手动设置
  4. 🟡 WiFi 模块接入:焊接 N24250 模块,实现无线调试/控制
  5. Camera 性能优化:配合李明涛 usbfs 低延迟通道方案,目标 100ms → 接近 Linux 10ms

第4周 (2026-08-03 ~ 2026-08-07)

本周工作

1. SG2002 UART1/2 回环失败 — 时钟根因定位与修复

问题:UART1 (/dev/ttyS1) 和 UART2 (/dev/ttyS2) 回环测试,TX 发送 35 字节成功,RX 收到 0 字节。短接 A18/A19 已确认物理层连通。

根因

  • CLKGEN 的 CLK_EN_1 寄存器(offset 0x004)中 UART1/2 的 core clock 和 APB clock 未显式使能
  • RSTC 的 SOFT_RSTN_0(offset 0x000)中 UART1/2 复位位未释放
  • UART0 由 U-Boot 初始化所以正常工作,UART1/2 在内核里无人管

修复api/src/vfs/dev/tty_serial.rs):

  • 添加 CLKGEN_BASE (0x03002000) 和 RSTC_BASE (0x03003000) 常量
  • 添加 enable_uart1_clock_and_reset()enable_uart2_clock_and_reset() 函数
  • new_tty_s1()new_tty_s2() 开头调用
  • 编译通过(Rust nightly-2026-01-01, riscv64gc-unknown-none-elf),生成 boot.sd (1.55MB)

2. cpumask panic 修复

现象:板子启动后立即 panic:

panicked at cpumask-0.1.0/src/lib.rs:124:9:
assertion failed: index < SIZE

根因

  • axplat-riscv64-sg2002/src/init.rsaxplat::percpu::init_primary(0) 曾被注释掉
  • per-CPU 区域未初始化 → this_cpu_id() 返回垃圾值 → cpumask::CpuMask::one_shot() 硬断言失败
  • cpumask crate 更新后暴露了此问题(用的是硬断言 assert! 而非 debug_assert!,release 也会触发)

修复:取消注释 init_primary(0),重新编译。

3. 版本管理 — boot.sd 部署状态

修复版与旧版对比:

版本编译时间大小MD5状态
boot.sd(SD卡当前)8/6 11:481,549,772f45b0c8c...❌ 有 cpumask panic
boot.sd.v2(修复版)8/6 12:371,549,780b6909a12...✅ 待部署

SD 卡文件已整理备份,部署命令已准备:

sudo cp /mnt/sde1/boot.sd /mnt/sde1/boot.sd.bak_20260807
sudo cp /home/jiangyuyue/boot.sd.v2 /mnt/sde1/boot.sd
sync

4. 电机调试进展

  • PC 端 ESP32 直连验证:26/26 协议测试全部通过
    • INIT/CONFIG/SET_SPEED/STOP/BRAKE/RESET 全通
    • 编码器计数、ISR 触发、RPM 均正常
  • 结论:ESP32 固件 100% 正常,问题在 SG2002 ↔ ESP32 的 UART 通信链路

5. Windows 平台适配

  • motor_debug.py 双平台重写(pyserial + termios 兜底)
  • motor_driver.py Windows 适配完成
  • uart_loopback.py 板端回环诊断脚本新增

当前状态总览

组件PC端SG2002板端
ESP32 + 电机✅ 26/26 全通🔴 UART 待验证
UART 时钟修复🔴 已改待测
cpumask panic🔴 修复版待部署
TPU 管线✅ 5.2fps
Camera✅ 100ms 稳定
Servo✅ 驱动就绪

下周计划

  • SD 卡部署 boot.sd.v2,验证 cpumask panic 已修复
  • 短接 A18/A19 跑 UART1/2 回环测试,确认时钟修复生效
  • 回环通过后接回 ESP32 验证电机通信
  • 全管线联调(Camera → TPU → 电机/舵机)

第5周 (2026-08-10 ~ 2026-08-14)

SG2002 项目背景

基于算能 SG2002(LicheeRV Nano)+ StarryOS 搭建网球抓取机器人,目标实现「摄像头视觉识别网球 → 电机追球 → 舵机夹取」的自动抓球闭环。前几周已完成 StarryOS 移植、TPU 四语言推理、yolov8n_tennis 检测管线(5.2 fps)、CrabUsb 摄像头等时传输。本周任务是打通电机、舵机、摄像头三条底层链路。

本周工作目标

  1. 打通 UART1 电机链路(追球移动)
  2. 打通 UART2 舵机链路(夹爪夹取)
  3. 修复 USB 摄像头 /dev/video0 缺失,恢复视觉管线
  4. 调研板载 WiFi 联网方案

本周工作内容

1. UART1 电机通信打通

定位 SG2002 ↔ ESP32「零数据」的 4 个根因并修复:内核缺 CLKGEN 时钟使能、RSTC 复位释放、IOBLK 上拉,加 pinmux 0x68=6 遗漏(UART1_RX 寄存器从未配置)。结果 motor_debug.py 15/15 通过、轮子实际转动,08-13 复测通过。

2. UART2 舵机通信打通

纠正 pinmux 误判(舵机接 A28/A29=IIC0 → 0x70/0x74=2);真正卡点是波特率(StarryOS 默认 38400 vs 舵机 115200)。08-14 复测通过、舵机转动;定位偶发不转为释力态(需 #000PULR!),角度映射待校准。

3. UVC 摄像头修复 + 管线联调

/dev/video0 缺失三重根因:错用源码树、缺 sg2002-v4l2 feature、缺 sg2002-dwc2 主机驱动(真正元凶)。修复后 /dev/video0 注册成功,real_pipeline.py 端到端 5.0 fps,检测触发 GRAB/SEARCH 切换。

4. WiFi 方案调研

板载模组为 AIC8800D(SDIO),StarryOS 无法驱动;定 ESP32-C3 中继方案(复用 UART1)。

本周工作产出

模块产出状态
电机(UART1)15/15 通过,轮子转
舵机(UART2)舵机转动(角度待校准)
摄像头 + 管线5.0 fps,检测触发状态机切换
WiFi 方案ESP32-C3 中继确定

三条链路各自打通,端到端自主抓球闭环尚未串起。

下周计划

  1. 端到端自主抓球闭环(识别 → 追球 → 夹取)
  2. 舵机夹爪角度校准 + 管线加 #000PULR! 防御释力态
  3. ESP32-C3 遥控架构确定
  4. 修复重复运行内存泄漏 panic

第6周 (2026-08-17 ~ 2026-08-23)

本周工作目标

  1. 端到端自主抓球闭环(识别 → 追球 → 夹取)
  2. 舵机夹爪角度校准
  3. 追球运动控制调优
  4. 相机挂死问题收口,完成工作交接

本周工作内容

1. 抓球闭环联调(08-18)

  • 修复舵机角度量程 bug(_angle_to_pulse 270°→180°,90° 输出 1500 而非 1166)
  • 实测夹爪行程(全闭 1462 ~ 全开 2023 脉冲)并校准角度
  • 补抓球多步序列 + GRAB 保持逻辑(夹住后不因检测丢失松爪)
  • 定位串口两坑:T 时间字段必须 4 位(T1000 才生效);夹爪线插反会短路单线总线

2. 追球跑通(08-20)

  • 电机方向映射最终定论:arg1=左轮、正值=前进(三组客观数据交叉验证唯一解,排除视角陷阱)
  • 真机追球验证:车朝球开、球 size 放大 4 倍到 near 停车
  • 降转向增益(0.08/0.10→0.05/0.06)消除逼近时蛇形摆动

3. 相机挂死收口(08-21)

  • 真机定论:UVC DMA 挂死为内核态(DWC2),用户态重启子进程不可恢复
  • 管道读取模式定论:select 对 pipe 不生效,唯一实时读法为朴素阻塞读(4.2fps)
  • PC 端加挂死检测(电机看门狗 + 静默超时),提示断电重启,用户态不再自恢复

4. 交接整理(08-21)

  • 撰写 docs/HANDOVER.md,把用户态管线现状、内核侧依赖、铁律、待办交接给李明涛
  • 仓库重组为 3 个(真机管线 / tpu_runtime / starryos_experiments),统一 CHANGELOG
  • 输出 REPRODUCE.md 复现指南,复现资产 9/9 全部发布到 GitHub

本周工作成果

模块产出状态
抓球闭环舵机量程修复 + 夹爪校准 + 多步抓取序列
追球电机映射定论,真机追球跑通,降增益消摆动
相机挂死根因定论 + PC 端检测提示断电
交接HANDOVER 文档 + 3 仓库重组 + 复现指南发布

第7周 (2026-08-24 ~ 2026-08-30)

本周工作目标

  1. TinyNav (ESP32-P4) 小车从串口调试迈向无线遥控
  2. 打通 WiFi 链路(微雪 C6 协处理器),实现手机网页遥控
  3. 解决 P4 PWM 外设失效问题,让速度可调

本周工作内容

1. 手机网页遥控全功能跑通(08-27)

手机连热点 TinyNav-Car → 浏览器打开遥控页 → 前进/后退/左转/右转/停车 5 键 + 速度滑块,模式 4 默认开机即遥控。全链路为 SoftAP + HTTP 网页 → 指令解析 → GPIO 电机驱动 → 软件 PWM 调速,速度滑块已实测生效(20 档,5% 分辨率)。

2. WiFi 后端选型:esp_hosted,不是 ePPP(本周最大弯路)

  • 根因:微雪 C6 出厂固件是 ESP-Hosted slave,不是 ePPP 标准固件
  • ePPP 方案在 sdmmc_card_init 处失败;改用 esp_hosted(esp_wifi_remote + esp_hosted ≥2.12)后 WiFi 一次通过
  • 架构级取舍而非补丁:P4 只有一条 SDMMC,SD 卡与 WiFi 无法共存。web 模式(mode=4)跳过 SD 卡 + 深度相机初始化,把 SDMMC 让给 SDIO 连 C6

3. P4 PWM 外设失效 → 软件 PWM 绕行

  • 现象:MCPWM、LEDC 在 IDF v6.0 下配置正确但不输出 PWM
  • 根因未深挖,采用绕行方案:电机改 GPIO 直接驱动 + esp_timer 50us 回调软 PWM(1kHz)
  • 复用价值:外设失效时,软件定时器 PWM 是低成本兜底,且档位、频率都可改

4. 工具链与环境(08-25)

  • 串口模式切换 + serial monitor 工具 + 串口输出指南,方便无屏调试
  • ESP_IDF_VERSION 必须精确等于 "6.0"(不带 patch),否则组件 Kconfig 加载错误文件,WIFI_RMT_* 配置缺失
  • IDF v6.0 不支持中文路径(cmake 栈溢出崩溃),工程由 C:\Users\蒋玉月\TinyNav 迁至 D:\TinyNav

本周工作成果

模块产出状态
网页遥控SoftAP + HTTP 5键 + 速度滑块,mode=4 默认开机
WiFi 后端esp_hosted 方案跑通(C6 为 ESP-Hosted slave)
电机调速软件 PWM 1kHz 调速生效
环境工具串口模式切换工具 + D:\TinyNav 迁移 + IDF v6.0

当前状态与下周计划

当前状态:无线网页遥控全功能可用;web 模式为让出 SDMMC 旁路了 SD 卡与深度相机(AI 模式暂不可用)。

已知问题

  • 小车刚接电源的瞬间会自己乱跑(疑似 GPIO 默认电平 / 电机驱动初始化时序问题,尚未定位)——上电安全存在隐患
  • MCPWM/LEDC 外设失效根因未深挖

下周计划

  1. 排查上电瞬间电机乱跑:检查 GPIO 默认态与初始化顺序,确保上电即停机态,消除安全隐患
  2. 恢复 AI 模式:SD 卡改 SDSPI 释放 SDMMC(或明确接受 SD/WiFi 二选一)
  3. 软件 PWM 档位细化(当前 20 档)

杨铮

Octos 任务编排层 / 最小工具闭环验证 / 轮足双臂技能接口前置调研

基本信息

内容
姓名杨铮
方向Octos 编排层、任务分解、技能调用、状态监听、重试闭环
项目嘲风轮足双臂机器人
当前阶段阶段 1:Octos 最小 demo 跑通与技能接口前置规范
验证工作区/Users/ken/robot-octos-demo
归档目录docs/src/yangzheng/
周期2026-07 ~ 2027-02

文档入口

最新进展

截至 2026-07-19:

  1. 已确认 octos 2.0.0 可在本机运行,并完成本地技能 robot-pick-skill 的发现与直接调用验证;
  2. 已在 /Users/ken/robot-octos-demo 内完成一次真实 octos chat 工具闭环,模型可把中文请求路由到 pick_object
  3. 已确认 demo 工作区不是顶层 Git 仓库,而是“系统 Octos + 本地 skill + 嵌套上游源码副本”的混合形态;
  4. 已在 octos-src 内完成 cargo check --locked -p octos-cli 静态构建检查;
  5. 已识别当前最主要的工程问题是项目级 data-dir 与全局 provider 配置继承关系不稳定。

当前判断

当前已验证的是 Octos 编排最小闭环,不是轮足真机移动、操作或视觉判定闭环。下一步应该把这次最小 demo 的成功路径抽象成三类接口需求:

  • 移动技能接口;
  • 操作技能接口;
  • 复合任务接口。

在接口稳定前,不应直接把 demo 成功等同于真机编排已完成。

第 2 周(2026-07-14 ~ 2026-07-19)

杨铮 · Octos 任务编排层 / 最小工具闭环验证 阶段声明:先跑通 Octos 最小 demo,再向移动 / 操作 / 复合任务接口规范收口

一、本周工作总览

日期主题结果
07-19验收目录与项目形态核查已完成
07-19本地 skill robot-pick-skill 直接执行验证已完成
07-19octos chat 中文请求到 pick_object 的真实闭环验证已完成
07-19octos-srcoctos-cli 构建检查已完成
07-19运行问题归因与下一步接口收敛已完成

二、关键成果

2.1 最小 Octos demo 已跑通

/Users/ken/robot-octos-demo 中,已经完成以下闭环:

中文自然语言请求
→ octos chat
→ 模型选择 pick_object
→ 本地 skill 执行
→ 工具结果返回
→ 自然语言答复

成功案例中,用户请求“帮我把球捡起来,在地上”,系统实际调用了:

pick_object(object="球", location="地上")

最终返回“已经帮你把球从地上捡起来了!”。

2.2 项目形态已核清

本次用于验证的工作区不是单一 Rust 工程,而是:

  • 顶层 demo 目录 /Users/ken/robot-octos-demo
  • 顶层本地技能目录 .octos/skills/robot-pick-skill
  • 系统已安装的 octos 2.0.0
  • 嵌套上游源码副本 /Users/ken/robot-octos-demo/octos-src

这意味着当前阶段的主要运行路径是:

系统 Octos
+ 项目内本地 skill
+ 项目内 data-dir / config

而不是先在顶层 demo 目录重新构建一个全新的 octos 二进制。

2.3 源码级检查通过

octos-src 中已执行:

cargo check --locked -p octos-cli

最终输出:

Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 03s

这说明当前附带的上游源码副本至少在 octos-cli 维度能够完成静态构建检查。

三、问题与判断

3.1 当前主要问题不是技能失效,而是配置继承

octos chat 使用项目内新的 --data-dir 运行时,第一次验证失败,错误为:

no LLM provider configured

在显式追加:

--config "$HOME/.config/octos/config.json"

之后,闭环验证成功。

当前更合理的判断是:

  • 问题点在项目级运行态没有稳定继承全局 provider 配置;
  • 问题点不在 robot-pick-skill 本身;
  • 问题点也不在 octos chat 基本调用链路。

3.2 运行告警说明后续工程化仍需补齐

成功运行时仍出现以下告警:

  • legacy global skill directory is no longer scanned;
  • local plugin manifest 缺少 sha256,被标记为 unverified plugin;
  • tool count 较高,可能影响部分模型稳定性。

这些问题没有阻止本周 demo 成功,但都属于后续如果要把 demo 演化成长期维护项目时必须处理的工程化项。

四、对杨铮阶段任务的意义

这次验证已经足够支撑阶段 1 的前半部分:

  • Octos 部署与最小工具调用 demo 已跑通;
  • LLM 可以完成“中文请求 -> 本地技能调用”的基本编排;
  • 可以开始从 demo 成功路径抽象技能接口规范。

当前还没有直接完成的内容是:

  • 移动命令颗粒度定义;
  • 移动结果字段设计;
  • 坐标系约定;
  • 操作技能与复合任务统一 schema。

因此,下一步不应继续重复做“能不能跑通 Octos”,而应转向接口定义与替换路径设计。

五、下周计划

  1. 以当前 pick_object demo 为基线,整理移动 / 操作 / 复合任务三类技能 schema 草案;
  2. 补一份“项目级 data-dir / profile / provider 继承关系”运行说明,减少重复踩坑;
  3. 评估本地 skill manifest 中 sha256、校验与 profile 级安装方式;
  4. 把 mock skill 的成功路径抽象成未来真实 VLA / 机器人技能的统一输入输出契约;
  5. 对接阶段 2 所需的 planner 形态,明确是单次 function-call 序列还是状态机驱动重规划。

六、证据位置

  • /Users/ken/robot-octos-demo/reports/evidence/project-initial-audit.txt
  • /Users/ken/robot-octos-demo/reports/evidence/environment.txt
  • /Users/ken/robot-octos-demo/reports/evidence/octos-chat-robot-pick.txt
  • /Users/ken/robot-octos-demo/reports/evidence/octos-chat-robot-pick-config.txt
  • /Users/ken/robot-octos-demo/reports/evidence/cargo-check-octos-cli.txt

01 · Octos 最小工具闭环与目录验收

日期:2026-07-19

一、背景

本轮工作的目标不是直接验证真机动作,而是为“杨铮负责的 Octos 编排层”先拿到一个可信的最小成功样本:确认 Octos 可以在本机跑通一次从中文请求到本地工具调用的真实闭环,并梳理这个 demo 对后续技能接口设计的意义。

本次实际验收工作区为:

/Users/ken/robot-octos-demo

最终归档目录位于:

/Users/ken/chaofeng/docs/src/yangzheng/

二、核查过程

1. 先确认项目形态

核查后确认:

  • /Users/ken/robot-octos-demo 顶层不是 Git 仓库;
  • 顶层存在本地技能目录 .octos/skills/robot-pick-skill
  • 系统安装了 octos 2.0.0,命令位于 /opt/homebrew/bin/octos
  • 顶层还附带嵌套源码副本 octos-src

这说明它是一个“系统 Octos + 本地 skill + 嵌套源码”的 demo 验收目录。

2. 先验证技能入口本身

直接执行:

printf '{"object":"ball","location":"floor"}' | skills/robot-pick-skill/main pick_object

返回:

success: true
Simulated robot successfully picked up ball from floor.

因此可以先排除“技能入口脚本损坏”的可能。

3. 再验证真实 octos chat

第一次在项目内使用新的 --data-dir 运行 octos chat 时,遇到错误:

no LLM provider configured

随后显式追加:

--config "$HOME/.config/octos/config.json"

第二次运行成功,模型调用了:

pick_object(object="球", location="地上")

最终返回中文答复“已经帮你把球从地上捡起来了!”。

4. 最后补一层源码检查

octos-src 中执行:

cargo check --locked -p octos-cli

检查通过,说明 demo 附带的上游源码副本至少在 octos-cli 维度是可构建的。

三、当前结论

1. 这次成功说明了什么

已经可以确认:

  • 本机 Octos 环境可用;
  • 本地 skill 发现机制可用;
  • 中文自然语言到本地工具的最小闭环可用;
  • 这个 demo 可以作为后续接口规范设计的起点。

2. 这次成功不说明什么

仍不能据此宣称:

  • 真机移动编排已经完成;
  • 真实 VLA 推理已经接入;
  • 视觉判定与重试闭环已经完成;
  • 复合任务 planner 已经稳定可用。

这次只是把“编排能不能起得来”这件事先做实了。

四、对后续工作的直接影响

后续更值得推进的方向有三项:

  1. pick_object 这种最小 schema 出发,设计移动 / 操作 / 复合任务三类接口;
  2. 规范项目级 data-dirconfig、profile 和 skill 安装关系;
  3. 为未来 mock -> 仿真 -> 真机替换保留统一的工具输入输出契约。

五、相关证据

  • /Users/ken/robot-octos-demo/reports/evidence/environment.txt
  • /Users/ken/robot-octos-demo/reports/evidence/project-initial-audit.txt
  • /Users/ken/robot-octos-demo/reports/evidence/octos-chat-robot-pick-config.txt
  • /Users/ken/robot-octos-demo/reports/evidence/cargo-check-octos-cli.txt