vlp16_driver_test.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. /*
  2. * @Description: vlp16驱动测试
  3. * @Author: yct
  4. * @Date: 2021-07-26 14:11:26
  5. * @LastEditTime: 2021-11-23 15:38:49
  6. * @LastEditors: yct
  7. */
  8. #include <iostream>
  9. #include <fstream>
  10. // velodyne driver seperation test
  11. #include "../velodyne_lidar/velodyne_driver/input.h"
  12. #include "../velodyne_lidar/velodyne_driver/rawdata.h"
  13. GOOGLE_GLOG_DLL_DECL void shut_down_logging(const char* data, int size)
  14. {
  15. time_t tt;
  16. time( &tt );
  17. tt = tt + 8*3600; // transform the time zone
  18. tm* t= gmtime( &tt );
  19. char buf[255]={0};
  20. sprintf(buf,"./%d%02d%02d-%02d%02d%02d-dump.txt",
  21. t->tm_year + 1900,
  22. t->tm_mon + 1,
  23. t->tm_mday,
  24. t->tm_hour,
  25. t->tm_min,
  26. t->tm_sec);
  27. FILE* tp_file=fopen(buf,"w");
  28. fprintf(tp_file,data,strlen(data));
  29. fclose(tp_file);
  30. }
  31. bool velo_driver_test()
  32. {
  33. velodyne_driver::InputSocket sock;
  34. if (!sock.init("", 2368))
  35. {
  36. std::cout << "sock init failed" << std::endl;
  37. return false;
  38. }
  39. velodyne_rawdata::RawData data;
  40. data.setup("VLP16", "/home/youchen/extra_space/chutian/measure/puai_wj_2021/setting/VLP16db.yaml", 1.2, 0.1, 0, 360);
  41. int count = 0;
  42. unsigned char pkt[1206];
  43. std::vector<Lidar_point> t_point;
  44. while (count++ < 50000)
  45. {
  46. int ret = sock.getPacket(pkt);
  47. if (ret != 0)
  48. std::cout << "get pack: " << ret << std::endl;
  49. else
  50. {
  51. // t_point.clear();
  52. // memset(&pkt[1205], 0, 1);
  53. // printf("%s\n", pkt);
  54. data.unpack(pkt, t_point);
  55. std::cout << "point size: " << t_point.size() << std::endl;
  56. if(t_point.size() > 30000)
  57. {
  58. std::ofstream out("/home/youchen/extra_space/chutian/measure/puai_wj_2021/build/point.txt");
  59. if(out.is_open())
  60. {
  61. for (size_t i = 0; i < t_point.size(); i++)
  62. {
  63. char buf[255] = {0};
  64. sprintf(buf, "%.3f %.3f %.3f %.6f\n", t_point[i].x, t_point[i].y, t_point[i].z, t_point[i].timestamp);
  65. out << buf;
  66. }
  67. out.close();
  68. return true;
  69. }
  70. else
  71. {
  72. std::cout << "cannot open file to write cloud." << std::endl;
  73. }
  74. }
  75. }
  76. usleep(500);
  77. }
  78. sock.uninit();
  79. return true;
  80. }
  81. // velodyne driver combination test
  82. #include "../velodyne_lidar/velodyne_driver/velodyne_lidar_device.h"
  83. void device_test()
  84. {
  85. velodyne::velodyneLidarParams params;
  86. params.set_ip("");
  87. params.set_port(2368);
  88. params.set_model("VLP16");
  89. params.set_calibrationfile("/home/youchen/extra_space/chutian/measure/puai_wj_2021/setting/VLP16db.yaml");
  90. params.mutable_calib()->set_y(1.57);
  91. Velodyne_lidar_device t_device;
  92. t_device.init(params);
  93. usleep(1000 * 1000);
  94. std::mutex p_mutex;
  95. pcl::PointCloud<pcl::PointXYZ>::Ptr p_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  96. Error_manager ec = t_device.get_new_cloud_and_wait(&p_mutex, p_cloud, std::chrono::steady_clock::now(), 6000);
  97. if (ec == SUCCESS)
  98. {
  99. std::ofstream out("/home/youchen/extra_space/chutian/measure/puai_wj_2021/build/device_point.txt");
  100. if (out.is_open())
  101. {
  102. for (size_t i = 0; i < p_cloud->size(); i++)
  103. {
  104. char buf[255] = {0};
  105. sprintf(buf, "%.3f %.3f %.3f\n", p_cloud->points[i].x, p_cloud->points[i].y, p_cloud->points[i].z);
  106. out << buf;
  107. }
  108. std::cout << "cloud written" << std::endl;
  109. out.close();
  110. }
  111. else
  112. {
  113. std::cout << "cannot open file to write cloud." << std::endl;
  114. }
  115. }else{
  116. std::cout << "get cloud failed" << std::endl;
  117. }
  118. t_device.uninit();
  119. }
  120. // ground region class function test
  121. #include "../velodyne_lidar/ground_region.h"
  122. #include "../tool/measure_filter.h"
  123. #include "../tool/point_tool.h"
  124. #include "../tool/proto_tool.h"
  125. #include "../laser/Laser.h"
  126. #include <livox_sdk.h>
  127. bool g_exit = false;
  128. void region_detect()
  129. {
  130. // ************ region detect algorithm time counting ****************
  131. std::string exce = "../tests/region_4_26x_g.txt", envi = "../tests/region_4_env_g.txt";
  132. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_exce(new pcl::PointCloud<pcl::PointXYZ>);
  133. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_envi(new pcl::PointCloud<pcl::PointXYZ>);
  134. bool res = read_pointcloud(exce, cloud_exce);
  135. res &= read_pointcloud(envi, cloud_envi);
  136. if (!res)
  137. {
  138. std::cout << "cannot open file to read cloud." << std::endl;
  139. return;
  140. }
  141. else
  142. {
  143. velodyne::velodyneManagerParams t_velo_params;
  144. std::string prototxt_path = "../setting/velodyne_manager.prototxt";
  145. if (!proto_tool::read_proto_param(prototxt_path, t_velo_params) || t_velo_params.region_size()<2)
  146. {
  147. return;
  148. }
  149. // 初始化region
  150. velodyne::Region param;
  151. param.CopyFrom(t_velo_params.region(1));
  152. pcl::PointCloud<pcl::PointXYZ>::Ptr left = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  153. pcl::PointCloud<pcl::PointXYZ>::Ptr right = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  154. if (!read_pointcloud("../setting/left_model.txt", left) || !read_pointcloud("../setting/right_model.txt", right))
  155. {
  156. std::cout << "cannot read left/right model " << std::endl;
  157. return;
  158. }
  159. Ground_region t_region;
  160. std::cout << "before init" << std::endl;
  161. t_region.init(param, left, right);
  162. std::cout << "after init" << std::endl;
  163. // ************ add livox sampling func test ****************
  164. auto sampling_func = [=]()
  165. {
  166. Error_manager code;
  167. //读laser配置
  168. Laser_proto::Laser_parameter_all laser_parameters;
  169. if (!proto_tool::read_proto_param("../setting/laser.prototxt", laser_parameters))
  170. {
  171. LOG(ERROR) << "read laser parameter failed";
  172. return;
  173. }
  174. int laser_cout = laser_parameters.laser_parameters_size();
  175. if (laser_cout == 0)
  176. {
  177. LOG(ERROR) << " no lidars ";
  178. return;
  179. }
  180. std::vector<Laser_base *> plasers;
  181. plasers.resize(laser_cout);
  182. for (int i = 0; i < laser_parameters.laser_parameters_size(); ++i)
  183. {
  184. plasers[i] = LaserRegistory::CreateLaser(laser_parameters.laser_parameters(i).type(), i,
  185. laser_parameters.laser_parameters(i));
  186. if (plasers[i] != NULL)
  187. {
  188. if (plasers[i]->connect_laser() != SUCCESS)
  189. {
  190. char description[255] = {0};
  191. sprintf(description, "Laser %d connect failed...", i);
  192. LOG(ERROR) << description;
  193. }
  194. }
  195. }
  196. for (int i = 0; i < laser_parameters.laser_parameters_size(); ++i)
  197. {
  198. std::string type = laser_parameters.laser_parameters(i).type();
  199. if (type.find("Livox") != type.npos || type.find("Horizon") != type.npos)
  200. {
  201. if (Start() == false)
  202. {
  203. Uninit();
  204. LOG(ERROR) << "Livox laser init failed...";
  205. return;
  206. }
  207. break;
  208. }
  209. }
  210. usleep(3000 * 1000);
  211. LOG(INFO) << "init ok...";
  212. //采集
  213. int cycles = 360000;
  214. int frames = 0;
  215. while (cycles-->0)
  216. {
  217. auto t_start_point = std::chrono::system_clock::now();
  218. pcl::PointCloud<pcl::PointXYZ> scan_cloud;
  219. std::mutex cloud_lock;
  220. std::vector<Laser_task *> laser_task_vector;
  221. for (int i = 0; i < plasers.size(); ++i)
  222. {
  223. int frame_count = laser_parameters.laser_parameters(i).frame_num();
  224. if (plasers[i] != nullptr)
  225. {
  226. //创建扫描任务,
  227. Laser_task *laser_task = new Laser_task();
  228. //
  229. laser_task->task_init(TASK_CREATED, &scan_cloud, &cloud_lock);
  230. laser_task->set_task_frame_maxnum(frame_count);
  231. laser_task_vector.push_back(laser_task);
  232. //发送任务单给雷达
  233. code = plasers[i]->execute_task(laser_task);
  234. if (code != SUCCESS)
  235. {
  236. LOG(ERROR) << " capture failed :" << code.get_error_description();
  237. break;
  238. }
  239. }
  240. }
  241. if(code != SUCCESS)
  242. {
  243. for (int i = 0; i < laser_task_vector.size(); ++i)
  244. {
  245. if (laser_task_vector[i] != 0)
  246. {
  247. delete laser_task_vector[i];
  248. laser_task_vector[i] = NULL;
  249. }
  250. }
  251. usleep(500 * 1000);
  252. continue;
  253. }
  254. //等待雷达完成任务单
  255. double second = 0.0;
  256. while (1)
  257. {
  258. //判断是否强制退出
  259. //判断雷达任务单是否全部完成
  260. bool tb_laser_complete = true;
  261. for (int i = 0; i < laser_task_vector.size(); ++i)
  262. {
  263. tb_laser_complete &= (TASK_OVER == laser_task_vector[i]->get_task_statu());
  264. }
  265. if (tb_laser_complete)
  266. {
  267. break;
  268. }
  269. //计算扫描时间,若超时,并且没有点,则返回错误.
  270. auto t_end_point = std::chrono::system_clock::now();
  271. auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t_end_point - t_start_point);
  272. second = double(duration.count()) *
  273. std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
  274. if (second > 0.5)
  275. {
  276. LOG(WARNING) << "capture time out";
  277. break;
  278. }
  279. usleep(1000 * 10);
  280. }
  281. //检查雷达任务完成情况,是否是正常完成
  282. //释放扫描任务单
  283. for (int i = 0; i < laser_task_vector.size(); ++i)
  284. {
  285. if (laser_task_vector[i] != 0)
  286. {
  287. delete laser_task_vector[i];
  288. laser_task_vector[i] = NULL;
  289. }
  290. }
  291. LOG(INFO) << " frame :" << ++frames << ", cloud size: " << scan_cloud.size()
  292. << " , time:" << second<<" sec";
  293. usleep(200 * 1000);
  294. }
  295. };
  296. std::thread *sampling_thread = new std::thread(sampling_func);
  297. sampling_thread->detach();
  298. // 手动检测,测试计算耗时
  299. pcl::PointCloud<pcl::PointXYZ>::Ptr temp_cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  300. cv::RNG rnd(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count());
  301. for (size_t i = 0; i < 50000; i++)
  302. {
  303. temp_cloud->clear();
  304. temp_cloud->operator+=(*cloud_exce);
  305. // 添加随机变换
  306. Eigen::Vector2d trans_offset(rnd.uniform(-0.05, 0.05), rnd.uniform(-0.05, 0.05));
  307. Eigen::Rotation2Dd rot(rnd.uniform(-4 * M_PI / 180.0, 4 * M_PI / 180.0));
  308. for (size_t i = 0; i < temp_cloud->size(); i++)
  309. {
  310. Eigen::Vector2d t_point(temp_cloud->points[i].x, temp_cloud->points[i].y);
  311. t_point = rot.toRotationMatrix() * t_point + trans_offset;
  312. temp_cloud->points[i].x = t_point.x();
  313. temp_cloud->points[i].y = t_point.y();
  314. }
  315. detect_wheel_ceres3d::Detect_result t_result;
  316. Error_manager ec = t_region.detect(temp_cloud, t_result);
  317. if(ec!=SUCCESS)
  318. LOG(ERROR) << ec.to_string();
  319. usleep(1000*10);
  320. // 单轮中仅随机变换一次
  321. temp_cloud->clear();
  322. temp_cloud->operator+=(*cloud_envi);
  323. for (size_t i = 0; i < temp_cloud->size(); i++)
  324. {
  325. Eigen::Vector2d t_point(temp_cloud->points[i].x, temp_cloud->points[i].y);
  326. t_point = rot.toRotationMatrix() * t_point + trans_offset;
  327. temp_cloud->points[i].x = t_point.x();
  328. temp_cloud->points[i].y = t_point.y();
  329. }
  330. ec = t_region.detect(temp_cloud, t_result);
  331. if(ec!=SUCCESS)
  332. LOG(ERROR) << ec.to_string();
  333. usleep(1000*10);
  334. }
  335. g_exit = true;
  336. if(sampling_thread!=nullptr)
  337. {
  338. if(sampling_thread->joinable()){
  339. sampling_thread->join();
  340. }
  341. delete sampling_thread;
  342. sampling_thread = nullptr;
  343. }
  344. // 检测自动识别功能
  345. // std::cout << "---------------" << std::endl;
  346. // for (size_t i = 0; i < 12; i++)
  347. // {
  348. // t_region.update_cloud(t_cloud);
  349. // usleep(1000*100);
  350. // }
  351. // Common_data::Car_wheel_information t_wheel_info;
  352. // ec = Measure_filter::get_instance_references().get_filtered_wheel_information(0, t_wheel_info);
  353. // if (ec == SUCCESS)
  354. // {
  355. // std::cout << t_wheel_info.to_string() << std::endl;
  356. // }
  357. // else { std::cout << ec.to_string() << std::endl; }
  358. }
  359. }
  360. // velodyne manager test
  361. #include "../velodyne_lidar/velodyne_manager.h"
  362. void velo_manager_test()
  363. {
  364. Velodyne_manager_task t_velodyne_manager_task;
  365. Common_data::Car_wheel_information t_car_information_by_velodyne;
  366. t_velodyne_manager_task.task_init(TASK_CREATED,"",NULL,std::chrono::milliseconds(3000),
  367. 0, std::chrono::system_clock::now());
  368. Error_manager ec = Velodyne_manager::get_instance_references().velodyne_manager_init(0);
  369. std::cout << "veodyne_manager = " << Velodyne_manager::get_instance_references().check_status().to_string() << std::endl;
  370. if(ec != SUCCESS)
  371. {
  372. std::cout << "manager init failed: " << ec.to_string() << std::endl;
  373. return;
  374. }
  375. usleep(1000 * 500);
  376. Velodyne_manager::get_instance_references().execute_task(&t_velodyne_manager_task);
  377. ec = Velodyne_manager::get_instance_references().execute_task(&t_velodyne_manager_task);
  378. std::cout << "manager execute base check result: " << ec.to_string() << std::endl;
  379. // 等待处理完成,来自于system_executor
  380. while (t_velodyne_manager_task.is_task_end() == false)
  381. {
  382. if (t_velodyne_manager_task.is_over_time())
  383. {
  384. //超时处理。取消任务。
  385. Velodyne_manager::get_instance_pointer()->cancel_task(&t_velodyne_manager_task);
  386. ec.error_manager_reset(Error_code::VELODYNE_MANAGER_TASK_OVER_TIME, Error_level::MINOR_ERROR,
  387. " t_velodyne_manager_task is_over_time ");
  388. t_velodyne_manager_task.set_task_error_manager(ec);
  389. }
  390. else
  391. {
  392. //继续等待
  393. std::this_thread::sleep_for(std::chrono::microseconds(1));
  394. std::this_thread::yield();
  395. }
  396. }
  397. //提取任务单 的错误码
  398. ec = t_velodyne_manager_task.get_task_error_manager();
  399. if (ec == Error_code::SUCCESS)
  400. {
  401. t_car_information_by_velodyne = t_velodyne_manager_task.get_car_wheel_information();
  402. }
  403. else
  404. {
  405. LOG(INFO) << " velodyne_manager_task error :::::::" << t_velodyne_manager_task.get_task_error_manager().to_string();
  406. }
  407. std::cout << "--------------------------"<< std::endl;
  408. Velodyne_manager::get_instance_references().Velodyne_manager_uninit();
  409. }
  410. // 测试通信功能
  411. #include "../system/system_communication.h"
  412. #include "../system/system_executor.h"
  413. void message_test()
  414. {
  415. nnxx::socket socket{nnxx::SP, nnxx::BUS};
  416. // socket.bind("tcp://127.0.0.1:7000");
  417. socket.connect("tcp://192.168.2.113:30010");
  418. int n = 0;
  419. message::Base_msg base_msg;
  420. message::Ground_detect_request_msg t_ground_detect_request;
  421. message::Base_info t_base_info;
  422. t_base_info.set_msg_type(message::Message_type::eGround_detect_request_msg);
  423. t_base_info.set_timeout_ms(4000);
  424. t_base_info.set_sender(message::Communicator::eEmpty);
  425. t_base_info.set_receiver(message::Communicator::eGround_measurer);
  426. t_ground_detect_request.mutable_base_info()->CopyFrom(t_base_info);
  427. t_ground_detect_request.set_command_key("key for test only");
  428. t_ground_detect_request.set_terminal_id(0);
  429. usleep(1000 * 1000);
  430. std::cout << "try to send" << std::endl;
  431. socket.send(t_ground_detect_request.SerializeAsString());
  432. usleep(1000 * 100);
  433. while (true)
  434. {
  435. // for (size_t i = 0; i < 10; i++)
  436. // {
  437. // 接收消息
  438. std::string t_receive_string = socket.recv<std::string>(1);
  439. if (t_receive_string.length() > 0)
  440. {
  441. bool result = base_msg.ParseFromString(t_receive_string);
  442. // 接收并打印车位状态信息
  443. std::cout << "====check result====================" << result << "============================" << std::endl;
  444. std::cout << "cycle " << n << std::endl;
  445. if (base_msg.base_info().msg_type() == message::Message_type::eGround_detect_response_msg)
  446. {
  447. message::Ground_detect_response_msg t_ground_detect_response;
  448. std::cout << "----------------- check result -----------------" << std::endl;
  449. t_ground_detect_response.ParseFromString(t_receive_string);
  450. std::cout << "result: "<<t_ground_detect_response.DebugString()<< std::endl;
  451. // std::cout << sift_response.DebugString() << std::endl;
  452. // continue;
  453. }else if(base_msg.base_info().msg_type() == message::Message_type::eGround_status_msg)
  454. {
  455. message::Ground_status_msg t_status_msg;
  456. std::cout << "----------------- heartbeat -----------------" << std::endl;
  457. t_status_msg.ParseFromString(t_receive_string);
  458. std::cout << "heartbeat: "<<t_status_msg.DebugString()<< std::endl;
  459. }
  460. }
  461. // }
  462. // std::this_thread::yield();
  463. n++;
  464. usleep(1000 * 1);
  465. }
  466. }
  467. int main()
  468. {
  469. const char* logPath = "./log/";
  470. google::InitGoogleLogging("LidarMeasurement");
  471. google::SetStderrLogging(google::INFO);
  472. google::SetLogDestination(0, logPath);
  473. google::SetLogFilenameExtension("zxlog");
  474. google::InstallFailureSignalHandler();
  475. google::InstallFailureWriter(&shut_down_logging);
  476. FLAGS_colorlogtostderr = true; // Set log color
  477. FLAGS_logbufsecs = 0; // Set log output speed(s)
  478. FLAGS_max_log_size = 1024; // Set max log file size(GB)
  479. FLAGS_stop_logging_if_full_disk = true;
  480. // ************ add livox sampling preparation ****************
  481. // velo_driver_test();
  482. // device_test();
  483. region_detect();
  484. // velo_manager_test();
  485. // message_test();
  486. g_exit = true;
  487. getchar();
  488. return 0;
  489. }