LinmotSerialPortDevice.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. using Aitex.Core.RT.DataCenter;
  2. using MECF.Framework.Common.Net;
  3. using MECF.Framework.Simulator.Core.Driver;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using System.Timers;
  11. namespace MECF.Framework.Simulator.Core.Commons
  12. {
  13. public class LinmotSerialPortDevice : BaseSerialSimulator
  14. {
  15. #region 常量
  16. private const string PORT_NAME = "com24";
  17. private byte[] _channels =new byte[] { 1, 2, 3, 4 };
  18. //状态字,13位-是否正在运动,11-home标识,10-是否到达目标位置,5-Quick Stop常为1,4-Power常为1,0-Operation enabled
  19. private Dictionary<int, short> _statusWordDictionary = new Dictionary<int, short>();
  20. private Dictionary<int, int> _currentPositionDictionary = new Dictionary<int, int>();
  21. IByteTransform _byteTransform;
  22. private Dictionary<int,int> _targetPositionDictionary = new Dictionary<int, int>();
  23. private Dictionary<int,int> _nextPositionDictionary = new Dictionary<int, int>();
  24. private Dictionary<int,int> _positionInterDictionary = new Dictionary<int, int>();
  25. private Dictionary<int,string> _directionDictionary = new Dictionary<int, string>();
  26. private Dictionary<int, System.Timers.Timer> _timerDictionary = new Dictionary<int, System.Timers.Timer>();
  27. private Dictionary<int, int> _speedDictionary = new Dictionary<int, int>();
  28. #endregion
  29. #region 内部变量
  30. #endregion
  31. public LinmotSerialPortDevice(string port) : base(port, SerialType.BUFFER)
  32. {
  33. _byteTransform = new SmallEndianByteTransformBase();
  34. _timerDictionary[1] = new System.Timers.Timer();
  35. _timerDictionary[1].Elapsed += Timer1_Elapsed;
  36. _timerDictionary[1].Interval = 100;
  37. _timerDictionary[1].Enabled = false;
  38. _timerDictionary[2] = new System.Timers.Timer();
  39. _timerDictionary[2].Elapsed += Timer2_Elapsed;
  40. _timerDictionary[2].Interval = 100;
  41. _timerDictionary[2].Enabled = false;
  42. _timerDictionary[3] = new System.Timers.Timer();
  43. _timerDictionary[3].Elapsed += Timer3_Elapsed;
  44. _timerDictionary[3].Interval = 100;
  45. _timerDictionary[3].Enabled = false;
  46. _timerDictionary[4] = new System.Timers.Timer();
  47. _timerDictionary[4].Elapsed += Timer4_Elapsed;
  48. _timerDictionary[4].Interval = 100;
  49. _timerDictionary[4].Enabled = false;
  50. for(int i=1;i<=4;i++)
  51. {
  52. _statusWordDictionary[i] = 0;
  53. _currentPositionDictionary[i] = 0;
  54. _directionDictionary[i] = "";
  55. _nextPositionDictionary[i] = 0;
  56. _positionInterDictionary[i] = 0;
  57. _targetPositionDictionary[i] = 0;
  58. _speedDictionary[i] = 0;
  59. }
  60. }
  61. private void Timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  62. {
  63. Elaspsed(1);
  64. }
  65. private void Timer2_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  66. {
  67. Elaspsed(2);
  68. }
  69. private void Timer3_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  70. {
  71. Elaspsed(3);
  72. }
  73. private void Timer4_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  74. {
  75. Elaspsed(4);
  76. }
  77. private void Elaspsed(int index)
  78. {
  79. _currentPositionDictionary[index] += _positionInterDictionary[index];
  80. if ((_directionDictionary[index] == "down" && _currentPositionDictionary[index] <= _targetPositionDictionary[index]) ||
  81. _directionDictionary[index] == "up" && _currentPositionDictionary[index] >= _targetPositionDictionary[index])
  82. {
  83. if (_targetPositionDictionary[index] == _nextPositionDictionary[index])
  84. {
  85. _statusWordDictionary[index] = 2103;
  86. _timerDictionary[index].Stop();
  87. return;
  88. }
  89. _targetPositionDictionary[index] = _nextPositionDictionary[index];
  90. if (_targetPositionDictionary[index] >= _currentPositionDictionary[index])
  91. {
  92. _directionDictionary[index] = "up";
  93. }
  94. else
  95. {
  96. _directionDictionary[index] = "down";
  97. }
  98. _positionInterDictionary[index] = (_targetPositionDictionary[index] - _currentPositionDictionary[index]) / 100;
  99. }
  100. }
  101. protected override void ProcessMessageBuffer(byte[] data)
  102. {
  103. Console.WriteLine($"Process {MessageConvert(data)}");
  104. if (data[0] != 0x01 && data[data.Length-1]!=0x04)
  105. {
  106. return;
  107. }
  108. int count = data.Length;
  109. byte[] tmp = new byte[data.Length];
  110. Array.Copy(data, 0, tmp, 0, data.Length);
  111. while(count>0)
  112. {
  113. var result = AnalyseData(tmp);
  114. if(result.startIndex!=-1&&result.endIndex!=-1)
  115. {
  116. Console.WriteLine($"Process success {MessageConvert(data)}");
  117. byte[] byt = new byte[result.endIndex - result.startIndex+1];
  118. Array.Copy(tmp, result.startIndex, byt, 0, byt.Length);
  119. AnalyseStandardByte(byt);
  120. if(result.endIndex==tmp.Length-1)
  121. {
  122. break;
  123. }
  124. byte[] temp = new byte[tmp.Length - result.endIndex - 1];
  125. Array.Copy(tmp, result.endIndex + 1, temp, 0, temp.Length);
  126. tmp=new byte[temp.Length];
  127. Array.Copy(temp,0,tmp, 0, temp.Length);
  128. }
  129. else
  130. {
  131. Console.WriteLine($"Process fail {MessageConvert(data)}");
  132. return;
  133. }
  134. }
  135. }
  136. private void AnalyseStandardByte(byte[] data)
  137. {
  138. byte channel = data[1];
  139. if (!_channels.Contains(channel))
  140. {
  141. return;
  142. }
  143. if(data.Length<7)
  144. {
  145. return;
  146. }
  147. byte length = data[2];
  148. //指令
  149. if (data.Length >= 8)
  150. {
  151. if (data[4] == 0x00 && data[5] == 0x01)
  152. {
  153. if (data[6] == 0x3E && data[7] == 0x00)//switch off
  154. {
  155. if (_statusWordDictionary[channel] >= 2048)
  156. {
  157. _statusWordDictionary[channel] = 2096;
  158. }
  159. else
  160. {
  161. _statusWordDictionary[channel] = 48;
  162. }
  163. }
  164. else if (data[6] == 0x3F && data[7] == 0x00)//switch on
  165. {
  166. _statusWordDictionary[channel] = 2103;
  167. }
  168. else if (data[6] == 0x3F && data[7] == 0x20)//goto initial position
  169. {
  170. _statusWordDictionary[channel] = 11319;
  171. _currentPositionDictionary[channel] = 50000;
  172. }
  173. else if (data[6] == 0x1F && data[7] == 0x00)//freeze
  174. {
  175. _statusWordDictionary[channel] = 2103;
  176. _timerDictionary[channel].Stop();
  177. }
  178. }
  179. else
  180. {
  181. if (data[4] == 0x00 && data[5] == 0x02)
  182. {
  183. if (data[7] == 0x01)//VAI Go to Position
  184. {
  185. Console.WriteLine("VAI Go to Position");
  186. _statusWordDictionary[channel] = 10295;
  187. byte[] positionByt = new byte[4];
  188. Array.Copy(data, 8, positionByt, 0, 4);
  189. if (!_timerDictionary[channel].Enabled)
  190. {
  191. _targetPositionDictionary[channel] = BitConverter.ToInt32(positionByt, 0);
  192. _positionInterDictionary[channel] = (_targetPositionDictionary[channel] - _currentPositionDictionary[channel]) / 100;
  193. _timerDictionary[channel].Enabled = true;
  194. if (_targetPositionDictionary[channel] < _currentPositionDictionary[channel])
  195. {
  196. _directionDictionary[channel] = "down";
  197. }
  198. else
  199. {
  200. _directionDictionary[channel] = "up";
  201. }
  202. _timerDictionary[channel].Start();
  203. }
  204. else
  205. {
  206. _nextPositionDictionary[channel] = BitConverter.ToInt32(positionByt, 0);
  207. }
  208. }
  209. else if (data[7]==0x20)//Command Table
  210. {
  211. _statusWordDictionary[channel] = 10295;
  212. }
  213. }
  214. else if (data[4] == 0x01 && data[5]==0x03)//RAM
  215. {
  216. if (data[6] == 0xCB && data[7]==0x14)
  217. {
  218. int value = _byteTransform.TransInt32(data, 8);
  219. _speedDictionary[channel] = value;
  220. }
  221. }
  222. }
  223. }
  224. WriteBuffer(response(channel));
  225. }
  226. /// <summary>
  227. /// 解析
  228. /// </summary>
  229. /// <param name="byt"></param>
  230. /// <returns></returns>
  231. private (int startIndex,int endIndex) AnalyseData(byte[] byt)
  232. {
  233. int startIndex = -1;
  234. int endIndex = -1;
  235. int dataLength = 0;
  236. for (int i=0;i<byt.Length;i++)
  237. {
  238. if (byt[i]==0x01&&startIndex==-1)
  239. {
  240. startIndex = i;
  241. dataLength = byt[2];
  242. }
  243. if (startIndex != -1 && byt[i]==0x04)
  244. {
  245. if (i == dataLength + 3)
  246. {
  247. endIndex = i;
  248. break;
  249. }
  250. }
  251. }
  252. return (startIndex, endIndex);
  253. }
  254. private byte[] response(byte channel)
  255. {
  256. byte[] byt = new byte[20];
  257. byt[0] = 0x01;
  258. byt[1] = channel;
  259. byt[2] = (byte)(byt.Length - 4);
  260. byt[3] = 0x02;
  261. byte[] statuswordByt = _byteTransform.GetBytes(_statusWordDictionary[channel]);
  262. byt[7] = statuswordByt[0];
  263. byt[8] = statuswordByt[1];
  264. byte[] positionByte = _byteTransform.GetBytes(_currentPositionDictionary[channel]);
  265. Array.Copy(positionByte, 0, byt, 15, positionByte.Length);
  266. byt[19] = 0x04;
  267. return byt;
  268. }
  269. }
  270. }