机器人项目实战(5):从单次抓取,到接收指令连续做事

机器人项目实战(5):从单次抓取,到接收指令连续做事

前面几篇,我分别整理了相机、识别、抓取参考、灵巧手求解和实机动作适配。

最后这一篇,把它们放回完整任务里。

任务目标仍然是橙子、苹果、香蕉、柠檬,以及锤子和螺丝刀。不过,程序除了完成一次抓取,还要处理目标挤在一起、连续搬运,以及小智发来的新指令。

我把这一阶段的流程组织成:接收任务、观察桌面、准备目标、抓取放置,再更新场景。

1. 先让指令变成明确的任务

接入小智后,机器人侧通过串口接收结构化指令。

我把串口解析和机器人任务执行分开。解析层负责从字节流中找出完整指令,检查帧头、帧尾和校验值;任务层再根据功能码和参数,决定调用哪个任务。

当前指令帧长度是 10 字节:

复制代码
帧头|功能码|6 字节参数|校验值|帧尾

对应到抓取相关任务,主要有:

  • 抓取指定类别并放置;
  • 按给定类别顺序抓取;
  • 按配置顺序循环搬运;
  • 将指定物体递到交接位置。

这样,机器人侧拿到的是确定的任务名称和参数。上层输入方式变化时,底层抓取流程仍然可以复用。

2. 抓之前,先看目标周围有没有其他东西

如果目标单独放着,可以继续计算抓取。目标附近还有其他物体时,我在流程中加入了抓前打散。

这里先检测当前配置中的全部类别,再根据水平检测框是否相交进行分组。框的边或角接触,也归入相交关系。

分组还包含间接连接。例如:

markdown 复制代码
苹果与香蕉的框相交
香蕉与柠檬的框相交
    ↓
三者归为同一组

判断依据是图像中的检测框关系。程序随后只处理当前目标所在的组,不去打散其他独立区域。

如果目标所在组只有它自己,就直接进入抓取准备。

3. 从哪边拨开?

确定目标所在组后,我先计算一个包住整组物体的水平矩形,并取它的中心 C。

接着,在矩形四个角里选择起点 P。

选择时,我计算每个角到各成员检测框的距离,取其中最小值,再选择这个最小值最大的角。直观上,就是优先从相对空一些的角进入。

拨动方向从 P 指向 C,并继续越过中心,终点设为:

css 复制代码
终点 = 2C - P

也就是把中心作为中点,沿这条线拨到另一侧。

得到图像中的起点和中心后,我用组内有效深度的中位数,将它们还原到三维空间,再转换到机器人基坐标系,生成水平方向的拨动路径。

这样,拨动距离会随分组范围变化,而不是每组都使用同一个固定长度。

4. 拨完以后,重新拍照

拨动执行分成转手、移动到预位置、下探、水平拨动和抬升几个阶段,随后返回观察位置。

回到观察位之后,我重新拍照、重新识别,再为目标分组。

这一轮使用的是更新后的检测结果。物体已经被拨动,前一张图里的位置也就完成了它的作用。

整个过程形成一个循环:

markdown 复制代码
观察与分组
    ↓
目标独立 → 进入抓取
    ↓ 否
规划并执行拨动
    ↓
返回观察位,重新识别

当前最多尝试 5 次拨动。达到次数后仍处于相交组,就结束这次准备流程并返回原因。

5. 把一次抓取接成完整动作

目标准备完成后,复用前面几篇的流程:

markdown 复制代码
生成抓取参考
    ↓
灵巧手求解与 TCP 换算
    ↓
准备手形、到达预抓取位置
    ↓
接近、闭合、等待、抬升
    ↓
移动到放置位置、松手
    ↓
返回观察位

在当前搬运任务中,我使用镜像方式生成另一侧的放置位姿,并为放置轨迹增加基坐标系 Z 方向的偏移。

顺序抓取时,每个物体走完抓取和放置,再回到观察位处理下一个。

我没有在开始时一次算完所有物体的位置,而是让每轮抓取使用当时的场景数据。前一个物体被拿走,或者打散动作改变了布局,后面的目标位置就跟着更新。

6. 抓完之后,再看一次来源区域

顺序任务中,我还加入了抓取后的复拍检查。

完成抓取、放置并返回来源侧观察位后,程序重新检测当前类别。如果仍然检测到该类别,就按配置重新执行这轮流程;没有检测到,再推进到下一个类别。

这里采用的是类别级判断,适合当前按类别组织的任务。

目标没有识别到时,我也保留了跳过、重试和中止三种策略。当前默认使用跳过,让任务继续处理后面的类别;重试则有次数上限。

这样,任务列表与实际桌面之间就有了衔接:每一步既知道接下来要找什么,也会根据当前画面决定怎样继续。

7. 连续搬运,需要管理这一轮的目标

循环搬运建立在顺序抓取上,两侧分别配置观察位置。

每个搬运方向开始时,我先拍一张图,确定这一方向中实际出现的目标类别,并保留配置中的顺序。

这张图用于确定本方向的任务名单,后续每次抓取仍会更新目标位置。等这一方向完成后,再根据完成列表组织反向搬运。

我把"这一轮处理哪些类别"和"某个物体当前在哪里"分开管理:

  • 类别列表决定任务顺序;
  • 每轮识别提供当前的位置和抓取数据。

这样,连续任务既有明确进度,也能跟随桌面变化更新动作。

8. 正在搬运,又收到新指令怎么办?

小智接入以后,串口监听需要在任务运行期间继续接收数据。

因此,我让串口接收和任务执行分开运行。新指令到来时,先保存为待执行任务,不在当前动作中间直接启动另一套动作。

对于循环搬运这类持续任务,新指令会提出切换请求,等当前物体完成放置等阶段后,再交给下一个任务。

待执行位置只保留最新的一条指令。当前任务结束后,有新任务就继续执行;没有待执行任务,则返回初始观察位。

我希望这里的行为尽量清楚:收到指令、正在执行、等待切换和执行结束,是几个独立状态。

写在最后

从最初选相机,到接入深度、完成标定,再到识别目标、求解手形和组织任务,这个项目逐步从单个功能变成了相互配合的流程。

最后这部分,我主要做了三件事:目标挤在一起时先打散,动作改变场景后重新观察,再通过任务层连接连续搬运和外部指令。

回头看,各模块之间的数据衔接和执行顺序,占了很大一部分工作。相机提供当前场景,感知给出目标,求解生成姿态,设备执行动作,任务层决定下一步。

到这里,这个系列从设备选型写到了任务执行。后续继续调整时,我会优先记录那些有具体问题、实际改动和运行结果的部分,再围绕它们补充新的文章。

相关推荐
旺仔仔仔1 小时前
机器人项目实战(2):识别物体、提取点云,再到抓取姿态
算法
姜鱼问生1 小时前
密码明明一样,为什么 GPG 说“错的“?
后端·算法·架构
启观川2 小时前
数据结构与算法-第 3 章 常用算法-贪心算法
数据结构·笔记·python·算法·贪心算法
对空六课2 小时前
指标口径生效时间的版本查询实现
大数据·服务器·前端·算法·数据分析
对空六课2 小时前
RFM分层边界变化的回溯计算
大数据·服务器·前端·数据库·人工智能·算法·数据分析
一勺思维2 小时前
我为什么把 Agent 的核心逻辑从 LangChain 里搬出来手写
算法
碧海银沙音频科技研究院2 小时前
基于炬芯ATS308X的LE aduio LC3编解码算法功能实现
算法
小蒋观天下2 小时前
厂区人员徘徊游荡判别——基于时序轨迹速度的逗留行为分级算法落地
大数据·人工智能·深度学习·算法·机器学习·ai大模型
程序员清风2 小时前
堆与优先队列:从 Top K 到任务调度
java·数据结构·算法