using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using EIP_Protocol;
using MainForm;
using MathNet.Numerics.RootFinding;
using Newtonsoft.Json;
namespace CommonLib
{
public class AtlasScrew_Right : BaseScrew
{
MTF6KConnStus connFlow = new MTF6KConnStus();
public TightResult tightResult = new TightResult();
string receiveMsg;
//连接状态
//public bool connectStaus = false;
public Thread MTF6KThread;
public AtlasScrew_Right(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 (sender is Communicate sender1)
{
ReceiveIP = sender1.IpAddress.ToString();
}
if (connFlow == MTF6KConnStus.Ready)
{
MTF6K.ParseKerwords(e.byteMes, false);
//ReceiveIP = ((CommonLib.Communicate)sender).IpAddress.ToString();
}
else
{
MTF6K.ParseKerwords(e.byteMes, true);
}
}
///
/// 连接MTF6K流程
///
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);
Form_Home home = new Form_Home();
#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}";
// //写入PLC
// double maxfTorque = tightResult.torque.Aggregate((currentMax, next) => currentMax > next ? currentMax : next);
// double maxfCircles = tightResult.angle.Aggregate((currentMax, next) => currentMax > next ? currentMax : next);
// OP70_ScrewDataSet_t resultToPlC = new OP70_ScrewDataSet_t
// {
// fTorque = (float)maxfTorque,
// fCircles = (float)maxfCircles
// };
// home.WriteResultToPlc(7, "", "g_OP70_MES.Left.screwDriver", 1, resultToPlC);
//}
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}";
//写入PLC
double maxfTorque = tightResult.torque.Aggregate((currentMax, next) => currentMax > next ? currentMax : next);
double maxfCircles = tightResult.angle.Aggregate((currentMax, next) => currentMax > next ? currentMax : next);
OP70_ScrewDataSet_t resultToPlC = new OP70_ScrewDataSet_t
{
fTorque = (float)maxfTorque,
fCircles = (float)maxfCircles
};
home.WriteResultToPlc(7, "", "g_OP70_MES.Right.screwDriver", 1, resultToPlC);
}
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 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 (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;
}
}
}
}
}