private void DequeueRoll(Queue <RollPosition> robotRollQ, RollPosition roll, ListView lv) { try { lock (robotRollQ) { if (robotRollQ == null || robotRollQ.Count == 0) { return; } var roll2 = robotRollQ.Peek(); if (roll2 != null && roll.LabelCode == roll2.LabelCode) //如果取出来还是原来那一个,就删一下 { robotRollQ.Dequeue(); log($"号码出机器人队列: {roll.LabelCode}.", LogType.ROBOT_STACK); } if (roll2 == null) { log($"!来源: {nameof(DequeueRoll)}, 机器人队列中无此号码: {roll.LabelCode}", LogType.ROBOT_STACK); } } FrmMain.showRobotQue(robotRollQ, lv); } catch (Exception ex) { log($"!来源: {nameof(DequeueRoll)}, {roll.LabelCode}. {ex}", LogType.ROBOT_STACK, LogViewType.OnlyFile); } }
private void BadShape(RollPosition roll) { var layerLabels = LableCode.GetLableCodesOfRecentFloor(roll.ToLocation, roll.PanelNo, roll.Floor); if (LayerShape.IsSlope(layerLabels) || LayerShape.IsVshape(layerLabels)) { FrmMain.logOpt.Write($"!{roll.RealLocation} 第{roll.Floor}层 形状不规则。板号{roll.PanelNo}", LogType.ROBOT_STACK); } }
private void BadShape(RollPosition roll) { var layerLabels = LableCode.GetLableCodesOfRecentFloor(roll.ToLocation, roll.PanelNo, roll.Floor); if (LayerShape.IsSlope(layerLabels) || LayerShape.IsVshape(layerLabels)) { lock (client) { PlcHelper.NotifyBadLayerShape(client, param, roll.RealLocation); } log($"!{roll.RealLocation}/{roll.Floor}形状不规则。板号{roll.PanelNo}", LogType.ROBOT_STACK); } }
public bool AddRoll(RollPosition roll) { lock (Rolls) { if (!IsInRoll(roll)) { Rolls.Enqueue(roll); return(true); } else { return(false); } } }
public void NotifyOpcJobFinished(RollPosition roll) { try { switch (roll.PnlState) { case PanelState.HalfFull: FrmMain.logOpt.Write($"{roll.RealLocation}: 半满板信号发出。slot: ", LogType.ROBOT_STACK); break; case PanelState.Full: FrmMain.logOpt.Write($"{roll.RealLocation}: 满板信号发出。slot: ", LogType.ROBOT_STACK); LableCode.SetPanelFinished(roll.PanelNo); lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(roll.RealLocation); } break; case PanelState.LessHalf: break; default: FrmMain.logOpt.Write($"!板状态不明,不发信号, {roll.PnlState}", LogType.ROBOT_STACK); break; } if (roll.Status == (int)LableState.FloorLastRoll && roll.PnlState != PanelState.Full) { BadShape(roll); } #if DEBUG var panel = LableCode.GetPanel(roll.PanelNo); if (roll.Status == (int)LableState.FloorLastRoll && roll.PnlState != PanelState.Full && roll.Floor == panel.MaxFloor) { throw new Exception($"板满状态不一致。{roll.LabelCode}, {roll.ToLocation}/{roll.RealLocation}"); roll.PnlState = PanelState.Full; LableCode.SetPanelFinished(roll.PanelNo); lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(roll.RealLocation); } } #endif } catch (Exception ex) { FrmMain.logOpt.Write($"!来源: {nameof(NotifyOpcJobFinished)}, {ex}", LogType.ROBOT_STACK); } }
private void runtask(Queue <RollPosition> que, bool sideA, ref bool isrunning, ListView view) { RollPosition roll = null; lock (TaskQueues.LOCK_LOCHELPER) { if (que.Count > 0) { roll = que.Peek(); } } if (roll != null) { JobTask(ref isrunning, sideA, que, roll, view); } }
private void DequeueRoll(Queue <RollPosition> robotRollQ, RollPosition roll, ListView lv) { lock (TaskQueues.LOCK_LOCHELPER) { if (robotRollQ == null || robotRollQ.Count == 0) { return; } var roll2 = robotRollQ.Peek(); if (roll2 != null && roll.LabelCode == roll2.LabelCode) //如果取出来还是原来那一个,就删一下 { robotRollQ.Dequeue(); FrmMain.showRobotQue(robotRollQ, lv); } } }
private bool WritePositionPro(RollPosition rollPos) { const int DELAY = 10; // 写变量之前,先设置完成状态为0。 var writeReady = rCtrl.SetVariables(VariableType.B, 1, 1, "0"); var a = rCtrl.SetVariables(VariableType.B, 10, 1, rollPos.ChangeAngle ? "1" : "0"); Thread.Sleep(DELAY); var b = rCtrl.SetVariables(VariableType.B, 0, 1, rollPos.BaseIndex.ToString()); Thread.Sleep(DELAY); var c = rCtrl.SetVariables(VariableType.B, 5, 1, "1"); //? Thread.Sleep(DELAY); // 原点高位旋转 var d = rCtrl.SetPostion(PosVarType.Robot, rollPos.Origin, 100, PosType.User, 0, rollPos.GetRealLocationNo()); Thread.Sleep(DELAY); //基座 var e = rCtrl.SetPostion(PosVarType.Base, new PostionVar(rollPos.Base2 * 1000, 0, 0, 0, 0), 0, PosType.Robot, 0, 0); Thread.Sleep(DELAY); // 目标位置 var f = rCtrl.SetPostion(PosVarType.Robot, rollPos.Target, 101, PosType.User, 0, rollPos.GetRealLocationNo()); Thread.Sleep(DELAY); // 写变量之后,设置完成状态为1. var writeOk = rCtrl.SetVariables(VariableType.B, 1, 1, "1"); return(a && b && c && d && e && f && writeReady && writeOk); }
/// <summary> /// 尝试多次机器人写坐标,直到成功或用完次数。 /// </summary> /// <param name="rollPos"></param> /// <param name="times"></param> /// <returns></returns> public bool TryWritePositionPro(RollPosition rollPos, int times = 5) { const int DELAY = 100; var counts = 0; var wstatus = false; var t = TimeCount.TimeIt(() => { while (times > 0) { counts++; wstatus = WritePositionPro(rollPos); if (wstatus) { break; } times--; Thread.Sleep(DELAY); } }); log($"机器人写坐标{(wstatus ? "成功" : "失败")}耗时{t}毫秒,尝试次数{counts}, {rollPos.LabelCode}, {rollPos.Pos_s()} ChangeAngle {rollPos.ChangeAngle}。", LogType.ROBOT_STACK); return(wstatus); }
/// <summary> /// 判断队列中是否已经有该布卷。 /// </summary> /// <param name="roll"></param> /// <returns></returns> public bool IsInRoll(RollPosition roll) { return(Rolls.Any(item => { return item.IsSameLabel(roll); })); }
public bool JobTask(ref bool isrun, bool isSideA, Queue <RollPosition> robotRollQ, RollPosition roll, ListView lv) { // 等待板可放料 FrmMain.logOpt.Write($"{roll.RealLocation}等待可放料信号。", LogType.ROBOT_STACK); if (!PanelAvailable(roll.RealLocation)) { FrmMain.logOpt.Write($"!{roll.RealLocation}未收到可放料信号,请检查板状态和是否有形状不规则报警。", LogType.ROBOT_STACK); return(false); } else { FrmMain.logOpt.Write($"{roll.RealLocation}收到可放料信号。", LogType.ROBOT_STACK); } // 机器人正忙,等待。 while (isrun) { if (TryIsBusy()) { onerror?.Invoke(true, "机器人忙"); FrmMain.logOpt.Write($"!机器人正忙", LogType.ROBOT_STACK); Thread.Sleep(OPCClient.DELAY * 10); } else { break; } } onerror?.Invoke(true, "机器人准备好"); var writeok = TryWritePositionPro(roll); if (!writeok) { onerror?.Invoke(false, $"发坐标失败"); log($"!{roll.LabelCode}发送坐标失败。", LogType.ROBOT_STACK); return(false); } if (TryRunJob(JOB_NAME)) { onerror?.Invoke(true, $"{JOB_NAME}动作发送完成"); log($"发出机器人示教器动作{JOB_NAME}命令成功, {roll.LabelCode}", LogType.ROBOT_STACK); lock (client) { client.TryWrite(param.RobotParam.RobotJobStart, true); } } else { onerror?.Invoke(false, "动作发送失败"); log($"!机器人示教器动作{JOB_NAME}发送失败, {roll.LabelCode}", LogType.ROBOT_STACK); return(false); } Thread.Sleep(RobotHelper.DELAY * 100); // 500ms. while (isrun) { var side = isSideA ? "A" : "B"; onerror?.Invoke(true, $"等待抓料信号({side}) "); var leaving = false; lock (client) { leaving = isSideA ? param.RobotParam.PlcSnA.ReadSN(client) : param.RobotParam.PlcSnB.ReadSN(client); } if (!leaving) { onerror?.Invoke(true, $"等待抓料信号({side})..."); } if (leaving) { onerror?.Invoke(true, $"{roll.LabelCode}抓起"); log($"布卷抓起: {roll.brief()}.", LogType.ROBOT_STACK); DequeueRoll(robotRollQ, roll, lv); // 出队列 LableCode.SetOnPanelState(roll.LabelCode); // 写数据库。 var sideslot = isSideA ? param.RobotParam.RobotStartA : param.RobotParam.RobotStartB; lock (client) { client.TryWrite(sideslot, false); if (isSideA) { param.RobotParam.PlcSnA.WriteSN(client); } else { param.RobotParam.PlcSnB.WriteSN(client); } } break; } Thread.Sleep(RobotHelper.DELAY * 200); // 1000ms. } // 等待布卷上垛信号 while (isrun) { if (TryIsRollOnPanel()) { NotifyOpcJobFinished(roll); // 告知OPC onerror?.Invoke(true, $"{roll.LabelCode}上垛"); log($"收到布卷{roll.LabelCode}上垛信号,布卷已上垛,实际交地:{roll.RealLocation}。", LogType.ROBOT_STACK); break; } Thread.Sleep(RobotHelper.DELAY * 20); } Thread.Sleep(RobotHelper.DELAY * 400); return(true); }
public void NotifyOpcJobFinished(RollPosition roll) { try { switch (roll.PnlState) { case PanelState.HalfFull: lock (client) { client.TryWrite(param.BAreaFloorFinish[roll.RealLocation], true); } log($"{roll.RealLocation}: 半板信号发出。slot: {param.BAreaFloorFinish[roll.RealLocation]}", LogType.ROBOT_STACK); break; case PanelState.Full: string msg; ErpHelper.NotifyPanelEnd(erpapi, roll.PanelNo, roll.RealLocation, out msg); log(msg, LogType.ROBOT_STACK); LableCode.SetPanelFinished(roll.PanelNo); lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(roll.RealLocation); } lock (client) { PlcHelper.NotifyFullPanel(client, param, roll.RealLocation); } break; case PanelState.LessHalf: break; default: log($"!板状态不明,不发信号, {roll.PnlState}", LogType.ROBOT_STACK); break; } if (roll.Status == (int)LableState.FloorLastRoll && roll.PnlState != PanelState.Full) { BadShape(roll); } var panel = LableCode.GetPanel(roll.PanelNo); if (roll.Status == (int)LableState.FloorLastRoll && roll.PnlState != PanelState.Full && roll.Floor == panel.MaxFloor) { log("!---异常板满状态处理---", LogType.ROBOT_STACK); roll.PnlState = PanelState.Full; string msg; ErpHelper.NotifyPanelEnd(erpapi, roll.PanelNo, roll.RealLocation, out msg); client.TryWrite(param.BAreaPanelFinish[roll.RealLocation], true); log($"{roll.RealLocation}: 异常满板信号发出。slot: {param.BAreaPanelFinish[roll.RealLocation]}", LogType.ROBOT_STACK); log(msg, LogType.ROBOT_STACK); LableCode.SetPanelFinished(roll.PanelNo); lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(roll.RealLocation); } const int SIGNAL_3 = 3; client.TryWrite(param.BAreaPanelState[roll.RealLocation], SIGNAL_3); log($"{roll.RealLocation}: 异常板状态信号发出,状态值: {SIGNAL_3}。slot: {param.BAreaPanelState[roll.RealLocation]}", LogType.ROBOT_STACK); } } catch (Exception ex) { log($"!来源: {nameof(NotifyOpcJobFinished)}, {ex}", LogType.ROBOT_STACK); } }
public bool IsSameLabel(RollPosition roll) { return(this.LabelCode == roll.LabelCode); }
private bool WritePositionPro(RollPosition rollPos) { return(true); }
public bool JobTask(ref bool isrun, bool isSideA, Queue <RollPosition> robotRollQ, RollPosition roll, ListView lv) { // 等待板可放料 if (!PanelAvailable(roll.RealLocation)) { FrmMain.logOpt.Write($"!{roll.RealLocation}未收到可放料信号,请检查板状态和是否有形状不规则报警。", LogType.ROBOT_STACK); return(false); } // 机器人正忙,等待。 while (isrun) { if (IsBusy()) { FrmMain.logOpt.Write($"!机器人正忙", LogType.ROBOT_STACK); #if DEBUG Thread.Sleep(FakeOpcClient.DELAY * 10); #endif } else { break; } } if (!TryWritePositionPro(roll)) { return(false); } if (TryRunJob(JOB_NAME)) { log($"发出机器人示教器动作{JOB_NAME}命令成功。", LogType.ROBOT_STACK); client.TryWrite(param.RobotParam.RobotJobStart, true); } else { log($"!机器人示教器动作{JOB_NAME}发送失败。", LogType.ROBOT_STACK); return(false); } Thread.Sleep(RobotHelper.DELAY * 200); //删除对列布卷 while (isrun) { var leaving = client.TryReadBool(isSideA ? param.RobotParam.RobotStartA : param.RobotParam.RobotStartB); if (leaving) { log($"roll is leaving: {roll.LabelCode}.", LogType.ROBOT_STACK, LogViewType.OnlyFile); DequeueRoll(robotRollQ, roll, lv); client.TryWrite(isSideA ? param.RobotParam.RobotStartA : param.RobotParam.RobotStartB, false); break; } Thread.Sleep(RobotHelper.DELAY); } // 等待布卷上垛信号 while (isrun) { if (IsRollOnPanel()) { // 写数据库。 LableCode.SetOnPanelState(roll.LabelCode); // 告知OPC NotifyOpcJobFinished(roll); log("布卷已上垛。", LogType.ROBOT_STACK, LogViewType.Both); break; } Thread.Sleep(RobotHelper.DELAY * 20); } // 等待机器人结束码垛。 while (isrun && IsBusy()) { Thread.Sleep(RobotHelper.DELAY * 20); } DequeueRoll(robotRollQ, roll, lv); if (!isrun) //解决压布,布卷未上垛问题 // 写数据库。 { LableCode.SetOnPanelState(roll.LabelCode); // 告知OPC NotifyOpcJobFinished(roll); log($"{roll.LabelCode}布卷已上垛。", LogType.ROBOT_STACK, LogViewType.Both); } log($"robot job done: {roll.LabelCode}.", LogType.ROBOT_STACK); return(true); }