public CalResult(CacheState state_, LableCode codeToCache_, LableCode codeFromCache_) { state = state_; CodeCome = codeToCache_; CodeFromCache = codeFromCache_; message = ""; }
public void DeleteCodeFromQueAndDb(string code) { lock (TaskQueues.LOCK_LOCHELPER) { deleteFromTaskq(FrmMain.taskQ, code); } log($"号码{code}已从队列中删除"); var label = LableCode.QueryByLCode(code); if (label != null) { label.Remark += ";delete"; // 只有没计算过位置的布卷才可以从数据库中删除。 if (string.IsNullOrEmpty(label.PanelNo) || label.FloorIndex == 0) { LableCode.Delete(label.LCode); LableCode.SaveToHistory(label); log($"号码{label.LCode}已经从数据库中删除"); } else { log($"号码{label.LCode}不能从数据库删除,板号: {label.PanelNo}, 层位置: {label.FloorIndex}"); } // tell plc. notifyOpc(label.LCode); } else { var msg = $"数据库中没有这个号码: {code}"; log(msg); } }
/// <summary> /// 从数据库里取板号,并赋给标签对象。 /// 如果取出的空的,就新产生一个板号。 /// </summary> /// <param name="lc">标签</param> /// <param name="dateShiftNo">任务码</param> /// <returns></returns> public static PanelInfo GetPanelNo(LableCode lc, string dateShiftNo) { var pf = LableCode.GetTolactionCurrPanelNo(lc.ToLocation, dateShiftNo); lc.SetupPanelInfo(pf); return(pf); }
void showlabel(LableCode c) { lbx.Items.Insert(0, $"扫描时间: {c.CreateDate.ToString()}"); lbx.Items.Insert(0, $"板上坐标: {c.Coordinates}"); switch (c.Status) { case 5: lbx.Items.Insert(0, $"状态: 已上垛,且板已完成。"); break; case 3: lbx.Items.Insert(0, $"状态: 已上垛。"); break; case 2: lbx.Items.Insert(0, $"状态: 未上垛,是层最后一卷。"); break; case 0: default: lbx.Items.Insert(0, $"状态: 未上垛。"); break; } lbx.Items.Insert(0, $"层: {c.Floor} 层序号: {c.FloorIndex}"); lbx.Items.Insert(0, $"板号: {c.PanelNo}"); lbx.Items.Insert(0, $"长度: {c.Length}mm 直径: {c.Diameter}mm"); lbx.Items.Insert(0, $"号码: {c.LCode}"); lbx.Items.Insert(0, $"名义交地: {c.ToLocation} 实际交地: {c.RealLocation}"); lbx.Items.Insert(0, $"---------------------"); }
public void NotifyOpcJobFinished(string panelNo, string tolocation, string reallocation, bool panelfull) { try { var pState = panelfull ? PanelState.Full : PanelState.HalfFull; switch (pState) { case PanelState.HalfFull: var lcode = FrmMain.taskQ.UFGetPanelLastRoll(tolocation, panelNo); LableCode.UserSetPanelLastRoll(lcode); //设置板最后一卷布。 FrmMain.logOpt.Write($"{reallocation} 半板信号发出,最后一卷布标签{lcode}。slot: ", LogType.ROBOT_STACK); break; case PanelState.Full: FrmMain.logOpt.Write($"{reallocation}: 满板信号发出。slot: ", LogType.ROBOT_STACK); LableCode.SetPanelFinished(panelNo); // 满板时设置自由板位标志。 lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(reallocation); } break; case PanelState.LessHalf: break; default: FrmMain.logOpt.Write($"!板状态不明,不发信号, {pState}", LogType.ROBOT_STACK); break; } } catch (Exception ex) { FrmMain.logOpt.Write($"!来源: {nameof(NotifyOpcJobFinished)}, {ex}", LogType.ROBOT_STACK); } }
/// <summary> /// 手工删除标签号码。 /// </summary> /// <param name="code">标签号码</param> private void DeleteLabelByHand(string code) { // 删除号码。 var lc = LableCode.QueryByLCode(code); if (lc == null) { CommonHelper.Warn("不存在这个号码!"); return; } var area = lc.ParseLocationArea(); var bAndOnBoard = (area == "B" && lc.Status >= (int)LableState.OnPanel); var aCarea = (area == "A" || area == "C"); if (!bAndOnBoard && !aCarea) { CommonHelper.Warn("只能删除B区已上垛的号码, 或者A区、C区的号码!"); return; } if (LableCode.Delete(code) || deleteFromTaskq(FrmMain.taskQ, code)) { notifyOpc(code); lbxLog.Items.Insert(0, $"{lbxLog.Items.Count} {code}已经删除。"); FrmMain.logOpt.Write(string.Format("删除标签{0}成功", code), LogType.NORMAL); } else { FrmMain.logOpt.Write(string.Format("删除标签{0}失败", code), LogType.NORMAL); } }
/// <summary> /// 当前布卷和缓存中的一个布卷可能占用的坐标 /// </summary> /// <param name="l1"></param> /// <returns></returns> private static decimal expectedWidth(LableCode l1) { // 预期宽度 var edgespace = GetEdgeSpace(FrmMain.taskQ.CacheSide, l1.ToLocation, clsSetting.EdgeSpace); var expected = Math.Abs(l1.Cx + l1.Cy) + edgespace; return(expected); }
/// <summary> /// 当前布卷和缓存中的一个布卷可能占用的坐标 /// </summary> /// <param name="l1"></param> /// <param name="l2"></param> /// <param name="installedWidth">板上已有布卷总宽度</param> /// <returns></returns> private static decimal expectedWidth(decimal installedWidth, LableCode l1, LableCode l2) { // 预期宽度 var edgespace = GetEdgeSpace(FrmMain.taskQ.CacheSide, l1.ToLocation, clsSetting.EdgeSpace); var expected = installedWidth + l1.Diameter + clsSetting.RollSep + l2.Diameter + edgespace; return(expected); }
private void loadPanels() { lbxLocation.Items.Clear(); var lst = LableCode.QueryAreaBLocations(); lbxLocation.Items.AddRange(lst.ToArray()); }
public RollPosition(LableCode label, string side, PanelState pnlState, decimal x, decimal y, decimal z, decimal rz) { this.LabelCode = label.LCode; PanelNo = label.PanelNo; Floor = label.Floor; Status = label.Status; FloorIndex = label.FloorIndex; // 布卷按长度调整板上位置, 以确定坐标偏移。 var adj = AdjustPosByRollLength(x, clsSetting.SplintWidth, label.Length); //X = x; //Y = y; X = x + (side == "B" ? -adj.offsetx : adj.offsetx); Y = y + (side == "B" ? -adj.offsety : adj.offsety); Z = z; Rz = rz; // if (robotChangeAngle.Contains(RealLocation)) { ChangeAngle = x < 0 || y > 0;//3\4\5\9\10\11标签朝外 } else { ChangeAngle = x > 0 || y < 0; } RealLocation = label.RealLocation; ToLocation = label.ToLocation; diameter = label.Diameter; // Index = CalculateBaseIndex(label.ToLocation, x, y); Index = CalculateBaseIndex(RealLocation, x, y); // LocationNo = int.Parse(label.ToLocation.Substring(1, 2)); // LocationNo改为getLocationNo. // BaseIndex = 4 * (GetLocationNo() - 1) + Index + 1; BaseIndex = 4 * (GetRealLocationNo() - 1) + Index + 1; Side = side; PnlState = pnlState; // var tmp = int.Parse(label.ToLocation.Substring(1, 2)); var tmp = GetRealLocationNo(); var origin = RobotParam.GetOrigin(tmp); var point = RobotParam.GetPoint(tmp, Index); Base1 = origin.Base; Base2 = point.Base; XOffSet = GetXOffSet(origin.Base, point.Base); X = X + XOffSet; Origin = new PostionVar(XOffSet, 0, 1700, origin.Rx, origin.Ry, origin.Rz + rz); Target = new PostionVar(X, Y, Z, origin.Rx, origin.Ry, origin.Rz + rz); }
private static bool NoMoreBiggerRoolsInCacheQ(LableCode lc, IEnumerable <LableCode> cacheq) { // 同一个板上直径比当前大的。 var q = cacheq.Count((x) => { return(lc.Diameter > x.Diameter + clsSetting.CacheIgnoredDiff); }); return(q <= 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 static void CalculatePosition(List <LableCode> lcs, LableCode lc, int state) { if (lc == null) { return; // throw new Exception($"nameof(CalculatePosition), lc is null."); } lc.FloorIndex = CalculateFloorIndex(lcs); OnlinCalculatePosition(lcs, lc, state); }
private static SideFullState IsPanelFullPro(List <LableCode> lcs, LableCode lc) { // 以下是新的做法。 // 满则返回莫格缓存中的布卷 // 不满则返回null var MAX_WIDTH = FindMaxHalfWidth(lc); // 板上宽度 var installedWidth = Math.Abs(CalculateXory(lcs)); return(findSmallerFromCachedRollsPro(lc, installedWidth, MAX_WIDTH)); }
public void save(LableCode lablecode, int pos) { foreach (var p in cacheposes) { if (p.id == pos) { p.labelcode = lablecode; return; } } }
private static string InitPanelNo(DateTime dtime) { string panelNo; lock (foo) { // panelNo = LableCode.GetLastPanelNo(string.Format("{0}", dtime.ToString(clsSetting.LABEL_CODE_DATE_FORMAT))); panelNo = LableCode.GetLastPanelNo($"{dtime.ToString(clsSetting.LABEL_CODE_DATE_FORMAT)}"); panelNo = string.IsNullOrEmpty(panelNo) ? string.Format("{0}{1}", dtime.ToString(clsSetting.PANEL_PATTERN), "0000") : (decimal.Parse(panelNo) + 1).ToString(); } return(panelNo); }
private void checkInDb(string code) { var lc = LableCode.QueryByLCode(code); if (lc != null) { lbxLog.Items.Insert(0, $"{lbxLog.Items.Count} 数据库: {lc.LCode} {lc.ToLocation} 实际交地: {lc.RealLocation} 扫描时间: {lc.CreateDate} 板号: {lc.PanelNo}"); } else { lbxLog.Items.Insert(0, $"{lbxLog.Items.Count} {code}数据库中没有此号码。"); } }
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); } }
// private static decimal expectedWidthNoEdgeSpace(decimal installedWidth, LableCode l1, LableCode l2) { // 预期宽度 // l2可能是空值 if (l1 == null) { throw new Exception($"{nameof(expectedWidthNoEdgeSpace)}, lablecode l1 is null"); } var cachedRollDiameter = l2 != null ? l2.Diameter : 0; var expected = installedWidth + l1.Diameter + clsSetting.RollSep + cachedRollDiameter; return(expected); }
/// <summary> /// 2期缓存计算办法 /// </summary> /// <param name="pinfo"></param> /// <param name="lc"></param> /// <param name="lcs"></param> /// <param name="cacheq">缓存队列</param> /// <returns>返回的是需要从缓存位取出的布卷。如果不需要取出,返回null。</returns> private static CalResult CalculateCache(PanelInfo pinfo, LableCode lc) { var cr = new CalResult(CacheState.Go, lc, null); var cachecount = (pinfo.OddStatus ? 0 : 1) + (pinfo.EvenStatus ? 0 : 1); List <LableCode> cachedRolls; lock (TaskQueues.LOCK_LOCHELPER) { cachedRolls = FrmMain.taskQ.CacheSide.Where(x => x.labelcode != null && x.labelcode.ToLocation == lc.ToLocation) .Select(x => x.labelcode) .ToList(); } switch (cachedRolls.Count()) { case 0: //当前层已没有了缓存。//当前布卷直接缓存起来。 cr.state = CacheState.Cache; break; case 1: //当前层只有一卷缓存。 case 2: //当前层有两卷缓存。 if (cachedRolls.Count() == cachecount) //缓存卷数与需要缓存卷数相等 { var smaller = cachedRolls.Where(x => x.Diameter + clsSetting.CacheIgnoredDiff < lc.Diameter) .OrderBy(x => x.Diameter) .FirstOrDefault(); if (smaller != null) { cr.CodeFromCache = smaller; lc.GetOutLCode = cr.CodeFromCache.LCode; cr.state = CacheState.GetThenCache; } else { cr.state = CacheState.Go; } } else if (cachedRolls.Count() < cachecount) { cr.state = CacheState.Cache; } else { cr.state = CacheState.Go; } break; } return(cr); }
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 btnSearch_Click(object sender, EventArgs e) { mtxCode.SelectAll(); var key = shrink(mtxCode.Text); if (string.IsNullOrEmpty(key)) { return; } Cursor = Cursors.WaitCursor; try { if (!ckHistory.Checked) { var c = LableCode.QueryByLCode(key); if (c != null) { showlabel(c); } else { showwarning(key, "当前运行数据"); } lbx.Items.Insert(0, $"<当前运行数据>查询结果:"); lbx.Items.Insert(0, $"---------------------"); } if (ckHistory.Checked) { var c = LableCode.QueryByLCodeFromHis(key); if (c != null && c.Count() != 0) { foreach (var obj in c) { showlabel(obj); } } else { showwarning(key, "历史数据"); } var count = c == null ? 0 : c.Count; lbx.Items.Insert(0, $"<历史数据>查询结果({count}):"); lbx.Items.Insert(0, $"---------------------"); } } finally { Cursor = Cursors.Default; } }
private static decimal FindMaxHalfWidth(LableCode lc) { var lenOfUpperFloor = lc.Floor > 1 ? LableCode.GetFloorHalfAvgLength(lc.PanelNo, lc.Floor) : 0; if (lenOfUpperFloor > 0) { return(Math.Min(lenOfUpperFloor, clsSetting.SplintLength / 2)); } else { // 默认最大宽度 return(clsSetting.SplintLength / 2); } }
/// <summary> /// 通知失败时,要告知plc /// FrmMain.ERPAlarm(FrmMain.opcClient, FrmMain.opcParam, ERPAlarmNo.COMMUNICATION_ERROR); /// </summary> /// <param name="erpapi"></param> /// <param name="panelNo"></param> /// <param name="msg"></param> /// <param name="handwork"></param> /// <param name="realloc"></param> /// <returns></returns> public static bool NotifyPanelEnd(IErpApi erpapi, string panelNo, string realloc, out string msg, bool handwork = false) { if (string.IsNullOrEmpty(panelNo)) { msg = $"!实际交地{realloc}/{panelNo}板号完成取消,板号为空。"; return(false); } // 这个从数据库取似更合理。 var data = LableCode.QueryLabelcodeByPanelNo(panelNo); if (data == null) { msg = $"!实际交地{realloc}/{panelNo}板号完成取消,未能查到数据库的标签。"; return(false); } var erpParam = new Dictionary <string, string> { { "Board_No", panelNo }, // first item. { "AllBarCode", string.Join(",", data.ToArray()) } // second item. }; var re = erpapi.Post(clsSetting.PanelFinish, erpParam, clsSetting.ErpTimeout); var mode = handwork ? "手工" : "自动"; var paramJson = JsonConvert.SerializeObject(erpParam); var resultJson = JsonConvert.SerializeObject(re); // show result. if (re["ERPState"] == "OK") { if (re["State"] == "Fail") { msg = $"!{mode}板号{paramJson}完成失败, {re["ERR"]}"; return(false); } else { msg = $"{mode}板号{paramJson}完成成功。{re["Data"]}"; return(true); } } else { msg = $"{mode}板号{paramJson}完成失败, {resultJson}"; return(false); } }
/// <summary> /// 主要函数。 /// </summary> /// <param name="state"></param> /// <param name="saveCode"></param> /// <param name="getCode"></param> /// <returns></returns> public PlcCacheResult WhenRollArrived(CacheState state, LableCode saveCode, LableCode getCode) { PlcCacheResult result = null; const int NULL_POS = 0; var posToGet = 0; var posToSave = 0; switch (state) { case CacheState.Go: result = new PlcCacheResult(state, NULL_POS, NULL_POS); break; case CacheState.Cache: posToSave = SelectNearestNullPos(saveCode.ToLocation, -1); save(saveCode, posToSave); result = new PlcCacheResult(state, NULL_POS, posToSave); break; case CacheState.GetThenCache: // 考虑错开机械手。 posToGet = getPosByCode(getCode); posToSave = SelectNearestNullPos(saveCode.ToLocation, posToGet); save(saveCode, posToSave); result = new PlcCacheResult(state, posToGet, posToSave); break; case CacheState.GetThenGo: posToGet = getPosByCode(getCode); result = new PlcCacheResult(state, posToGet, NULL_POS); break; case CacheState.GoThenGet: posToGet = getPosByCode(getCode); result = new PlcCacheResult(state, posToGet, NULL_POS); break; case CacheState.CacheAndGet: posToGet = getPosByCode(getCode); posToSave = SelectNearestNullPos(saveCode.ToLocation, posToGet);; result = new PlcCacheResult(state, posToGet, posToSave); break; } return(result); }
private static void CalculatePosition(List <LableCode> lcs, LableCode lc, LableCode lc2, int state) { CalculatePosition(lcs, lc, SideFullState.NO_FULL); lc2.FloorIndex = lc.FloorIndex + 2; var d = Math.Abs(lc.Cx + lc.Cy) + lc.Diameter + clsSetting.RollSep; var xory = d * (lc.FloorIndex % 2 == 1 ? 1 : -1); xory = OffsetSideLastRollXory(state, lc2, xory); lc2.Coordinates = string.Format("{0},{1},{2}", lc.Cz, lc.Crz, xory); lc2.Cx = lc.Crz == 0 ? 0 : xory; lc2.Cy = lc.Crz == 0 ? xory : 0; lc2.Cz = lc.Cz; lc2.Crz = lc.Crz; }
public int getPosByCode(LableCode getcode) { var pp = from p in cacheposes where p.labelcode != null && p.labelcode.LCode == getcode.LCode select p; if (pp.Count() == 1) { var id = pp.First().id; cacheposes[id - 1].labelcode = null; return(id); } else { throw new Exception($"取缓存位异常: getcode: {getcode.LCode} count: {pp.Count()}"); } }
/// <summary> /// [交地]|[长度] /// </summary> /// <param name="code"></param> /// <param name="erpapi"></param> /// <param name="warnhandler"></param> /// <returns>[交地]|[长度]</returns> public static string GetLocationAndLength(IErpApi erpapi, string code, Action <string, bool> warnhandler) { var tolocation = string.Empty; var dt = LableCode.QueryByLCode(code); if (dt != null) { FrmMain.logOpt.Write($"!号码重复: {code}", LogType.NORMAL); warnhandler?.Invoke("重复扫码", true); } else { var str = new Dictionary <string, string>(); try { str = erpapi.Post(clsSetting.GetLocation, new Dictionary <string, string> { { "Bar_Code", code } }, clsSetting.ErpTimeout); if (str["ERPState"] == "OK") { var res = JsonConvert.DeserializeObject <DataTable>(str["Data"].ToString()); if (res.Rows.Count > 0 && res.Rows[0]["LOCATION"].ToString() != "Fail") { tolocation = res.Rows[0]["LOCATION"].ToString(); FrmMain.logOpt.Write($"号码: {code}, 交地: {tolocation}", LogType.NORMAL); } else { warnhandler?.Invoke("取交地失败", true); FrmMain.logOpt.Write($"!{code}获取交地失败。{JsonConvert.SerializeObject(str)}", LogType.NORMAL); } } else { warnhandler?.Invoke("取交地失败", true); FrmMain.logOpt.Write($"!{code}获取交地失败。{JsonConvert.SerializeObject(str)}", LogType.NORMAL); } } catch (Exception ex) { warnhandler?.Invoke("取交地失败", true); FrmMain.logOpt.Write($"!来源: {nameof(GetLocationAndLength)}, {ex}, {JsonConvert.SerializeObject(str)}", LogType.NORMAL); } } return(tolocation); }
private static decimal CalculateXory(List <LableCode> lcs, LableCode lc) { decimal xory; if (lc.FloorIndex <= 2) { xory = lc.FloorIndex % 2 == 1 ? 0 : -clsSetting.RollSep; } else { var lastRoll = (from s in lcs where IsRollInSameSide(s, lc) orderby s.FloorIndex descending select s).First(); xory = (Math.Abs(lastRoll.Cx + lastRoll.Cy) + lastRoll.Diameter + clsSetting.RollSep) * (lc.FloorIndex % 2 == 1 ? 1 : -1); } return(xory); }
public void NotifyOpcJobFinished(string panelNo, string tolocation, string reallocation, bool panelfull) { try { var pState = panelfull ? PanelState.Full : PanelState.HalfFull; switch (pState) { case PanelState.HalfFull: var lcode = FrmMain.taskQ.UFGetPanelLastRoll(tolocation, panelNo); LableCode.UserSetPanelLastRoll(lcode); //设置板最后一卷布。 log($"{reallocation} 半板信号发出,最后一卷布标签{lcode}。slot: {param.BAreaFloorFinish[reallocation]}", LogType.ROBOT_STACK); client.TryWrite(param.BAreaFloorFinish[reallocation], true); break; case PanelState.Full: string msg; ErpHelper.NotifyPanelEnd(erpapi, panelNo, reallocation, out msg); log(msg, LogType.ROBOT_STACK); LableCode.SetPanelFinished(panelNo); // 满板时设置自由板位标志。 lock (TaskQueues.LOCK_LOCHELPER) { TaskQueues.lochelper.OnFull(reallocation); } lock (client) { PlcHelper.NotifyFullPanel(client, param, reallocation); } break; case PanelState.LessHalf: break; default: log($"!板状态不明,不发信号, {pState}", LogType.ROBOT_STACK); break; } } catch (Exception ex) { log($"!来源: {nameof(NotifyOpcJobFinished)}, {ex}", LogType.ROBOT_STACK); } }