using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using MathNet.Numerics.RootFinding; using Newtonsoft.Json; namespace CommonLib { public class AtlasScrew : BaseScrew { MTF6KConnStus connFlow = new MTF6KConnStus(); public TightResult tightResult = new TightResult(); string receiveMsg; //连接状态 //public bool connectStaus = false; public Thread MTF6KThread; public AtlasScrew(object ip, object port, int connectTimeOut,int sendDataTimeOut,string direction) { Ip = ip.ToString(); Port = port.ToString(); ConnectTimeOut = connectTimeOut; SendDataTimeOut = sendDataTimeOut; IsCarriage = true; IsShield = false; Direction = direction; } /// /// MTF6K连接流程结构体 /// enum MTF6KConnStus { Idle, Disconnect, Connected, CheckConnect, SelectPSET, CheckSelectPSET, SelectBatch, CheckSelectBatch, SubscribeResult, CheckSubscribeResult1, CheckSubscribeResult2, CheckSubscribeResult3, SubscribeCurve, CheckSubscribeCurve, Ready, UnsubcribeResult, UnsubscribeCurve, }; /// /// 拧紧结果 /// public class TightResult { public double[] torque; public double[] angle; public double torCoef = 0.0; public double angCoef = 0.0; public double PearkTorque = 0.0;//峰值扭矩 public double TotalAngle = 0.0;//总角度 public double TotalDuration;//总持续时间 public int ResultCode = 0;//结果代码 public TightResult() { } public void Reset() { torCoef = 0.0; angCoef = 0.0; ResultCode = 0; PearkTorque = 0.0;//峰值扭矩 TotalAngle = 0.0;//总角度 TotalDuration = 0.0;//总持续时间 MTF6K.isDataRecvFinish = false; } } private Communicate TCP; public override void Initial() { base.Initial(); try { // 如果线程已经存在,先关闭旧线程 if (MTF6KThread != null && MTF6KThread.IsAlive) { MTF6KThread.Abort(); // 强制终止线程(注意:Abort 不推荐使用,建议改用信号机制) MTF6KThread = null; } // 如果 TCP 已经连接,先关闭连接 if (TCP != null) { TCP.ConnectedResult -= new Communicate.ConnectResultEventHandler(Comm_ConnectedResult); TCP.MessageReceived -= new Communicate.MessageReceivedEventHandler(Comm_MessageReceived); TCP.closeSocket(); TCP = null; } TCP = new Communicate("TCP1", Ip, Convert.ToInt32(Port)); TCP.FormOpening = true; TCP.ConnectedResult += new Communicate.ConnectResultEventHandler(Comm_ConnectedResult); TCP.MessageReceived += new Communicate.MessageReceivedEventHandler(Comm_MessageReceived); MTF6KThread = new Thread(MTF6KFlow); MTF6KThread.IsBackground = true; MTF6KThread.Start(); IsOk = true; } catch (Exception) { IsOk = IsShield ? true : false; } } /// /// MTF6K -TCP连接状态 /// /// /// public void Comm_ConnectedResult(object sender, Communicate.ResultEventArgs e) { if (e.conResult) { connFlow = MTF6KConnStus.Connected; connectStaus = true; } else { connectStaus = false; } } /// /// 接收数据-MTF6K /// /// /// public void Comm_MessageReceived(object sender, Communicate.MessageEventArgs e) { if (connFlow == MTF6KConnStus.Ready) MTF6K.ParseKerwords(e.byteMes, false); else { MTF6K.ParseKerwords(e.byteMes, true); } } /// /// 连接MTF6K流程 /// private void MTF6KFlow() { while (true) { Thread.Sleep(20); while (connectStaus) { Thread.Sleep(20); try { switch (connFlow) { case MTF6KConnStus.Idle: break; case MTF6KConnStus.Disconnect: { TCP.SendMessage(MTF6K.disconnect); connectStaus = false; TCP.FormOpening = false; TCP.ConnectedResult -= new Communicate.ConnectResultEventHandler(Comm_ConnectedResult); TCP.MessageReceived -= new Communicate.MessageReceivedEventHandler(Comm_MessageReceived); TCP.closeSocket(); TCP = null; } break; case MTF6KConnStus.Connected: TCP.SendMessage(MTF6K.disconnect); Thread.Sleep(20); TCP.SendMessage(MTF6K.connect); connFlow = MTF6KConnStus.CheckConnect; break; case MTF6KConnStus.CheckConnect: if (MTF6K.MID == "0002") { TCP.SendMessage(MTF6K.keepAlive); connFlow = MTF6KConnStus.SelectPSET; } else { } break; case MTF6KConnStus.SelectPSET: TCP.SendMessage(MTF6K.switchPSET1); connFlow = MTF6KConnStus.CheckSelectPSET; break; case MTF6KConnStus.CheckSelectPSET: if (MTF6K.MID == "0005") { connFlow = MTF6KConnStus.SubscribeResult; } else if (MTF6K.MID == "0004") { connFlow = MTF6KConnStus.SubscribeResult; } break; case MTF6KConnStus.SubscribeResult: TCP.SendMessage(MTF6K.subscribeTightingResult); connFlow = MTF6KConnStus.CheckSubscribeResult1; break; case MTF6KConnStus.CheckSubscribeResult1: if (MTF6K.MID == "1202") { connFlow = MTF6KConnStus.SubscribeCurve; } else { } break; case MTF6KConnStus.SubscribeCurve: TCP.SendMessage(MTF6K.subscribeLastTightingCurve); connFlow = MTF6KConnStus.CheckSubscribeCurve; break; case MTF6KConnStus.CheckSubscribeCurve: if (MTF6K.MID == "0005") { connFlow = MTF6KConnStus.Ready; } else { } break; case MTF6KConnStus.Ready: { if (MTF6K.MID == "0901" && MTF6K.isDataRecvFinish == true) { MTF6K.MID = "error"; MTF6K.TightingResult.Convert(out tightResult.ResultCode, out tightResult.PearkTorque, out tightResult.TotalAngle, out tightResult.TotalDuration); tightResult.torque = new double[MTF6K.CurveResult.SampleCount]; tightResult.angle = new double[MTF6K.CurveResult.SampleCount]; MTF6K.CurveResult.Convert(out tightResult.torque, out tightResult.torCoef, out tightResult.angle, out tightResult.angCoef); tightResult.PearkTorque = tightResult.PearkTorque / 98; #region double preDegree = 0; double curDegree = 0; bool Step3 = false; double PearkTorque = 0.0; double Pearkdegree = 0.0; double mindegree = 0; double minvalue = 0; JD.Clear(); NL.Clear(); List pearkTorqueList = new List(); // 存储 PearkTorque List pearkDegreeList = new List(); // 存储 Pearkdegree for (int i = 0; i < tightResult.angle.Length; i++) { double degree = tightResult.angle[i] * tightResult.angCoef; double torque = tightResult.torque[i] * tightResult.torCoef / 98; preDegree = curDegree; curDegree = degree; if (i > tightResult.angle.Length - 5 && torque <= 0) { continue; } JD.Add(Math.Round(degree,0).ToString()); NL.Add(Math.Round(torque,2).ToString()); //反转 if (curDegree - preDegree <= 0 && degree < 0) { if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } if (torque < mindegree) { mindegree = torque; minvalue = degree; } } else if (curDegree - preDegree > 0)//正转 { if (degree < 360 && !Step3)//切换扭矩值 { if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } } else { Step3 = true; if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } } } pearkTorqueList.Add(Math.Round(Pearkdegree)); // 添加到列表 pearkDegreeList.Add(Math.Round(PearkTorque, 2)); // 添加到列表 } //精度 JD_MEAN = Math.Round(Pearkdegree); //扭力 NL_MEAN = Math.Round(PearkTorque, 2); // 调用 AddData 方法,存储数据 AddData(JD_MEAN, NL_MEAN, pearkTorqueList.ToArray(), pearkDegreeList.ToArray()); #endregion } } break; case MTF6KConnStus.UnsubscribeCurve: TCP.SendMessage(MTF6K.unsubscribeLastTightingCurve); break; case MTF6KConnStus.UnsubcribeResult: TCP.SendMessage(MTF6K.unsubscribeTightingResult); break; } } catch (Exception e) { //logHelper.WriteLog("阿特拉斯通讯异常:" + e.StackTrace); } } } } // 线程安全锁对象 private readonly object _queueLock = new object(); // 添加数据到缓存 private readonly Queue<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> _dataQueueLeft = new Queue<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)>(); private readonly Queue<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> _dataQueueRight = new Queue<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)>(); // 添加数据到缓存 public void AddData(double jdMean, double nlMean, double[] pearkTorque, double[] pearkDegree) { lock (_queueLock) { if (Direction == "Left") { _dataQueueLeft.Enqueue((jdMean, nlMean, pearkTorque, pearkDegree)); } else if (Direction == "Right") { _dataQueueRight.Enqueue((jdMean, nlMean, pearkTorque, pearkDegree)); } } } // 获取并清空缓存中的所有数据(左侧) public IEnumerable<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> GetCachedDataLeft() { lock (_queueLock) { var cachedData = _dataQueueLeft.ToList(); // 将当前队列内容复制到列表 _dataQueueLeft.Clear(); // 清空队列 return cachedData; } } // 获取并清空缓存中的所有数据(右侧) public IEnumerable<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> GetCachedDataRight() { lock (_queueLock) { var cachedData = _dataQueueRight.ToList(); // 将当前队列内容复制到列表 _dataQueueRight.Clear(); // 清空队列 return cachedData; } } public void DrawCurveDegTor() { double preDegree = 0; double curDegree = 0; bool Step3 = false; double PearkTorque = 0.0; double Pearkdegree = 0.0; for (int i = 0; i < tightResult.angle.Length; i++) { double degree = tightResult.angle[i] * tightResult.angCoef; double torque = tightResult.torque[i] * tightResult.torCoef / 98; preDegree = curDegree; curDegree = degree; //反转 if (curDegree - preDegree <= 0 && degree < 0) { if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } } else if (curDegree - preDegree > 0)//正转 { if (degree < 360 && !Step3)//切换扭矩值 { if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } } else { Step3 = true; if (torque > PearkTorque) { PearkTorque = torque; Pearkdegree = degree; } } //bianliang.NL_MEAN = PearkTorque; // bianliang.JD_MEAN = Pearkdegree; } } } } }