plc_data.cpp 5.5 KB

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