main.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. #include "grpc/service.h"
  21. #if __VIEW__PCL
  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. struct Clamp{
  71. Wanji_716N_lidar_device lidar;
  72. clamp_safety_detect detector;
  73. Safety_status safety_statu;
  74. pcl::PointCloud<pcl::PointXYZ>::Ptr last_cloud;
  75. std::mutex mutex;
  76. };
  77. bool run(Wanji_716N_lidar_device *device, clamp_safety_detect *pdetector, Safety_status *safety) {
  78. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  79. device->get_last_cloud(cloud, std::chrono::system_clock::now());
  80. if (cloud->size() < 150) {
  81. return false;
  82. }
  83. pdetector->detect(cloud, *safety);
  84. return true;
  85. }
  86. void thread_func(Clamp *clamp) {
  87. clamp->last_cloud = static_cast<boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>>>(new pcl::PointCloud<pcl::PointXYZ>());
  88. while (true) {
  89. clamp->mutex.lock();
  90. clamp->last_cloud->clear();
  91. clamp->lidar.get_last_cloud(clamp->last_cloud, std::chrono::system_clock::now());
  92. if (clamp->last_cloud->size() < 150) {
  93. // continue;
  94. } else {
  95. clamp->safety_statu.time_point = std::chrono::steady_clock::now();
  96. clamp->detector.detect(clamp->last_cloud, clamp->safety_statu);
  97. }
  98. clamp->mutex.unlock();
  99. usleep(100 * 1000);
  100. }
  101. }
  102. int main() {
  103. #if __VIEW__PCL
  104. // return 1;
  105. pcl::visualization::PCLVisualizer g_viewer;
  106. #endif
  107. //初始化日志
  108. init_glog();
  109. StreamRpcServer *m_grpc_server = new StreamRpcServer;
  110. m_grpc_server->Listenning("0.0.0.0", 9876);
  111. // 雷达数量
  112. const int CLAMP_SIZE = 4;
  113. //调试模式下,先打开调试窗口
  114. #if __VIEW__PCL
  115. return 1;
  116. int v1,v2,v3,v4;
  117. //窗口参数分别对应 x_min, y_min, x_max, y_max, viewport
  118. /*g_viewer.createViewPort(0.0, 0.5, 0.5, 1, v1);
  119. g_viewer.createViewPort(0.5, 0.5, 1.0, 1, v2);
  120. g_viewer.createViewPort(0.0, 0, 0.5, 0.5, v3);
  121. g_viewer.createViewPort(0.5, 0, 1.0, 0.5, v4);
  122. g_viewer.addText("192.168.0.2", 10,10, 20, 0,1,0, "ip v1", v1);
  123. g_viewer.addText("192.168.0.x2", 10,10, 20, 0,1,0, "ip v2", v2);
  124. g_viewer.addText("192.168.0.x3", 10,10, 20, 0,1,0, "ip v3", v3);
  125. g_viewer.addText("192.168.0.x4", 10,10, 20, 0,1,0, "ip v4", v4);
  126. g_viewer.addCoordinateSystem(0.2,"v1_axis",v1);
  127. g_viewer.addCoordinateSystem(0.2,"v2_axis",v2);
  128. g_viewer.addCoordinateSystem(0.2,"v3_axis",v3);
  129. g_viewer.addCoordinateSystem(0.2,"v4_axis",v4);*/
  130. #endif
  131. //雷达
  132. Clamp clamps[CLAMP_SIZE];
  133. LOG(INFO) << "load etc file from " << ETC_PATH"/etc/clamp_safety_lidars.json";
  134. lidarsJsonConfig config(ETC_PATH"/etc/clamp_safety_lidars.json");
  135. for (int i = 0; i < CLAMP_SIZE; ++i) {
  136. lidarsJsonConfig::LidarConfig lidar;
  137. config.getLidarConfig(i, lidar);
  138. lidar.info();
  139. Point2D_tool::Polar_coordinates_box t_polar_coordinates_box;
  140. Point2D_tool::Point2D_transform t_point2D_transform;
  141. t_polar_coordinates_box.angle_min = lidar.angle_min;
  142. t_polar_coordinates_box.angle_max = lidar.angle_max;
  143. t_polar_coordinates_box.distance_min = lidar.range_min;
  144. t_polar_coordinates_box.distance_max = lidar.range_max;
  145. Point2D_tool::Point2D_box t_point2D_box;
  146. t_point2D_box.x_min = lidar.scan_box_limit.minx;
  147. t_point2D_box.x_max = lidar.scan_box_limit.maxx;
  148. t_point2D_box.y_min = lidar.scan_box_limit.miny;
  149. t_point2D_box.y_max = lidar.scan_box_limit.maxy;
  150. Error_manager code = clamps[i].lidar.init(lidar.net_config.ip_address, lidar.net_config.port,
  151. t_polar_coordinates_box, t_point2D_box, t_point2D_transform);
  152. if (code != SUCCESS) {
  153. LOG(ERROR) << code.get_error_description();
  154. return EXIT_FAILURE;
  155. }
  156. clamps[i].safety_statu.set_timeout(0.3);
  157. }
  158. //调试状态下,绑定识别器输出窗口
  159. #if __VIEW__PCL
  160. clamps[0].detector.set_viewer(&g_viewer,v1);
  161. clamps[1].detector.set_viewer(&g_viewer,v2);
  162. clamps[2].detector.set_viewer(&g_viewer,v3);
  163. clamps[3].detector.set_viewer(&g_viewer,v4);
  164. while(1)
  165. {
  166. usleep(100*1000);
  167. auto t1=std::chrono::steady_clock::now();
  168. //调试状态下,顺序执行,因为viewer不支持多线程
  169. run(&(clamps[0].lidar),&(clamps[0].detector),&(clamps[0].safety_statu));
  170. run(&(clamps[1].lidar),&(clamps[1].detector),&(clamps[1].safety_statu));
  171. run(&(clamps[2].lidar),&(clamps[2].detector),&(clamps[2].safety_statu));
  172. run(&(clamps[3].lidar),&(clamps[3].detector),&(clamps[3].safety_statu));
  173. auto t2=std::chrono::steady_clock::now();
  174. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  175. double time= double(duration.count()) * std::chrono::microseconds::period::num /
  176. std::chrono::microseconds::period::den;
  177. //printf("total time :%.3f s\n",time);
  178. g_viewer.spinOnce();
  179. }
  180. #else
  181. // 和plc建立连接,一直等待连接成功
  182. auto snap7_client = &Snap7Clamp::get_instance_references();
  183. snap7_client->communication_init();
  184. Snap7Clamp::Snap7_communication_statu status = snap7_client->get_status();
  185. while (status == Snap7Clamp::SNAP7_COMMUNICATION_READY || status == Snap7Clamp::SNAP7_COMMUNICATION_RECEIVE) {
  186. sleep(1);
  187. status = snap7_client->get_status();
  188. }
  189. // 启动四个线程,分别采集四个雷达的数据。
  190. std::thread threads[CLAMP_SIZE];
  191. for (int i = 0; i < CLAMP_SIZE; ++i) {
  192. threads[i] = std::thread(thread_func, &clamps[i]);
  193. }
  194. int heart = 0;
  195. while (true) {
  196. usleep(100 * 1000);
  197. heart = (heart + 1) % 255;
  198. snap7_client->plcData.pingpong = heart;
  199. for (int i = 0; i < 4; i++) {
  200. std::unique_lock<std::mutex> t_lock(clamps[i].mutex);
  201. std::unique_lock<std::mutex> t_lock1(snap7_client->m_data_lock);
  202. if (!clamps[i].safety_statu.is_timeout()) {
  203. // LOG(WARNING) << "id: " << i << ", we: " << clamps[i].safety_statu.wheel_exist << ", cx: " << clamps[i].safety_statu.cx * 1000;
  204. // LOG(INFO) << "orid " << i;
  205. // LOG(INFO) << "wheel_exist " << clamps[i].safety_statu.wheel_exist;
  206. // LOG(INFO) << "cx " << clamps[i].safety_statu.cx * 1000;
  207. // LOG(INFO) << "gap " << clamps[i].safety_statu.gap * 1000;
  208. // LOG(INFO) << "clamp_completed " << clamps[i].safety_statu.clamp_completed;
  209. snap7_client->plcData.wheels[i].wheel_exist = clamps[i].safety_statu.wheel_exist;
  210. // snap7_client->plcData.wheels[i].offset = heart;
  211. // snap7_client->plcData.wheels[i].gap = 255 - heart;
  212. snap7_client->plcData.wheels[i].offset = clamps[i].safety_statu.cx * 1000;
  213. snap7_client->plcData.wheels[i].gap = clamps[i].safety_statu.gap * 1000;
  214. snap7_client->plcData.wheels[i].clamp_completed = clamps[i].safety_statu.clamp_completed;
  215. } else {
  216. // snap7_client->plcData.clear();
  217. }
  218. snap7_client->setCloudData(1 << i, clamps[i].last_cloud);
  219. TransitData::get_instance_pointer()->setCloud(i, clamps[i].last_cloud);
  220. }
  221. }
  222. #endif
  223. return EXIT_SUCCESS;
  224. }