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;
}
}
}
}
}