AC_BOX_Bean_Partial.cs
16.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
using Asa;
using OnlineStore.Common;
using OnlineStore.LoadCSVLibrary;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace OnlineStore.DeviceLibrary
{
partial class AC_BOX_Bean
{
/// <summary>
/// 设置设备运行状态
/// </summary>
/// <param name="runStatus"></param>
void setStoreRunStatus(StoreRunStatus runStatus)
{
storeRunStatus = runStatus;
LogInfo($"设置设备运行状态:{storeRunStatus.ToString()}");
}
/// <summary>
/// 设置设备状态
/// </summary>
/// <param name="status"></param>
void setStoreStatus(StoreStatus status)
{
storeStatus = status;
LogInfo($"设置设备状态:{storeStatus.ToString()}");
}
void setStatus(StoreRunStatus runStatus, StoreStatus status)
{
setStoreRunStatus(runStatus);
setStoreStatus(status);
}
/// <summary>
/// 设备是否空闲
/// </summary>
/// <returns></returns>
bool isIdle()
{
return storeRunStatus.Equals(StoreRunStatus.Runing) && (MoveInfo?.MoveType.Equals(StoreMoveType.None) ?? false);
}
/// <summary>
/// 获取料架备注
/// 包含料信息
/// </summary>
/// <param name="defualtMark"></param>
/// <returns></returns>
private string GetMarkInfo(string defualtMark = "0")
{
string mark = defualtMark;
//如果料架号是空,需要送到VMI线
if (MoveInfo.MoveType.Equals(StoreMoveType.OutStore))
{
if (CurrShelfID.EndsWith("00"))
{
mark = defualtMark;
}
else if(isNGShelf())
{
mark = defualtMark; ;
}
//包装料会发往分盘区, 紧急料区, 包装线区
// urgentReel 这个为true是紧急料 出到紧急料区
// cutReel 为true是分盘料,AGV会拉到到分盘区
//料串会发到分盘区和紧急料区
//两个都为false 包装料默认拉到包装线体, 料串默认拉到紧急料区
if (MoveInfo.MoveParam.urgentReel)
{
//紧急料,需要到紧急料区
mark = MoveInfo.MoveParam.rfid + ",urgent";
}
else if (MoveInfo.MoveParam.cutReel)
{
//cutReel 为true是分盘料,AGV会拉到到分盘区
mark = MoveInfo.MoveParam.rfid + ",cut";
}
else
{
mark = MoveInfo.MoveParam.rfid + ",pack";
}
}
else if (MoveInfo.MoveType.Equals(StoreMoveType.InStore))
{
if(isNGShelf())
mark = defualtMark;
else
{
mark = defualtMark + ",ok";
}
}
return mark;
}
/// <summary>
/// 设备是否可以动作
/// </summary>
/// <param name="msg"></param>
/// <returns></returns>
bool canStartMove(out string msg)
{
StringBuilder sb = new StringBuilder();
if (isInSuddenDown)
sb.Append("急停中;");
if (isNoAirCheck)
sb.Append("未检测到气压信号;");
if (!isIdle())
{
sb.Append("忙碌中;");
}
msg = sb.ToString();
if (!string.IsNullOrEmpty(msg))
return false;
return true;
}
bool canInStore(out string msg)
{
msg = "";
return true;
}
bool canOutStore(out string msg)
{
if(canStartMove(out msg))
{
if (WaitShelfEnter)
{
msg+="有入库料架在路上";
return false;
}
}
return true;
}
#region 出入库结果验证
public bool CompressSigTimeOut = false;
public bool IsScanCodeWithLockedShelf = true; //锁定的料架是否扫码
private void CheckWait()
{
List<WaitResultInfo> list = MoveInfo.WaitList;
//当等待超过一分钟时,需要打印提示
TimeSpan span = DateTime.Now - MoveInfo.LastSetpTime;
string NotOkMsg = "";
if (list.Count <= 0)
{
MoveInfo.EndStepWait();
return;
}
bool isOk = true;
if (MoveInfo.OneWaitCanEndStep)
{
isOk = false;
}
foreach (WaitResultInfo wait in list)
{
if (wait.IsEnd)
{
continue;
}
NotOkMsg = wait.ToStr();
if (wait.WaitType.Equals(WaitEnum.W001_AxisMove))
{
string msg = "";
if (wait.IsHomeMove)
{
wait.IsEnd = ACHomeMoveIsEnd(wait.AxisInfo, out msg);
}
else
{
wait.IsEnd = ACAxisMoveIsEnd(wait.AxisInfo, wait.TargetPosition, wait.TargetSpeed, out msg);
}
if (!msg.Equals(""))
{
isOk = false;
WarnMsg = msg;
Alarm(StoreAlarmType.AxisMoveError, GetAlarmCodeByAxis(wait.AxisInfo).ToString(), WarnMsg, MoveInfo.MoveType);
break;
}
}
else if (wait.WaitType.Equals(WaitEnum.W002_IOValue))
{
wait.IsEnd = IOValue(wait.IoType).Equals(wait.IoValue);
int timeOutMs = Config.IOSingle_TimerOut;
if (MoveInfo.MoveStep.Equals(StoreMoveStep.BS_08_WaitLineIn) ||
MoveInfo.MoveStep.Equals(StoreMoveStep.BI_04_WaitTakeSingle))
{
timeOutMs = 30000;
}
else if (MoveInfo.MoveStep.Equals(StoreMoveStep.BI_03_LineRun))
{
timeOutMs = 40000;
}
if ((!wait.IsEnd) && span.TotalMilliseconds > timeOutMs && NoAlarm())
{
ConfigIO io = Config.getWaitIO(wait.IoType);
WarnMsg = Name + "[" + MoveInfo.MoveType + "][" + MoveInfo.MoveStep + "] 等待(" + io.DisplayStr + "=" + wait.IoValue + ") 超时";
if (WarnMsg.Contains(IO_Type.Compress_Check) && MoveInfo.MoveStep.Equals(StoreMoveStep.SO_09_CheckComSig))
{
CompressSigTimeOut = true;
WarnMsg += "出库时料叉未检测到信号!";
}
Alarm(StoreAlarmType.IoSingleTimeOut, io.ElectricalDefinition, WarnMsg, MoveInfo.MoveType);
LogUtil.error(Name + "[" + MoveInfo.MoveType + "][" + MoveInfo.MoveStep + "] 等待(" + io.DisplayStr + "=" + wait.IoValue + ") 超时", logType + 14);
if (!MoveInfo.OneWaitCanEndStep)
{
isOk = false;
break;
}
}
}
else if (wait.WaitType.Equals(WaitEnum.W003_Time))
{
wait.IsEnd = (span.TotalMilliseconds >= wait.TimeMSeconds);
}
else if (wait.WaitType.Equals(WaitEnum.W007_ReelHeight))
{
}
else if (wait.WaitType.Equals(WaitEnum.W008_Compress))
{
//等待信号亮或者走到绝对位置才停止
if (IOValue(TargetIoType).Equals(TargetIoValue))
{
LogUtil.info("CheckWait 检测到" + TargetIoType + "=" + TargetIoValue + ",停止压紧轴运行");
wait.IsEnd = true;
ComAxisStopCheck();
}
else
{
bool moveOk = ACServerManager.GetBusyStatus(wait.AxisInfo.DeviceName, wait.AxisInfo.GetAxisValue()).Equals(0);
if (moveOk)
{
//TODO 判断是否达到高度,如果未达到,继续上升
wait.IsEnd = true;
ComAxisStopCheck();
}
}
}
else if (wait.WaitType.Equals(WaitEnum.W009_ScanCode))
{
wait.IsEnd = (LastScanCodes.Count > 0);
}
else if (wait.WaitType.Equals(WaitEnum.W010_AgvStatus))
{
if (wait.AgvAction.Equals((int)ClientAction.Ready))
{
//Ready时使用状态判断,arrive时需要判断料架号是否正确
ClientAction agvA = AgvClient.GetAction(Config.AgvNodeName);
wait.IsEnd = ((int)agvA).Equals(wait.AgvAction);
}
if (!wait.IsEnd && span.TotalSeconds > 10)
{
//如果是等待AGV到达,等待有料架信号也算结束
if (wait.AgvAction.Equals((int)ClientAction.Arrive) && MoveInfo.MoveStep.Equals(StoreMoveStep.BI_00_ReadyShelf))
{
if (IOValue(IO_Type.LineTake_Check).Equals(IO_VALUE.HIGH))
{
LogInfo("BI_01_ReadyShelf 等待agv到达Arrive,检测到 LineTake_Check 信号,结束等待");
wait.IsEnd = true;
}
else if (IOValue(IO_Type.LineIn_Check).Equals(IO_VALUE.HIGH))
{
LogInfo("BI_01_ReadyShelf 等待agv到达Arrive,检测到 LineIn_Check 信号,结束等待");
wait.IsEnd = true;
}
}
else if (wait.AgvAction.Equals((int)ClientAction.Arrive) && MoveInfo.MoveStep.Equals(StoreMoveStep.BS_03_WaitEmptyAgv))
{
if (IOValue(IO_Type.LineTake_Check).Equals(IO_VALUE.LOW) && IOValue(IO_Type.LineIn_Check).Equals(IO_VALUE.LOW))
{
LogInfo("BS_03_WaitArrive 等待agv到达Arrive,检测到 LineTake_Check和LineIn_Check都没有信号,结束等待");
wait.IsEnd = true;
}
}
}
}
else if (wait.WaitType.Equals(WaitEnum.W011_DoorCloseEvent))
{
if (AgvClient.closeDoorTimeMap.ContainsKey(Config.AgvNodeName))
{
DateTime time = AgvClient.closeDoorTimeMap[Config.AgvNodeName];
if (time >= MoveInfo.LastSetpTime)
{
wait.IsEnd = true;
}
}
}
if (wait.IsEnd)
{
if (MoveInfo.OneWaitCanEndStep)
{
isOk = true;
break;
}
}
else
{
if (!MoveInfo.OneWaitCanEndStep)
{
isOk = false;
break;
}
}
}
if (isOk)
{
MoveInfo.EndStepWait();
}
else if (span.TotalSeconds > MoveInfo.TimeOutSeconds)
{
if (NotOkMsg.Contains(IO_Type.Compress_Check) && MoveInfo.MoveStep.Equals(StoreMoveStep.SO_09_CheckComSig))
{
CompressSigTimeOut = true;
NotOkMsg += "出库时料叉未检测到信号!";
}
WarnMsg = Name + "[" + MoveInfo.MoveType + "][" + MoveInfo.MoveStep + "]等待 " + NotOkMsg
+ "超时[" + FormUtil.GetSpanStr(span) + "] ";
int second = 10;
second = (int)(MoveInfo.TimeOutSeconds / span.TotalSeconds) * 10;
if (second > 120)
{
second = 120;
}
else if (second < 10)
{
second = 10;
}
LogUtil.error(WarnMsg, logType + 100, second);
Alarm(StoreAlarmType.IoSingleTimeOut, "", WarnMsg, MoveInfo.MoveType);
}
}
private static DateTime lastComRHomeTime = DateTime.Now;
private void InOutBackToP1(int InOut_P1)
{
//判断是否在P1,如果是,不需要运行
if (ACServerManager.isInPosition(Config.InOut_Axis, InOut_P1))
{
LogUtil.debug(Name + "进出轴当前已经在P1,不需要再回P1");
}
else
{
ACAxisMove(Config.InOut_Axis, InOut_P1, Config.InOutAxis_P1_Speed);
}
//StoreMove.WaitList.Add(WaitResultInfo.WaitAxisOrg(Config.InOut_Axis,IO_VALUE.HIGH));
}
#endregion
public ConcurrentQueue<InOutParam> waitOutStoreList = new ConcurrentQueue<InOutParam>();
private List<string> LastScanCodes = new List<string>();
private int ComTargetPosition = 0;
private int LastWidth = 0;
private int LastHeight = 0;
/// <summary>
/// 最后一次使用的料架号
/// </summary>
// private string LastRfidID = "";//服务器发送的出库rfid
private InOutParam LastOutParam = new InOutParam();
private string GetLastRfid()
{
//出库料架使用,返回上次使用的料架绑定的虚拟料架号
return LastOutParam.rfid;
}
#region 压紧轴压紧处理
private System.Timers.Timer axisCheckTimer = null;
private string TargetIoType = IO_Type.Compress_Check;
private IO_VALUE TargetIoValue = IO_VALUE.HIGH;
public bool ComAxisStartCheck(string targetIo = "", IO_VALUE value = IO_VALUE.HIGH)
{
if (String.IsNullOrEmpty(targetIo))
{
targetIo = IO_Type.Compress_Check;
}
if (axisCheckTimer == null)
{
axisCheckTimer = new System.Timers.Timer();
axisCheckTimer.AutoReset = true;
axisCheckTimer.Interval += 50;
axisCheckTimer.Elapsed += CheckTimer_Elapsed;
axisCheckTimer.Enabled = false;
}
TargetIoValue = value;
TargetIoType = targetIo;
axisCheckTimer.Start();
return true;
}
private bool ComAxisStopCheck()
{
if (!(axisCheckTimer == null))
{
ACServerManager.SuddenStop(Config.Comp_Axis);
axisCheckTimer.Stop();
}
return true;
}
private bool IsInProcess = false;
private void CheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (IsInProcess) { return; }
IsInProcess = true;
if (IOValue(TargetIoType).Equals(TargetIoValue))
{
LogUtil.info(Name + "压紧轴运动:检测到 " + TargetIoType + "=" + TargetIoValue + ",停止运动");
ACServerManager.SuddenStop(Config.Comp_Axis.DeviceName, Config.Comp_Axis.GetAxisValue());
ComAxisStopCheck();
}
IsInProcess = false;
}
#endregion
}
}