AtlasScrew.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using MathNet.Numerics.RootFinding;
  7. using Newtonsoft.Json;
  8. namespace CommonLib
  9. {
  10. public class AtlasScrew : BaseScrew
  11. {
  12. MTF6KConnStus connFlow = new MTF6KConnStus();
  13. public TightResult tightResult = new TightResult();
  14. string receiveMsg;
  15. //连接状态
  16. //public bool connectStaus = false;
  17. public Thread MTF6KThread;
  18. public AtlasScrew(object ip, object port, int connectTimeOut,int sendDataTimeOut,string direction)
  19. {
  20. Ip = ip.ToString();
  21. Port = port.ToString();
  22. ConnectTimeOut = connectTimeOut;
  23. SendDataTimeOut = sendDataTimeOut;
  24. IsCarriage = true;
  25. IsShield = false;
  26. Direction = direction;
  27. }
  28. /// <summary>
  29. /// MTF6K连接流程结构体
  30. /// </summary>
  31. enum MTF6KConnStus
  32. {
  33. Idle,
  34. Disconnect,
  35. Connected,
  36. CheckConnect,
  37. SelectPSET,
  38. CheckSelectPSET,
  39. SelectBatch,
  40. CheckSelectBatch,
  41. SubscribeResult,
  42. CheckSubscribeResult1,
  43. CheckSubscribeResult2,
  44. CheckSubscribeResult3,
  45. SubscribeCurve,
  46. CheckSubscribeCurve,
  47. Ready,
  48. UnsubcribeResult,
  49. UnsubscribeCurve,
  50. };
  51. /// <summary>
  52. /// 拧紧结果
  53. /// </summary>
  54. public class TightResult
  55. {
  56. public double[] torque;
  57. public double[] angle;
  58. public double torCoef = 0.0;
  59. public double angCoef = 0.0;
  60. public double PearkTorque = 0.0;//峰值扭矩
  61. public double TotalAngle = 0.0;//总角度
  62. public double TotalDuration;//总持续时间
  63. public int ResultCode = 0;//结果代码
  64. public TightResult()
  65. {
  66. }
  67. public void Reset()
  68. {
  69. torCoef = 0.0;
  70. angCoef = 0.0;
  71. ResultCode = 0;
  72. PearkTorque = 0.0;//峰值扭矩
  73. TotalAngle = 0.0;//总角度
  74. TotalDuration = 0.0;//总持续时间
  75. MTF6K.isDataRecvFinish = false;
  76. }
  77. }
  78. private Communicate TCP;
  79. public override void Initial()
  80. {
  81. base.Initial();
  82. try
  83. {
  84. // 如果线程已经存在,先关闭旧线程
  85. if (MTF6KThread != null && MTF6KThread.IsAlive)
  86. {
  87. MTF6KThread.Abort(); // 强制终止线程(注意:Abort 不推荐使用,建议改用信号机制)
  88. MTF6KThread = null;
  89. }
  90. // 如果 TCP 已经连接,先关闭连接
  91. if (TCP != null)
  92. {
  93. TCP.ConnectedResult -= new Communicate.ConnectResultEventHandler(Comm_ConnectedResult);
  94. TCP.MessageReceived -= new Communicate.MessageReceivedEventHandler(Comm_MessageReceived);
  95. TCP.closeSocket();
  96. TCP = null;
  97. }
  98. TCP = new Communicate("TCP1", Ip, Convert.ToInt32(Port));
  99. TCP.FormOpening = true;
  100. TCP.ConnectedResult += new Communicate.ConnectResultEventHandler(Comm_ConnectedResult);
  101. TCP.MessageReceived += new Communicate.MessageReceivedEventHandler(Comm_MessageReceived);
  102. MTF6KThread = new Thread(MTF6KFlow);
  103. MTF6KThread.IsBackground = true;
  104. MTF6KThread.Start();
  105. IsOk = true;
  106. }
  107. catch (Exception)
  108. {
  109. IsOk = IsShield ? true : false;
  110. }
  111. }
  112. /// <summary>
  113. /// MTF6K -TCP连接状态
  114. /// </summary>
  115. /// <param name="sender"></param>
  116. /// <param name="e"></param>
  117. public void Comm_ConnectedResult(object sender, Communicate.ResultEventArgs e)
  118. {
  119. if (e.conResult)
  120. {
  121. connFlow = MTF6KConnStus.Connected;
  122. connectStaus = true;
  123. }
  124. else
  125. {
  126. connectStaus = false;
  127. }
  128. }
  129. /// <summary>
  130. /// 接收数据-MTF6K
  131. /// </summary>
  132. /// <param name="sender"></param>
  133. /// <param name="e"></param>
  134. public void Comm_MessageReceived(object sender, Communicate.MessageEventArgs e)
  135. {
  136. if (connFlow == MTF6KConnStus.Ready)
  137. MTF6K.ParseKerwords(e.byteMes, false);
  138. else
  139. {
  140. MTF6K.ParseKerwords(e.byteMes, true);
  141. }
  142. }
  143. /// <summary>
  144. /// 连接MTF6K流程
  145. /// </summary>
  146. private void MTF6KFlow()
  147. {
  148. while (true)
  149. {
  150. Thread.Sleep(20);
  151. while (connectStaus)
  152. {
  153. Thread.Sleep(20);
  154. try
  155. {
  156. switch (connFlow)
  157. {
  158. case MTF6KConnStus.Idle:
  159. break;
  160. case MTF6KConnStus.Disconnect:
  161. {
  162. TCP.SendMessage(MTF6K.disconnect);
  163. connectStaus = false;
  164. TCP.FormOpening = false;
  165. TCP.ConnectedResult -= new Communicate.ConnectResultEventHandler(Comm_ConnectedResult);
  166. TCP.MessageReceived -= new Communicate.MessageReceivedEventHandler(Comm_MessageReceived);
  167. TCP.closeSocket();
  168. TCP = null;
  169. }
  170. break;
  171. case MTF6KConnStus.Connected:
  172. TCP.SendMessage(MTF6K.disconnect);
  173. Thread.Sleep(20);
  174. TCP.SendMessage(MTF6K.connect);
  175. connFlow = MTF6KConnStus.CheckConnect;
  176. break;
  177. case MTF6KConnStus.CheckConnect:
  178. if (MTF6K.MID == "0002")
  179. {
  180. TCP.SendMessage(MTF6K.keepAlive);
  181. connFlow = MTF6KConnStus.SelectPSET;
  182. }
  183. else
  184. { }
  185. break;
  186. case MTF6KConnStus.SelectPSET:
  187. TCP.SendMessage(MTF6K.switchPSET1);
  188. connFlow = MTF6KConnStus.CheckSelectPSET;
  189. break;
  190. case MTF6KConnStus.CheckSelectPSET:
  191. if (MTF6K.MID == "0005")
  192. {
  193. connFlow = MTF6KConnStus.SubscribeResult;
  194. }
  195. else if (MTF6K.MID == "0004")
  196. {
  197. connFlow = MTF6KConnStus.SubscribeResult;
  198. }
  199. break;
  200. case MTF6KConnStus.SubscribeResult:
  201. TCP.SendMessage(MTF6K.subscribeTightingResult);
  202. connFlow = MTF6KConnStus.CheckSubscribeResult1;
  203. break;
  204. case MTF6KConnStus.CheckSubscribeResult1:
  205. if (MTF6K.MID == "1202")
  206. {
  207. connFlow = MTF6KConnStus.SubscribeCurve;
  208. }
  209. else
  210. { }
  211. break;
  212. case MTF6KConnStus.SubscribeCurve:
  213. TCP.SendMessage(MTF6K.subscribeLastTightingCurve);
  214. connFlow = MTF6KConnStus.CheckSubscribeCurve;
  215. break;
  216. case MTF6KConnStus.CheckSubscribeCurve:
  217. if (MTF6K.MID == "0005")
  218. {
  219. connFlow = MTF6KConnStus.Ready;
  220. }
  221. else
  222. { }
  223. break;
  224. case MTF6KConnStus.Ready:
  225. {
  226. if (MTF6K.MID == "0901" && MTF6K.isDataRecvFinish == true)
  227. {
  228. MTF6K.MID = "error";
  229. MTF6K.TightingResult.Convert(out tightResult.ResultCode, out tightResult.PearkTorque, out tightResult.TotalAngle, out tightResult.TotalDuration);
  230. tightResult.torque = new double[MTF6K.CurveResult.SampleCount];
  231. tightResult.angle = new double[MTF6K.CurveResult.SampleCount];
  232. MTF6K.CurveResult.Convert(out tightResult.torque, out tightResult.torCoef, out tightResult.angle, out tightResult.angCoef);
  233. tightResult.PearkTorque = tightResult.PearkTorque / 98;
  234. #region
  235. double preDegree = 0;
  236. double curDegree = 0;
  237. bool Step3 = false;
  238. double PearkTorque = 0.0;
  239. double Pearkdegree = 0.0;
  240. double mindegree = 0;
  241. double minvalue = 0;
  242. JD.Clear();
  243. NL.Clear();
  244. List<double> pearkTorqueList = new List<double>(); // 存储 PearkTorque
  245. List<double> pearkDegreeList = new List<double>(); // 存储 Pearkdegree
  246. for (int i = 0; i < tightResult.angle.Length; i++)
  247. {
  248. double degree = tightResult.angle[i] * tightResult.angCoef;
  249. double torque = tightResult.torque[i] * tightResult.torCoef / 98;
  250. preDegree = curDegree;
  251. curDegree = degree;
  252. if (i > tightResult.angle.Length - 5 && torque <= 0)
  253. {
  254. continue;
  255. }
  256. JD.Add(Math.Round(degree,0).ToString());
  257. NL.Add(Math.Round(torque,2).ToString());
  258. //反转
  259. if (curDegree - preDegree <= 0 && degree < 0)
  260. {
  261. if (torque > PearkTorque)
  262. {
  263. PearkTorque = torque;
  264. Pearkdegree = degree;
  265. }
  266. if (torque < mindegree)
  267. {
  268. mindegree = torque;
  269. minvalue = degree;
  270. }
  271. }
  272. else if (curDegree - preDegree > 0)//正转
  273. {
  274. if (degree < 360 && !Step3)//切换扭矩值
  275. {
  276. if (torque > PearkTorque)
  277. {
  278. PearkTorque = torque;
  279. Pearkdegree = degree;
  280. }
  281. }
  282. else
  283. {
  284. Step3 = true;
  285. if (torque > PearkTorque)
  286. {
  287. PearkTorque = torque;
  288. Pearkdegree = degree;
  289. }
  290. }
  291. }
  292. pearkTorqueList.Add(Math.Round(Pearkdegree)); // 添加到列表
  293. pearkDegreeList.Add(Math.Round(PearkTorque, 2)); // 添加到列表
  294. }
  295. //精度
  296. JD_MEAN = Math.Round(Pearkdegree);
  297. //扭力
  298. NL_MEAN = Math.Round(PearkTorque, 2);
  299. // 调用 AddData 方法,存储数据
  300. AddData(JD_MEAN, NL_MEAN, pearkTorqueList.ToArray(), pearkDegreeList.ToArray());
  301. #endregion
  302. }
  303. }
  304. break;
  305. case MTF6KConnStus.UnsubscribeCurve:
  306. TCP.SendMessage(MTF6K.unsubscribeLastTightingCurve);
  307. break;
  308. case MTF6KConnStus.UnsubcribeResult:
  309. TCP.SendMessage(MTF6K.unsubscribeTightingResult);
  310. break;
  311. }
  312. }
  313. catch (Exception e)
  314. {
  315. //logHelper.WriteLog("阿特拉斯通讯异常:" + e.StackTrace);
  316. }
  317. }
  318. }
  319. }
  320. // 线程安全锁对象
  321. private readonly object _queueLock = new object();
  322. // 添加数据到缓存
  323. 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)>();
  324. 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)>();
  325. // 添加数据到缓存
  326. public void AddData(double jdMean, double nlMean, double[] pearkTorque, double[] pearkDegree)
  327. {
  328. lock (_queueLock)
  329. {
  330. if (Direction == "Left")
  331. {
  332. _dataQueueLeft.Enqueue((jdMean, nlMean, pearkTorque, pearkDegree));
  333. }
  334. else if (Direction == "Right")
  335. {
  336. _dataQueueRight.Enqueue((jdMean, nlMean, pearkTorque, pearkDegree));
  337. }
  338. }
  339. }
  340. // 获取并清空缓存中的所有数据(左侧)
  341. public IEnumerable<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> GetCachedDataLeft()
  342. {
  343. lock (_queueLock)
  344. {
  345. var cachedData = _dataQueueLeft.ToList(); // 将当前队列内容复制到列表
  346. _dataQueueLeft.Clear(); // 清空队列
  347. return cachedData;
  348. }
  349. }
  350. // 获取并清空缓存中的所有数据(右侧)
  351. public IEnumerable<(double JD_MEAN, double NL_MEAN, double[] PearkTorque, double[] Pearkdegree)> GetCachedDataRight()
  352. {
  353. lock (_queueLock)
  354. {
  355. var cachedData = _dataQueueRight.ToList(); // 将当前队列内容复制到列表
  356. _dataQueueRight.Clear(); // 清空队列
  357. return cachedData;
  358. }
  359. }
  360. public void DrawCurveDegTor()
  361. {
  362. double preDegree = 0;
  363. double curDegree = 0;
  364. bool Step3 = false;
  365. double PearkTorque = 0.0;
  366. double Pearkdegree = 0.0;
  367. for (int i = 0; i < tightResult.angle.Length; i++)
  368. {
  369. double degree = tightResult.angle[i] * tightResult.angCoef;
  370. double torque = tightResult.torque[i] * tightResult.torCoef / 98;
  371. preDegree = curDegree;
  372. curDegree = degree;
  373. //反转
  374. if (curDegree - preDegree <= 0 && degree < 0)
  375. {
  376. if (torque > PearkTorque)
  377. {
  378. PearkTorque = torque;
  379. Pearkdegree = degree;
  380. }
  381. }
  382. else if (curDegree - preDegree > 0)//正转
  383. {
  384. if (degree < 360 && !Step3)//切换扭矩值
  385. {
  386. if (torque > PearkTorque)
  387. {
  388. PearkTorque = torque;
  389. Pearkdegree = degree;
  390. }
  391. }
  392. else
  393. {
  394. Step3 = true;
  395. if (torque > PearkTorque)
  396. {
  397. PearkTorque = torque;
  398. Pearkdegree = degree;
  399. }
  400. }
  401. //bianliang.NL_MEAN = PearkTorque;
  402. // bianliang.JD_MEAN = Pearkdegree;
  403. }
  404. }
  405. }
  406. }
  407. }