123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading;
- using MainForm;
- 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;
- }
- /// <summary>
- /// MTF6K连接流程结构体
- /// </summary>
- enum MTF6KConnStus
- {
- Idle,
- Disconnect,
- Connected,
- CheckConnect,
- SelectPSET,
- CheckSelectPSET,
- SelectBatch,
- CheckSelectBatch,
- SubscribeResult,
- CheckSubscribeResult1,
- CheckSubscribeResult2,
- CheckSubscribeResult3,
- SubscribeCurve,
- CheckSubscribeCurve,
- Ready,
- UnsubcribeResult,
- UnsubscribeCurve,
- };
- /// <summary>
- /// 拧紧结果
- /// </summary>
- public class TightResult
- {
- /// <summary>
- /// 扭矩数组
- /// </summary>
- public double[] torque;
- /// <summary>
- /// 角度数组
- /// </summary>
- public double[] angle;
- /// <summary>
- ///
- /// </summary>
- public double torCoef = 0.0;
- /// <summary>
- ///
- /// </summary>
- public double angCoef = 0.0;
- /// <summary>
- /// 峰值扭矩
- /// </summary>
- public double PearkTorque = 0.0;
- /// <summary>
- /// 总角度
- /// </summary>
- public double TotalAngle = 0.0;//总角度
- /// <summary>
- /// 总持续时间
- /// </summary>
- public double TotalDuration;//总持续时间
- /// <summary>
- /// 结果代码
- /// </summary>
- 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;
- }
- }
- /// <summary>
- /// MTF6K -TCP连接状态
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public void Comm_ConnectedResult(object sender, Communicate.ResultEventArgs e)
- {
- if (e.conResult)
- {
- connFlow = MTF6KConnStus.Connected;
- connectStaus = true;
- }
- else
- {
- connectStaus = false;
- }
- }
- /// <summary>
- /// 接收数据-MTF6K
- /// </summary>
- /// <param name="sender"></param>
- /// <param name="e"></param>
- public void Comm_MessageReceived(object sender, Communicate.MessageEventArgs e)
- {
- if (connFlow == MTF6KConnStus.Ready)
- {
- MTF6K.ParseKerwords(e.byteMes, false);
- ReceiveIP = ((CommonLib.Communicate)sender).IpAddress.ToString();
- }
- else
- {
- MTF6K.ParseKerwords(e.byteMes, true);
- }
- }
- /// <summary>
- /// 连接MTF6K流程
- /// </summary>
- private void MTF6KFlow()
- {
- int screwIndex = 0;
- 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);
-
- #region 保存数据
- string dic = GlobalContext.AtlasLogDir + "扭力曲线\\";
- if (!Directory.Exists(dic))
- {
- Directory.CreateDirectory(dic);
- }
- string 扭力曲线文件名 = dic + DateTime.Now.ToString("yyyy_MM_dd") +".csv" ;
- string strDirection = "";
- string strValue="";
- StringBuilder sbStr =new StringBuilder();
- if (!File.Exists(扭力曲线文件名))
- {
- // 记录时间,产品SN,螺丝序号
- //sbStr.AppendLine("序号,产品SN,扭力数组,角度数组,峰值扭矩,总角度,总持续时间,结果代码,工位");
- sbStr.Append("序号,产品SN,扭力数组,角度数组,峰值扭矩,总角度,总持续时间,结果代码,工位");
- File.WriteAllText(扭力曲线文件名, sbStr.ToString());
- }
- if (ReceiveIP == GlobalContext.AtlasAddressLeft)
- {
- //左工位
- Form_Home.screwIndex_left += 1;//螺丝序号,采集一次加一次,进站时先清0
- screwIndex = Form_Home.screwIndex_left;
- strDirection = "左工位";
- string torqueData = string.Join(",", tightResult.torque);
- string angleData = string.Join(",", tightResult.angle);
- string sn = Form_Home.barcode_left.strProductBarcode;
- strValue=$"{screwIndex},{sn},{torqueData},{angleData},{tightResult.PearkTorque},{tightResult.TotalAngle}" +
- $",{tightResult.TotalDuration},{tightResult.ResultCode},{strDirection}";
- }
- else if (ReceiveIP == GlobalContext.AtlasAddressRight)
- {
- Form_Home.screwIndex_right += 1;//螺丝序号,采集一次加一次,进站时先清0
- screwIndex = Form_Home.screwIndex_right;
- strDirection = "右工位";
- string torqueData = string.Join(",", tightResult.torque);
- string angleData = string.Join(",", tightResult.angle);
- string sn = Form_Home.barcode_left.strProductBarcode;
- strValue = $"{screwIndex},{sn},{torqueData},{angleData},{tightResult.PearkTorque},{tightResult.TotalAngle}" +
- $",{tightResult.TotalDuration},{tightResult.ResultCode},{strDirection}";
- }
-
- using(StreamWriter writer=new StreamWriter(扭力曲线文件名,true)){
- writer.WriteLine(strValue);
- }
- #endregion 保存数据
- //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<double> pearkTorqueList = new List<double>(); // 存储 PearkTorque
- //List<double> pearkDegreeList = new List<double>(); // 存储 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 (ReceiveIP == GlobalContext.AtlasAddressLeft)
- {
- _dataQueueLeft.Enqueue((jdMean, nlMean, pearkTorque, pearkDegree));
- }
- else if (Direction == GlobalContext.AtlasAddressRight)
- {
- _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;
- }
- }
- }
- }
- }
|