wj_lidar_test.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. // #include <pcl/visualization/cloud_viewer.h>
  2. #include <fstream>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <sys/stat.h>
  10. #include <dirent.h>
  11. #include "../wj_lidar/wj_lidar_encapsulation.h"
  12. #include "../wj_lidar/region_detect.h"
  13. #include <thread>
  14. #include <mutex>
  15. #include "../tool/s7_plc.h"
  16. #define DB 4
  17. #define BLOCK_SIZE 6
  18. #define CMD_ 0
  19. #define RNDX_ 1
  20. #define RNDB_ 2
  21. #define STATUS_ 3
  22. #define CURRX_ 4
  23. #define CURRB_ 5
  24. typedef std::chrono::duration<int, std::ratio<1, 1000>> milli_type;
  25. std::atomic<bool> g_measure_cmd, g_measure_completed;
  26. // 范围:
  27. // x -2400 0
  28. // b -20 20
  29. // plc(0,0)->laser(4.315, 84.46)
  30. // x 0 2400
  31. // ->laser(1.915, 84.46)
  32. class Temp_plc
  33. {
  34. public:
  35. Temp_plc(std::string ip)
  36. {
  37. mb_exit = false;
  38. mb_ready = false;
  39. mb_device_responsing = false;
  40. m_ip_str = ip;
  41. memset(m_data, 0, sizeof(short) * BLOCK_SIZE);
  42. mb_ready = m_plc.connect(ip);
  43. mp_update_thread = new std::thread(Temp_plc::update_thread, this);
  44. mp_update_thread->detach();
  45. }
  46. ~Temp_plc()
  47. {
  48. mb_exit = true;
  49. mb_ready = false;
  50. if(mp_update_thread!=nullptr)
  51. {
  52. // mp_update_thread->join();
  53. delete (mp_update_thread);
  54. mp_update_thread = nullptr;
  55. }
  56. }
  57. bool write_data(short data, int index)
  58. {
  59. if(mb_exit || ! mb_ready)
  60. {
  61. std::cout << "plc not ready." << std::endl;
  62. return false;
  63. }
  64. // std::cout << "???" << std::endl;
  65. std::lock_guard<std::mutex> lck(m_mutex);
  66. // std::cout << "111" << std::endl;
  67. mb_ready = m_plc.WriteShorts(DB, index, 1, &data);
  68. // std::cout << "222" << std::endl;
  69. return true;
  70. }
  71. bool write_cmd(short rndx, short rndb)
  72. {
  73. // std::cout << "???" << std::endl;
  74. bool result = write_data(rndx, RNDX_);
  75. result &= write_data(rndb, RNDB_);
  76. result &= write_data((short)1, CMD_);
  77. return result;
  78. }
  79. short get_status()
  80. {
  81. // 1空闲,2正忙,3错误
  82. return m_data[STATUS_];
  83. }
  84. short get_curr_x()
  85. {
  86. return m_data[CURRX_];
  87. }
  88. short get_curr_b()
  89. {
  90. return m_data[CURRB_];
  91. }
  92. short get_last_x()
  93. {
  94. return m_last_data[CURRX_];
  95. }
  96. short get_last_b()
  97. {
  98. return m_last_data[CURRB_];
  99. }
  100. bool get_data(short *data)
  101. {
  102. if(mb_exit || ! mb_ready)
  103. {
  104. std::cout << "plc not ready." << std::endl;
  105. return false;
  106. }
  107. if(data == nullptr)
  108. {
  109. std::cout << "data nullptr" << std::endl;
  110. return false;
  111. }
  112. std::lock_guard<std::mutex> lck(m_mutex);
  113. memcpy(data, m_data, BLOCK_SIZE * sizeof(short));
  114. disp_data();
  115. return true;
  116. }
  117. private:
  118. // cmd rndx rndb status x b
  119. void disp_data()
  120. {
  121. char buf[512];
  122. memset(buf, 0, 512);
  123. sprintf(buf, "cmd: %d, rndx: %d, rndb: %d, status: %d, x: %d, b: %d",m_data[0],m_data[1],m_data[2],m_data[3],m_data[4],m_data[5]);
  124. std::cout << buf << std::endl;
  125. }
  126. static void update_thread(Temp_plc *p)
  127. {
  128. if(p == nullptr)
  129. {
  130. std::cout << "plc nullptr" << std::endl;
  131. return;
  132. }
  133. std::chrono::steady_clock::time_point current_time = std::chrono::steady_clock::now();
  134. std::chrono::time_point<std::chrono::steady_clock, milli_type> current_time_in_milliseconds = std::chrono::time_point_cast<milli_type>(current_time);
  135. int now_in_milliseconds = current_time_in_milliseconds.time_since_epoch().count();
  136. uint64 seed = uint64(now_in_milliseconds);
  137. cv::RNG rnd = cv::RNG(seed);
  138. while (!p->mb_exit)
  139. {
  140. // std::cout << "cycling" << std::endl;
  141. if (p->m_plc.getConnection() && p->mb_ready)
  142. {
  143. // 自动读
  144. {
  145. std::lock_guard<std::mutex> lck(p->m_mutex);
  146. p->mb_ready = p->m_plc.ReadShorts(DB, 0, BLOCK_SIZE, p->m_data);
  147. memcpy(p->m_last_data, p->m_data, BLOCK_SIZE * sizeof(short));
  148. }
  149. p->disp_data();
  150. // 查询状态
  151. if(p->get_status() == 1)
  152. {
  153. if (!p->mb_device_responsing)
  154. {
  155. // 设备空闲,启动测量
  156. g_measure_cmd = true;
  157. // 等待测量结束
  158. while (!g_measure_completed)
  159. {
  160. usleep(1000 * 100);
  161. {
  162. std::lock_guard<std::mutex> lck(p->m_mutex);
  163. p->mb_ready = p->m_plc.ReadShorts(DB, 0, BLOCK_SIZE, p->m_data);
  164. memcpy(p->m_last_data, p->m_data, BLOCK_SIZE * sizeof(short));
  165. }
  166. std::cout << "wating for measurement." << std::endl;
  167. }
  168. g_measure_completed = false;
  169. std::cout << "measure finished." << std::endl;
  170. // 写指令
  171. p->mb_device_responsing = true;
  172. short rndx, rndb;
  173. do{
  174. rndx = rnd.uniform(0, 8);
  175. rndb = 0;
  176. // rnd.uniform(-20, 20);
  177. } while (abs(rndx*300 - p->get_curr_x()) < 300);// || abs(rndb - p->get_curr_b()) < 3);
  178. std::cout << "write cmd: "<< rndx*300<<", "<<rndb << std::endl;
  179. p->mb_ready = p->write_cmd(rndx*300, rndb);
  180. }
  181. else{
  182. std::cout << "waiting for status switch." << std::endl;
  183. }
  184. }
  185. // 设备接收到指令,状态已切换到正忙,等待完成
  186. if(p->get_status() == 2 && p->mb_device_responsing)
  187. {
  188. p->mb_device_responsing = false;
  189. // 清除指令
  190. p->mb_ready = p->write_data((short)0, CMD_);
  191. }else{
  192. // p->write_data(1, 3);
  193. }
  194. }else{
  195. std::lock_guard<std::mutex> lck(p->m_mutex);
  196. p->m_plc.disconnect();
  197. if (p->m_ip_str != "")
  198. {
  199. p->mb_ready = p->m_plc.connect(p->m_ip_str);
  200. // LOG(WARNING) << "find plc connection error, trying to connect";
  201. if (p->mb_ready)
  202. {
  203. std::cout << "successfully reconnect." << std::endl;
  204. }
  205. else
  206. {
  207. std::cout << "failed to connect plc." << std::endl;
  208. }
  209. }
  210. }
  211. usleep(1000*p->m_update_interval_milli);
  212. }
  213. }
  214. private:
  215. std::string m_ip_str;
  216. bool mb_exit;
  217. bool mb_ready;
  218. std::mutex m_mutex;
  219. std::thread *mp_update_thread; // plc更新线程
  220. S7PLC m_plc; // S7协议句柄
  221. const int m_update_interval_milli = 100; // plc更新频率
  222. short m_data[BLOCK_SIZE];
  223. short m_last_data[BLOCK_SIZE];
  224. bool mb_device_responsing; // 设备状态切换中
  225. bool mb_device_working; // 设备工作中
  226. };
  227. void init_glog()
  228. {
  229. FLAGS_max_log_size = 100;
  230. FLAGS_logbufsecs = 0;
  231. google::InitGoogleLogging("LidarMeasurement_test");
  232. google::SetStderrLogging(google::INFO);
  233. google::InstallFailureSignalHandler();
  234. FLAGS_colorlogtostderr = true; // Set log color
  235. FLAGS_logbufsecs = 0; // Set log output speed(s)
  236. FLAGS_max_log_size = 1024; // Set max log file size(GB)
  237. FLAGS_stop_logging_if_full_disk = true;
  238. }
  239. void save_cloud_txt(std::string txt, pcl::PointCloud<pcl::PointXYZ>::Ptr pCloud)
  240. {
  241. std::ofstream os;
  242. os.open(txt, std::ios::out);
  243. for (int i = 0; i < pCloud->points.size(); i++)
  244. {
  245. pcl::PointXYZ point = pCloud->points[i];
  246. char buf[255];
  247. memset(buf, 0, 255);
  248. sprintf(buf, "%f %f %f\n", point.x, point.y, point.z);
  249. os.write(buf, strlen(buf));
  250. }
  251. os.close();
  252. }
  253. bool ReadProtoParam(std::string path, wj::wjLidarParams &params)
  254. {
  255. int fd = open(path.c_str(), O_RDONLY);
  256. if (fd == -1)
  257. return false;
  258. FileInputStream *input = new FileInputStream(fd);
  259. bool success = google::protobuf::TextFormat::Parse(input, &params);
  260. // std::cout<<m_global_param.data_path()<<std::endl;
  261. delete input;
  262. close(fd);
  263. return success;
  264. }
  265. bool ReadProtoParam(std::string path, wj::wjManagerParams &params)
  266. {
  267. int fd = open(path.c_str(), O_RDONLY);
  268. if (fd == -1)
  269. return false;
  270. FileInputStream *input = new FileInputStream(fd);
  271. bool success = google::protobuf::TextFormat::Parse(input, &params);
  272. // std::cout<<m_global_param.data_path()<<std::endl;
  273. delete input;
  274. close(fd);
  275. return success;
  276. }
  277. bool read_pointcloud(std::string filename, pcl::PointCloud<pcl::PointXYZ>::Ptr &pointcloud)
  278. {
  279. // std::lock_guard<std::mutex> lck(m_cloud_mutex);
  280. pointcloud->clear();
  281. std::ifstream in(filename);
  282. if (!in.is_open())
  283. {
  284. std::cout << "failed to open file " << filename << std::endl;
  285. return false;
  286. }
  287. while (!in.eof())
  288. {
  289. std::string t_linestr;
  290. if (getline(in, t_linestr))
  291. {
  292. std::vector<std::string> str_vector;
  293. std::stringstream ss(t_linestr);
  294. std::string num_str;
  295. while (getline(ss, num_str, ' '))
  296. {
  297. str_vector.push_back(num_str);
  298. }
  299. if (str_vector.size() != 3)
  300. {
  301. std::cout << "unsupported point cloud / cannot find point x y z value: " << filename << std::endl;
  302. return false;
  303. }
  304. pcl::PointXYZ t_cloud;
  305. t_cloud.x = stod(str_vector[0]);
  306. t_cloud.y = stod(str_vector[1]);
  307. t_cloud.z = stod(str_vector[2]);
  308. pointcloud->push_back(t_cloud);
  309. }
  310. }
  311. in.close();
  312. // std::cout << "file read finished with points " << pointcloud->size() << std::endl;
  313. return true;
  314. }
  315. void list_dir( const char * dir_name,std::vector<std::string>& files)
  316. {
  317. if( 0 == dir_name )
  318. {
  319. std::cout<<" dir_name is null ! "<<std::endl;
  320. return;
  321. }
  322. struct stat s;
  323. lstat( dir_name , &s );
  324. if( ! S_ISDIR( s.st_mode ) )
  325. {
  326. return;
  327. }
  328. struct dirent * filename;
  329. DIR * dir;
  330. dir = opendir( dir_name );
  331. if( NULL == dir )
  332. {
  333. return;
  334. }
  335. int iName=0;
  336. while( ( filename = readdir(dir) ) != NULL )
  337. {
  338. if( strcmp( filename->d_name , "." ) == 0 ||
  339. strcmp( filename->d_name , "..") == 0)
  340. continue;
  341. char wholePath[256] = {0};
  342. sprintf(wholePath, "%s", (std::string(dir_name)+std::string("/")+filename->d_name).c_str());
  343. // std::cout << "??? "<<wholePath << std::endl;
  344. struct stat t_s;
  345. lstat(wholePath, &t_s);
  346. if (S_ISDIR(t_s.st_mode))
  347. {
  348. list_dir(wholePath, files);
  349. }else{
  350. files.push_back(wholePath);
  351. }
  352. }
  353. }
  354. void lidar_test()
  355. {
  356. Wj_lidar_encapsulation *lidar = new Wj_lidar_encapsulation();
  357. wj::wjLidarParams params;
  358. bool result = ReadProtoParam("../src/test/wj_lidar_settings.prototxt", params);
  359. LOG(INFO) << "读配置结果" << result;
  360. // params.mutable_net_config()->set_ip_address("192.168.0.2");
  361. // params.mutable_net_config()->set_port(2110);
  362. if (lidar != 0)
  363. {
  364. Error_manager code = lidar->initialize(params);
  365. LOG(INFO) << code.to_string();
  366. // usleep(1000 * 1);
  367. if (code == SUCCESS)
  368. {
  369. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  370. for (int i = 0; i < 10; i++)
  371. {
  372. LOG(INFO) << "connect status: " << lidar->get_connection_status();
  373. code = lidar->get_cloud(cloud, std::chrono::steady_clock::now(), 3000);
  374. if (code == SUCCESS)
  375. {
  376. char temp[100];
  377. memset(temp, 0, 100);
  378. sprintf(temp, "cloud_%d.txt", i);
  379. if (cloud->size() > 0)
  380. {
  381. save_cloud_txt(temp, cloud);
  382. LOG(INFO) << "cloud saved to " << std::string(temp);
  383. }
  384. }
  385. else
  386. {
  387. LOG(WARNING) << code.to_string();
  388. }
  389. usleep(1000 * 30);
  390. LOG(INFO) << "end of cycle";
  391. }
  392. }
  393. }
  394. delete lidar;
  395. }
  396. void sample_detect(std::string base_path)
  397. {
  398. // 读取配置
  399. wj::wjManagerParams params;
  400. if (!ReadProtoParam("/home/youchen/Documents/measure/MainStructure/LidarMeasure/build/setting/wj_manager_settings.prototxt", params))
  401. {
  402. std::cout << "read proto failed" << std::endl;
  403. return;
  404. }
  405. // 初始化各模块
  406. std::vector<Region_detector *> t_detectors;
  407. for (size_t i = 0; i < params.regions_size(); i++)
  408. {
  409. t_detectors.push_back(new Region_detector(i, params.regions(i)));
  410. }
  411. std::cout << "init detector: "<< t_detectors.size() << std::endl;
  412. // 遍历点云,除去整车库点云与失败的点云
  413. std::vector<std::__cxx11::string> files;
  414. pcl::PointCloud<pcl::PointXYZ>::Ptr tp_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  415. list_dir(base_path.c_str(), files);
  416. pcl::PointXYZ t_point;
  417. int success_count=0, failed_count=0;
  418. for (size_t i = 0; i < files.size(); i++)
  419. {
  420. // 除去失败点云
  421. if(files[i].find("failed", 0) < files[i].size())
  422. continue;
  423. if (read_pointcloud(files[i], tp_cloud))
  424. {
  425. // 除去完整点云
  426. if(tp_cloud->size() > 400 || tp_cloud->size() < 100)
  427. continue;
  428. // 找到中心点,判断所属区域
  429. t_point = tp_cloud->points[tp_cloud->size() - 5];
  430. int index = static_cast<int>(t_point.x / 3.3);
  431. // std::cout << "detect index: " << index << std::endl;
  432. tp_cloud->resize(tp_cloud->size() - 5);
  433. detect_wheel_ceres::Detect_result t_result;
  434. if(t_detectors.size() <= index)
  435. {
  436. std::cout << "fatal, region detector size error : "<< t_detectors.size()<<", "<<index << std::endl;
  437. return;
  438. }
  439. std::string t_info;
  440. Error_manager ec = t_detectors[index]->detect(tp_cloud, t_result.cx, t_result.cy, t_result.theta,t_result.front_theta, t_result.wheel_base, t_result.width, t_info, false);
  441. if(ec == SUCCESS)
  442. {
  443. success_count++;
  444. }
  445. else
  446. {
  447. failed_count++;
  448. std::cout << "detect failed" << std::endl;
  449. }
  450. }
  451. else
  452. {
  453. std::cout << "read failed" << std::endl;
  454. }
  455. // usleep(1000 * 1000);
  456. }
  457. std::cout << "detect finished with (success, failed): " << success_count << ", " << failed_count << std::endl;
  458. }
  459. void plc_test_only()
  460. {
  461. // 初始化一个plc类用于读写
  462. Temp_plc t_plc("192.168.0.1");
  463. int count = 500;
  464. while(count-->0)
  465. {
  466. std::cout << "cycle " << 500 - count << std::endl;
  467. if (g_measure_cmd)
  468. {
  469. g_measure_cmd = false;
  470. usleep(1000 * 150);
  471. std::cout << "measured..." << std::endl;
  472. g_measure_completed = true;
  473. }
  474. usleep(1000 * 1000);
  475. }
  476. }
  477. #include "pcl/io/pcd_io.h"
  478. void accuracy_validation()
  479. {
  480. g_measure_cmd = false;
  481. g_measure_completed = false;
  482. time_t tt = time(0);
  483. struct tm *tc = localtime(&tt);
  484. char buf[255] = {0};
  485. memset(buf, 0, 255);
  486. sprintf(buf, "./result_%d-%02d-%02d.txt", tc->tm_year + 1900,
  487. tc->tm_mon + 1, tc->tm_mday);
  488. std::ofstream out;
  489. out.open(buf, std::ios::app);
  490. if(!out.is_open())
  491. {
  492. std::cout << "open file failed, "<< buf << std::endl;
  493. return;
  494. }
  495. // 读取配置
  496. wj::wjManagerParams params;
  497. if (!ReadProtoParam("/home/youchen/Documents/measure/MainStructure/LidarMeasure/build/setting/wj_manager_settings_gedian.prototxt", params))
  498. {
  499. std::cout << "read proto failed" << std::endl;
  500. return;
  501. }
  502. // 初始化各模块
  503. // 初始化激光
  504. std::vector<Wj_lidar_encapsulation *> t_lidars;
  505. for (int i = 0; i < params.wj_lidar_size(); ++i)
  506. {
  507. t_lidars.push_back(new Wj_lidar_encapsulation());
  508. Error_manager code = t_lidars[i]->initialize(params.wj_lidar(i));
  509. // 错误码信息已在内部打印
  510. if (code != SUCCESS)
  511. {
  512. std::cout << "万集雷达连接失败 "<< i << std::endl;
  513. return;
  514. }
  515. }
  516. std::cout << "init lidar: "<< t_lidars.size() << std::endl;
  517. // 初始化测量
  518. std::vector<Region_detector *> t_detectors;
  519. for (size_t i = 0; i < params.regions_size(); i++)
  520. {
  521. t_detectors.push_back(new Region_detector(i, params.regions(i)));
  522. }
  523. std::cout << "init detector: "<< t_detectors.size() << std::endl;
  524. // 初始化一个plc类用于读写
  525. Temp_plc t_plc("192.168.0.100");
  526. short t_plc_data[BLOCK_SIZE];
  527. // g_measure_cmd = true;
  528. char ch = 'x';
  529. int mcount = 0;
  530. while (ch != 'q')
  531. {
  532. std::cout << "please input cmd (m for measure, q for quit):" << std::endl;
  533. std::cin >> ch;
  534. if (ch == 'm')
  535. {
  536. std::cout << "start measure process." << std::endl;
  537. while (true)
  538. {
  539. if(g_measure_cmd){
  540. mcount++;
  541. g_measure_cmd = false;
  542. int repeated_count = 6;
  543. while(repeated_count-->0){
  544. // 获取点云
  545. pcl::PointCloud<pcl::PointXYZ>::Ptr total_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  546. for (int i = 0; i < t_lidars.size(); ++i)
  547. {
  548. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  549. if (t_lidars[i]->get_cloud(cloud, std::chrono::steady_clock::now()) == SUCCESS)
  550. {
  551. total_cloud->operator+=(*cloud);
  552. }
  553. }
  554. std::cout << "get cloud size: "
  555. << total_cloud->size() << std::endl;
  556. // pcl::PCDWriter t_writer;
  557. // t_writer.write(std::string("./cloud/")+std::to_string(mcount)+std::to_string(repeated_count) + ".pcd", *total_cloud);
  558. // 测量获得结果,测试时通常只存在一个区域测量块
  559. detect_wheel_ceres::Detect_result t_result;
  560. std::string t_info;
  561. Error_manager ec = t_detectors[0]->detect(total_cloud, t_result.cx, t_result.cy, t_result.theta, t_result.front_theta, t_result.wheel_base, t_result.width, t_info, false);
  562. // Error_manager ec = t_detectors[0]->find_circle(total_cloud, t_result.cx, t_result.cy);
  563. // 从plc获取编码值
  564. short cx, cy, theta;
  565. cx = t_plc.get_last_x();
  566. cy = 0;
  567. theta = t_plc.get_last_b();
  568. // 测量结果与plc读取数据写入文件
  569. char line_buf[512];
  570. memset(line_buf, 0, 512);
  571. if (ec == SUCCESS)
  572. {
  573. sprintf(line_buf, "success,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,plc,%d,%d,%d",
  574. t_result.cx, t_result.cy, t_result.theta, t_result.front_theta, t_result.wheel_base, t_result.width,
  575. cx, cy, theta);
  576. }
  577. else
  578. {
  579. sprintf(line_buf, "failed,0.0,0.0,0.0,0.0,0.0,0.0,plc,%d,%d,%d",
  580. cx, cy, theta);
  581. std::cout << "detect failed: "<< ec.to_string()<<" "<<t_info.c_str() << std::endl;
  582. }
  583. out << line_buf << std::endl;
  584. std::cout << line_buf << ", " << strlen(line_buf) << std::endl;
  585. }
  586. out << "seperation line" << std::endl;
  587. g_measure_completed = true;
  588. usleep(1000 * 50);
  589. }
  590. }
  591. }
  592. }
  593. if(out.is_open())
  594. {
  595. out.close();
  596. }
  597. }
  598. int main(int argc, char *argv[])
  599. {
  600. init_glog();
  601. // lidar_test();
  602. // usleep(1000 * 1000);
  603. // lidar_test();
  604. // usleep(1000 * 1000);
  605. // lidar_test();
  606. // usleep(1000 * 1000);
  607. // std::chrono::steady_clock::time_point current_time = std::chrono::steady_clock::now();
  608. // std::chrono::time_point<std::chrono::steady_clock, milli_type> current_time_in_milliseconds = std::chrono::time_point_cast<milli_type>(current_time);
  609. // int now_in_milliseconds = current_time_in_milliseconds.time_since_epoch().count();
  610. // uint64 seed = uint64(now_in_milliseconds);
  611. // cv::RNG rnd = cv::RNG(seed);
  612. // for (size_t i = 0; i < 100; i++)
  613. // {
  614. // short ttx = (short)rnd.uniform(-2400, 0);
  615. // std::cout << ttx<< std::endl;
  616. // }
  617. // wj test
  618. // sample_detect("/home/youchen/Documents/measure/MainStructure/wj_data_records");
  619. // plc_test_only();
  620. accuracy_validation();
  621. // LOG(INFO) << "end";
  622. getchar();
  623. return 0;
  624. }