MainThreadClass.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. using CCDCount.MODEL.CameraClass;
  2. using CCDCount.MODEL.ConfigModel;
  3. using CCDCount.MODEL.ShuLiClass;
  4. using LogClass;
  5. using MvCameraControl;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.Drawing;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Runtime.Remoting.Messaging;
  13. using System.Threading;
  14. namespace CCDCount.DLL
  15. {
  16. public class MainThreadClass
  17. {
  18. #region 变量与实例
  19. Thread SwitchIdentifyImageThread = null;
  20. bool IsSwitch = false;
  21. public ShuLiClass shuLiClass = null;
  22. CameraClass cameraClass = new CameraClass();
  23. public string ThisCameraDevice = string.Empty;
  24. public string ThisCameraSN = string.Empty;
  25. public string ThisCamerName = string.Empty;
  26. public int ThisCamerNo = -1;
  27. //留给主界面的回调函数
  28. public event EventHandler<ActiveObjectEventArgsClass> WorkerToFrom;
  29. public bool CameraStatic { get { return _CameraStatic; } }
  30. private bool _CameraStatic = false;
  31. public bool CameraRunStatic { get { return cameraClass.IsGrabbing; } }
  32. public bool IsOpenLoadThread { get { return _IsOpenLoadThread; }}
  33. private bool _IsOpenLoadThread = false;
  34. public int HistoryActiveNum { get { return shuLiClass.GetHistoryActiveNum(); } }
  35. public int OkHistoryNum { get { return shuLiClass.GetOkHistoryNum(); } }
  36. public int NgHistoryNum { get { return shuLiClass.GetNgHistoryNum(); } }
  37. ZmcauxClass zmcauxClass = new ZmcauxClass();
  38. //private BottingClass Botting = new BottingClass();
  39. //private MechanicalControlClass MechanicalControl = new MechanicalControlClass();
  40. /// <summary>
  41. /// 数粒状态计时器
  42. /// </summary>
  43. Stopwatch stopwatch = Stopwatch.StartNew();
  44. /// <summary>
  45. /// 数粒状态
  46. /// </summary>
  47. private bool _ShuLiState = true;
  48. public bool ShuLiState { get { return _ShuLiState; } }
  49. #endregion
  50. #region 公共方法
  51. public MainThreadClass(ShuLiConfigClass configClass,CameraConfig CameraConfig)
  52. {
  53. // 数粒配置文件地址
  54. if (configClass!=null)
  55. {
  56. // 创建数粒对象(配置文件)
  57. shuLiClass = new ShuLiClass(configClass);
  58. }
  59. else
  60. {
  61. // 创建数粒对象(默认)
  62. shuLiClass = new ShuLiClass();
  63. }
  64. _IsOpenLoadThread = CameraConfig.IsOpenLoad;
  65. ThisCameraSN = CameraConfig.CameraSNNum;
  66. ThisCamerName = CameraConfig.CameraName;
  67. ThisCameraDevice = CameraConfig.DeviceName;
  68. ThisCamerNo = CameraConfig.CamerNo;
  69. }
  70. /// <summary>
  71. /// 开始主线程
  72. /// </summary>
  73. public bool StartMianThread(CameraConfig DeviceConfig)
  74. {
  75. bool result = false;
  76. // 相机列表
  77. List<CameraInfoClass> list = new List<CameraInfoClass>();
  78. // 获取相机列表
  79. cameraClass.GetCameraList(out list);
  80. if (list.Count == 0)
  81. {
  82. LOG.error(string.Format("{0}:没有相机", "MainThreadClass-StartMianThread"));
  83. // 如果没有相机,则退出
  84. return result;
  85. }
  86. // 加载相机
  87. // cameraClass.LoadCamereDevice(list.First().DeviceSN);
  88. if(!cameraClass.LoadCamereDevice(DeviceConfig))
  89. {
  90. LOG.error(string.Format("{0}:相机加载失败", "MainThreadClass-StartMianThread"));
  91. return result;
  92. }
  93. // 取图线程开启
  94. cameraClass.StartCamera();
  95. _CameraStatic = true;
  96. // 数据交换线程开启
  97. StartSwitchThread();
  98. // 为数粒算法的识别成功一粒回调函数添加方法
  99. shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
  100. // 开启识别线程
  101. shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
  102. zmcauxClass.OpenZmcauxCard();
  103. result = true;
  104. return result;
  105. }
  106. /// <summary>
  107. /// 开始主线程
  108. /// </summary>
  109. public bool StartMianThread()
  110. {
  111. bool result = false;
  112. // 相机列表
  113. List<CameraInfoClass> list = new List<CameraInfoClass>();
  114. // 获取相机列表
  115. cameraClass.GetCameraList(out list);
  116. if (list.Count == 0)
  117. {
  118. // 如果没有相机,则退出
  119. return result;
  120. }
  121. // 为数粒算法的识别成功一粒回调函数添加方法
  122. shuLiClass.WorkCompleted += Worker_OneGrainCompleted;
  123. // 加载相机
  124. if (!cameraClass.LoadCamereDevice(new CameraConfig() { CameraSNNum = list.First().DeviceSN}))
  125. return result;
  126. _CameraStatic = true;
  127. // 取图线程开启
  128. cameraClass.StartCamera();
  129. // 数据交换线程开启
  130. StartSwitchThread();
  131. // 开启识别线程
  132. shuLiClass.StartIdentifyFuntion(cameraClass.GetCamereImageSize().Width);
  133. zmcauxClass.OpenZmcauxCard();
  134. result = true;
  135. return result;
  136. }
  137. /// <summary>
  138. /// 停止主线程
  139. /// </summary>
  140. public void StopMianThread()
  141. {
  142. shuLiClass.WorkCompleted -= Worker_OneGrainCompleted;
  143. // 相机取图线程关闭
  144. cameraClass.StopCamera();
  145. // 数据交换线程关闭
  146. StopSwitchThread();
  147. // 数粒识别线程关闭
  148. shuLiClass.StopIdentifyFuntion();
  149. zmcauxClass.CloseZmcauxCard();
  150. }
  151. public bool ReLoadCamera(string CameraSN)
  152. {
  153. bool result = false;
  154. result = cameraClass.ReLoadCameraDevice(CameraSN);
  155. if (result)
  156. {
  157. CameraConfig ReloadCaonfig = cameraClass.GetConfigValue();
  158. ThisCameraSN = ReloadCaonfig.CameraSNNum;
  159. ThisCamerName = ReloadCaonfig.CameraName;
  160. ThisCameraDevice = ReloadCaonfig.DeviceName;
  161. }
  162. return result;
  163. }
  164. public void DisposeCamera()
  165. {
  166. cameraClass.StopCamera();
  167. ThisCameraSN = string.Empty;
  168. ThisCamerName = string.Empty;
  169. ThisCameraDevice = string.Empty;
  170. }
  171. /// <summary>
  172. /// 获取显示用的图片数据
  173. /// </summary>
  174. /// <param name="ImageHeight"></param>
  175. /// <param name="Data"></param>
  176. public void GetShowImage(int ImageHeight,out Bitmap ImageData)
  177. {
  178. List<RowStartEndCol> RowsShowList = new List<RowStartEndCol>();
  179. ActiveObjectClass NewActive = shuLiClass.GetLastActive();
  180. if (NewActive == null)
  181. {
  182. LOG.log(string.Format("{0}:没有获取到数粒数据", "MainThreadClass-GetShowImage"));
  183. ImageData = null;
  184. return;
  185. }
  186. List<ActiveObjectClass> Data = shuLiClass.GetHistoryActive().Where(o => o.LastSeenLine > NewActive.LastSeenLine - ImageHeight).ToList();
  187. Data.ForEach(o => o.RowsData.ForEach(p => RowsShowList.Add(p)));
  188. Bitmap BitmapImage = new Bitmap(NewActive.ImageWidth, ImageHeight);
  189. Graphics g = Graphics.FromImage(BitmapImage);
  190. Pen redPen = new Pen(Color.Red, 1);
  191. List<RowStartEndCol> ShowList = RowsShowList.Where(o => o.RowsCol > NewActive.LastSeenLine - BitmapImage.Height).ToList();
  192. RowsShowList.Where(o => o.RowsCol < NewActive.LastSeenLine - BitmapImage.Height).ToList().ForEach(o => RowsShowList.Remove(o));
  193. RowsShowList.Clear();
  194. ShowList.ForEach(o => g.DrawLine(redPen, new Point(o.StartCol, (int)(NewActive.LastSeenLine - o.RowsCol)), new Point(o.EndCol, (int)(NewActive.LastSeenLine - o.RowsCol))));
  195. ShowList.Clear();
  196. ImageData = BitmapImage.Clone() as Bitmap;
  197. BitmapImage.Dispose();
  198. //GC.Collect();
  199. }
  200. /// <summary>
  201. /// 获取此刻的Config数据
  202. /// </summary>
  203. /// <param name="config"></param>
  204. public void GetConfigValue(out CameraConfig Camconfig,out ShuLiConfigClass shuLiConfig)
  205. {
  206. //判断是否加载了相机
  207. if(cameraClass.IsLoadCamera())
  208. //获取已经加载的相机的配置
  209. Camconfig = cameraClass.GetConfigValue();
  210. else
  211. //新建一个相机配置
  212. Camconfig = new CameraConfig();
  213. //读取视觉配置
  214. shuLiConfig = shuLiClass.GetConfigValue();
  215. }
  216. /// <summary>
  217. /// 获取相机此刻的Config数据
  218. /// </summary>
  219. /// <param name="CameraConfig"></param>
  220. public void GetCameraConfig(out CameraConfig CameraConfig)
  221. {
  222. //判断是否加载了相机
  223. if (cameraClass.IsLoadCamera())
  224. //获取已经加载的相机的配置
  225. CameraConfig = cameraClass.GetConfigValue();
  226. else
  227. //新建一个相机配置
  228. CameraConfig = new CameraConfig();
  229. }
  230. /// <summary>
  231. /// 保存所有Config
  232. /// </summary>
  233. public void SaveAllConfig()
  234. {
  235. shuLiClass.SaveConfig();
  236. }
  237. /// <summary>
  238. /// 获取相机连接状态
  239. /// </summary>
  240. /// <returns></returns>
  241. public bool GetCameraConnectStatic()
  242. {
  243. bool result = false;
  244. if(cameraClass != null)
  245. result = cameraClass.IsConnectCamera();
  246. return result;
  247. }
  248. public void Dispose()
  249. {
  250. //MechanicalControl.Dispose();
  251. }
  252. #endregion
  253. #region 私有方法
  254. //bool IsFill = false;
  255. //bool IsXuanZhuanCloseFaMen = false;
  256. /// <summary>
  257. /// 每数完一粒识别线程执行的事件
  258. /// </summary>
  259. /// <param name="sender"></param>
  260. /// <param name="e"></param>
  261. private void Worker_OneGrainCompleted(object sender, ActiveObjectEventArgsClass e)
  262. {
  263. LOG.log("有活跃物体转换为了历史物体,回调事件被触发!",6);
  264. if (e.Actives.Where(o => o.StateCode == 7).Count() > 0)
  265. {
  266. stopwatch.Restart();
  267. _ShuLiState = false;
  268. }
  269. else if (stopwatch.ElapsedMilliseconds > 1000)
  270. {
  271. stopwatch.Stop();
  272. _ShuLiState = true;
  273. }
  274. foreach (ActiveObjectClass oneActive in e.Actives)
  275. {
  276. LOG.log(string.Format("输出当前颗粒信息,开始行:{0},结束行:{1},开始时间:{2}结束时间:{3},颗粒状态:{4}",
  277. oneActive.StartLine, oneActive.LastSeenLine, oneActive.StartCheckTime.ToString("O"), oneActive.EndCheckTime.ToString("O"), oneActive.StateCode), 6);
  278. }
  279. // 事件处理逻辑
  280. float step = -1;
  281. float[] floats = new float[9];
  282. zmcauxClass.GetMessageFromVar("countStep", ref step);
  283. LOG.log(string.Format("{0}:countStep = {1}", "MainThreadClass-Worker_OneGrainCompleted", step),6);
  284. if (step < 1 || step>3)
  285. {
  286. zmcauxClass.GetMessageFromArray("CCD_DATA4", ref floats, 0, 9);
  287. }
  288. else
  289. {
  290. switch (step)
  291. {
  292. case 1:
  293. zmcauxClass.GetMessageFromArray("CCD_DATA1", ref floats, 0, 9);
  294. break;
  295. case 2:
  296. zmcauxClass.GetMessageFromArray("CCD_DATA2", ref floats, 0, 9);
  297. break;
  298. case 3:
  299. zmcauxClass.GetMessageFromArray("CCD_DATA3", ref floats, 0, 9);
  300. break;
  301. }
  302. }
  303. LOG.log("读取轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6);
  304. foreach (ActiveObjectClass oneActive in e.Actives)
  305. {
  306. if (oneActive.StateCode != 0)
  307. {
  308. floats[8] += 1;
  309. }
  310. else
  311. {
  312. if (oneActive.ChannelNO != -1)
  313. floats[oneActive.ChannelNO] += 1;
  314. else
  315. floats[8] += 1;
  316. }
  317. }
  318. LOG.log("写入轴卡结果数据:" + floats[0] + " " + floats[1] + " " + floats[2] + " " + floats[3] + " " + floats[4] + " " + floats[5] + " " + floats[6] + " " + floats[7] + " " + floats[8],6);
  319. if (step < 1 || step>3)
  320. {
  321. zmcauxClass.SetMessageToArray("CCD_DATA4", floats, 0, 9);
  322. }
  323. else
  324. {
  325. switch (step)
  326. {
  327. case 1:
  328. zmcauxClass.SetMessageToArray("CCD_DATA1", floats, 0, 9);
  329. break;
  330. case 2:
  331. zmcauxClass.SetMessageToArray("CCD_DATA2", floats, 0, 9);
  332. break;
  333. case 3:
  334. zmcauxClass.SetMessageToArray("CCD_DATA3", floats, 0, 9);
  335. break;
  336. }
  337. }
  338. //OnOneGrain(e.Actives);
  339. }
  340. /// <summary>
  341. /// 装瓶逻辑
  342. /// </summary>
  343. private void BottLogicFunction()
  344. {
  345. }
  346. /// <summary>
  347. /// 对外通知事件
  348. /// </summary>
  349. private void OnOneGrain(List<ActiveObjectClass> activeObject)
  350. {
  351. ActiveObjectEventArgsClass activeObjectEventArgs = new ActiveObjectEventArgsClass(activeObject);
  352. // 触发事件
  353. WorkerToFrom?.Invoke(this, activeObjectEventArgs);
  354. }
  355. #endregion
  356. #region 线程方法
  357. /// <summary>
  358. /// 开启交换线程
  359. /// </summary>
  360. private void StartSwitchThread()
  361. {
  362. IsSwitch = true;
  363. SwitchIdentifyImageThread = new Thread(SwitchIdentifyImageProcess);
  364. SwitchIdentifyImageThread.Start();
  365. }
  366. /// <summary>
  367. /// 关闭交换线程
  368. /// </summary>
  369. private void StopSwitchThread()
  370. {
  371. try
  372. {
  373. // 标志位设为false
  374. IsSwitch = false;
  375. if (SwitchIdentifyImageThread != null && SwitchIdentifyImageThread.IsAlive)
  376. SwitchIdentifyImageThread.Join();
  377. }
  378. catch (Exception ex)
  379. {
  380. LOG.error("Start thread failed!, " + ex.Message);
  381. throw;
  382. }
  383. }
  384. /// <summary>
  385. /// 交换线程
  386. /// </summary>
  387. private void SwitchIdentifyImageProcess()
  388. {
  389. IFrameOut IFramedata = null;
  390. Stopwatch stopwatch = Stopwatch.StartNew();
  391. stopwatch.Start();
  392. while (IsSwitch)
  393. {
  394. if (stopwatch.ElapsedMilliseconds > 1000)
  395. {
  396. Console.WriteLine("交换线程-相机获取实例中的图像缓存队列长度:{0}", cameraClass.ImageNum);
  397. Console.WriteLine("交换线程-图像处理实例中的待识别图像缓存队列长度{0}", shuLiClass.ImageNum);
  398. GC.Collect();
  399. stopwatch.Restart();
  400. }
  401. //Thread.Sleep(5);
  402. bool result = cameraClass.GetOnceImage(out IFramedata);
  403. if (result)
  404. {
  405. if (IFramedata == null)
  406. continue;
  407. shuLiClass.SetOnceIdentifyImageData(IFramedata);
  408. }
  409. else
  410. continue;
  411. IFramedata.Dispose();
  412. }
  413. stopwatch.Stop();
  414. }
  415. #endregion
  416. }
  417. }