源码依据:
D:\Team\Program\TeamAAS-2.0\TeamAAS-VM\Services\RemoteCommandService.cs(2125 行,生产核心调度)、Services\CameraCalibrationService.cs(标定动作)、Services\CalibrationService.cs(运行时坐标换算)、Models\PickInfo.cs(夹具模型)、Team.FFFeederService(供料器类库)。 兄弟文档:DEVICE_FLOW.md(设备对照表)、ARCHITECTURE.md、EXPERIENCE.md。
机械手到位(待拍位) ──TCP发触发命令──▶ 上位机 BgCommunicate(TcpService 监听)
│ RemoteCommandService.ExecuteAsync(指令, 回调)
├─ 解析触发命令 → 找到对应视觉流程(Procedure)
├─ Feeder 拍照前动作(开背光/振动, 可选)
├─ 相机 Grab()(先应用配方曝光/增益)
├─ 运行视觉流程(ToolBlock) → 找到工件像素坐标 X,Y,U
├─ 标定换算 ConvertPixelToPosition → 机器人坐标 X,Y(,U)
▼
机械手 ◀──TCP 回复"触发命令,OK,X,Y,U" ──┘
(机械手用坐标去抓;吸/夹 IO 由机器人程序按 CalibParame 预置的参数自持完成)
核心思想:上位机是"应答式视觉服务器"——机器人/PLC 发触发命令,上位机拍照算坐标回传; 拾放动作本身由机器人程序执行,上位机不逐步遥控。
触发命令[,参数...];ExecuteAsync 拆出 triggerCommand 与 commandParams;TryEnterCommandExecution——同一触发命令上一次没跑完,直接回 触发命令,NG;switch(triggerCommand) 分发,主要内置命令:
LoadProduct,{产品名} —— 加载产品(读产品目录下流程/配方);GetProductName[,编号] / GetProductID[,产品名] —— 产品查询;GetToolParam,{触发命令},{工具号} / GetProcessParam,{触发命令} —— 取参数;TriggerCommand,如 V1)→ 走视觉任务;{触发命令},OK,{输出项} 或 {触发命令},NG,{原因}。按优先级两条路:
ScriptHelper.ExecuteVisionScriptingAsync
(CS-Script/Roslyn 编译执行,整段流程逻辑可被工程师用 C# 接管);ExecuteNormalVisionTaskAsync;ExecuteFeederVisionTaskAsync(见第五节)。ExecuteNormalVisionTaskAsync 步骤:
SetLightBeforePhoto:按流程配置开光源/背光(可带等待延时);camera.Grab();
拍照失败按配置的重试上限重试;GetVisionOutput:按产品里配置的输出项收集结果——
"x,y,u; x,y,u; ..."(分号分多个目标),逐点
ConvertPixelToPosition 换算成机器人坐标(保留 3 位小数,附加字段原样带回去);
移动相机(MobileJ4/XY模组)必须携带机器人当前位姿 robotPos 参与换算,否则报
RobotPositionNull;{触发命令},OK,{输出1},{输出2}...。枚举:FixedUp=0 / FixedDown=1 / MobileJ2=2 / MobileJ4=3 / MobileDown_XYPlatform=4 / None=99。
| 方式 | 物理布局 | 标定九点取点动作 | 运行时像素→机器人换算 | 工具坐标步骤 |
|---|---|---|---|---|
| FixedDown 固定向下 | 相机固定工位上方俯视,机械手吸标定块在下方走位 | 防遮挡循环(每点):CalibMotion(点i) → CalibOutIO(0) 放下块 → CalibMotion(Home) 退待机 → 拍照 → CalibMotion(点i) 回来 → CalibOutIO(1) 吸回;九点完回 Home |
仿射矩阵直出机器人 mm →(带 robotCoord 时)ToolCoord.ComputeTool 转工具坐标;回传角度取反 |
需要:CalibrateFixedDownCameraTool |
| FixedUp 固定向上 | 相机朝上(背光板下),机械手举块到镜头上方 | CalibMotion(点i, Z) → 拍照(无遮挡问题) |
同 FixedDown 族(ComputeTool) | 需要:CalibrateFixedUpCameraTool |
| MobileJ2 | 相机装 J2 臂随臂下移 | 同上(走到点位拍照) | 仿射直出 + 转工具坐标;角度取反 | 需要 |
| MobileJ4 | 相机装末端腕(眼在手,随 U 轴旋转) | 先 CalibMotion(中心点) 并把 Mark 点换算到工具坐标系记录;九点矩阵 = Mark − (点i − 点1 位移)(把 Mark 拉回相机中心) |
仿射出 mm 偏移 → 按 (当前U − MarkU) 构造旋转矩阵修正偏移 → 叠加机器人当前坐标 | 需要:CalibrateJ4MovingDownCameraTool |
| MobileDown_XYPlatform | 相机装 XY 龙门模组下移 | 同 J4 偏移换算(Mark=中心点,不做工具换算) | 同 J4 偏移公式但旋转角恒 0(模组无旋转) | 跳过 |
| None 独立相机 | 手动 | 手动 | 手动 | 不适用 |
共同前置(旋转预备标定):机械手走 P0 / P0+X / P0+Y 各拍一张 → Gram-Schmidt 求图像系↔机器人系
旋转矩阵 + PixelScaleX/Y(mm/px);九点机器人坐标先经该矩阵的逆变换对齐坐标轴,再进仿射求解
(2.0 用 OpenCvSharp EstimateAffine2D;我们用正规方程+高斯消元,数学等价)。
验证步骤:0.9 幅面再取 5 点 → RMSEX/RMSEY/最大偏差。
模型:PickInfo { PickPlaceModel: Suction|Clamp; Inhal: int; Blow: int; }(+ 产品/标定里的
WaitSuction/WaitBlow 延时)。同一对 IO 位,两种语义:
| 夹具 | Inhal(吸气/夹紧 IO 位) | Blow(吹气/松开 IO 位) | 时序 |
|---|---|---|---|
| Suction 吸取(默认) | 吸真空电磁阀 | 破真空吹气 | 到位→吸真空→等 WaitSuction→搬运输送→破真空→等 WaitBlow→放料 |
| Clamp 夹爪 | 夹紧电磁阀 | 松开 | 到位→夹紧→等 WaitSuction→搬运→松开→等 WaitBlow→放料 |
交互方式:标定/建产品时用 CalibParame,{夹具类型},{Inhal},{Blow},{Speed},{Accel},{Power},{WaitSuction},{WaitBlow}
一次性下发给机器人;生产节拍里吸/放的 IO 时序由机器人程序自持(上位机不逐步遥控)。
标定向导与手动调试用 CalibOutIO,1/0 直接开关(向导第 2 步的「吸气/破真空」按钮即此)。
控制链路:Team.FFFeederService 独立类库——
{K1}/{K0} 背光开关、{UV1}~{UV26} 选振动组、
{DV} 保存、{HC} 停止、{CA}~{CI},{毫秒} 方向振动(前/后/左/右/斜向);振幅/频率/相位经寄存器读写
(平台起始地址 300、料斗 742、序列 950);断线 1s 重连。SetAuxPowerOut 背光/辅助输出,振动强度/方向/配置号读写)。与视觉/机器人联动(生产):
ExecuteFeederVisionTaskAsync:解析触发命令选项(是否先振动 / 是否先拍照);ExecuteFeederForPhotoBefore:先振动供料 + OpenLightAsync 开环形背光(带亮度与延时);FeederStockWork(振动供料任务)与机器人取料节拍配合;FeederClearWork 清料任务
(配置 Config\FeederClearanceTasksConfiguration.cfg,支持按编号取消)。与标定联动:向导第 2 步「下一步」时 Feeder.OpenLightAsync() 开背光;九点每个点拍照前
OpenLight() + 设亮度——保证背光曝光一致。
| 2.0 能力 | 本程序现状 | 动作 |
|---|---|---|
| 机器人 TCP 协议(全指令+回显确认) | ✅ EpsonRobot 已同源实现 | 无 |
| 相机多品牌 + 软触发 | ✅ 已移植(GenImage 载体更通用) | 无 |
| 吸气/夹爪 PickInfo + CalibParame/CalibOutIO | ✅ 已实现 | 无 |
| Feeder TEAM/Afag TCP + 配方 | ✅ 已实现 | 无 |
| 标定向导 7 步 + 旋转预备标定 + 九点 + 验证 | ✅ 已移植 | 无 |
| RemoteCommandService(触发命令→拍照→视觉→回坐标) | ❌ 只有 FlowRunner 心跳的简化版 | 补"视觉触发服务":触发命令映射到我们的流程(视觉 procedure=一条流程),跑完按输出项(点位项经标定换算)应答——完美契合我们的流程配置模式 |
| 输出点位自动标定换算(IsPointTran) | ❌ | 同上,作为视觉触发服务的输出选项 |
| 设置页添加对话框(AddRobot/AddCamera/AddFeeder…) | ❌(配置文件直改) | 移植 UI |
| 标定 Feeder 背光联动 / 畸变校正 | ❌ | 补 |
| 移动相机换算(J4/XY 模组 robotPos 修正) | ✅ 已移植 | 无 |
实施建议:第 1、2 行(视觉触发服务 + 点位换算输出)是"我们在流程里配置、对外当视觉服务器"的 关键缺口——做好了,机器人侧协议与 2.0 完全一致,现场无需改机器人程序。 该服务适配层薄、验收标准清晰,适合派高级工程师 agent 实施;架构侧由本侧验收。