using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using System.Linq; namespace A032.Process { public partial class ProcessControl { #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}的绑定设备信息"); } 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); } /// /// 信号要求长信号触发,避免误触发 /// /// /// /// [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 models = new List(); // 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 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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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)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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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)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() { 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 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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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)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() { { "OUTPUT_X", new HTuple() }, { "OUTPUT_Y", new HTuple() }, { "OUTPUT_Angle", new HTuple() } }, new Dictionary() { { "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)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() { 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() { { "OUTPUT_Result", new HTuple() } }, new Dictionary() { { "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() { "-1" }); // // throw new ProcessException("产线忙,等待超时"); // //} // //else // //{ // // bind.Robot.SendMsg(RobotMsgType.Send, -1, true, RobotMsgAction.State, RobotMsgParas.LineSnap, new List() { "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 } }