|
|
@@ -5,6 +5,7 @@ using CSScripting;
|
|
|
using MathNet.Numerics.Distributions;
|
|
|
using MathNet.Numerics.LinearAlgebra;
|
|
|
using MathNet.Numerics.RootFinding;
|
|
|
+using Newtonsoft.Json;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using NPOI.Util;
|
|
|
using Opc.Ua;
|
|
|
@@ -20,6 +21,8 @@ using System.Collections;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Collections.ObjectModel;
|
|
|
using System.ComponentModel;
|
|
|
+using System.Data;
|
|
|
+using System.Diagnostics;
|
|
|
using System.Drawing;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
@@ -83,6 +86,8 @@ namespace TeamAAS_VP.Core
|
|
|
Timer yieldtimer;
|
|
|
private DateTime StartTime = DateTime.Now;
|
|
|
SerialPortClient client;
|
|
|
+ Stopwatch swCT = new Stopwatch();
|
|
|
+ List<LockResult> lockResultsAll = new List<LockResult>();//一个产品的总结果
|
|
|
#endregion
|
|
|
|
|
|
#region 属性
|
|
|
@@ -201,6 +206,16 @@ namespace TeamAAS_VP.Core
|
|
|
get { return _NumStatistics; }
|
|
|
set { SetProperty(ref _NumStatistics, value); }
|
|
|
}
|
|
|
+
|
|
|
+ private double _CTtime;
|
|
|
+ /// <summary>
|
|
|
+ /// ct
|
|
|
+ /// </summary>
|
|
|
+ public double CTtime
|
|
|
+ {
|
|
|
+ get { return _CTtime; }
|
|
|
+ set { SetProperty(ref _CTtime, value); }
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
#region 命令
|
|
|
@@ -213,7 +228,7 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
public Management(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IConfigService configService,
|
|
|
IRobotService robotService, ICameraService cameraService, IFeederService feederService, IPlcService plcService, IProductService productService,
|
|
|
- ICalibrationService calibrationService, IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService,
|
|
|
+ ICalibrationService calibrationService, IRemoteCommandService remoteCommandService, ISystemDatabaseService systemDatabaseService, ILightManagerService lightManagerService,
|
|
|
IMesService mesService)
|
|
|
{
|
|
|
_regionManager = regionManager;
|
|
|
@@ -248,17 +263,17 @@ namespace TeamAAS_VP.Core
|
|
|
{
|
|
|
NumStatistics = new NumberStatistics();
|
|
|
var latestHeadChangeRecord = await _systemDatabaseService.GetLatestHeadChangeRecordAsync();
|
|
|
- if (latestHeadChangeRecord!=null)
|
|
|
+ if (latestHeadChangeRecord != null)
|
|
|
{
|
|
|
NumStatistics.HeaderNum = latestHeadChangeRecord.CurrentLockCount;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
var latestNozzleChangeRecord = await _systemDatabaseService.GetLatestNozzleChangeRecordAsync();
|
|
|
- if (latestNozzleChangeRecord!=null)
|
|
|
+ if (latestNozzleChangeRecord != null)
|
|
|
{
|
|
|
NumStatistics.NozzleNum = latestNozzleChangeRecord.CurrentLockCount;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
NumStatistics.Feeder1Num = _configService.GetRemainingCountByFeederNumber(1);
|
|
|
NumStatistics.Feeder2Num = _configService.GetRemainingCountByFeederNumber(2);
|
|
|
|
|
|
@@ -627,7 +642,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
- SendTaskMessage(string.Format(Lang.电批连接失败0,ex.Message), MessageLevel.Alarm);
|
|
|
+ SendTaskMessage(string.Format(Lang.电批连接失败0, ex.Message), MessageLevel.Alarm);
|
|
|
LogHelper.WriteLogError(Lang.连接电批时出错, ex);
|
|
|
}
|
|
|
}
|
|
|
@@ -675,7 +690,7 @@ namespace TeamAAS_VP.Core
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogHelper.WriteLogError("初始化扭力测量仪时出错!", ex);
|
|
|
- SendTaskMessage("初始化扭力测量仪时出错!"+ex.Message, MessageLevel.Error);
|
|
|
+ SendTaskMessage("初始化扭力测量仪时出错!" + ex.Message, MessageLevel.Error);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -1227,7 +1242,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
|
|
|
//获取产品编码
|
|
|
- _productService.CurrentProductCode = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address,0));
|
|
|
+ _productService.CurrentProductCode = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, 0));
|
|
|
//如果产品编码为空,则以当前的时间戳作为编码
|
|
|
if (string.IsNullOrEmpty(_productService.CurrentProductCode))
|
|
|
{
|
|
|
@@ -1277,7 +1292,7 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
// 执行视觉任务
|
|
|
var _cts = new CancellationTokenSource();
|
|
|
- var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token,null);
|
|
|
+ var visionResult = await _remoteCommandService.ExecutePhotoGetSinglePoint(process, null, null, _cts.Token, null);
|
|
|
if (visionResult.IsSucceed)
|
|
|
{
|
|
|
//披头偏差
|
|
|
@@ -1320,7 +1335,7 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage(Lang.触发下相机拍照, MessageLevel.Debug);
|
|
|
//相机的编号
|
|
|
Int16 cameraIndex = plc.ReadNode<Int16>(addressConfig.In_DowmCameraNum.Address);
|
|
|
- SendTaskMessage(string.Format(Lang.编号0,cameraIndex), MessageLevel.Info);
|
|
|
+ SendTaskMessage(string.Format(Lang.编号0, cameraIndex), MessageLevel.Info);
|
|
|
|
|
|
// 获取流程
|
|
|
var process = _productService.GetCurrentProductProcedureModelById(currentProduct.FixedUpCamera1ProcedureId);
|
|
|
@@ -1423,7 +1438,7 @@ namespace TeamAAS_VP.Core
|
|
|
var process = _productService.GetCurrentProductProcedureModelById(currentProduct.MoveDownCameraLockPhotoProcedureId);
|
|
|
if (process == null)
|
|
|
{
|
|
|
- SendTaskMessage(string.Format(Lang.未找到上相机锁附组装拍照对应的视觉流程流程ID0,currentProduct.MoveDownCameraLockPhotoProcedureId), MessageLevel.Alarm);
|
|
|
+ SendTaskMessage(string.Format(Lang.未找到上相机锁附组装拍照对应的视觉流程流程ID0, currentProduct.MoveDownCameraLockPhotoProcedureId), MessageLevel.Alarm);
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_UpCameraPutStatus.Address, (Int16)2);
|
|
|
return;
|
|
|
}
|
|
|
@@ -1597,7 +1612,7 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage(Lang.收到开始锁付信号, MessageLevel.Debug);
|
|
|
//位置编号
|
|
|
Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
|
|
|
- SendTaskMessage(string.Format(Lang.编号0,positionIndex), MessageLevel.Info);
|
|
|
+ SendTaskMessage(string.Format(Lang.编号0, positionIndex), MessageLevel.Info);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -1624,7 +1639,7 @@ namespace TeamAAS_VP.Core
|
|
|
SendTaskMessage(Lang.收到停止锁付信号, MessageLevel.Debug);
|
|
|
//位置编号
|
|
|
Int16 positionIndex = plc.ReadNode<Int16>(addressConfig.In_ProductNum.Address);
|
|
|
- SendTaskMessage(string.Format(Lang.编号0,positionIndex), MessageLevel.Info);
|
|
|
+ SendTaskMessage(string.Format(Lang.编号0, positionIndex), MessageLevel.Info);
|
|
|
//获取当前锁付点
|
|
|
var screwPoint = currentProduct.ScrewPoints.FirstOrDefault(p => p.Number == positionIndex);
|
|
|
//获取当前的机器人点位
|
|
|
@@ -1634,7 +1649,7 @@ namespace TeamAAS_VP.Core
|
|
|
float pressure = plc.ReadNode<float>(addressConfig.In_PressureValue.Address);
|
|
|
//当前用户名
|
|
|
string currentUserName = _systemDatabaseService.GetCurrentUser().UserName;
|
|
|
-
|
|
|
+
|
|
|
//吸嘴最后一次的记录
|
|
|
var nozzleRecord = await _systemDatabaseService.GetLatestNozzleChangeRecordAsync();
|
|
|
//最后一次的吸嘴编号
|
|
|
@@ -1696,6 +1711,7 @@ namespace TeamAAS_VP.Core
|
|
|
var _ = lockResult.SaveToCsvAsync(curveFileFullPath);
|
|
|
}
|
|
|
|
|
|
+ lockResultsAll.Add(lockResult);
|
|
|
App.Current.Dispatcher.Invoke(() =>
|
|
|
{
|
|
|
_eventAggregator.GetEvent<LockFinishNotification>().Publish(lockResult);
|
|
|
@@ -1703,9 +1719,9 @@ namespace TeamAAS_VP.Core
|
|
|
//记录锁付结果至数据库
|
|
|
await _systemDatabaseService.RecordLockResultAsync(lockResult);
|
|
|
//披头数量+1
|
|
|
- NumStatistics.HeaderNum=await _systemDatabaseService.IncrementLatestHeadLockCountAsync(currentUserName);
|
|
|
+ NumStatistics.HeaderNum = await _systemDatabaseService.IncrementLatestHeadLockCountAsync(currentUserName);
|
|
|
//吸嘴数量+1
|
|
|
- NumStatistics.NozzleNum=await _systemDatabaseService.IncrementLatestNozzleLockCountAsync(currentUserName);
|
|
|
+ NumStatistics.NozzleNum = await _systemDatabaseService.IncrementLatestNozzleLockCountAsync(currentUserName);
|
|
|
|
|
|
await plc.WriteNodeAsync(addressConfig.In_WorkDone.Address, (Int16)0);
|
|
|
}
|
|
|
@@ -1766,7 +1782,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- SendTaskMessage(string.Format(Lang.多相机坐标合并请求已结束或被取消state0,state), MessageLevel.Alarm);
|
|
|
+ SendTaskMessage(string.Format(Lang.多相机坐标合并请求已结束或被取消state0, state), MessageLevel.Alarm);
|
|
|
await plc.WriteNodeAsync(addressConfig.Out_CameraDone.Address, (Int16)0);
|
|
|
}
|
|
|
}
|
|
|
@@ -1802,11 +1818,11 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
}
|
|
|
// 过站检查
|
|
|
- else
|
|
|
+ else
|
|
|
{
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
{
|
|
|
- if (string.Format(addressConfig.In_MesCheck.Address,i).Contains(tuple.nodeId))
|
|
|
+ if (string.Format(addressConfig.In_MesCheck.Address, i).Contains(tuple.nodeId))
|
|
|
{
|
|
|
if (tuple.value is Int16 state)
|
|
|
{
|
|
|
@@ -1819,12 +1835,14 @@ namespace TeamAAS_VP.Core
|
|
|
return;
|
|
|
}
|
|
|
var code = plc.ReadNode<string>(string.Format(addressConfig.In_Code.Address, i));
|
|
|
+ //询问mes
|
|
|
if (state == 1)
|
|
|
{
|
|
|
+ swCT.Restart();
|
|
|
//这里缺少从MES获取产品配方的内容,需要补充
|
|
|
-
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
(bool isSuccess, string response) = await _mesService.StationGetAsync(code, 2);
|
|
|
if (i == 0)
|
|
|
{
|
|
|
@@ -1856,10 +1874,14 @@ namespace TeamAAS_VP.Core
|
|
|
|
|
|
//这里缺少上传MES的本站数据结果及开始和结束时间,需要补充
|
|
|
|
|
|
- (bool isSuccess, string response) = await _mesService.SubmitGetAsync(code, true,DateTime.Now,DateTime.Now);
|
|
|
+ (bool isSuccess, string response) = await _mesService.SubmitGetAsync(code, true, DateTime.Now, DateTime.Now);
|
|
|
//假设上传成功,这里缺少上传失败的处理
|
|
|
|
|
|
await plc.WriteNodeAsync(string.Format(addressConfig.Out_MesStatus.Address, i), (Int16)3);
|
|
|
+ swCT.Stop();
|
|
|
+ CTtime = Math.Round(swCT.Elapsed.TotalSeconds, 3);
|
|
|
+ WriteProductLog(lockResultsAll, code, CTtime);
|
|
|
+ lockResultsAll.Clear();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -1869,7 +1891,7 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
@@ -1944,6 +1966,81 @@ namespace TeamAAS_VP.Core
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
+
|
|
|
+ #region 产品锁付记录进行存储
|
|
|
+ /// <summary>
|
|
|
+ /// 产品锁付记录进行存储
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="result">结果</param>
|
|
|
+ public void WriteProductLog(List<LockResult> lockResults,string rfid,double ct)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ string result = "";//产品的总结果
|
|
|
+ foreach (var item in lockResults)
|
|
|
+ {
|
|
|
+ result = "OK";
|
|
|
+ if (!item.LockPassed)
|
|
|
+ {
|
|
|
+ result = "NG";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ DateTime dt = DateTime.Now;
|
|
|
+ int number = lockResults.Count;//螺丝数量
|
|
|
+ string path = $"E:\\Data\\生产数据\\{dt.ToString("yyyy-MM")}\\{dt.ToString("yyyy-MM-dd")}.csv";
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ //具体的ct需要优化
|
|
|
+ sb.Append($"{dt.ToString("yyyy-MM-dd HH:mm:ss")},{lockResults[0].ProductName},{Math.Round(ct, 3)},{rfid},{result},{lockResults[number-1].NozzleNumber},{lockResults[number - 1].HeadNumber},");
|
|
|
+ foreach (var item in lockResults)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ sb.Append($"{item.LockPassed},{item.ResultDetails},{item.LockTorque},{item.TargetTorqueUpperLimit},{item.TargetTorqueLowerLimit},{item.LockTurns},{item.TargetTurnsUpperLimit},{item.TargetTurnsLowerLimit},{item.Pressure},{item.PositionX},{item.PositionY},{item.StartPositionZ},{item.EndPositionZ},{item.LockDescentSpeed},");
|
|
|
+ }
|
|
|
+ catch (Exception)
|
|
|
+ {
|
|
|
+ sb.Append($",,,,,,,,,,,,,,");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //========================
|
|
|
+ if (!Directory.Exists(Path.GetDirectoryName(path))) //判断文件夹是否
|
|
|
+ {
|
|
|
+ Directory.CreateDirectory(Path.GetDirectoryName(path)); //创建文件夹
|
|
|
+ }
|
|
|
+
|
|
|
+ if (File.Exists(path))
|
|
|
+ {
|
|
|
+ // 使用 StreamWriter 以追加模式打开文件
|
|
|
+ StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
|
|
|
+ sw.WriteLine(sb.ToString().TrimEnd(','));
|
|
|
+ sw.Close();
|
|
|
+ sw.Dispose();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8);
|
|
|
+ StringBuilder sb1 = new StringBuilder();
|
|
|
+ StringBuilder sb_up = new StringBuilder();
|
|
|
+ StringBuilder sb_down = new StringBuilder();
|
|
|
+ sb1.Append("时间,产品名称,CT,RFID,产品结果,吸嘴数量,披头数量,");
|
|
|
+ for (int i = 0; i < number; i++)
|
|
|
+ {
|
|
|
+ sb1.Append($"螺丝{i + 1}结果,螺丝{i + 1}结果详情,螺丝{i + 1}扭矩,螺丝{i + 1}扭矩上限,螺丝{i + 1}扭矩下限,螺丝{i + 1}圈数,螺丝{i + 1}圈数上限,螺丝{i + 1}圈数下限,螺丝{i + 1}压力值,螺丝{i + 1}锁附X,螺丝{i + 1}锁附Y,螺丝{i + 1}开始位置Z,螺丝{i + 1}结束位置Z,螺丝{i + 1}锁附下降速度,");
|
|
|
+ }
|
|
|
+ sw.WriteLine(sb1.ToString().TrimEnd(','));
|
|
|
+ sw.WriteLine(sb.ToString().TrimEnd(','));
|
|
|
+ sw.Close();
|
|
|
+ sw.Dispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ LogHelper.WriteLogError("写入产品记录时出错!", ex);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
#endregion
|
|
|
}
|
|
|
}
|