PRODUCTION_FLOW.md 10 KB

生产运行全流程与分支详解(对照 TeamAAS-2.0 在产实现)

源码依据: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.mdEXPERIENCE.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 发触发命令,上位机拍照算坐标回传; 拾放动作本身由机器人程序执行,上位机不逐步遥控。


二、触发入口:指令-应答协议(RemoteCommandService.ExecuteAsync)

  1. 外部(机器人/PLC/上位系统)通过 TCP 发来一行文本,逗号分割:触发命令[,参数...]
  2. ExecuteAsync 拆出 triggerCommandcommandParams
  3. 并发防重TryEnterCommandExecution——同一触发命令上一次没跑完,直接回 触发命令,NG
  4. switch(triggerCommand) 分发,主要内置命令:
    • LoadProduct,{产品名} —— 加载产品(读产品目录下流程/配方);
    • GetProductName[,编号] / GetProductID[,产品名] —— 产品查询;
    • GetToolParam,{触发命令},{工具号} / GetProcessParam,{触发命令} —— 取参数;
    • 视觉触发命令(每个视觉流程在产品里配置了一个 TriggerCommand,如 V1)→ 走视觉任务;
    • 清料任务(编号制,可取消)。
  5. 应答格式统一:{触发命令},OK,{输出项}{触发命令},NG,{原因}

三、视觉引导分支(ExecuteVisionTaskAsync)

按优先级两条路:

  1. 脚本优先:流程目录存在脚本文件 → ScriptHelper.ExecuteVisionScriptingAsync (CS-Script/Roslyn 编译执行,整段流程逻辑可被工程师用 C# 接管);
  2. 内置流程(无脚本时):
    • 普通流程 → ExecuteNormalVisionTaskAsync
    • Feeder 视觉流程ExecuteFeederVisionTaskAsync(见第五节)。

ExecuteNormalVisionTaskAsync 步骤:

  1. SetLightBeforePhoto:按流程配置开光源/背光(可带等待延时);
  2. 拍照:先应用产品配方的相机参数(曝光/增益;UVC 的亮度/对比度)→ camera.Grab(); 拍照失败按配置的重试上限重试;
  3. 运行视觉流程(VisionPro ToolBlock / OCR 等);
  4. GetVisionOutput:按产品里配置的输出项收集结果——
    • 普通项:直接输出值;
    • 点位项(IsPointTran):值格式 "x,y,u; x,y,u; ..."(分号分多个目标),逐点 ConvertPixelToPosition 换算成机器人坐标(保留 3 位小数,附加字段原样带回去); 移动相机(MobileJ4/XY模组)必须携带机器人当前位姿 robotPos 参与换算,否则报 RobotPositionNull
  5. 回调应答:{触发命令},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:吸取 vs 夹取)

模型: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 步的「吸气/破真空」按钮即此)。


六、Feeder 分支(供料 + 背光联动)

控制链路Team.FFFeederService 独立类库——

  • TEAM 品牌:TouchSocket TcpClient,ASCII 大括号命令:{K1}/{K0} 背光开关、{UV1}~{UV26} 选振动组、 {DV} 保存、{HC} 停止、{CA}~{CI},{毫秒} 方向振动(前/后/左/右/斜向);振幅/频率/相位经寄存器读写 (平台起始地址 300、料斗 742、序列 950);断线 1s 重连。
  • Afag 品牌:aflex 协议(SetAuxPowerOut 背光/辅助输出,振动强度/方向/配置号读写)。

与视觉/机器人联动(生产)

  1. ExecuteFeederVisionTaskAsync:解析触发命令选项(是否先振动 / 是否先拍照);
  2. ExecuteFeederForPhotoBefore:先振动供料 + OpenLightAsync 开环形背光(带亮度与延时);
  3. 拍照失败按重试上限重试 → 运行视觉流程 → 输出点位集合(Feeder 场景常为多目标);
  4. 产品流程里 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 实施;架构侧由本侧验收。