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);
            }
        }
Beispiel #2
0
        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);
         }
     }
 }
Beispiel #5
0
        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);
            }
        }
Beispiel #7
0
        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);
 }
Beispiel #14
0
 private bool WritePositionPro(RollPosition rollPos)
 {
     return(true);
 }
Beispiel #15
0
        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);
        }