plc_data.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. }
  81. void Plc_data::update_error_info(int id, std::string error_info)
  82. {
  83. if(id<0 || id>=MAX_REGIONS)
  84. return ;
  85. std::lock_guard<std::mutex> lock(g_lock);
  86. m_current_error_info[id] = error_info;
  87. }
  88. /**
  89. * plc更新线程,将区域状态写入plc
  90. * */
  91. void Plc_data::plc_update_thread(Plc_data *p)
  92. {
  93. if (p == 0)
  94. {
  95. LOG(ERROR) << "plc update thread null pointer";
  96. return;
  97. }
  98. while (!p->m_cond_exit.WaitFor(1))
  99. {
  100. // 判断plc状态
  101. if (p->m_plc.getConnection() && p->mb_is_ready)
  102. {
  103. // 写入电子围栏状态
  104. wj_lidar_message::Fence_statu_message fence_message;
  105. for (int i = 0; i < ELE_FENCE_COUNT; ++i)
  106. {
  107. g_lock.lock();
  108. p->mb_is_ready = p->m_plc.WriteShorts(ELE_FENCE_DB_NUM,
  109. ELE_FENCE_BOUNDARY_START_ADDR + i * ELE_FENCE_OFFSET,
  110. 2,
  111. p->m_data + (i * 2));
  112. memcpy(p->m_last_data + (i * 2), p->m_data + (i * 2), 2 * sizeof(short));
  113. ///post 消息
  114. fence_message.add_fence_statu();
  115. int index=fence_message.fence_statu_size()-1;
  116. fence_message.mutable_fence_statu(index)->set_terminal_id(i);
  117. fence_message.mutable_fence_statu(index)->set_cloud_statu(p->m_data[i * 2]);
  118. fence_message.mutable_fence_statu(index)->set_position_statu(p->m_data[i * 2+1]);
  119. fence_message.mutable_fence_statu(index)->set_error_info(p->m_current_error_info[i]);
  120. g_lock.unlock();
  121. usleep(10 * 1000);
  122. }
  123. MeasureTopicPublisher::GetInstance()->Publish(fence_message.SerializeAsString());
  124. }
  125. else
  126. {
  127. // 重连plc
  128. LOG(WARNING) << "find plc connection error, trying to reconnect.";
  129. g_lock.lock();
  130. p->m_plc.disconnect();
  131. // LOG(WARNING) << "find plc connection error, diconnect first.";
  132. if (p->m_ip_str != "")
  133. {
  134. p->mb_is_ready = p->m_plc.connect(p->m_ip_str);
  135. // LOG(WARNING) << "find plc connection error, trying to connect";
  136. if (p->mb_is_ready)
  137. {
  138. LOG(INFO) << "successfully reconnect.";
  139. }
  140. else
  141. {
  142. LOG(WARNING) << "failed to connect plc.";
  143. }
  144. }
  145. g_lock.unlock();
  146. usleep(p->m_update_interval_milli * 5 * 1000);
  147. }
  148. usleep(p->m_update_interval_milli * 1000);
  149. }
  150. }
  151. /**
  152. * 有参构造
  153. * */
  154. Plc_data::Plc_data(std::string ip) : mp_update_thread(0),
  155. m_ip_str(""),
  156. mb_is_ready(0)
  157. {
  158. m_ip_str = ip;
  159. memset(m_data, 0, MAX_REGIONS*2 * sizeof(short));
  160. memset(m_last_data, 0, MAX_REGIONS*2 * sizeof(short));
  161. // p_plc = new S7PLC();
  162. if (m_ip_str != "")
  163. {
  164. if (m_plc.connect(m_ip_str))
  165. {
  166. mb_is_ready = true;
  167. }
  168. else
  169. {
  170. LOG(ERROR) << "Plc_data instance, connect failed";
  171. }
  172. }
  173. else
  174. {
  175. LOG(ERROR) << "Plc_data instance, empty ip string.";
  176. }
  177. m_cond_exit.Notify(false);
  178. mp_update_thread = new std::thread(plc_update_thread, this);
  179. mp_update_thread->detach();
  180. }
  181. /**
  182. * 获取plc连接状态
  183. * */
  184. bool Plc_data::get_plc_status()
  185. {
  186. return mb_is_ready;
  187. }