main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. //
  2. // Created by zx on 22-8-30.
  3. //
  4. #include <pcl/point_types.h>
  5. #include <pcl/point_cloud.h>
  6. #include <pcl/io/pcd_io.h>
  7. #include <pcl/segmentation/sac_segmentation.h>
  8. #include <pcl/ModelCoefficients.h>
  9. #include <pcl/filters/extract_indices.h>
  10. #include <pcl/segmentation/extract_clusters.h>
  11. #include "detect/clamp_safety_detect.h"
  12. #include "plc/snap7_communication_base.h"
  13. #include <fstream>
  14. #include "lidar/wanji_716N_device.h"
  15. #include <byteswap.h>
  16. #include "tool/pathcreator.h"
  17. #include <glog/logging.h>
  18. #include <google/protobuf/io/zero_copy_stream_impl.h>
  19. #include <google/protobuf/text_format.h>
  20. #include "clamp_parameter.pb.h"
  21. #include "tool/proto_tool.h"
  22. #include<stdio.h>
  23. #include<stdlib.h>
  24. #include<unistd.h>
  25. #include<string.h>
  26. #include<sys/types.h>
  27. #include<arpa/inet.h>
  28. #include<net/if.h>
  29. #include<string.h>
  30. #include<signal.h>
  31. #include<sys/wait.h>
  32. #include<sys/ioctl.h>
  33. #include<regex.h>
  34. using google::protobuf::io::FileInputStream;
  35. using google::protobuf::io::FileOutputStream;
  36. using google::protobuf::io::ZeroCopyInputStream;
  37. using google::protobuf::io::CodedInputStream;
  38. using google::protobuf::io::ZeroCopyOutputStream;
  39. using google::protobuf::io::CodedOutputStream;
  40. using google::protobuf::Message;
  41. int set_ip(const char* eth, const char* ip)
  42. {
  43. printf("---Debug--- %s %s.\n", eth, ip);
  44. int sock_set_ip;
  45. struct sockaddr_in sin_set_ip;
  46. struct ifreq ifr_set_ip;
  47. memset( &ifr_set_ip,0,sizeof(ifr_set_ip));
  48. sock_set_ip = socket( AF_INET, SOCK_STREAM, 0 );
  49. //printf("sock_set_ip=====%d\n",sock_set_ip);
  50. if(sock_set_ip<0)
  51. {
  52. perror("socket create failse...SetLocalIp!");
  53. return -1;
  54. }
  55. memset( &sin_set_ip, 0, sizeof(sin_set_ip));
  56. strncpy(ifr_set_ip.ifr_name, eth, sizeof(ifr_set_ip.ifr_name)-1);
  57. sin_set_ip.sin_family = AF_INET;
  58. sin_set_ip.sin_addr.s_addr = inet_addr(ip);
  59. memcpy( &ifr_set_ip.ifr_addr, &sin_set_ip, sizeof(sin_set_ip));
  60. printf("ip===%s\n",ip);
  61. if( ioctl( sock_set_ip, SIOCSIFADDR, &ifr_set_ip) < 0 )
  62. {
  63. perror( "Not setup interface");
  64. return -1;
  65. }
  66. //设置激活标志
  67. ifr_set_ip.ifr_flags |= IFF_UP |IFF_RUNNING;
  68. //get the status of the device
  69. if( ioctl( sock_set_ip, SIOCSIFFLAGS, &ifr_set_ip ) < 0 )
  70. {
  71. perror("SIOCSIFFLAGS");
  72. return -1;
  73. }
  74. close( sock_set_ip );
  75. return 0;
  76. }
  77. #if __VIEW__PCL
  78. pcl::visualization::PCLVisualizer g_viewer;
  79. #endif
  80. GOOGLE_GLOG_DLL_DECL void shut_down_logging(const char* data, int size)
  81. {
  82. time_t tt;
  83. time( &tt );
  84. tt = tt + 8*3600; // transform the time zone
  85. tm* t= gmtime( &tt );
  86. char buf[255]={0};
  87. sprintf(buf,"./%d%02d%02d-%02d%02d%02d-dump.txt",
  88. t->tm_year + 1900,
  89. t->tm_mon + 1,
  90. t->tm_mday,
  91. t->tm_hour,
  92. t->tm_min,
  93. t->tm_sec);
  94. FILE* tp_file=fopen(buf,"w");
  95. fprintf(tp_file,data,strlen(data));
  96. fclose(tp_file);
  97. }
  98. void init_glog()
  99. {
  100. time_t tt = time(0);//时间cuo
  101. struct tm* t = localtime(&tt);
  102. char strYear[255]={0};
  103. char strMonth[255]={0};
  104. char strDay[255]={0};
  105. sprintf(strYear,"%04d", t->tm_year+1900);
  106. sprintf(strMonth,"%02d", t->tm_mon+1);
  107. sprintf(strDay,"%02d", t->tm_mday);
  108. char buf[255]={0};
  109. getcwd(buf,255);
  110. char strdir[255]={0};
  111. sprintf(strdir,"%s/log/%s/%s/%s", buf,strYear,strMonth,strDay);
  112. PathCreator creator;
  113. creator.Mkdir(strdir);
  114. char logPath[255] = { 0 };
  115. sprintf(logPath, "%s/", strdir);
  116. FLAGS_max_log_size = 100;
  117. FLAGS_logbufsecs = 0;
  118. google::InitGoogleLogging("clamp_safety");
  119. google::SetStderrLogging(google::INFO);
  120. google::SetLogDestination(0, logPath);
  121. google::SetLogFilenameExtension("zxlog");
  122. google::InstallFailureSignalHandler();
  123. google::InstallFailureWriter(&shut_down_logging);
  124. FLAGS_colorlogtostderr = true; // Set log color
  125. FLAGS_logbufsecs = 0; // Set log output speed(s)
  126. FLAGS_max_log_size = 1024; // Set max log file size(GB)
  127. FLAGS_stop_logging_if_full_disk = true;
  128. }
  129. typedef struct
  130. {
  131. Wanji_716N_lidar_device lidar;
  132. clamp_safety_detect detector;
  133. Safety_status safety_statu;
  134. std::mutex mutex;
  135. }Clamp;
  136. float SWAP_float(float x)
  137. {
  138. int b;
  139. memcpy(&b,&x,sizeof(float));
  140. int t= ((((b) & 0xff000000) >> 24) | (((b) & 0x00ff0000) >> 8) |(((b) & 0x0000ff00) << 8) | (((b) & 0x000000ff) << 24));
  141. float value=0;
  142. memcpy(&value,&t,sizeof(float));
  143. return value;
  144. }
  145. bool run(Wanji_716N_lidar_device* device,clamp_safety_detect* pdetector,Safety_status* safety)
  146. {
  147. // auto t1 = std::chrono::steady_clock::now();
  148. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  149. device->get_last_cloud(cloud, std::chrono::system_clock::now());
  150. if (cloud->size() < 100)
  151. {
  152. return false;
  153. }
  154. pdetector->detect(cloud,*safety);
  155. // auto t2 = std::chrono::steady_clock::now();
  156. // auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  157. // double time = double(duration.count()) * std::chrono::microseconds::period::num /
  158. // std::chrono::microseconds::period::den;
  159. return true;
  160. }
  161. void thread_func(Clamp* clamp)
  162. {
  163. while(1)
  164. {
  165. clamp->mutex.lock();
  166. Safety_status safety_t;
  167. if(run(&(clamp->lidar),&(clamp->detector),&safety_t))
  168. clamp->safety_statu=safety_t;
  169. clamp->mutex.unlock();
  170. usleep(100*1000);
  171. }
  172. }
  173. bool string2point(std::string str,pcl::PointXYZ& point)
  174. {
  175. std::istringstream iss;
  176. iss.str(str);
  177. float value;
  178. float data[3]={0};
  179. for(int i=0;i<3;++i)
  180. {
  181. if(iss>>value)
  182. {
  183. data[i]=value;
  184. }
  185. else
  186. {
  187. return false;
  188. }
  189. }
  190. point.x=data[0];
  191. point.y=data[1];
  192. point.z=data[2];
  193. return true;
  194. }
  195. pcl::PointCloud<pcl::PointXYZ>::Ptr ReadTxtCloud(std::string file)
  196. {
  197. std::ifstream fin(file.c_str());
  198. const int line_length=64;
  199. char str[line_length]={0};
  200. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  201. while(fin.getline(str,line_length))
  202. {
  203. pcl::PointXYZ point;
  204. if(string2point(str,point))
  205. {
  206. printf("%f, %f, %f.\n", point.x, point.y, point.z);
  207. cloud->push_back(point);
  208. }
  209. }
  210. return cloud;
  211. }
  212. // int test() {
  213. // pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = ReadTxtCloud("points.txt");
  214. // Line line;
  215. // clamp_safety_detect detector;
  216. // Safety_status safety;
  217. // int v1;
  218. // g_viewer.createViewPort(0.0, 0.0, 1, 1, v1);
  219. // g_viewer.addText("192.168.0.2", 10,10, 20, 0,1,0, "ip v1", v1);
  220. // detector.set_viewer(&g_viewer,v1);
  221. // g_viewer.addCoordinateSystem(0.2,"v1_axis",v1);
  222. // detector.fit_line(cloud, line);
  223. // detector.check_wheel_line(line,safety);
  224. // g_viewer.spinOnce();
  225. // printf("\n%f.\n", line.cx);
  226. // return 0;
  227. // }
  228. int main(int argc, char* argv[])
  229. {
  230. // return test();
  231. clamp_safety::clamp_parameter parameter;
  232. std::string cfg_file = "../setting/parameter.prototxt";
  233. if(proto_tool::read_proto_param(cfg_file,parameter)==false)
  234. {
  235. LOG(ERROR)<<" read prototxt failed";
  236. return -1;
  237. }
  238. set_ip(parameter.local_parameter().eth_name().c_str(), parameter.local_parameter().local_ip().c_str());
  239. int CLAMP_SIZE=4;
  240. //usleep(10000*1000);
  241. //初始化日志
  242. init_glog();
  243. //调试模式下,先打开调试窗口
  244. #if __VIEW__PCL
  245. int v1,v2,v3,v4;
  246. //窗口参数分别对应 x_min, y_min, x_max, y_max, viewport
  247. g_viewer.createViewPort(0.0, 0.5, 0.5, 1, v1);
  248. g_viewer.createViewPort(0.5, 0.5, 1.0, 1, v2);
  249. g_viewer.createViewPort(0.0, 0, 0.5, 0.5, v3);
  250. g_viewer.createViewPort(0.5, 0, 1.0, 0.5, v4);
  251. g_viewer.addText("192.168.0.2", 10,10, 20, 0,1,0, "ip v1", v1);
  252. g_viewer.addText("192.168.0.x2", 10,10, 20, 0,1,0, "ip v2", v2);
  253. g_viewer.addText("192.168.0.x3", 10,10, 20, 0,1,0, "ip v3", v3);
  254. g_viewer.addText("192.168.0.x4", 10,10, 20, 0,1,0, "ip v4", v4);
  255. g_viewer.addCoordinateSystem(0.2,"v1_axis",v1);
  256. g_viewer.addCoordinateSystem(0.2,"v2_axis",v2);
  257. g_viewer.addCoordinateSystem(0.2,"v3_axis",v3);
  258. g_viewer.addCoordinateSystem(0.2,"v4_axis",v4);
  259. #endif
  260. //雷达
  261. Clamp clamps[CLAMP_SIZE];
  262. if(parameter.lidars_size()>CLAMP_SIZE)
  263. {
  264. printf("lidar num > viewer num\n");
  265. return -2;
  266. }
  267. for(int i=0;i<parameter.lidars_size();++i)
  268. {
  269. clamp_safety::LidarParameter lidar=parameter.lidars(i);
  270. Point2D_tool::Polar_coordinates_box t_polar_coordinates_box;
  271. Point2D_tool::Point2D_box t_point2D_box;
  272. Point2D_tool::Point2D_transform t_point2D_transform;
  273. t_polar_coordinates_box.angle_min = lidar.angle_min();
  274. t_polar_coordinates_box.angle_max = lidar.angle_max();
  275. t_polar_coordinates_box.distance_min = lidar.range_min();
  276. t_polar_coordinates_box.distance_max = lidar.range_max();
  277. t_point2D_box.x_min = lidar.scan_box_limit().minx();
  278. t_point2D_box.x_max = lidar.scan_box_limit().maxx();
  279. t_point2D_box.y_min = lidar.scan_box_limit().miny();
  280. t_point2D_box.y_max = lidar.scan_box_limit().maxy();
  281. Error_manager code=clamps[i].lidar.init(lidar.net_config().ip_address(),lidar.net_config().port(),
  282. t_polar_coordinates_box,t_point2D_box,t_point2D_transform);
  283. if(code!=SUCCESS)
  284. {
  285. LOG(ERROR)<<code.get_error_description();
  286. return -3;
  287. }
  288. clamps[i].safety_statu.set_timeout(0.3);
  289. }
  290. //调试状态下,绑定识别器输出窗口
  291. #if __VIEW__PCL
  292. if (parameter.lidars_size()>0)
  293. clamps[0].detector.set_viewer(&g_viewer,v1);
  294. if (parameter.lidars_size()>1)
  295. clamps[1].detector.set_viewer(&g_viewer,v2);
  296. if (parameter.lidars_size()>2)
  297. clamps[2].detector.set_viewer(&g_viewer,v3);
  298. if (parameter.lidars_size()>3)
  299. clamps[3].detector.set_viewer(&g_viewer,v4);
  300. while(1)
  301. {
  302. usleep(100*1000);
  303. auto t1=std::chrono::steady_clock::now();
  304. //调试状态下,顺序执行,因为viewer不支持多线程
  305. if (parameter.lidars_size()>0)
  306. run(&(clamps[0].lidar),&(clamps[0].detector),&(clamps[0].safety_statu));
  307. if (parameter.lidars_size()>1)
  308. run(&(clamps[1].lidar),&(clamps[1].detector),&(clamps[1].safety_statu));
  309. if (parameter.lidars_size()>2)
  310. run(&(clamps[2].lidar),&(clamps[2].detector),&(clamps[2].safety_statu));
  311. if (parameter.lidars_size()>3)
  312. run(&(clamps[3].lidar),&(clamps[3].detector),&(clamps[3].safety_statu));
  313. auto t2=std::chrono::steady_clock::now();
  314. auto duration = std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1);
  315. double time= double(duration.count()) * std::chrono::microseconds::period::num /
  316. std::chrono::microseconds::period::den;
  317. //printf("total time :%.3f s\n",time);
  318. g_viewer.spinOnce();
  319. }
  320. #else
  321. //plc相关
  322. Snap7_communication_base snap7_client;
  323. std::string plc_ip = parameter.plc_parameter().ip_address();
  324. Error_manager code = snap7_client.communication_init(plc_ip);
  325. while (code != SUCCESS)
  326. {
  327. Snap7_communication_base::Snap7_communication_statu status = snap7_client.get_status();
  328. switch (status)
  329. {
  330. case Snap7_communication_base::SNAP7_COMMUNICATION_READY:
  331. case Snap7_communication_base::SNAP7_COMMUNICATION_RECEIVE:
  332. code = SUCCESS;
  333. break;
  334. default:
  335. break;
  336. }
  337. LOG(ERROR)<<code;
  338. sleep(1);
  339. // return -1;
  340. }
  341. //正式代码,多线程执行,连接plc。
  342. std::thread threads[CLAMP_SIZE];
  343. for(int i=0;i<CLAMP_SIZE;++i)
  344. {
  345. threads[i]=std::thread(thread_func,&clamps[i]);
  346. }
  347. #pragma pack(push,1)
  348. struct PLCData
  349. {
  350. unsigned short pingpong;
  351. unsigned short wheel_exist1;
  352. float offset1;
  353. float gap1;
  354. unsigned short clamp_completed1;
  355. unsigned short wheel_exist2;
  356. float offset2;
  357. float gap2;
  358. unsigned short clamp_completed2;
  359. unsigned short wheel_exist3;
  360. float offset3;
  361. float gap3;
  362. unsigned short clamp_completed3;
  363. unsigned short wheel_exist4;
  364. float offset4;
  365. float gap4;
  366. unsigned short clamp_completed4;
  367. void info() {
  368. printf("pingdong = %d.\n", pingpong);
  369. printf("wheel_exist1 = %d, offset1 = %f, gap1 = %f, clamp_completed1 = %d.\n", wheel_exist1, offset1, gap1, clamp_completed1);
  370. printf("wheel_exist2 = %d, offset2 = %f, gap2 = %f, clamp_completed2 = %d.\n", wheel_exist1, offset1, gap1, clamp_completed1);
  371. printf("wheel_exist3 = %d, offset3 = %f, gap3 = %f, clamp_completed3 = %d.\n", wheel_exist1, offset1, gap1, clamp_completed1);
  372. printf("wheel_exist4 = %d, offset4 = %f, gap4 = %f, clamp_completed4 = %d.\n", wheel_exist1, offset1, gap1, clamp_completed1);
  373. }
  374. };
  375. #pragma pack(pop)
  376. Snap7_buf buf;
  377. buf.m_communication_mode = Snap7_buf::Communication_mode::LOOP_COMMUNICATION;
  378. int heart=0;
  379. struct PLCData plc_data;
  380. while(true)
  381. {
  382. usleep(100*1000);
  383. memset(&plc_data,0,sizeof(plc_data));
  384. heart=(heart+1)%255;
  385. plc_data.pingpong=bswap_16(heart);
  386. clamps[0].mutex.lock();
  387. if(clamps[0].safety_statu.is_timeout()==false)
  388. {
  389. plc_data.wheel_exist1=bswap_16((unsigned short)clamps[0].safety_statu.wheel_exist);
  390. plc_data.offset1=SWAP_float(clamps[0].safety_statu.cx*1000);
  391. plc_data.gap1=SWAP_float(clamps[0].safety_statu.gap*1000);
  392. plc_data.clamp_completed1=bswap_16((unsigned short)clamps[0].safety_statu.clamp_completed);
  393. //printf("safety 1 off :%.3f gap:%.3f\n",clamps[0].safety_statu.cx,clamps[0].safety_statu.gap);
  394. }
  395. clamps[0].mutex.unlock();
  396. clamps[1].mutex.lock();
  397. if(clamps[1].safety_statu.is_timeout()==false)
  398. {
  399. plc_data.wheel_exist2=bswap_16((unsigned short)clamps[1].safety_statu.wheel_exist);
  400. plc_data.offset2=SWAP_float(clamps[1].safety_statu.cx*1000);
  401. plc_data.gap2=SWAP_float(clamps[1].safety_statu.gap*1000);
  402. plc_data.clamp_completed2=bswap_16((unsigned short)clamps[1].safety_statu.clamp_completed);
  403. //printf("safety 2 off :%.3f gap:%.3f\n",clamps[1].safety_statu.cx,clamps[1].safety_statu.gap);
  404. }
  405. clamps[1].mutex.unlock();
  406. clamps[2].mutex.lock();
  407. if(clamps[2].safety_statu.is_timeout()==false)
  408. {
  409. plc_data.wheel_exist3=bswap_16((unsigned short)clamps[2].safety_statu.wheel_exist);
  410. plc_data.offset3=SWAP_float(clamps[2].safety_statu.cx*1000);
  411. plc_data.gap3=SWAP_float(clamps[2].safety_statu.gap*1000);
  412. plc_data.clamp_completed3=bswap_16((unsigned short)clamps[2].safety_statu.clamp_completed);
  413. //printf("safety 3 off :%.3f gap:%.3f\n",clamps[2].safety_statu.cx,clamps[2].safety_statu.gap);
  414. }
  415. clamps[2].mutex.unlock();
  416. clamps[3].mutex.lock();
  417. if(clamps[3].safety_statu.is_timeout()==false)
  418. {
  419. plc_data.wheel_exist4=bswap_16((unsigned short)clamps[3].safety_statu.wheel_exist);
  420. plc_data.offset4=SWAP_float(clamps[3].safety_statu.cx*1000);
  421. plc_data.gap4=SWAP_float(clamps[3].safety_statu.gap*1000);
  422. plc_data.clamp_completed4=bswap_16((unsigned short)clamps[3].safety_statu.clamp_completed);
  423. //printf("safety 4 off :%.3f gap:%.3f\n",clamps[3].safety_statu.cx,clamps[3].safety_statu.gap);
  424. }
  425. clamps[3].mutex.unlock();
  426. printf("cx1 = %.4f, cx2 = %.4f, cx3 = %.4f, cx4 = %.4f.\n", clamps[0].safety_statu.cx, clamps[1].safety_statu.cx, clamps[2].safety_statu.cx, clamps[3].safety_statu.cx);
  427. // plc_data.info();
  428. buf.m_id=9070;
  429. buf.m_size=sizeof(plc_data);
  430. buf.m_start_index=0;
  431. buf.mp_buf_reverse=&plc_data;
  432. code=snap7_client.write_data_buf(buf);
  433. if(code!=SUCCESS)
  434. {
  435. snap7_client.communication_uninit();
  436. usleep(500*1000);
  437. snap7_client.communication_init(plc_ip);
  438. usleep(500*1000);
  439. std::cout<<code<<std::endl;
  440. }
  441. }
  442. #endif
  443. printf("end");
  444. return 0;
  445. }