PLCMonitor.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. #include "PLCMonitor.h"
  2. #include <unistd.h>
  3. #include "../common.h"
  4. namespace modbus
  5. {
  6. #ifndef WIN32
  7. #define Sleep(T) usleep((T)*1000)
  8. #endif
  9. const clock_t CPLCMonitor::PLC_LASER_TIMEOUT_READY = 1000*1000; //完成信号到心跳延时
  10. const clock_t CPLCMonitor::PLC_LASER_TIMEOUT_PINGPANG = 100*1000;
  11. const clock_t CPLCMonitor::PLC_LASER_TIMEOUT_START = 300*1000;
  12. const clock_t CPLCMonitor::PLC_LASER_TIMEOUT_MAXMEASURE = 60000*1000;
  13. CPLCMonitor::CPLCMonitor(void* pOwnerObject)
  14. :_monitoring(false)
  15. , _heartbeat_write_clock(clock())
  16. , m_callback(0)
  17. ,m_pointer(0)
  18. ,m_PlcDataCallback(0)
  19. ,m_thread_read(0)
  20. {
  21. memset(&_value, 0, sizeof(_value));
  22. }
  23. CPLCMonitor::~CPLCMonitor()
  24. {
  25. _monitoring = false;
  26. if (m_thread_read)
  27. {
  28. if(m_thread_read->joinable())
  29. m_thread_read->join();
  30. m_thread_read = 0;
  31. }
  32. }
  33. int CPLCMonitor::connect(const char *ip, int port, int slave_id)
  34. {
  35. cs_pcl.lock();
  36. if (-1 == dev.initialize(ip, port, slave_id))
  37. {
  38. cs_pcl.unlock();
  39. return -1;
  40. }
  41. cs_pcl.unlock();
  42. _monitoring = true;
  43. if (FALSE == Start())
  44. {
  45. dev.deinitialize();
  46. return -1;
  47. }
  48. m_thread_read = new std::thread(thread_monitor, this);
  49. m_strIP = ip;
  50. m_port = port;
  51. m_slave_id = slave_id;
  52. return 0;
  53. }
  54. void CPLCMonitor::set_callback(CommandCallback func, PLCMonitorCallback monitorCallback,void* pointer)
  55. {
  56. m_callback = func;
  57. m_PlcDataCallback=monitorCallback;
  58. m_pointer = pointer;
  59. }
  60. int CPLCMonitor::reconnect()
  61. {
  62. cs_pcl.lock();
  63. if (-1 == dev.initialize(m_strIP.c_str(), m_port, m_slave_id))
  64. {
  65. cs_pcl.unlock();
  66. return -1;
  67. }
  68. cs_pcl.unlock();
  69. return 0;
  70. }
  71. void CPLCMonitor::disconnect()
  72. {
  73. _monitoring = false;
  74. Join(1000);
  75. cs_pcl.lock();
  76. dev.deinitialize();
  77. cs_pcl.unlock();
  78. }
  79. int CPLCMonitor::read_registers(int addr, int nb, uint16_t *dest)
  80. {
  81. cs_pcl.lock();
  82. int rc = dev.read_registers(addr, nb, dest);
  83. cs_pcl.unlock();
  84. if (0 != rc)
  85. {
  86. reconnect();//端开,重连
  87. }
  88. return rc;
  89. }
  90. int CPLCMonitor::write_registers(int addr, int nb, uint16_t *dest)
  91. {
  92. cs_pcl.lock();
  93. int rc = dev.write_registers(addr, nb, dest);
  94. cs_pcl.unlock();
  95. return rc;
  96. }
  97. int CPLCMonitor::read_register(int addr, uint16_t *dest)
  98. {
  99. cs_pcl.lock();
  100. int rc = dev.read_register(addr, dest);
  101. cs_pcl.unlock();
  102. return rc;
  103. }
  104. int CPLCMonitor::write_register(int addr, uint16_t *dest)
  105. {
  106. cs_pcl.lock();
  107. int rc = dev.write_register(addr, dest);
  108. cs_pcl.unlock();
  109. return rc;
  110. }
  111. int CPLCMonitor::clear_laserstatus_register(uint16_t value)
  112. {
  113. cs_pcl.lock();
  114. int rc = dev.write_register(REG_WHISKBOOMLASER_STATUS, &value);
  115. cs_pcl.unlock();
  116. _heartbeat_write_clock = clock();
  117. return rc;
  118. }
  119. int CPLCMonitor::write_laserstatus_register(uint16_t value)
  120. {
  121. uint16_t dest = 0xff;
  122. cs_pcl.lock();
  123. int rc = dev.read_register(REG_WHISKBOOMLASER_STATUS, &dest);
  124. if (PLC_LASER_ERROR != dest)
  125. {
  126. rc = dev.write_register(REG_WHISKBOOMLASER_STATUS, &value);
  127. }
  128. cs_pcl.unlock();
  129. _heartbeat_write_clock = clock();
  130. if (0 != rc)
  131. {
  132. reconnect();//端开,重连
  133. }
  134. return rc;
  135. }
  136. int CPLCMonitor::write_laserresult_register(int addr,uint16_t *pvalue)
  137. {
  138. uint16_t dest = 0xff;
  139. cs_pcl.lock();
  140. int rc= dev.write_registers(addr, 10, pvalue);
  141. /*int rc = dev.read_register(REG_WHISKBOOMLASER_STATUS, &dest);
  142. if (PLC_LASER_ERROR != dest)
  143. {
  144. rc = dev.write_registers(REG_WHISKBOOMLASER_STATUS, 7, pvalue);
  145. }*/
  146. cs_pcl.unlock();
  147. _heartbeat_write_clock = clock();
  148. return rc;
  149. }
  150. void CPLCMonitor::MeasureComplete(bool bOK)
  151. {
  152. //_measure_finished = TRUE;
  153. if (!bOK)
  154. {
  155. write_laserstatus_register(PLC_LASER_FINISH_FAILED);
  156. }
  157. else
  158. {
  159. write_laserstatus_register(PLC_LASER_FINISH_OK);
  160. }
  161. }
  162. bool CPLCMonitor::setMeasureResult(int addr, struct whiskboom_laser_value * p)
  163. {
  164. if (p == 0||addr<0) //失败,没有摆扫结果,硬件错误;
  165. {
  166. return false;
  167. }
  168. else
  169. {
  170. uint16_t response[10] = { 0 };
  171. memset(response, 0, sizeof(uint16_t) * 10);
  172. if (p->corrected)
  173. {
  174. response[6] = eLaser_data_ok;
  175. }
  176. else {
  177. response[6] = eLaser_data_failed;
  178. }
  179. response[0] = (p->x);
  180. response[1] = p->y;
  181. response[2] = (int(p->a) % 18000);
  182. response[3] = p->l;
  183. response[4] = p->w;
  184. response[5] = p->h;
  185. response[7] = p->l; ////轴距
  186. write_laserresult_register(addr,(uint16_t *)response);
  187. return true;
  188. }
  189. }
  190. void CPLCMonitor::Monitoring()
  191. {
  192. const int SIGNAL_NUM = 64;
  193. const int SIGNAL_ADDR = 0;
  194. static uint16_t value[SIGNAL_NUM] = { 0 };
  195. static uint16_t last_value[SIGNAL_NUM] = { 0 };
  196. int rc = read_registers(SIGNAL_ADDR, SIGNAL_NUM, last_value);
  197. LOG(INFO) << "\tStart signal monitoring thread";
  198. while (_monitoring)
  199. {
  200. memset(value, 0, SIGNAL_NUM * sizeof(uint16_t));
  201. int rc = read_registers(SIGNAL_ADDR, SIGNAL_NUM, value);
  202. if (rc == 0)
  203. {
  204. for (int i = REG_PARKSTATUS; i < SIGNAL_NUM; ++i)
  205. {
  206. if (value[i] != last_value[i])
  207. {
  208. if(m_PlcDataCallback && m_pointer)
  209. m_PlcDataCallback(value,SIGNAL_NUM,m_pointer);
  210. break;
  211. }
  212. }
  213. memcpy(last_value, value, sizeof(uint16_t)*SIGNAL_NUM);
  214. }
  215. Sleep(200);
  216. }
  217. LOG(INFO) << "\tStop signal monitor thread!";
  218. }
  219. void CPLCMonitor::thread_monitor(void* lp)
  220. {
  221. CPLCMonitor* plc = (CPLCMonitor*)lp;
  222. plc->Monitoring();
  223. }
  224. void CPLCMonitor::Run()
  225. {
  226. uint16_t value[2] = { 0xffff,0xffff };
  227. uint16_t parking_status = 0xff;
  228. uint16_t response[7] = { 0 };
  229. int rc = -1;
  230. clock_t current_clock;
  231. uint16_t finite_state_machines = PLC_LASER_READY;
  232. write_laserstatus_register(finite_state_machines);
  233. uint16_t las_parkstatus = 0;
  234. while (_monitoring)
  235. {
  236. memset(value, 0xff, sizeof(value));
  237. rc = read_registers(REG_PARKSTATUS, 2, value);
  238. if (-1 == rc)
  239. {
  240. fprintf(stderr, "CPLCMonitor: read regiser failed\n");
  241. }
  242. parking_status = value[0];
  243. finite_state_machines = value[1];
  244. //上次状态为:开始测量,测量中
  245. if (PLC_LASER_START == finite_state_machines
  246. || PLC_LASER_WORKING == finite_state_machines)
  247. {
  248. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_READY)
  249. {
  250. write_laserstatus_register(PLC_LASER_PING);
  251. finite_state_machines = PLC_LASER_PING;
  252. }
  253. }
  254. //PLC 我要停车等待状态
  255. if (PLC_PARKING_WAIT == parking_status|| 2 == parking_status)
  256. {
  257. current_clock = clock();
  258. //激光上次状态为:测量完成成功或者测量完成失败的状态
  259. if (PLC_LASER_FINISH_OK == finite_state_machines
  260. || PLC_LASER_FINISH_FAILED == finite_state_machines)
  261. {
  262. //超过10秒,开始返回就绪状态
  263. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_READY)
  264. {
  265. //先清除数据
  266. if (PLC_LASER_FINISH_FAILED == finite_state_machines)
  267. {
  268. /*memset(response, 0, 7 * sizeof(uint16_t));
  269. write_laserresult_register((uint16_t *)response);*/
  270. }
  271. write_laserstatus_register(PLC_LASER_READY);
  272. finite_state_machines = PLC_LASER_READY;
  273. }
  274. }
  275. //激光上次状态为:就绪或者心跳状态1,
  276. else if (PLC_LASER_READY == finite_state_machines
  277. || PLC_LASER_PONG == finite_state_machines)
  278. {
  279. //超过3秒,开始返回心跳状态2
  280. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_PINGPANG)
  281. {
  282. write_laserstatus_register(PLC_LASER_PING);
  283. finite_state_machines = PLC_LASER_PING;
  284. }
  285. }
  286. //激光上次状态为:心跳状态2
  287. else if (PLC_LASER_PING == finite_state_machines)
  288. {
  289. //超过3秒,开始返回心跳状态1
  290. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_PINGPANG)
  291. {
  292. write_laserstatus_register(PLC_LASER_PONG);
  293. finite_state_machines = PLC_LASER_PONG;
  294. }
  295. }
  296. //激光上次状态为:测量开始,测量中)
  297. else if (PLC_LASER_START == finite_state_machines
  298. || PLC_LASER_WORKING == finite_state_machines)
  299. {
  300. //此时激光可能在测量状态中,让激光测量停止,结果:
  301. // 1. 如果未在测量状态,激光接受状态不会有任何返回值,
  302. // 2. 如果在测量状态会有测量失败信息须处理
  303. LOG(ERROR) << "\t 测量中开始信号终止";
  304. /* cs_cmd.Lock();
  305. for (std::vector<CLaserNet*>::iterator it = _cmdlistLaserPointer.begin(); it != _cmdlistLaserPointer.end(); ++it)
  306. (*it)->Stop();
  307. cs_cmd.Unlock();*/
  308. write_laserstatus_register(PLC_LASER_READY);
  309. finite_state_machines = PLC_LASER_READY;
  310. }
  311. //不可修复错误,等系统重启
  312. else if (PLC_LASER_ERROR == finite_state_machines)
  313. {
  314. fprintf(stderr, "\n\n\n\n\n\n不可修复错误,等系统重启\n\n\n\n\n\n");
  315. }
  316. else
  317. {
  318. fprintf(stderr, "\n\n\n\n\n\n&&&&&&&&&!!!!!!!!!!!!!@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$完全不可能出现的状态\n\n\n\n\n\n");
  319. }
  320. las_parkstatus = PLC_PARKING_WAIT;
  321. }
  322. //PLC 我要停车测量开始
  323. else if (parking_status>0)
  324. {
  325. //激光上次状态为:就绪,心跳状态1,心跳状态2
  326. if(PLC_LASER_READY == finite_state_machines
  327. || PLC_LASER_PING == finite_state_machines
  328. || PLC_LASER_PONG == finite_state_machines
  329. || PLC_LASER_FINISH_OK == finite_state_machines
  330. || PLC_LASER_FINISH_FAILED == finite_state_machines)
  331. {
  332. ///// 测量
  333. if (PLC_PARKING_WAIT == las_parkstatus && parking_status==1)
  334. {
  335. //置测量结果为未完成状态
  336. _measure_finished = FALSE;
  337. //测量开始
  338. if (m_callback)
  339. {
  340. //char plate = parking_status;
  341. uint16_t param = 0x03;
  342. m_callback(true, param, m_pointer, parking_status);
  343. }
  344. //返回测量开始状态
  345. write_laserstatus_register(PLC_LASER_START);
  346. finite_state_machines = PLC_LASER_START;
  347. }
  348. ////// 电子围栏测量
  349. /*else if ((PLC_LASER_READY == finite_state_machines
  350. || PLC_LASER_PING == finite_state_machines
  351. || PLC_LASER_PONG == finite_state_machines)
  352. &&parking_status == 2)
  353. {
  354. //置测量结果为未完成状态
  355. _measure_finished = FALSE;
  356. //测量开始
  357. if (m_callback)
  358. {
  359. uint16_t param = 0x03;
  360. m_callback(true, param, m_pointer, parking_status);
  361. }
  362. //返回测量开始状态
  363. write_laserstatus_register(PLC_LASER_START);
  364. finite_state_machines = PLC_LASER_START;
  365. }*/
  366. }
  367. //上次状态为:测量完成成功,测量完成错误,
  368. if (PLC_LASER_FINISH_OK == finite_state_machines
  369. || PLC_LASER_FINISH_FAILED == finite_state_machines)
  370. {
  371. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_PINGPANG)
  372. {
  373. write_laserstatus_register(PLC_LASER_PING);
  374. finite_state_machines = PLC_LASER_PING;
  375. }
  376. }
  377. //激光上次状态为:开始测量
  378. else if (PLC_LASER_START == finite_state_machines)
  379. {
  380. current_clock = clock();
  381. //超过200毫秒,返回测量中
  382. if (current_clock - _heartbeat_write_clock >= PLC_LASER_TIMEOUT_START)
  383. {
  384. write_laserstatus_register(PLC_LASER_WORKING);
  385. finite_state_machines = PLC_LASER_WORKING;
  386. }
  387. }
  388. else if (PLC_LASER_WORKING == finite_state_machines)
  389. {
  390. if (TRUE == _measure_finished)
  391. {
  392. //测量完成
  393. /* memset(response, 0, sizeof(uint16_t) * 7);
  394. if (_value.corrected)
  395. {
  396. response[0] = PLC_LASER_FINISH_OK;
  397. }
  398. else {
  399. response[0] = PLC_LASER_FINISH_FAILED;
  400. }
  401. response[1] = _value.x;
  402. response[2] = _value.y;
  403. response[3] = (int(_value.a) % 18000);
  404. response[4] = _value.l;
  405. response[5] = _value.w;
  406. response[6] = _value.h;
  407. write_laserresult_register((uint16_t *)response);*/
  408. write_laserstatus_register(PLC_LASER_FINISH_FAILED);
  409. finite_state_machines = PLC_LASER_FINISH_FAILED;
  410. }
  411. else {
  412. current_clock = clock();
  413. if (current_clock - _heartbeat_write_clock > PLC_LASER_TIMEOUT_MAXMEASURE) //10分钟还没返回测量结果, 说明系统可能出错了
  414. {
  415. write_laserstatus_register(PLC_LASER_ERROR);
  416. finite_state_machines = PLC_LASER_ERROR;
  417. }
  418. }
  419. }
  420. else if (PLC_LASER_ERROR == finite_state_machines)
  421. {
  422. fprintf(stderr, "\n\n\n\n\n\n不可修复错误,等系统重启\n\n\n\n\n\n");
  423. }
  424. else
  425. {
  426. fprintf(stderr, "\n\n\n\n\n\n&&&&&&&&&!!!!!!!!!!!!!@@@@@@@@@@@@@@$$$$$$$$$$$$$$$$$$$完全不可能出现的状态\n\n\n\n\n\n");
  427. }
  428. las_parkstatus = PCL_PARKING_REQUEST;
  429. }
  430. else
  431. {
  432. if (PCL_PARKING_ERROR != las_parkstatus)
  433. {
  434. LOG(ERROR)<<("\t严重警告:PLC我要停车状态异常,不可修复错误,等系统重启");
  435. //停止所有激光
  436. if (m_callback)
  437. {
  438. char laser = 0xFF;
  439. m_callback(false, uint16_t(laser), m_pointer, parking_status);
  440. }
  441. write_laserstatus_register(PLC_LASER_READY);
  442. finite_state_machines = PLC_LASER_READY;
  443. }
  444. Sleep(200);
  445. las_parkstatus = PCL_PARKING_ERROR;
  446. }
  447. Sleep(50);
  448. }
  449. }
  450. }