| | |
| | | using Bro.Common.Helper; |
| | | using Bro.Common.Interface; |
| | | using Bro.Common.Model; |
| | | using Bro.Device.HikCamera; |
| | | using HalconDotNet; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Drawing; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | |
| | | namespace A032.Process |
| | | { |
| | | public enum ResultState |
| | | { |
| | | OK = 1, |
| | | NG = -1, |
| | | Undetermined = -2, |
| | | } |
| | | |
| | | public partial class ProcessControl |
| | | { |
| | | public void QueryRobotIO() |
| | | #region Robot监听事件 |
| | | [ProcessMethod("", "Robot_Monitor_Alarm", "机器人监听事件-报警", true)] |
| | | public ProcessResponse Robot_Monitor_Alarm(IOperationConfig config, IDevice device) |
| | | { |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | } |
| | | if (bind == null) |
| | | { |
| | | throw new ProcessException($"未能获取{device.Name}的绑定设备信息"); |
| | | } |
| | | |
| | | [ProcessMethod("HikCamera", "RobotCorrection", "拍摄,确认机器人调整位置", true)] |
| | | public ProcessResponse RobotCorrection(IOperationConfig config) |
| | | { |
| | | bind.AGV.CancelTask(); |
| | | bind.UnitState = AGVState.Warning; |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | [ProcessMethod("", "Robot_Monitor_EmptyTrayEmpty", "机器人监听事件-空Tray区域清空", true)] |
| | | public ProcessResponse Robot_Monitor_EmptyTrayEmpty(IOperationConfig config, IDevice device) |
| | | { |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | if (bind == null) |
| | | { |
| | | throw new ProcessException($"未能获取{device.Name}的绑定设备信息"); |
| | | } |
| | | |
| | | bind.EmptyTrayNum = 0; |
| | | |
| | | TrayTask task = new TrayTask(); |
| | | task.TaskType = TaskType.LoadEmptyTrayToAGV; |
| | | //task.Priority = 10; |
| | | task.SourceDeviceId = device.Id; |
| | | //task.SourceDeviceName = device.Name; |
| | | |
| | | //如果目前地址被占用,地址有可能为空,需要在任务指派时再次确认 |
| | | task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | |
| | | InsertTask(task); |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 信号要求长信号触发,避免误触发 |
| | | /// </summary> |
| | | /// <param name="config"></param> |
| | | /// <param name="device"></param> |
| | | /// <returns></returns> |
| | | [ProcessMethod("", "Robot_Monitor_FullTrayFull", "机器人监听事件-满Tray区域放满", true)] |
| | | public ProcessResponse Robot_Monitor_FullTrayFull(IOperationConfig config, IDevice device) |
| | | { |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | if (bind == null) |
| | | { |
| | | throw new ProcessException($"未能获取{device.Name}的绑定设备信息"); |
| | | } |
| | | |
| | | //if (bind.FullTrayNum >= Config.AGVAvailableTrayNums) |
| | | { |
| | | bind.FullTrayNum = Config.AGVAvailableTrayNums; |
| | | |
| | | TrayTask task = new TrayTask(); |
| | | task.TaskType = TaskType.UnloadFullTrayToLine; |
| | | task.SourceDeviceId = device.Id; |
| | | |
| | | //如果目前地址被占用,地址有可能为空,需要在任务指派时再次确认 |
| | | task.Location = Config.PositionCollection.FirstOrDefault(u => !u.IsOccupied && u.Description == PathPositionDefinition.UnloadFullTray); |
| | | |
| | | InsertTask(task); |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | [ProcessMethod("", "Robot_Monitor_FullTrayEmpty", "机器人监听事件-满Tray区域清空", true)] |
| | | public ProcessResponse Robot_Monitor_FullTrayEmpty(IOperationConfig config, IDevice device) |
| | | { |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | if (bind == null) |
| | | { |
| | | throw new ProcessException($"未能获取{device.Name}的绑定设备信息"); |
| | | } |
| | | |
| | | bind.FullTrayNum = 0; |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | //[ProcessMethod("", "Robot_Monitor_LoadEmptyTrayReady", "机器人监听事件-载入空Tray就绪", true)] |
| | | //public ProcessResponse Robot_Monitor_LoadEmptyTrayReady(IOperationConfig config, IDevice device) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | // if (bind == null) |
| | | // { |
| | | // throw new ProcessException("未能根据机器人信息获取绑定设备信息", null); |
| | | // } |
| | | |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // new ProcessException("上空Tray完成信号仅在上空Tray地点有效", null); |
| | | // return new ProcessResponse(true); |
| | | // } |
| | | |
| | | // List<AGVTaskModel> models = new List<AGVTaskModel>(); |
| | | // models.Add(new AGVTaskModel(TaskAvailableLevel.AGV, EmptyTrayReady)); |
| | | // AddNewTaskToBind(bind, models); |
| | | |
| | | // return new ProcessResponse(true); |
| | | //} |
| | | |
| | | [ProcessMethod("", "Robot_Monitor_Reset", "机器人监听事件-Reset复位", true)] |
| | | public ProcessResponse Robot_Monitor_Reset(IOperationConfig config, IDevice device) |
| | | { |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == device.Id); |
| | | |
| | | if (bind == null) |
| | | { |
| | | throw new ProcessException($"未能获取{device.Name}的绑定设备信息"); |
| | | } |
| | | bind.AGV.CancelTask(); |
| | | |
| | | Reset(bind.Id); |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | #endregion |
| | | |
| | | #region PLC监听事件 |
| | | [ProcessMethod("", "PLC_NoticeEmptyTray", "PLC通知需要上空Tray", true)] |
| | | public ProcessResponse PLC_NoticeEmptyTray(IOperationConfig config, IDevice device) |
| | | { |
| | | TrayTask task = new TrayTask(); |
| | | task.TaskType = TaskType.UnloadEmptyTrayToMachine; |
| | | task.SourceDeviceId = device.Id; |
| | | //task.SourceDeviceName = device.Name; |
| | | task.Location = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.DeviceOwner == device.Id); |
| | | |
| | | InsertTask(task); |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | [ProcessMethod("", "PLC_NoticeFullTray", "PLC通知满Tray需要取走", true)] |
| | | public ProcessResponse PLC_NoticeFullTray(IOperationConfig config, IDevice device) |
| | | { |
| | | TrayTask task = new TrayTask(); |
| | | task.TaskType = TaskType.LoadFullTrayFromMachine; |
| | | task.SourceDeviceId = device.Id; |
| | | //task.SourceDeviceName = device.Name; |
| | | task.Location = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.DeviceOwner == device.Id); |
| | | |
| | | InsertTask(task); |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | #endregion |
| | | |
| | | [ProcessMethod("OperationTest", "OperationDemo", "单步测试方法", true)] |
| | | public ProcessResponse OperationDemo(IOperationConfig config, IDevice device) |
| | | { |
| | | string s = (-1).ToString("D2"); |
| | | string a = (1).ToString("D2"); |
| | | |
| | | OperationTestConfig opConfig = config as OperationTestConfig; |
| | | |
| | | var bind = Config.AGVBindCollection.FirstOrDefault(u => u.AGVId == opConfig.AGVId); |
| | | if (bind == null) |
| | | throw new ProcessException("未能获取指定AGV信息或AGV绑定的设备信息"); |
| | | |
| | | switch (opConfig.TaskInfo.TaskType) |
| | | { |
| | | case TaskType.LoadEmptyTrayToAGV: |
| | | LoadEmptyTrayToAGV(opConfig.TaskInfo, bind); |
| | | break; |
| | | case TaskType.LoadFullTrayFromMachine: |
| | | LoadFullTrayFromMachine(opConfig.TaskInfo, bind); |
| | | break; |
| | | case TaskType.UnloadEmptyTrayToMachine: |
| | | UnloadEmptyTrayToMachine(opConfig.TaskInfo, bind); |
| | | break; |
| | | case TaskType.UnloadFullTrayToLine: |
| | | UnloadFullTrayToLine(opConfig.TaskInfo, bind); |
| | | break; |
| | | default: |
| | | throw new ProcessException($"未能指定{opConfig.TaskInfo.TaskType.ToString()}的对应方法"); |
| | | } |
| | | |
| | | return new ProcessResponse(true); |
| | | } |
| | | |
| | | #region old |
| | | //#region 空Tray上料 |
| | | ////[ProcessMethod("", "AGV_LoadEmptyTray", "AGV去往空Tray上料", true)] |
| | | ////public ProcessResponse AGV_LoadEmptyTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置空Tray上料点"); |
| | | //// } |
| | | |
| | | //// bind.AGVDest = position.PositionCode; |
| | | //// bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | //// bind.AGVStatus = TaskStatus.Running; |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public bool AGV_LoadEmptyTray(string bindId) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置空Tray上料点"); |
| | | // } |
| | | |
| | | // if (bind.SetAGVStatus(TaskStatus.Running)) |
| | | // { |
| | | // bind.AGVDest = position.PositionCode; |
| | | // bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | // return true; |
| | | // } |
| | | // else |
| | | // { |
| | | // return false; |
| | | // } |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "AfterEmptyTrayPositionArrived", "到达空Tray上料点", true)] |
| | | ////public ProcessResponse AfterEmptyTrayPositionArrived(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置空Tray上料点", null); |
| | | //// } |
| | | |
| | | //// if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | //// { |
| | | //// throw new ProcessException("AGV尚未到达空Tray上料点", null); |
| | | //// } |
| | | |
| | | //// bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.EmptyTray, 0); |
| | | //// bind.RobotStatus = TaskStatus.Running; |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public void Robot_LoadEmptyTray(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadEmptyTray); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置空Tray上料点", null); |
| | | // } |
| | | |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // throw new ProcessException("AGV尚未到达空Tray上料点", null); |
| | | // } |
| | | |
| | | // bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.EmptyTray, 0); |
| | | // bind.RobotStatus = TaskStatus.Running; |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "EmptyTrayReady", "空Tray上料完成", true)] |
| | | ////public ProcessResponse EmptyTrayReady(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// bind.RobotStatus = bind.AGVStatus = TaskStatus.Available; |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | //#endregion |
| | | |
| | | //#region 空Tray往机台下料 |
| | | ////bool isEmptyTrayNeed = false; |
| | | ////bool isEmptyTrayTaskAssigned = false; |
| | | //RobotMsg RobotMsg_UnloadEmptyTray = new RobotMsg(); |
| | | |
| | | //private async void CheckUnloadEmptyTrayTask(int positionNo) |
| | | //{ |
| | | // await Task.Run(() => |
| | | // { |
| | | // var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); |
| | | |
| | | // if (taskStatus == null) |
| | | // return; |
| | | |
| | | // while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) |
| | | // { |
| | | // //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_UnloadEmptyTray; |
| | | |
| | | // //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodName == "AGV_UnloadEmptyTray"))) |
| | | // { |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); |
| | | // if (bind != null) |
| | | // { |
| | | // var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); |
| | | // //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_UnloadEmptyTray", new AGVBindOpConfig(bind.Id, position)); |
| | | // //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_UnloadEmptyTray", new AGVBindOpConfig(bind.Id)); |
| | | |
| | | // //bind.AddTask(model_AGV); |
| | | // //bind.AddTask(model_Robot); |
| | | |
| | | // if (AGV_UnloadEmptyTray(bind.Id, position)) |
| | | // { |
| | | // taskStatus.IsTaskAssgined = true; |
| | | // taskStatus.AgvId = bind.AGVId; |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | // Thread.Sleep(WAITTIME); |
| | | // } |
| | | // }); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "AGV_UnloadEmptyTray", "AGV去往卸载空Tray料位置", true)] |
| | | //public bool AGV_UnloadEmptyTray(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置空Tray下料点"); |
| | | // } |
| | | |
| | | // if (bind.SetAGVStatus(TaskStatus.Running)) |
| | | // { |
| | | // bind.AGVDest = position.PositionCode; |
| | | // bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | // return true; |
| | | // } |
| | | // else |
| | | // { |
| | | // return false; |
| | | // } |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Robot_UnloadEmptyTray", "机器人运动至空Tray拍照位置", true)] |
| | | //public void Robot_UnloadEmptyTraySnap(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray && u.PositionCode == bind.AGV.CurrentPosition); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置空Tray下料点"); |
| | | // } |
| | | |
| | | // taskAssignedList.RemoveAll(u => u.AgvId == bind.AGVId && u.PositionNo == position.PositionNo); |
| | | |
| | | // bind.RobotStatus = TaskStatus.Running; |
| | | // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.UnloadEmptyTraySnap, position.PositionNo); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Camera_UnloadEmptyTray", "相机确认空Tray卸载机器人位置调整", true)] |
| | | ////public ProcessResponse Camera_UnloadEmptyTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadEmptyTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置空Tray下料点"); |
| | | //// } |
| | | |
| | | //// if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | //// { |
| | | //// throw new ProcessException("AGV当前未处于空Tray下料点"); |
| | | //// } |
| | | |
| | | //// PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); |
| | | |
| | | //// if (visionConfig == null) |
| | | //// { |
| | | //// throw new ProcessException("未配置该相机的空Tray下料点的视觉操作配置"); |
| | | //// } |
| | | |
| | | //// float x = 0; |
| | | //// float y = 0; |
| | | //// float angle = 0; |
| | | |
| | | //// using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) |
| | | //// { |
| | | //// string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; |
| | | //// if (!_halconToolDict.ContainsKey(toolPath)) |
| | | //// { |
| | | //// throw new ProcessException($"未配置Camera_UnloadEmptyTray的视觉算法路径"); |
| | | //// } |
| | | |
| | | //// var tool = _halconToolDict[toolPath]; |
| | | //// tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); |
| | | //// tool.RunProcedure(); |
| | | |
| | | //// x = (float)tool.GetResultTuple("OUTPUT_X").D; |
| | | //// y = (float)tool.GetResultTuple("OUTPUT_Y").D; |
| | | //// angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; |
| | | //// } |
| | | |
| | | //// if (x <= 0 || y <= 0) |
| | | //// { |
| | | //// throw new ProcessException("Camera_UnloadEmptyTray视觉计算获取点位不可小于0"); |
| | | //// } |
| | | |
| | | //// float dx = visionConfig.StandardPoint.X - x; |
| | | //// float dy = visionConfig.StandardPoint.Y - y; |
| | | |
| | | //// HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); |
| | | |
| | | //// bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public ProcessResponse Camera_UnloadEmptyTray(string robotId, int positionNum) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); |
| | | |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置空Tray下料点"); |
| | | // } |
| | | |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // throw new ProcessException("AGV当前未处于空Tray下料点"); |
| | | // } |
| | | |
| | | // float adjust_X = 0.0f; |
| | | // float adjust_Y = 0.0f; |
| | | // float adjust_Angle = 0.0f; |
| | | |
| | | // if (Config.IsEnableVisionGuide) |
| | | // { |
| | | // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); |
| | | |
| | | // if (visionConfig == null) |
| | | // { |
| | | // throw new ProcessException("未配置该相机的空Tray下料点的视觉操作配置"); |
| | | // } |
| | | |
| | | // float x = 0; |
| | | // float y = 0; |
| | | // float angle = 0; |
| | | |
| | | // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadEmptyTray")) |
| | | // { |
| | | // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; |
| | | // if (!_halconToolDict.ContainsKey(toolPath)) |
| | | // { |
| | | // throw new ProcessException($"未配置Camera_UnloadEmptyTray的视觉算法路径"); |
| | | // } |
| | | |
| | | // var tool = _halconToolDict[toolPath]; |
| | | // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); |
| | | // tool.RunProcedure(); |
| | | |
| | | // x = (float)tool.GetResultTuple("OUTPUT_X").D; |
| | | // y = (float)tool.GetResultTuple("OUTPUT_Y").D; |
| | | // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; |
| | | // } |
| | | |
| | | // if (x <= 0 || y <= 0) |
| | | // { |
| | | // throw new ProcessException("Camera_UnloadEmptyTray视觉计算获取点位不可小于0"); |
| | | // } |
| | | |
| | | // float dx = visionConfig.StandardPoint.X - x; |
| | | // float dy = visionConfig.StandardPoint.Y - y; |
| | | |
| | | // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); |
| | | |
| | | // adjust_X = (float)dx_Robot.D; |
| | | // adjust_Y = (float)dy_Robot.D; |
| | | // adjust_Angle = visionConfig.StandardPoint.Angle - angle; |
| | | // } |
| | | |
| | | // //bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.EmptyTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); |
| | | // RobotMsg_UnloadEmptyTray.Action = RobotMsgAction.Unload; |
| | | // RobotMsg_UnloadEmptyTray.Para1 = RobotMsgParas.EmptyTray; |
| | | // RobotMsg_UnloadEmptyTray.Para2 = position.PositionNo; |
| | | // RobotMsg_UnloadEmptyTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); |
| | | // bind.Robot.SendMsg(RobotMsg_UnloadEmptyTray, true); |
| | | |
| | | // return new ProcessResponse(true); |
| | | //} |
| | | //#endregion |
| | | |
| | | //#region 从机台上满Tray |
| | | ////bool isFullTrayNeed = false; |
| | | ////bool isFullTrayTaskAssigned = false; |
| | | //RobotMsg RobotMsg_LoadFullTray = new RobotMsg(); |
| | | |
| | | //private async void CheckFullTrayTask(int positionNo) |
| | | //{ |
| | | // await Task.Run(() => |
| | | // { |
| | | // var taskStatus = taskAssignedList.FirstOrDefault(u => u.PositionNo == positionNo); |
| | | |
| | | // if (taskStatus == null) |
| | | // return; |
| | | |
| | | // while (taskStatus.IsTaskNeed && !taskStatus.IsTaskAssgined) |
| | | // { |
| | | // //Func<IOperationConfig, IDevice, ProcessResponse> action = AGV_LoadFullTray; |
| | | |
| | | // //if (!Config.AGVBindCollection.Any(b => b.TaskList.Any(t => t.MethodFunc.Method.Name == action.Method.Name))) |
| | | // { |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.UnitStatus == TaskStatus.Available); |
| | | // if (bind != null) |
| | | // { |
| | | // var position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNo); |
| | | // //AGVTaskModel model_AGV = new AGVTaskModel(TaskAvailableLevel.Both, "AGV_LoadFullTray", new AGVBindOpConfig(bind.Id, position)); |
| | | // //AGVTaskModel model_Robot = new AGVTaskModel(TaskAvailableLevel.AGV, "Robot_LoadFullTray", new AGVBindOpConfig(bind.Id)); |
| | | |
| | | // //bind.AddTask(model_AGV); |
| | | // //bind.AddTask(model_Robot); |
| | | |
| | | // if (AGV_LoadFullTray(bind.Id, position)) |
| | | // { |
| | | // taskStatus.IsTaskAssgined = true; |
| | | // taskStatus.AgvId = bind.AGVId; |
| | | // } |
| | | // } |
| | | // } |
| | | |
| | | // Thread.Sleep(300); |
| | | // } |
| | | // }); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "AGV_LoadFullTray", "AGV去往满Tray上料位置", true)] |
| | | //public bool AGV_LoadFullTray(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | |
| | | // //PathPosition position = (config as AGVBindOpConfig).Position; |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray上料点"); |
| | | // } |
| | | |
| | | // if (bind.SetAGVStatus(TaskStatus.Running)) |
| | | // { |
| | | // bind.AGVDest = position.PositionCode; |
| | | // bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | // return true; |
| | | // } |
| | | // else |
| | | // { |
| | | // return false; |
| | | // } |
| | | |
| | | // //return new ProcessResponse(true); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Robot_LoadFullTray", "机器人运动至满Tray拍照位置", true)] |
| | | ////public ProcessResponse Robot_LoadFullTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置满Tray上料点"); |
| | | //// } |
| | | |
| | | //// //if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | //// //{ |
| | | //// // throw new ProcessException("AGV当前未处于满Tray上料点"); |
| | | //// //} |
| | | |
| | | //// bind.RobotStatus = TaskStatus.Running; |
| | | //// bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LoadFullTraySnap, position.PositionNo); |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public void Robot_LoadFullTraySnap(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray && u.PositionCode == bind.AGV.CurrentPosition); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray上料点"); |
| | | // } |
| | | |
| | | // //if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // //{ |
| | | // // throw new ProcessException("AGV当前未处于满Tray上料点"); |
| | | // //} |
| | | |
| | | // bind.RobotStatus = TaskStatus.Running; |
| | | // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LoadFullTraySnap, position.PositionNo); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Camera_LoadFullTray", "相机确认满Tray上料机器人位置调整", true)] |
| | | ////public ProcessResponse Camera_LoadFullTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.LoadFullTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置满Tray上料点"); |
| | | //// } |
| | | |
| | | //// if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | //// { |
| | | //// throw new ProcessException("AGV当前未处于满Tray上料点"); |
| | | //// } |
| | | |
| | | //// PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); |
| | | |
| | | //// if (visionConfig == null) |
| | | //// { |
| | | //// throw new ProcessException("未配置该相机的满Tray上料点的视觉操作配置"); |
| | | //// } |
| | | |
| | | //// float x = 0; |
| | | //// float y = 0; |
| | | //// float angle = 0; |
| | | |
| | | //// using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) |
| | | //// { |
| | | //// string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; |
| | | //// if (!_halconToolDict.ContainsKey(toolPath)) |
| | | //// { |
| | | //// throw new ProcessException($"未配置Camera_LoadFullTray的视觉算法路径"); |
| | | //// } |
| | | |
| | | //// var tool = _halconToolDict[toolPath]; |
| | | //// tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); |
| | | //// tool.RunProcedure(); |
| | | |
| | | //// x = (float)tool.GetResultTuple("OUTPUT_X").D; |
| | | //// y = (float)tool.GetResultTuple("OUTPUT_Y").D; |
| | | //// angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; |
| | | //// } |
| | | |
| | | //// if (x <= 0 || y <= 0) |
| | | //// { |
| | | //// throw new ProcessException("Camera_LoadFullTray视觉计算获取点位不可小于0"); |
| | | //// } |
| | | |
| | | //// float dx = visionConfig.StandardPoint.X - x; |
| | | //// float dy = visionConfig.StandardPoint.Y - y; |
| | | |
| | | //// HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); |
| | | |
| | | //// bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public ProcessResponse Camera_LoadFullTray(string robotId, int positionNum) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); |
| | | |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.PositionNo == positionNum); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray上料点"); |
| | | // } |
| | | |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // throw new ProcessException("AGV当前未处于满Tray上料点"); |
| | | // } |
| | | |
| | | // float adjust_X = 0.0f; |
| | | // float adjust_Y = 0.0f; |
| | | // float adjust_Angle = 0.0f; |
| | | |
| | | // if (Config.IsEnableVisionGuide) |
| | | // { |
| | | // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); |
| | | |
| | | // if (visionConfig == null) |
| | | // { |
| | | // throw new ProcessException("未配置该相机的满Tray上料点的视觉操作配置"); |
| | | // } |
| | | |
| | | // float x = 0; |
| | | // float y = 0; |
| | | // float angle = 0; |
| | | |
| | | // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_LoadFullTray")) |
| | | // { |
| | | // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; |
| | | // if (!_halconToolDict.ContainsKey(toolPath)) |
| | | // { |
| | | // throw new ProcessException($"未配置Camera_LoadFullTray的视觉算法路径"); |
| | | // } |
| | | |
| | | // var tool = _halconToolDict[toolPath]; |
| | | // tool.SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); |
| | | // tool.RunProcedure(); |
| | | |
| | | // x = (float)tool.GetResultTuple("OUTPUT_X").D; |
| | | // y = (float)tool.GetResultTuple("OUTPUT_Y").D; |
| | | // angle = (float)tool.GetResultTuple("OUTPUT_Angle").D; |
| | | // } |
| | | |
| | | // if (x <= 0 || y <= 0) |
| | | // { |
| | | // throw new ProcessException("Camera_LoadFullTray视觉计算获取点位不可小于0"); |
| | | // } |
| | | |
| | | // float dx = visionConfig.StandardPoint.X - x; |
| | | // float dy = visionConfig.StandardPoint.Y - y; |
| | | |
| | | // HOperatorSet.AffineTransPoint2d(new HTuple(visionConfig.Matrix[0], visionConfig.Matrix[1], 0, visionConfig.Matrix[3], visionConfig.Matrix[4], 0), dx, dy, out HTuple dx_Robot, out HTuple dy_Robot); |
| | | |
| | | // adjust_X = (float)dx_Robot.D; |
| | | // adjust_Y = (float)dy_Robot.D; |
| | | // adjust_Angle = visionConfig.StandardPoint.Angle - angle; |
| | | // } |
| | | |
| | | // //bind.Robot.SendMsg(RobotMsgAction.Load, RobotMsgParas.FullTray, position.PositionNo, new List<float>() { (float)dx_Robot.D, (float)dy_Robot.D, angle }); |
| | | // RobotMsg_LoadFullTray.Action = RobotMsgAction.Load; |
| | | // RobotMsg_LoadFullTray.Para1 = RobotMsgParas.FullTray; |
| | | // RobotMsg_LoadFullTray.Para2 = position.PositionNo; |
| | | // RobotMsg_LoadFullTray.Datas = new List<float>() { adjust_X, adjust_Y, 0, adjust_Angle }.ConvertAll(s => s.ToString()).ToList(); |
| | | // bind.Robot.SendMsg(RobotMsg_LoadFullTray, true); |
| | | |
| | | // return new ProcessResponse(true); |
| | | //} |
| | | //#endregion |
| | | |
| | | //#region 满Tray产线下料 |
| | | ////[ProcessMethod("", "AGV_UnloadFullTray", "AGV去往卸载满Tray料", true)] |
| | | ////public ProcessResponse AGV_UnloadFullTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置满Tray下料点"); |
| | | //// } |
| | | |
| | | //// bind.AGVDest = position.PositionCode; |
| | | //// bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | //// bind.AGVStatus = TaskStatus.Running; |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public bool AGV_UnloadFullTray(string bindId) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray下料点"); |
| | | // } |
| | | |
| | | // if (bind.SetAGVStatus(TaskStatus.Running)) |
| | | // { |
| | | // bind.AGVDest = position.PositionCode; |
| | | // bind.AGV.TaskOrder(position.PositionCode); |
| | | |
| | | // return true; |
| | | // } |
| | | // else |
| | | // { |
| | | // return false; |
| | | // } |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Robot_UnloadFullTray", "机器人卸载满Tray", true)] |
| | | ////public ProcessResponse Robot_UnloadFullTray(IOperationConfig config, IDevice device) |
| | | ////{ |
| | | //// var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == (config as AGVBindOpConfig).BindId); |
| | | //// PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); |
| | | |
| | | //// if (position == null) |
| | | //// { |
| | | //// throw new ProcessException("路径配置未设置满Tray下料点"); |
| | | //// } |
| | | |
| | | //// if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | //// { |
| | | //// throw new ProcessException("AGV当前未处于满Tray下料点"); |
| | | //// } |
| | | |
| | | //// bind.RobotStatus = TaskStatus.Running; |
| | | //// bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LineSnap, position.PositionNo); |
| | | |
| | | //// return new ProcessResponse(true); |
| | | ////} |
| | | |
| | | //public void Robot_UnloadFullTraySnap(string bindId, PathPosition position) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.Id == bindId); |
| | | // //PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray下料点"); |
| | | // } |
| | | |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // throw new ProcessException("AGV当前未处于满Tray下料点"); |
| | | // } |
| | | |
| | | // bind.RobotStatus = TaskStatus.Running; |
| | | // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.LineSnap, position.PositionNo); |
| | | // //LogAsync(DateTime.Now, "Robot运动至下满Tray拍照", ""); |
| | | //} |
| | | |
| | | ////[ProcessMethod("", "Camera_UnloadFullTray", "相机操作卸载满Tray", true)] |
| | | ////public ProcessResponse Camera_UnloadFullTray(IOperationConfig config, IDevice device) |
| | | //public ProcessResponse Camera_UnloadFullTray(string robotId, int positionNum) |
| | | //{ |
| | | // var bind = Config.AGVBindCollection.FirstOrDefault(u => u.RobotId == robotId); |
| | | // PathPosition position = Config.PositionCollection.FirstOrDefault(u => u.Description == PathPositionDefinition.UnloadFullTray && u.PositionNo == positionNum); |
| | | |
| | | // if (position == null) |
| | | // { |
| | | // throw new ProcessException("路径配置未设置满Tray下料点"); |
| | | // } |
| | | |
| | | // if (bind.AGV.CurrentPosition != position.PositionCode) |
| | | // { |
| | | // throw new ProcessException("AGV当前未处于满Tray下料点"); |
| | | // } |
| | | |
| | | // //float adjust_X = 0.0f; |
| | | // //float adjust_Y = 0.0f; |
| | | // //float adjust_Angle = 0.0f; |
| | | // bool isLineReady = false; |
| | | |
| | | // if (Config.IsEnableVisionGuide) |
| | | // { |
| | | // PositionVisionConfig visionConfig = Config.VisionConfigCollection.FirstOrDefault(u => u.PositionCode == position.PositionCode && u.CameraId == bind.CameraId); |
| | | |
| | | // if (visionConfig == null) |
| | | // { |
| | | // throw new ProcessException("未配置该相机的满Tray下料点的视觉操作配置"); |
| | | // } |
| | | |
| | | |
| | | // int reTryTime = Config.LineBusyRetryTimes; |
| | | |
| | | // do |
| | | // { |
| | | // using (HObject hImage = CollectHImage(bind.Camera, visionConfig.CameraOpConfig, "Camera_UnloadFullTray")) |
| | | // { |
| | | // string toolPath = visionConfig.CameraOpConfig.AlgorithemPath; |
| | | // if (!_halconToolDict.ContainsKey(toolPath)) |
| | | // { |
| | | // throw new ProcessException($"未配置Camera_UnloadFullTray的视觉算法路径"); |
| | | // } |
| | | |
| | | // _halconToolDict[toolPath].SetDictionary(new Dictionary<string, HTuple>() { { "OUTPUT_Result", new HTuple() } }, new Dictionary<string, HObject>() { { "INPUT_Image", hImage } }); |
| | | // _halconToolDict[toolPath].RunProcedure(); |
| | | |
| | | // isLineReady = _halconToolDict[toolPath].GetResultTuple("OUTPUT_Result").I == 1; |
| | | // } |
| | | |
| | | // if (!isLineReady) |
| | | // { |
| | | // Thread.Sleep(Config.LineBusyWaitInterval * 1000); |
| | | // reTryTime--; |
| | | // } |
| | | // else |
| | | // { |
| | | // reTryTime = 0; |
| | | // } |
| | | // } while (reTryTime > 0); |
| | | |
| | | // //if (!isLineReady) |
| | | // //{ |
| | | // // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "-1" }); |
| | | // // throw new ProcessException("产线忙,等待超时"); |
| | | // //} |
| | | // //else |
| | | // //{ |
| | | // // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List<string>() { "1" }); |
| | | // //} |
| | | // } |
| | | // else |
| | | // { |
| | | // isLineReady = true; |
| | | // } |
| | | |
| | | // if (isLineReady) |
| | | // { |
| | | // bind.Robot.SendMsg(RobotMsgAction.Unload, RobotMsgParas.FullTray, position.PositionNo); |
| | | // } |
| | | // else |
| | | // { |
| | | // bind.Robot.SendMsg(RobotMsgAction.Move, RobotMsgParas.Home, position.PositionNo); |
| | | // } |
| | | |
| | | // return new ProcessResponse(true); |
| | | //} |
| | | //#endregion |
| | | #endregion |
| | | } |
| | | } |