RISC-V能不能跑机器人?——基于VisionFive 2、YOLOE、视觉闭环、Agent API与MCP的机械臂工程实践(含核心代码)

在 RISC-V 上做一套能真正抓东西的视觉机械臂

基于 VisionFive 2、YOLOE、视觉闭环、Agent API 与 MCP 的机械臂工程实践。

一块 RISC-V 开发板,加上一只 USB 摄像头和一套普通六舵机机械臂,能不能真正完成“看到目标—跟踪—接近—抓取”这一整套流程?这次我尝试把视觉识别、闭环控制、Agent API、MCP 和自然语言交互串到一起,看看它能不能从“识别到目标”真正走到“把东西抓起来”。
系统的目标很直接:让机械臂通过摄像头自己找到桌面上的物体,持续跟踪目标,移动到合适的位置完成抓取,再把物体搬到指定位置。除了直接运行程序之外,系统还接入了 Agent API、MCP 和 Telegram,可以把自然语言任务转换成受限制的机械臂动作
真正花时间的地方不是让舵机转起来,而是把视觉、目标跟踪、网络推理和机械动作放到同一条闭环里。摄像头安装在机械臂上,机械臂一动,视角也跟着变;目标可能移动、短暂消失,也可能在最后几厘米突然离开画面。所以整套系统没有依赖一次定位后直接执行,而是尽量保持“移动一点、重新观察、再决定下一步”的节奏。
  识别目标 → 持续跟踪 → 调整方向 → 分阶段接近
       → 近距离确认 → 抓取 → 抬升 → 搬运 / 放置

先上DEMO视频:


一、整套系统用了什么

控使用 StarFive VisionFive 2,搭载赛昉 JH7110 RISC-V SoC,板端运行 Ubuntu 24.04。摄像头使用 Logitech C270,通过 USB 接入;机械臂是一套六舵机结构,通过 CH340 串口适配器连接控制板。

另外还有一台 Windows 主机,主要承担计算量更大的目标识别,以及 Telegram 和大语言模型相关的上层交互。VisionFive 2 则保留所有真实硬件资源和物理动作:摄像头、串口、任务状态、视觉闭环和机械臂控制都在板端统一管理。

Windows 主机
├─ YOLOE 目标识别
├─ Telegram / LLM
└─ MCP Client
        │  局域网
        ▼
VisionFive 2
├─ Robot Agent API
├─ RobotSession
├─ Vision / PracticalFSM
└─ ArmDriver → CH340 → 六舵机机械臂
这样的分工没有刻意追求“所有东西都必须在 RISC-V 板子上跑”。对机器人来说,更重要的是实时控制链路是否稳定,以及模型结果回来以后还能不能反映当前画面。板端负责闭环,计算量较大的识别放到主机上,两边通过局域网协作。


二、视觉识别分成两条路线

目前感知链路分成两种。对于已经校准好的颜色目标,例如红色、蓝色、绿色等方块,直接在 VisionFive 2 上使用 HSV 颜色空间分割,再经过轮廓过滤得到目标中心位置。这个路径不依赖外部模型,延迟低,也比较适合桌面彩色方块。
如果目标不能通过固定颜色描述,就走外部 YOLOE。板端把当前摄像头帧压成 JPEG,通过客户端发送给 Windows 主机上的检测服务,返回检测结果后再转换成统一的 TargetObservation,供后面的 TRACK 和 APPROACH 使用。
已校准颜色 → 板端 HSV → TargetObservation
普通目标 → Windows YOLOE → TargetObservation
                                                       ↓
                                                 统一控制器
控制器真正关心的并不是模型用了什么,而是当前目标在图像中的 cx、cy、面积、置信度以及和机械臂控制有关的观测信息。这样感知路径可以替换,后面的机械控制不用跟着重写。


三、机械臂不是执行一段脚本,而是在不断重新看目标

自动抓取由 PracticalFSM 管理,主要状态是 SEARCH、TRACK、APPROACH、GRAB 和 MANUAL_PLACE。每个状态只负责一类动作,状态之间根据最新视觉观测和运行状态切换。
SEARCH → TRACK → APPROACH → GRAB → MANUAL_PLACE
SEARCH:先把目标找出来
SEARCH 主要控制底座转动,在设定的命令范围内扫描。如果当前画面没有目标,就按固定步长继续搜索;到达边界后再反向。检测到目标以后立即切换到 TRACK,而不是继续完成整段扫描。
TRACK:先对准,再往前
TRACK 根据目标横向位置进行底座修正。目标偏得较多时步长大一些,接近参考中心后再减小步长,避免机械臂在中心附近来回抖动。参考横向中心约为 260 像素,并设置了死区;误差落在死区内就不再横向移动。
这一步的作用很简单:不要看到目标以后就一味向前伸。如果横向偏差还很大,先把方向重新对好,后面的接近才有意义。

四、接近目标时不断重复“移动—观察”

目标对准以后进入 APPROACH。这里不会根据一帧图像估计一个最终点,再一次性把机械臂送过去,而是按距离分阶段向前。目标较远时使用较大的接近步长,进入近距离后把动作缩小。如果横向偏差重新超过阈值,就返回 TRACK 重新对准。
移动一点
   ↓
读取新的摄像头帧
   ↓
重新判断目标位置
   ↓
决定继续接近 / 重新对准 / 停止
这种方式没有把图像位置硬换算成厘米或世界坐标。当前硬件没有可靠关节编码器,也没有外部定位系统,与其给出一个看起来精确但没有测量依据的 XYZ,不如把控制建立在真实的新鲜观测上。

五、目标短暂消失以后怎么找回来

腕部相机有一个很典型的问题:机械臂为了跟住目标会自己转动,所以目标在画面里可能一直保持在中央附近。单看最近几帧的 cx,并不能完整反映目标到底往哪边移动。
因此系统进入 TRACK 时会记录当时的底座命令位置 track_origin_base。之后如果目标突然消失,就先计算这一段时间底座为了跟踪目标产生的净位移。这个方向比单纯看最后一帧更有参考价值。
目标丢失后的搜索方向优先级:
1. TRACK 期间 ID6 的净跟随方向
2. 最近目标 cx 的变化趋势
3. 最后一次看到目标的画面侧
4. 回到普通 SEARCH

这不是目标在世界坐标中的速度估计,只是一个短时间重新捕获策略。它的目的也不是预测很远,而是在目标刚刚离开画面时,别立刻从完全相反的方向重新扫描。


六、真正难调的是最后几厘米

机械臂距离目标较远时反而比较好处理。进入夹爪附近以后,目标会越来越靠近画面底部,机械臂再往前一点,摄像头看到的场景就可能发生很大变化。

所以近距离抓取单独增加了预抓取动作。中等近距离先做一次很小的 reach,再判断;极近距离会连续进行两次“小幅接近 + 新鲜帧确认”。参考控制路径类似下面这样:

500/125
→ 507/126
→ 新鲜目标帧
→ 514/126
→ 新鲜目标帧
→ GRAB

这里的 500/125、514/126 都是软件下发的舵机命令空间参数,不是厘米,也不是编码器实时测得的关节角。真正重要的是每一步之后重新看一次:如果目标已经不可见,就不继续把后面的近距离动作盲目执行完。


七、抓住以后先抬升,再做水平移动

夹爪闭合后,物体可能还贴着桌面。如果马上回收机械臂或者旋转底座,方块很容易擦过桌面。所以 GRAB 后的动作顺序是先保持 reach,单独抬升,再带着这个 carry-height 回收和转动。

闭合夹爪
→ 保持 ID5,抬升 ID4
→ 保持抬升状态回收
→ 保持抬升状态回正 / 搬运
→ MANUAL_PLACE

当前参考 carry-height 是 ID4 相对增加 50 个命令单位。它同样只是当前机械安装下的经验控制参数,不把它描述成实际抬升了多少厘米。

放置时也区分 PLACE 和 RELEASE。PLACE 会先去掉搬运高度,再等待下降、张开夹爪、回收到参考姿态;RELEASE 则只是在当前位置直接松开夹爪,不附带自动回收和归位。这样上层调用时语义比较明确。


八、把机械臂封装成一个有状态的 Robot Agent

为了让命令行、MCP、Telegram 或其他程序都能使用同一套机械臂,我没有让每个入口各自去打开摄像头和串口,而是在 VisionFive 2 上运行一个 Robot Agent。它通过 HTTP/JSON 暴露一组比较清晰的任务接口:

GET /health
GET /v1/status
POST /v1/grab
POST /v1/move
POST /v1/release
POST /v1/place
POST /v1/home
POST /v1/stop

Agent 本身不重新实现一套机械臂控制器。它下面只有一个 RobotSession,所有真实硬件任务都从这里进入。RobotSession 负责摄像头和串口的打开与关闭、硬件独占、目标解析、感知路径选择、自动抓取 worker、放置命令队列、STOP/HOME 协调以及运行状态管理。

这样做的好处是,不论上层入口是什么,最后使用的都是同一套物理运行时。不会出现 Telegram 启动一套控制器、CLI 又启动另一套控制器,然后同时抢摄像头和串口。

Agent 不只是“发一个动作”,还维护任务状态

机器人任务通常不是一次 HTTP 请求就能同步完成。例如 POST /v1/grab 返回成功,只表示抓取任务已经被接受,不表示物体已经抓到。客户端需要继续通过 GET /v1/status 查看状态。

IDLE → PICKING → PLACEMENT_READY → PLACING → COMPLETE
异常分支:STOPPED / ERROR

状态里还会保留 mission_id、target、fsm_state、last_error 等信息。对于上层程序来说,机械臂因此不再只是一个“发完串口命令就不知道发生了什么”的设备,而是一个可以查询任务生命周期的服务

软件状态和物理事实要分开

状态接口里特意区分 holding_assumed 和 physical_grasp_verified。holding_assumed=true 只表示控制流程已经执行到了持物阶段;当前参考硬件没有独立的抓取确认传感器,因此不能据此声称物体已经被传感器确认夹住。

同样,程序能够确定自己发出了什么 pulse、FSM 处在哪个状态,但不能把这些软件记录当成真实关节角、末端 XYZ 或抓取力。这个边界在 Agent 层统一处理,上层接口就不会把没有测量到的量包装成“机器人真实状态”。

网络重试也不能让机械臂重复动作

普通 Web 请求失败以后重试通常没什么问题,但机器人动作不一样。假设“向左移动一步”已经执行,只是返回包刚好丢了,客户端如果直接重试,机械臂就可能多走一步。

因此动作请求可以带 request_id。Agent 会在有界的进程内 replay cache 中保存已完成请求的结果;同一个请求因为网络问题重新发送时,可以返回之前的结果,而不是故意再执行一次相同的物理动作。真正的新动作则必须使用新的 request_id


九、MCP 是 Agent 上面的一层语义接口

Agent API 解决的是“程序怎么调用机械臂”,但 HTTP 路径、JSON 字段这些还是比较偏程序接口。如果希望让大语言模型或者 Agent 框架使用,就再往上加一层 MCP,把底层动作收敛成有限的语义工具。

robot_status
robot_grab
robot_move
robot_release
robot_place
robot_home
robot_stop

CP 不直接接串口,也不维护第二套 FSM。比如 robot_grab("red cube") 最后仍然调用 Agent 的 /v1/grab;robot_move(direction="left", steps=2) 也只是经过语义参数检查以后调用对应的 Agent 接口。

这一层最重要的作用是限制能力边界。MCP 不暴露原始 servo ID、任意 pulse、任意串口报文、Shell、SSH 或任意 Python,也没有随意给出绝对 XYZ 轨迹的接口。模型能决定的是“抓哪个”“往哪边移动”“什么时候放下”,不是底层舵机怎么转。

MCP 里的移动是“语义步长”,不是伪装成厘米

robot_move 当前主要提供 left、right、inward、farther 四个方向,并使用项目内部校准过的 semantic step。以参考配置为例,左右一个 semantic step 对应 ID6 增减 24 pulse;前后则由 ID5 和 ID4 联动完成。

这些单位属于机械臂命令空间,不写成“移动 3 cm”或者“转 10°”,因为当前硬件没有足够的传感器反馈来保证这种说法。MCP 也会检查请求到底执行了多少,如果因为机械运动边界只完成了一部分,就不会把它当成完整动作继续执行后面的计划。


十、Telegram 和大语言模型只是最上层入口

有了 Agent API 和 MCP,Telegram 接入就比较顺了。Telegram 负责接收用户文本,大语言模型把自然语言整理成高层语义计划,程序先做确定性检查,再调用 MCP 工具。
Telegram message
      ↓
text LLM
      ↓
semantic plan JSON
      ↓
deterministic validation
      ↓
MCP tools → Agent API → RobotSession → 机械臂
例如发送“抓起红色方块,然后往左移动一点”,模型需要做的是把它拆成 robot_grab("red cube"),等待进入可放置状态,再调用 robot_move("left", 1)。真正开始抓取以后,SEARCH、TRACK、APPROACH、什么时候闭爪,都由板端视觉 FSM 自己完成。
当前 Telegram 里的 LLM 接收用户文本、机器人状态和最近的语义动作上下文,摄像头帧并不会作为多模态输入发送给模型。这样 LLM 只负责低频的任务级决策,实时视觉闭环仍然留在本地控制器里。
停止指令不等待模型
“停止”“别动”“stop”这类指令会走单独的停止路径,不需要先等待一次大语言模型判断。软件 STOP 会停止当前任务和运动路径,但不会自动松开夹爪,也不能替代物理断电。真实机械设备上,软件层急停和物理断电仍然是两回事

十一、当前软件结构

为了保证这些入口最终落到同一套控制逻辑上,代码按职责拆成了几个主要模块:
roboticarm/
├─ vision/          目标解析与视觉观测
├─ inference/     YOLOE Client
├─ hardware/     Camera / Serial / ArmDriver
├─ control/         PracticalFSM
├─ runtime/       RobotSession
├─ agent_api/     Robot Agent HTTP API
└─ integrations/
   ├─ mcp/           MCP 语义工具
   └─ telegram/    Telegram + LLM
其中 RobotSession 是唯一真实物理运行时,PracticalFSM 是自动抓取控制器。CLI、HTTP Agent、MCP 和 Telegram 都只是不同入口,不各自维护一套机械臂动作逻辑。

十二、这套系统能确定什么,不能确定什么

实体机械臂很容易出现一种情况:软件里有一个数字,看起来就像机器人真的“测到了”这个数字。为了避免这种误解,当前系统把命令状态和物理测量严格分开。
这并不影响系统做视觉抓取,但决定了文章和接口里应该怎么描述结果。比如“执行了闭爪并进入持物状态”是当前软件能够确认的;“传感器已经确认抓取成功”则不是。

十三、RISC-V 在这套系统里负责什么

这套项目里,VisionFive 2 的角色比较清楚:直接面对摄像头、串口和机械臂,维护实时状态和视觉闭环;YOLOE 这类计算量大的识别可以放到局域网主机;自然语言理解则放到更上层。
用户 / Telegram
      ↓
LLM:理解任务
      ↓
MCP:限制成语义工具
      ↓
Agent API:维护机器人任务和状态
      ↓
VisionFive 2:视觉闭环 + 硬件控制
      ↓
机械臂:执行动作

这种结构并不要求一块 RISC-V 板子把所有 AI 工作全部包下来。对机器人来说,谁负责推理并不是唯一重点,真正需要理清的是哪一层可以做高延迟决策,哪一层必须保留确定性、低延迟和硬件独占。


目前这套系统已经把目标识别、持续跟踪、目标丢失后的重新捕获、分阶段接近、近距离新鲜帧确认、抓取、抬升、搬运和放置串到了一条完整控制链里。上层又通过 Agent API 和 MCP 把硬件控制封装成有限、可查询、可复用的语义动作,Telegram 只是其中一个交互入口。

还有一些问题值得继续做,比如更可靠的抓取结果确认、真实关节位置反馈、更完整的空间建模,以及移动过程中的定位精度。不过对于一套普通六舵机机械臂和腕部 USB 摄像头来说,从“看到一个目标”到“让不同上层程序安全地调用真实机械臂”,现在已经形成了一套比较完整的工程结构。

参考仓库:

https://github.com/vinaro-sopic/roboticarm


作者介绍

周匡正,筑波大学情报学学位项目在读硕士生。主要研究方向为计算机视觉与多模态图像处理。关注 RISC-V 生态与具身智能技术的结合与落地。

林琛博,纽卡斯尔大学工程学院电气与电子工程专业在读本科生。关注 RISC-V、嵌入式系统、计算机视觉与智能控制。

本篇文章由两位作者共同完成。



关于上海开放处理器产业创新中心

上海开放处理器产业创新中心(简称:创新中心)于2024年9月在上海浦东张江正式成立,坐落于集创路52号创芯天地一号楼15楼。创新中心是由国内领先的半导体设计公司芯原股份、芯来科技,以及达摩院(上海)共同发起设立的一家民办非企业单位。

创新中心旨在协同RISC-V产业链上下游企业,包括芯片设计企业、IP供应商、系统厂商、软件开发商、终端厂商以及顶尖科研院所,共建RISC-V关键共性技术平台,用开放的硬件平台构建开源的软件生态,从而有力促进RISC-V技术的产业化应用和商业化落地。

此外,创新中心还将与国内重点高校展开深度合作,通过共建RISC-V特色课程体系、设立联合实验室、建立实训实习基地等方式,系统性地培养具备RISC-V专业技能的复合型人才,为产业发展提供持续的人才支撑。

关于科技区角:国内科技展会垂直内容策划服务商,提供从论坛内容全案策划、会展市场化IP打造到精准专业观众一站式邀约服务,以产业内容吸引高质量B端人群,打通展会从议题设计、演讲嘉宾邀约、宣传预热、精准邀观到供需对接全链路。
声明:内容取材于网络,仅代表作者观点,如有内容违规问题,请联系处理。
RISC-V 机器人
more
刚刚,优必选交出超1.6万台成绩单!WRC之后,机器人行业真正拼什么?
为啥机器人跑步姿势五花八门?“捂脸跑”机器人爆火,工程师说出真实原因→
具身江湖志(四):它们,把机器人的大脑做实
被罚百万后,国内园林机械龙头砸12个亿加码机器人!
有奖直播报名中:GMSL 高速串行链路:赋能人形机器人与多传感器视觉系统的下一代连接方案
四大车企集体下场押注机器人业务;阿里、腾讯联手投资具身操作企业超45亿元 | 一周资本大事件
TikTok Shop新加坡成跨境商家新支点;小鹏机器人业务完成首轮超9亿美元融资|36氪出海·要闻回顾
小米首秀IFA柏林展,“人车家”生态与新一代铁大机器人同台亮相
对话 Sharpa 李一帆:通用机器人要么全能,要么无能
机器人为什么需要「空间记忆」?下一代地图可能不是地图……
Copyright © 2025-成都区角科技有限公司
蜀ICP备2025143415号-1
  
川公网安备51015602001305号