main.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. //
  2. // Created by zx on 22-8-30.
  3. //
  4. #include <cstdio>
  5. #include <unistd.h>
  6. #include <cstring>
  7. #include <fstream>
  8. #include <byteswap.h>
  9. #include <glog/logging.h>
  10. #include <pcl/point_types.h>
  11. #include <pcl/point_cloud.h>
  12. #include <google/protobuf/text_format.h>
  13. #include <google/protobuf/io/zero_copy_stream_impl.h>
  14. #include "detect/clamp_safety_detect.h"
  15. #include "plc/snap7_clamp.h"
  16. #include "lidar/wanji_716N_device.h"
  17. #include "tool/pathcreator.h"
  18. #include "lidar/lidarsJsonConfig.h"
  19. #include "defines.hpp"
  20. #if __VIEW__PCL
  21. pcl::visualization::PCLVisualizer g_viewer;
  22. #endif
  23. void shut_down_logging(const char *data, size_t size) {
  24. time_t tt;
  25. time(&tt);
  26. tt = tt + 8 * 3600; // transform the time zone
  27. tm *t = gmtime(&tt);
  28. char buf[255] = {0};
  29. sprintf(buf, "./%d%02d%02d-%02d%02d%02d-dump.txt",
  30. t->tm_year + 1900,
  31. t->tm_mon + 1,
  32. t->tm_mday,
  33. t->tm_hour,
  34. t->tm_min,
  35. t->tm_sec);
  36. FILE *tp_file = fopen(buf, "w");
  37. fprintf(tp_file, data, strlen(data));
  38. fclose(tp_file);
  39. }
  40. void init_glog() {
  41. time_t tt = time(nullptr);//时间cuo
  42. struct tm *t = localtime(&tt);
  43. char strYear[255] = {0};
  44. char strMonth[255] = {0};
  45. char strDay[255] = {0};
  46. sprintf(strYear, "%04d", t->tm_year + 1900);
  47. sprintf(strMonth, "%02d", t->tm_mon + 1);
  48. sprintf(strDay, "%02d", t->tm_mday);
  49. char buf[255] = {0};
  50. getcwd(buf, 255);
  51. char strdir[255] = {0};
  52. sprintf(strdir, "%s/log/%s/%s/%s", buf, strYear, strMonth, strDay);
  53. PathCreator creator;
  54. creator.Mkdir(strdir);
  55. char logPath[255] = {0};
  56. sprintf(logPath, "%s/", strdir);
  57. FLAGS_max_log_size = 100;
  58. FLAGS_logbufsecs = 0;
  59. google::InitGoogleLogging("clamp_safety");
  60. google::SetStderrLogging(google::INFO);
  61. google::SetLogDestination(google::INFO, logPath);
  62. google::SetLogFilenameExtension("log");
  63. google::InstallFailureSignalHandler();
  64. google::InstallFailureWriter(&shut_down_logging);
  65. FLAGS_colorlogtostderr = true; // Set log color
  66. FLAGS_logbufsecs = 0; // Set log output speed(s)
  67. FLAGS_max_log_size = 1024; // Set max log file size(GB)
  68. FLAGS_stop_logging_if_full_disk = true;
  69. }
  70. typedef struct {
  71. Wanji_716N_lidar_device lidar;
  72. clamp_safety_detect detector;
  73. Safety_status safety_statu;
  74. std::mutex mutex;
  75. } Clamp;
  76. bool run(Wanji_716N_lidar_device *device, clamp_safety_detect *pdetector, Safety_status *safety) {
  77. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  78. device->get_last_cloud(cloud, std::chrono::system_clock::now());
  79. if (cloud->size() < 150) {
  80. return false;
  81. }
  82. pdetector->detect(cloud, *safety);
  83. return true;
  84. }
  85. void thread_func(Clamp *clamp) {
  86. while (true) {
  87. clamp->mutex.lock();
  88. Safety_status safety_t;
  89. if (run(&(clamp->lidar), &(clamp->detector), &safety_t)) {
  90. clamp->safety_statu = safety_t;
  91. }
  92. clamp->mutex.unlock();
  93. usleep(100 * 1000);
  94. }
  95. }
  96. int main() {
  97. //初始化日志
  98. init_glog();
  99. // 雷达数量
  100. const int CLAMP_SIZE = 4;
  101. //调试模式下,先打开调试窗口
  102. #if __VIEW__PCL
  103. int v1,v2,v3,v4;
  104. //窗口参数分别对应 x_min, y_min, x_max, y_max, viewport
  105. g_viewer.createViewPort(0.0, 0.5, 0.5, 1, v1);
  106. g_viewer.createViewPort(0.5, 0.5, 1.0, 1, v2);
  107. g_viewer.createViewPort(0.0, 0, 0.5, 0.5, v3);
  108. g_viewer.createViewPort(0.5, 0, 1.0, 0.5, v4);
  109. g_viewer.addText("192.168.0.2", 10,10, 20, 0,1,0, "ip v1", v1);
  110. g_viewer.addText("192.168.0.x2", 10,10, 20, 0,1,0, "ip v2", v2);
  111. g_viewer.addText("192.168.0.x3", 10,10, 20, 0,1,0, "ip v3", v3);
  112. g_viewer.addText("192.168.0.x4", 10,10, 20, 0,1,0, "ip v4", v4);
  113. g_viewer.addCoordinateSystem(0.2,"v1_axis",v1);
  114. g_viewer.addCoordinateSystem(0.2,"v2_axis",v2);
  115. g_viewer.addCoordinateSystem(0.2,"v3_axis",v3);
  116. g_viewer.addCoordinateSystem(0.2,"v4_axis",v4);
  117. #endif
  118. //雷达
  119. Clamp clamps[CLAMP_SIZE];
  120. LOG(INFO) << "load etc file from " << ETC_PATH"/etc/clamp_safety_lidars.json";
  121. lidarsJsonConfig config(ETC_PATH"/etc/clamp_safety_lidars.json");
  122. for (int i = 0; i < CLAMP_SIZE; ++i) {
  123. lidarsJsonConfig::LidarConfig lidar;
  124. config.getLidarConfig(i, lidar);
  125. lidar.info();
  126. Point2D_tool::Polar_coordinates_box t_polar_coordinates_box;
  127. Point2D_tool::Point2D_transform t_point2D_transform;
  128. t_polar_coordinates_box.angle_min = lidar.angle_min;
  129. t_polar_coordinates_box.angle_max = lidar.angle_max;
  130. t_polar_coordinates_box.distance_min = lidar.range_min;
  131. t_polar_coordinates_box.distance_max = lidar.range_max;
  132. Point2D_tool::Point2D_box t_point2D_box;
  133. t_point2D_box.x_min = lidar.scan_box_limit.minx;
  134. t_point2D_box.x_max = lidar.scan_box_limit.maxx;
  135. t_point2D_box.y_min = lidar.scan_box_limit.miny;
  136. t_point2D_box.y_max = lidar.scan_box_limit.maxy;
  137. Error_manager code = clamps[i].lidar.init(lidar.net_config.ip_address, lidar.net_config.port,
  138. t_polar_coordinates_box, t_point2D_box, t_point2D_transform);
  139. if (code != SUCCESS) {
  140. LOG(ERROR) << code.get_error_description();
  141. return EXIT_FAILURE;
  142. }
  143. clamps[i].safety_statu.set_timeout(0.3);
  144. }
  145. //调试状态下,绑定识别器输出窗口
  146. #if __VIEW__PCL
  147. if (parameter.lidars_size()>0)
  148. clamps[0].detector.set_viewer(&g_viewer,v1);
  149. if (parameter.lidars_size()>1)
  150. clamps[1].detector.set_viewer(&g_viewer,v2);
  151. if (parameter.lidars_size()>2)
  152. clamps[2].detector.set_viewer(&g_viewer,v3);
  153. if (parameter.lidars_size()>3)
  154. clamps[3].detector.set_viewer(&g_viewer,v4);
  155. while(1)
  156. {
  157. usleep(100*1000);
  158. auto t1=std::chrono::steady_clock::now();
  159. //调试状态下,顺序执行,因为viewer不支持多线程
  160. if (parameter.lidars_size()>0)
  161. run(&(clamps[0].lidar),&(clamps[0].detector),&(clamps[0].safety_statu));
  162. if (parameter.lidars_size()>1)
  163. run(&(clamps[1].lidar),&(clamps[1].detector),&(clamps[1].safety_statu));
  164. if (parameter.lidars_size()>2)
  165. run(&(clamps[2].lidar),&(clamps[2].detector),&(clamps[2].safety_statu));
  166. if (parameter.lidars_size()>3)
  167. run(&(clamps[3].lidar),&(clamps[3].detector),&(clamps[3].safety_statu));
  168. auto t2=std::chrono::steady_clock::now();
  169. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  170. double time= double(duration.count()) * std::chrono::microseconds::period::num /
  171. std::chrono::microseconds::period::den;
  172. //printf("total time :%.3f s\n",time);
  173. g_viewer.spinOnce();
  174. }
  175. #else
  176. // 和plc建立连接,一直等待连接成功
  177. // auto snap7_client = &Snap7Clamp::get_instance_references();
  178. // snap7_client->communication_init();
  179. // Snap7Clamp::Snap7_communication_statu status = snap7_client->get_status();
  180. // while (status == Snap7Clamp::SNAP7_COMMUNICATION_READY || status == Snap7Clamp::SNAP7_COMMUNICATION_RECEIVE) {
  181. // sleep(1);
  182. // status = snap7_client->get_status();
  183. // }
  184. // 启动四个线程,分别采集四个雷达的数据。
  185. std::thread threads[CLAMP_SIZE];
  186. for (int i = 0; i < CLAMP_SIZE; ++i) {
  187. threads[i] = std::thread(thread_func, &clamps[i]);
  188. }
  189. int heart = 0;
  190. while (true) {
  191. usleep(100 * 1000);
  192. heart = (heart + 1) % 255;
  193. // snap7_client->plcData.pingpong = heart;
  194. for (int i = 0; i < 4; i++) {
  195. std::unique_lock<std::mutex> t_lock(clamps[i].mutex);
  196. // std::unique_lock<std::mutex> t_lock1(snap7_client->m_data_lock);
  197. if (!clamps[i].safety_statu.is_timeout()) {
  198. LOG(WARNING) << "id: " << i << ", we: " << clamps[i].safety_statu.wheel_exist << ", cx: " << clamps[i].safety_statu.cx * 1000;
  199. // LOG(INFO) << "orid " << i;
  200. // LOG(INFO) << "wheel_exist " << clamps[i].safety_statu.wheel_exist;
  201. // LOG(INFO) << "cx " << clamps[i].safety_statu.cx * 1000;
  202. // LOG(INFO) << "gap " << clamps[i].safety_statu.gap * 1000;
  203. // LOG(INFO) << "clamp_completed " << clamps[i].safety_statu.clamp_completed;
  204. // snap7_client->plcData.wheels[i].wheel_exist = clamps[i].safety_statu.wheel_exist;
  205. //// snap7_client->plcData.wheels[i].offset = heart;
  206. //// snap7_client->plcData.wheels[i].gap = 255 - heart;
  207. // snap7_client->plcData.wheels[i].offset = clamps[i].safety_statu.cx * 1000;
  208. // snap7_client->plcData.wheels[i].gap = clamps[i].safety_statu.gap * 1000;
  209. // snap7_client->plcData.wheels[i].clamp_completed = clamps[i].safety_statu.clamp_completed;
  210. } else {
  211. // snap7_client->plcData.clear();
  212. }
  213. }
  214. }
  215. #endif
  216. return EXIT_SUCCESS;
  217. }