plc_data.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. //
  2. // Created by zx on 2019/12/9.
  3. //
  4. #include "plc_data.h"
  5. #include <string.h>
  6. #include "wj_lidar_msg.pb.h"
  7. #include "../tool/MeasureTopicPublisher.h"
  8. Plc_data *Plc_data::g_ins = 0;
  9. std::mutex Plc_data::g_lock;
  10. /**
  11. * 获取单例句柄
  12. * */
  13. Plc_data *Plc_data::get_instance(std::string ip)
  14. {
  15. if (g_ins == 0)
  16. {
  17. std::lock_guard<std::mutex> lock(g_lock);
  18. if (g_ins == 0)
  19. {
  20. if (ip != "")
  21. {
  22. g_ins = new Plc_data(ip);
  23. LOG(INFO) << "plc data, handle created";
  24. }
  25. else
  26. {
  27. return 0;
  28. }
  29. }
  30. }
  31. return g_ins;
  32. }
  33. // void Plc_data::Release()
  34. // {
  35. // if (g_ins)
  36. // {
  37. // g_ins->m_cond_exit.Notify(true);
  38. // LOG(INFO) << "plc data, try to exit plc send thread";
  39. // g_lock.lock();
  40. // if (g_ins->p_send_thread)
  41. // {
  42. // LOG(INFO) << "plc data, try to join plc send thread";
  43. // // LOG(INFO) << g_ins->p_send_thread->joinable();
  44. // if (g_ins->p_send_thread->joinable())
  45. // g_ins->p_send_thread->join();
  46. // LOG(INFO) << "plc data, try to delete plc send thread";
  47. // delete g_ins->p_send_thread;
  48. // g_ins->p_send_thread = 0;
  49. // LOG(INFO) << "plc data, delete data send thread";
  50. // }
  51. // g_lock.unlock();
  52. // LOG(INFO) << "plc data, start to exit plc handle";
  53. // // if(g_instance->p_plc){
  54. // // LOG(INFO)<<"plc data, try to delete plc handle";
  55. // // delete g_instance->p_plc;
  56. // // g_instance->p_plc = 0;
  57. // // }
  58. // // LOG(INFO)<<"plc data, delete plc handle";
  59. // LOG(INFO) << "plc data, delete instance";
  60. // // delete g_ins;
  61. // // g_ins = 0;
  62. // LOG(INFO) << "plc data, instance deleted";
  63. // }
  64. // else
  65. // {
  66. // LOG(WARNING) << "plc data, cannot find the instance";
  67. // }
  68. // }
  69. /**
  70. * 更新区域状态
  71. * */
  72. void Plc_data::update_data(int state_code, int border_status, int id)
  73. {
  74. // LOG(INFO) << "plc data 更新数据 id: "<<id<<", code: "<<state_code;
  75. if(id<0 || id>=MAX_REGIONS)
  76. return ;
  77. std::lock_guard<std::mutex> lock(g_lock);
  78. m_data[2 * id] = state_code;
  79. m_data[2 * id + 1] = border_status;
  80. // added by yct, 轴距超长限制
  81. if(m_current_error_info[id].find("轴距") < m_current_error_info[id].size())
  82. {
  83. m_data[2 * id + 1] |= 0x0010;
  84. }
  85. }
  86. void Plc_data::update_error_info(int id, std::string error_info)
  87. {
  88. if(id<0 || id>=MAX_REGIONS)
  89. return ;
  90. std::lock_guard<std::mutex> lock(g_lock);
  91. m_current_error_info[id] = error_info;
  92. }
  93. /**
  94. * plc更新线程,将区域状态写入plc
  95. * */
  96. void Plc_data::plc_update_thread(Plc_data *p)
  97. {
  98. if (p == 0)
  99. {
  100. LOG(ERROR) << "plc update thread null pointer";
  101. return;
  102. }
  103. while (!p->m_cond_exit.WaitFor(1))
  104. {
  105. // 判断plc状态
  106. if (p->m_plc.getConnection() && p->mb_is_ready)
  107. {
  108. // 写入电子围栏状态
  109. wj_lidar_message::Fence_statu_message fence_message;
  110. for (int i = 0; i < ELE_FENCE_COUNT; ++i)
  111. {
  112. g_lock.lock();
  113. p->mb_is_ready = p->m_plc.WriteShorts(ELE_FENCE_DB_NUM,
  114. ELE_FENCE_BOUNDARY_START_ADDR + i * ELE_FENCE_OFFSET,
  115. 2,
  116. p->m_data + (i * 2));
  117. memcpy(p->m_last_data + (i * 2), p->m_data + (i * 2), 2 * sizeof(short));
  118. ///post 消息
  119. fence_message.add_fence_statu();
  120. int index=fence_message.fence_statu_size()-1;
  121. fence_message.mutable_fence_statu(index)->set_terminal_id(i);
  122. fence_message.mutable_fence_statu(index)->set_cloud_statu(p->m_data[i * 2]);
  123. fence_message.mutable_fence_statu(index)->set_position_statu(p->m_data[i * 2+1]);
  124. fence_message.mutable_fence_statu(index)->set_error_info(p->m_current_error_info[i]);
  125. g_lock.unlock();
  126. usleep(10 * 1000);
  127. }
  128. MeasureTopicPublisher::GetInstance()->Publish(fence_message.SerializeAsString());
  129. }
  130. else
  131. {
  132. // 重连plc
  133. LOG(WARNING) << "find plc connection error, trying to reconnect.";
  134. g_lock.lock();
  135. p->m_plc.disconnect();
  136. // LOG(WARNING) << "find plc connection error, diconnect first.";
  137. if (p->m_ip_str != "")
  138. {
  139. p->mb_is_ready = p->m_plc.connect(p->m_ip_str);
  140. // LOG(WARNING) << "find plc connection error, trying to connect";
  141. if (p->mb_is_ready)
  142. {
  143. LOG(INFO) << "successfully reconnect.";
  144. }
  145. else
  146. {
  147. LOG(WARNING) << "failed to connect plc.";
  148. }
  149. }
  150. g_lock.unlock();
  151. usleep(p->m_update_interval_milli * 5 * 1000);
  152. }
  153. usleep(p->m_update_interval_milli * 1000);
  154. }
  155. }
  156. /**
  157. * 有参构造
  158. * */
  159. Plc_data::Plc_data(std::string ip) : mp_update_thread(0),
  160. m_ip_str(""),
  161. mb_is_ready(0)
  162. {
  163. m_ip_str = ip;
  164. memset(m_data, 0, MAX_REGIONS*2 * sizeof(short));
  165. memset(m_last_data, 0, MAX_REGIONS*2 * sizeof(short));
  166. // p_plc = new S7PLC();
  167. if (m_ip_str != "")
  168. {
  169. if (m_plc.connect(m_ip_str))
  170. {
  171. mb_is_ready = true;
  172. }
  173. else
  174. {
  175. LOG(ERROR) << "Plc_data instance, connect failed";
  176. }
  177. }
  178. else
  179. {
  180. LOG(ERROR) << "Plc_data instance, empty ip string.";
  181. }
  182. m_cond_exit.Notify(false);
  183. mp_update_thread = new std::thread(plc_update_thread, this);
  184. mp_update_thread->detach();
  185. }
  186. /**
  187. * 获取plc连接状态
  188. * */
  189. bool Plc_data::get_plc_status()
  190. {
  191. return mb_is_ready;
  192. }