news 2026/10/16 3:15:26

我给八界写了个“地面杂物清理“Skill:从官方Demo的边界,到真机跑通的一条任务链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
我给八界写了个“地面杂物清理“Skill:从官方Demo的边界,到真机跑通的一条任务链

〇、问题和解法

问题:家里地面上的杂物每天都要收拾好几回。狗的玩具球、揉成团的换洗衣物、拖鞋、快递包装袋,今天一样明天一样,没有固定清单,全靠弯腰捡。

解决:我拿科沃斯八界开放的 45 项原子能力重新组装,写了一个地面杂物自主清理 Skill,叫 main_tidy,已经在真机上跑通。跑起来是这样的:机器人自己从充电桩下来,导航走到客厅,原地环视一圈,把地面上的杂物全部登记在册,然后逐个转身对准、下探、夹取、投箱,掉了它自己发现、重新捡,收完自己回去充电,全程没人碰遥控器。

先看真机结果,识别、夹取、投放三个瞬间。

同一地面,清理前后的对比。

两周真机调试,填了九个坑(两个官方级的坑见第四节),其中三个确认是固件问题,已反馈官方。这篇文章写清楚四件事:这个 Skill 解决什么问题、我是怎么把 45 项原子能力拼成它的、每个坑我是怎么解的、你想复现要准备什么。所有数据、日志、代码来自真机,文末开源。

一、场景与需求:地面上出现什么收什么

官方 Demo 抓的是玩具,固定的类别、固定的筐,词表外的东西直接跳过。真实家庭的地面不这么配合:狗的玩具球、衣物团、拖鞋、快递袋,今天一个样,明天一个样。

所以第一条设计原则就定下来了:不预设物品清单。地面上出现什么收什么,训练时没见过的类别,照样该收。

需求一共四条。

  • 全自动,从下桩到回充一条链跑完,无人干预
  • 开放集,地面上出现什么收什么
  • 安全,不碰家具、不伤宠物、收纳箱之外不放任何东西
  • 失败可恢复,卡住能自己出来,掉落能自己重捡

还有一条绕不开的现实约束。家庭环境里机器人无人看守,任何一次卡死都意味着任务失败。后文一半的设计都是围着这条约束做的,先把失败之后怎么办想清楚,再谈成功率。

先说现状。当前版本(v41)在摆位约束下稳定运行:杂物位于正前方 0.45~0.6m 抓取带,收纳箱在右前方 0.6~1.3m、开口朝机器人。放宽到任意摆放、任意房间是下一阶段的事(见第六节)。先把约束收窄、把闭环做稳,我觉得是正路。

二、官方 Skill 的边界和我改了什么

2.1 官方 toy_storage 能做到哪

八界官方把"玩具收纳"封装成了标准 Skill(toy_storage)上架应用市场,流程是搜筐、搜玩具(过滤筐内已有)、臂观测、检测、抓取、投放,失败统一重试 3 次。跑是能跑通的,官方能力的底子确实扎实。

2.2 四个撑不起真实场景的边界

但跑了两轮我就开始皱眉,四个问题。

  1. 每轮全场重搜。每收一件东西都要主动搜索一遍全屋,一轮 60 秒起步,还靠底盘跑动扫描,收 5 件就是 5 分钟
  2. 只认"玩具"单标签。词表外的杂物,检测直接跳过
  3. 单帧检测,无记忆。这一帧框到的东西,底盘一动下一帧就不知道去哪了
  4. 报 SUCCESS 就是成功吗。抓取半路掉落,日志照样报成功,物品还在地上,流程却"完成"了(伏笔,5.5 揭晓,全场最坑的一个)

这四条都有真机实证,其中三条翻过车,第五节逐条展开。边界 1 的对策写在 2.3 改进表第一行。

2.3 我的改进,逐条对症

基于官方原子能力,main_tidy对这四个边界各做了一个针对性改动,另外补了两层官方没有的防御。

#官方 toy_storage我的改法解决什么
1每轮全场重搜(60s+/轮)到位后原地批量登记,之后按记忆逐件取搜索耗时 O(n)→O(1)
2单标签"玩具"OVD 词表 + SHOE 无类别端点双端点接力开放集目标
3单帧检测无记忆地图坐标+视线角+观察位姿三元组记忆底盘位移后不丢目标
4统一重试 3 次错误码分类处置,各错各治重试不再无脑
5无假成功防御掉落实锤(36897)+ 自动重捡“日志成功、鞋在地上”
6线性流程无状态持物状态机,持物未投放绝不抓下一件连锁翻车

官方 Skill 解决的是演示可行,我要解决的是真实场景里连续可靠。所有改动都在应用层,底层 45 项原子能力一个没动。能做到这一点,靠的就是八界把这些能力真正开放了出来。

三、开发环境:原子能力就在下位机里

3.1 到手前提与开发环境

前提一件事:机器人要先完成一次建图。我这套方案里的重定位、定点导航全部建在这张图上,没建图的话导航能力起不来。

我实际用的开发环境:

项版本/值说明
下位机系统Ubuntu 22.04(双板架构,下板开放)SSH 进去就是完整 shell
中间件ROS 2 Humble相机、雷达话题都在
Python3.10系统自带
SDKbajie-sdk==1.5.0pip 安装,WebSocket 连本机
SSH 端口2222记一下,默认 22 不通
硬件六自由度机械臂(0~85cm,1kg 二指夹爪,自带相机)、头部 RGB+对齐深度双目、双 RK3588

3.2 三步接入

第一步,网页控制台。机器人开机后在同一局域网访问控制台页面,能看到相机画面、地图、手动控制,日常调试和录检测框画面都在这里。

第二步,SSH 进下位机。

ssh-p2222Agi@<机器人IP>

第三步,SDK 连接。SDK 在机器人本机上跑,连本机 WebSocket。

frombajie_sdkimportBajieRobot SDK=BajieRobot(ws_url="ws://127.0.0.1:9900/")ifnotSDK.Connect(timeout_sec=8.0):raiseSystemExit("SDK 连接失败")print(SDK.eco_robotInfo().battery.value)# 电量

到这里,45 项原子能力就全是你的了。它们落在下位机里,就是一个个脚本文件,每一项都看得见、可以读。

控制台的 API 清单页能看到每个能力的调用入口和实时状态。

3.3 第一个程序:12 项运动自检

SDK 通了先别急着写业务,我写了个motion_test.py给整台机器做体检:底盘前后、原地转向、头部两档俯仰、臂复位等 12 项逐个 PASS/FAIL。这个习惯后来救了我两次,一是确认硬件状态正常再开任务,二是顺带发现了转向指令欠交付,25° 指令实际只转 14°,欠了四成多。所以 main_tidy 里所有转向都带最终校验加两次修正,这是自检测出来的。

这套’能力即脚本’的形态对开发者很友好。SDK 文档没写清的行为,直接读脚本源码就能确认,我后面好几个坑都是这么定位的。

四、整体方案:一条七步任务链

4.1 任务链

整个 Skill 是一条串行任务链。

步骤动作原子能力
1 脱桩自主离开充电桩eco_leaveDock
2 导航定点导航到清理工作位eco_relocate+eco_navigateToPoint
3 登记原地批量登记全部地面目标eco_captureImages+eco_detect_objects+eco_computeObjectPose
4 门槛见到收纳箱才动手eco_detect_objects(容器词表)
5 清理复检、取景、夹取、投放,逐件执行eco_lookto+eco_pick+eco_place_in
6 补扫再登记一轮,收漏网目标同步骤 3
7 回充自主返回充电桩eco_startRecharge

一条链跑起来是这样的。

[1/7] 脱桩 → [2/7] 重定位+定点导航 → [3/7] 两档俯仰×2帧登记 → [4/7] 见箱门槛 → [5/7] 逐件 复检→取景→精抓→投放 → [6/7] 补扫登记 → [7/7] 回充

展开讲每一步实际发生什么。

步骤 3 的"登记"是全链地基:机器人原地不动,头部在两档俯仰各拍两帧,对每帧跑检测,把地面目标全部登记在册。每件东西记五样:类别、bbox、经eco_computeObjectPose解算的地图坐标(0.14°/px 像素方位角交叉校验,坏点弃用)、视线角 bearing、登记时的观察位姿。之后清理就靠这份档案干活。

步骤 4 的"门槛"是个保险:检测词表里挂了容器类标签,画面里见不到收纳箱就不开始抓,防止箱子没就位就空转。

步骤 5 的清理循环逐件执行,每个环节用的原子能力如下。

环节干什么原子能力
复检按记忆找到这一件eco_captureImages+eco_detect_objects
取景对准并站进抓取带eco_lookto+eco_setRobotHead+ 必要时eco_moveChassis后退
精抓臂观测+验身+出手eco_captureImages(ARM) +eco_match_obj_views+eco_pick
投放放进收纳箱eco_place_in

全收完再登记一轮补扫,兜住漏网目标,最后回充。

这类场景应用要的是原子能力的组合,这条链每一环都是官方能力拼装,没有一行代码碰底层。整条链的设计原则是每一步都默认下一步会出错,两周调试下来,这个默认救了任务很多次。先看两个官方级的坑。

4.2 语义区域导航,SDK 和 UI 不互通

第一个坑在导航。UI 地图上明明标了"客厅",语义区域导航却稳定报错 131072。用eco_manageSemanticMap一查,SDK 侧的语义区域是 0 条。UI 上画的区域和 SDK 里的地图数据是两套东西。

绕行方案是放弃语义区域,改用工作点标定加定点导航。机器人推到理想清理位,跑一次标定脚本存下坐标,之后每次定点导航过去,稳定可用。

importjson,mathfrombajie_sdkimportPointNavigationRequest wp=json.load(open("/home/Agi/workpoint.json"))SDK.eco_navigateToPoint(PointNavigationRequest(x=float(wp["x"]),y=float(wp["y"]),yaw=math.radians(float(wp.get("yaw",0.0)))),timeout_sec=180.0)

4.3 下桩死锁,cancel 都穿不透

第二个坑更凶。eco_leaveDock的表现是,物理下桩 10 秒完成(位移 0.6m),但任务句柄永久占死串行队列,后续任何运动能力全部报 8197(任务已在执行),eco_cancelAllMissions也清不掉,复现 5 次中 4 次,唯一恢复手段是整机重启。

固件级缺陷,应用层绕不过去,只能改任务编排。下桩和主任务拆成两段,第一段只负责下桩,完成后提示重启;重启后再跑第二段(导航、清理、回充),此时不在桩上,直接跳过下桩环节。

SDK.eco_leaveDock(timeout_sec=5.0)# 物理下桩约10s即完成# 固件缺陷:任务句柄占死队列,cancel 穿不透# → 本段到此为止,重启后再跑 full_mission 直接进入 导航→清理→回充

代价是多一次重启,换来的是不再偶发卡死。两个坑都已反馈官方。

五、七个坑,各个都有解法

两周真机调试,大部分时间花在解决问题上。两个官方级的坑(语义导航不互通、下桩死锁)在第四节已经讲了绕法,剩下七个实现级的坑,从 v37 到 v41 三个版本逐步修掉。这一节逐个按问题、解决来写,完整代码都在第七节的仓库里。

5.1 OVD 对深色物体失明,解法是双端点接力

问题:同一画面,白色物体检测正常,深色小物一个都检不出来。OVD(开放词汇检测)对深色物体会失明。

解决:官方检测有两条推理通道,OVD 按词表认类别(我挂了 12 个中文标签),SHOE 端点做无类别检测,框出来的东西一律叫"鞋子"。做法是 OVD 为主,没有有效检出才跑 SHOE 兜底。单次检测 10.3 秒,两个端点各跑一遍耗时直接翻倍,接力就好,无脑并跑没必要。

defdetect_targets(robot,view):"""OVD 为主,无有效检出才跑 SHOE 兜底(深色小物仅SHOE可见)"""pool=[]try:ovd=list(robot.eco_detect_objects(DetectObjectsRequest(rgb_image=view.rgb_image.img,labels=CATALOG_LABELS,entry=OvdEndpoint.OVD)).items)pool=pool_filter(ovd)exceptExceptionase:print(f" [OVD异常]{str(e)[:40]}")ifpool:returnpool shoes=list(robot.eco_detect_objects(DetectObjectsRequest(rgb_image=view.rgb_image.img,labels=["鞋子"],entry=OvdEndpoint.SHOE)).items)returnpool_filter(shoes)

这套做法依赖头部双视觉模组。RGB 负责纹理和颜色,对齐深度给出像素级距离,同视角互补,目标既能被认出也能被定位。

5.2 检测名字不可信,解法是外观验身

问题:SHOE 端点框出来的东西一律叫"鞋子",毛巾团会被标成 shoe_11。透明矿泉水瓶实测返回的标签是"未知物品",名字和实物对不上。按名字触发精抓(官方的eco_pick_with_arm_review拿目标名当 OVD 标签),必然拿到 0 候选。

解决:精抓阶段用eco_match_obj_views做外观验身。登记时存下目标的外观特征,精抓时做相似度匹配,比长相,不比名字。标签只是线索,外观才是身份,这个原则贯穿全链。彩蛋:匹配出的名字带"shoe"前缀就触发鞋子侧夹模式(官方同款逻辑),白色运动鞋实测 4/4。

# 精抓链自己拼:复位→瞄准→臂图检测→外观匹配→pickarm_view=robot.eco_captureImages(CameraType.ARM,timeout_sec=30.0)cands=pool_filter(detect_targets(robot,arm_view),floor=False)match=robot.eco_match_obj_views(ref_view,arm_view)# 外观嵌入相似度target=pick_candidate(cands,match,item)# 按匹配度选框robot.eco_pick(PickRequest(...))# 直接pick,绕开按名字的封装

(节选,完整精抓链见仓库main_tidy.py的pick_with_retry。)

5.3 投完第一个找不到第二个,解法是三元组记忆

问题:place_in投放动作自带一次底盘位移,机器人挪了,旧框全漂,实测漂移 190px 以上。回到第二个目标按旧 bbox 复检,直接扑空。

解决:目标记忆从"一个框"升级成三元组:地图坐标、视线角 bearing、登记时的观察位姿。复检时先按里程计驶回观察位姿(恢复登记时的几何),再按当前朝向和 bearing 预测目标该出现在画面哪个像素位置,取最近者。bearing 对平移免疫,底盘挪过也认得。

deffind_target(pool,robot,t):"""按当前朝向与目标bearing预测像素x,取横向最近者(±140px门)"""yw=yaw_now(robot)b=t.get("bearing")ifywisNoneorbisNone:# 无bearing时退回bbox匹配returnnearest_item(pool,t["bbox"])cx_pred=320+norm_deg(yw-b)/PIX_DEG# 640宽画面,右=正偏best,bd=None,1e9foritinpool:d=abs((it.bbox[0]+it.bbox[2])/2-cx_pred)ifd<bd:best,bd=it,dreturnbestifbd<140elseNone

配套还做了三级去重:地图距离 0.14m、bearing ±4°、同帧像素 120px,逐级合并重复目标。旧版只按 yaw ±12° 去重,同帧多个物体会被误合并成一个。

位姿解算也批量化了:旧版逐框调用eco_computeObjectPose,每次 7.8 秒,一帧 3 个目标就是 23 秒;新版一帧一次 RPC 算全部新框。

res=robot.eco_computeObjectPose([bbfor_,bbinkept],view,timeout_sec=8.0)

5.4 机械臂带外不动,解法是 0.45~0.6m 抓取带

问题:目标明明在画面里,eco_pick却报 57346(无可达抓取点),机械臂纹丝不动。

解决:先做标定实验找到稳定抓取带。同一个物体摆在三个位置各抓三次:画面下沿 y≈304(约 0.42m)0/3,中部 y≈261(约 0.5m)3/3,上部 y≈214(约 0.7m)0/3。稳定抓取带 [0.45, 0.6]m,对应画面 y∈[250, 290]。带内才取景出手;带外先换低头档重拍(近物在低头档会落到画面中部,免挪动),还不行就底盘后退 0.15m 重新登记。只后退不前进,原因见 5.6。

defensure_good_framing(robot,view,item):"""带外先换低头档重拍;仍带外后退0.15m——底盘唯一允许的平移"""ifnotout_of_band(item):returnFalse,view,item set_head(robot,HEAD_DOWN)# 低头档:近物落画面中部nv=robot.eco_captureImages(CameraType.HEAD,timeout_sec=30.0)tgt=nearest_item(detect_targets(robot,nv),item.bbox)iftgtisnotNoneandnotout_of_band(tgt):returnTrue,nv,tgt# 免挪动,重拍解决robot.eco_moveChassis(-0.15,0.0,timeout_sec=60.0)# 只后退...

(节选,完整实现见仓库main_tidy.py的ensure_good_framing。)

这一节还埋着两个官方接口的暗坑,一并记下。头部视图标定的地面过滤门(y1≥130 且框高≤150)误用到臂视图会把候选全杀光,臂相机俯视特写的框天然在画面上部,一套用全被杀,v38 回归实测"臂图候选恒空"就是这个。加上按名字精抓 0 候选的问题,整条精抓链只能自己拼:ARM_HOME 复位、eco_lookto瞄准、臂图检测、外观匹配、eco_pick。

5.5 掉落误报成功,解法是掉落实锤加状态机

问题:place 半路物体掉落,机械臂空着爪把整套放置动作做完,日志报 SUCCESS。eco_place_in不校验爪上负载,它只管"动作做完了",不管"东西进箱了"。

解决:三层防御。

第一层掉落实锤。place 再报 36897(未抓到物体)=爪是空的=东西半路掉了,确认掉落后原目标重新定位、重新入队,自动重捡。这里有个细节:旧版掉落后走"重新登记",结果新目标被去重逻辑当成旧目标吃掉,重捡从未真正生效,重排必须绕过去重。

第二层持物状态机。SEARCHING、CARRYING、PLACING 三个状态显式管理,铁律是持物未投放绝不抓下一件,否则掉落的第一件和正在抓的第二件会连锁翻车。补扫同理:持物终止就跳过补扫,否则会把爪里的东西当"新发现"再抓一次。

第三层两条禁令。持物期间禁止收臂,收臂的震动会把轻物甩出去(实测教训);连续三次投放失败保持持物直接停机,宁可停机等人,也不把东西放回地面。

res=place_in_box()ifres=="placed":t["status"]="done"elifres=="dropped":# place报36897 = 爪空 = 掉落实锤ift.get("drop_count",0)<=1andrelocate(t):work.append(t)# 原目标重新入队,自动重捡else:# "held":持物终止,人工介入t["held_flag"]=True

5.6 误框会撞东西,解法是四条铁律

问题:贴边一个幻影框,洗地机在背景里被框成了"鞋",机器人转身抬臂,把我桌上的监控撞翻了。开放集检测在真实背景里一定会误框,误框躲不掉,能设计的是误框之后不造成伤害。

解决:四条铁律全部写进代码。

  • 只认地面物:框顶 y1≥130 且框高≤150 才可能是地面小物,桌面高度的一票否决
  • 居中修正上限 ±35°:要转身超过 35° 才能居中的检出,视为贴边幻影,放弃
  • 收纳箱绝对免疫:名字命中容器词表直接排除,永不进抓取池
  • 底盘只后退不前进:朝目标前进这个动作被整个删掉,因为它压过毛巾、撞过箱子(两次事故换来的铁律)。需要靠近,就用"驶回已知安全位姿"代替"朝未知目标前进"
defpool_filter(items,floor=True):"""抓取池:容器免疫 + 基本尺寸 + 地面物过滤(floor门仅头部视图)"""out=[itforitinitemsifnotany(cinit.nameforcinCONTAINER_LABELS)and(it.bbox[2]-it.bbox[0])>=20and(it.bbox[3]-it.bbox[1])>=20]iffloor:out=[itforitinoutifis_floor_item(it.bbox)]returnout

这套在应用层再加保险的做法有官方定调背书。八界开放体系分 L1/L2/L3 三层,45 项高层原子能力已内置封装、无碰本体风险,只有直接操作 ROS 节点的 L3 层有风险。本文全程只用原子能力层,四条铁律是官方边界内再加的保险丝。

5.7 检测偏慢,解法是三项提速

问题:每次 OVD 检测 10.3 秒,拆开一看,其中 8 秒是yolo_label预处理服务超时,下位机日志里每次都有这行。

yolo_label preprocess unavailable, fallback to original labels: timed out

有意思的是 8 个标签和 19 个标签耗时一样,瓶颈在预处理服务起不来,检测管线退回原始路径硬扛。这 8 秒是固件层的问题,已反馈官方,应用层改不了。

解决:让这 10.3 秒少发生几次。

  • 批量位姿解算:逐框 7.8 秒改成一帧一次 RPC(5.3 已述)
  • OVD-first 单端点推理:OVD 有检出就不跑 SHOE,省一整次 10.3 秒
  • 俯仰缓存:同姿态重复的set_head直接跳过,每次省 1.2 秒

应用层能优化的都优化了,剩下的天花板在固件。对开源机器人来说,把问题定位清楚并反馈官方,本身就是生态贡献的一部分。

5.8 插曲:8206 充电互锁,重启解决

某天机器人明明站在客厅地上,所有运动能力却全部报 8206"机器正在充电",isCharge标志却是 0,状态标志和互锁逻辑自相矛盾。

refresh后 isCharge: 0 battery: 100 moveChassis 拒绝: code=8206, msg=机器正在充电 setHead 拒绝: code=8206, msg=机器正在充电 再读 isCharge: 0 ← 标志与互锁自相矛盾,refresh无法清除

SDK 侧无解,整机重启后全绿。

relocate: SUCCESS [0x00000000] setHead ok capture ok: (400, 640, 3) position: (0.15, -0.5, 0.038)

运维经验一句话:遇到大面积 8206 且实体并未在桩上,先重启再排查,别跟状态标志较劲(与 4.3 的下桩死锁同类)。

六、实测:数据、盲区与边界

同一布景、同一 v41 版本,六种代表性物体逐个实测。

物体结果说明
黄色毛巾团✅ 收纳入箱全链演示:识别→夹取→投放(见图1)
粉色薄布团✅ 收纳入箱OVD 词表命中
深色圆环✅ 收纳入箱SHOE 端点兜底命中
白色运动鞋✅ 收纳入箱侧夹模式,实测 4/4
透明矿泉水瓶❌ 自动跳过深度失效 41223 + RGB 低对比
平铺鞋垫❌ 自动跳过薄物抓取失败

6 个物体是单轮小样本,用来看能力边界,别当成统计意义上的成功率。

两个盲区值得单独看。平铺鞋垫太薄,夹爪闭合高度以下的物体抓不起来;透明瓶在 RGB 视角下和地砖几乎零对比度,深度图在其表面失效(41223),视觉和深度双重失效,物理原因决定,属于当前传感器方案的原理性边界。同一块毛巾,团起来稳稳收走,摊平了就抓不起来,薄物都在盲区里。

有盲区不影响能干什么的结论,但边界必须写进文档。main_tidy对这类物体识别后主动跳过,深度无效的目标不进抓取池,不卡死也不乱抓。

要复现的话,先跟机器人签一份"摆位合同",这是 v41 稳定运行的前提。

  • 杂物在正前方 0.45~0.6m 抓取带内,件间距 20cm 以上
  • 收纳箱在右前方 0.6~1.3m,开口朝机器人,落在头部视野里
  • 背景尽量收干净,工作中的洗地机就是幻影鞋制造机
  • 电量 30% 以上

当前版本 v41 的摆位约束示意如下,这是工程现状,终态在下面的迭代路线里。

迭代路线按优先级排三件事:抓取带约束放宽(任意位置加自主趋近)、透明物检测(HSV 标签色 seed 区域生长)、多房间任务编排。

七、开源与复现

本 Skill 已提交至八界官方 Skill 共享仓库,PR 编号 merge_requests/7(宿主仓库gitcode.com/ecovacs-bajie/ecovacs-bajie-csdn),评审中。全部代码在我的分支feat/yuanhao-floor-tidy上,仓库路径gitcode.com/gcw_rB4YDQD0/ecovacs-bajie-csdn,合并后源码进入官方仓库的yuanhao-floor-tidy/目录。

分支里两份文档建议先看:yuanhao-floor-tidy/README.md,含与官方 toy_storage 的对比、反应式架构说明和六物体实测表;yuanhao-floor-tidy/references/error-codes.md,36897、41223、57346、8197 及四个已反馈官方的坑的速查表。

合并后源码会固定在官方仓库的yuanhao-floor-tidy/目录,上面分支路径长期有效。完整结构如下。

yuanhao-floor-tidy/ ├── README.md # 功能、摆位约束、错误码表、能力边界 ├── SKILL.md # Agent 调用规范(意图→命令对照) ├── requirements.txt # bajie-sdk==1.5.0 ├── references/ │ └── error-codes.md # 错误码速查 + 已知固件问题 └── scripts/ ├── main_tidy.py # 原地清理核心(v41 稳定版) ├── full_mission.py # 全链:脱桩→导航→清理→回充(两段式) ├── scene_check.py # 30 秒布景预检(零运动) ├── motion_test.py # 12 项运动自检 ├── set_workpoint.py # 清理工作点标定 └── soft_reset.py # 任务队列软恢复

复现只要两步,SSH 进八界下位机后依次执行。

python3 scripts/scene_check.py# 布景预检,输出"布景合格✓"python3 scripts/main_tidy.py# 原地清理

想按你家客厅调整的话,这几个参数都在main_tidy.py顶部的配置区,改完即用。

参数当前值含义
抓取带[0.45, 0.6] m目标必须落在这个距离带才出手
检测词表12 个中文标签按你家常见杂物增删
复检匹配门±140pxbearing 预测位置与检测框的匹配窗口
居中修正上限±35°超出视为贴边幻影,放弃
地面物过滤y1≥130 且框高≤150头部视图的地面物判据
像素方位角0.14°/pxbearing 与像素换算系数
三级去重0.14m / ±4° / 120px地图、视线角、像素逐级合并
后退步长0.15m带外自纠的唯一底盘动作
电量门槛30%低于可能被拒任务,先充电

scene_check.py单独说一句。它用零运动的方式预检布景,看抓取带内有没有目标、收纳箱可不可见,30 秒内给出能不能跑的结论。开拍前跑一次,省得正式跑三轮才发现箱子摆远了。motion_test.py就是 3.3 那个体检脚本。这两个工具都是被真机逼出来的,也送给后面要复现的人。

八、写在最后

两周体验期结束,机器人已寄回。回头看,这次开发最值钱的产出有三条经验。

  1. 原子能力的价值在组合,更在组合之后的防御。45 项能力单独看都顺手,串成 7 步任务链后,错误处理代码占了全项目的近一半。真实场景的可靠性要靠设计,demo 给不了
  2. 遇到固件级缺陷,绕行设计加反馈官方是应用开发者的正解。下桩死锁(dock_down)、yolo_label 超时、充电互锁卡死,三个固件缺陷,加上 place 不校验负载这处接口设计缺陷,全部反馈官方并附了复现路径
  3. 把边界写明白,后面的人拿到的才是能用的方案。盲区、摆位约束、小样本口径全部写明,别人不用重踩一遍坑

给官方的两条建议,一并放进这篇(问题细节前面都写了):语义区域的 SDK 层和 UI 层尽早互通,"地图上看得见、SDK 查不到"对新手非常劝退;yolo_label预处理服务值得加一个常驻守护,一次超时让每次检测多背 8 秒。

八界开源社区:www.ecovacs-tech.com

参赛落款:本文为八界开源共创大赛 B 赛道(创意场景应用)参赛作品。代码与数据全部来自真机实测,欢迎 Fork 与修改,转载请注明出处。

附录:错误码速查表

调试期间整理的完整错误码对照,已随 Skill 开源(references/error-codes.md)。

码含义触发场景对策
36897未抓到物体没夹住 / place 爪空刷新参考重试;掉落重排重收
41223深度图无效深色 / 贴边 / 透明后退 0.15m 重拍
57346无可达抓取点带外 / 姿态受限跳过(不前进)
36864机械臂执行失败投放半路失败重试
8197任务已在执行队列被占soft_reset 清队列;无效则重启
131072语义区域导航失败SDK/UI 地图层不互通定点导航绕行
8206状态未刷新 / 互锁robotInfo 缓存态先 refresh;充电互锁卡死则重启
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/16 3:14:29

Odoo模块继承核心套路:模型、视图、方法重写全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/16 3:14:22

惠构思 AI|数据分析不是算数字,教你写出导师认可的实证章节

✨阅读引导&#xff1a;很多同学误以为数据分析就是跑软件导出表格&#xff0c;把一堆统计结果粘贴到论文就完成任务。导师真正想看的&#xff0c;是数据如何支撑你的研究假设&#xff0c;发现了哪些规律。不少人的实证章节&#xff0c;只有表格堆砌&#xff0c;缺少逻辑解读。…

作者头像 李华
网站建设 2026/10/16 3:14:22

在数据安全中,天锐DLP起什么作用

天锐DLP&#xff08;数据泄露防护系统&#xff09;在数据安全中扮演综合性防护平台的角色。它并非单一工具&#xff0c;而是以敏感内容识别技术为核心&#xff0c;融合终端安全管理、网络准入控制和审计分析能力的体系化解决方案。其目标是在数据全生命周期中&#xff0c;围绕识…

作者头像 李华
网站建设 2026/10/16 3:14:13

H3C S6520交换机路由器配置OSPF与BFD联动

H3C S6520交换机路由器配置OSPF与BFD联动及所遇到的邻居震荡问题 一、背景与目的 为了提高网络的可靠性和稳定性&#xff0c;采用OSPF&#xff08;Open Shortest Path First&#xff09;作为动态路由协议实现路由快速传递&#xff0c;能够自动发现网络拓扑变化并重新计算最佳路…

作者头像 李华
网站建设 2026/10/16 3:13:51

自定义表单设计器-教学讲解

自定义表单设计器 - 教学讲解目标读者&#xff1a;第一次接触本项目自定义表单设计器的同学 阅读时长&#xff1a;约 20 分钟 学完之后&#xff0c;你能完整说清楚下面这 3 件事&#xff1a; 设计器中间"手机壳"里的控件预览&#xff0c;到底是怎么画出来的&#xff…

作者头像 李华