wj_lidar_test.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. // #include "../wj_lidar/wj_lidar_encapsulation.h"
  2. #include "../wj_lidar/fence_controller.h"
  3. // #include <pcl/visualization/cloud_viewer.h>
  4. #include <fstream>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <boost/filesystem.hpp>
  12. /**
  13. * @description: 递归读取文件夹下所有文件
  14. * @param path: 待遍历文件夹名
  15. * @param filename_list: 存放获取文件名的数组
  16. * @return: 是否获取到文件名
  17. */
  18. bool recursive_file_read(std::string path, std::vector<std::string> &filename_list)
  19. {
  20. filename_list.clear();
  21. boost::filesystem::path myPath(path);
  22. boost::filesystem::recursive_directory_iterator endIter;
  23. int file_count = 0;
  24. for (boost::filesystem::recursive_directory_iterator iter(myPath); iter != endIter; iter++)
  25. {
  26. if (!boost::filesystem::is_directory(*iter))
  27. {
  28. filename_list.push_back(iter->path().string());
  29. file_count++;
  30. }
  31. }
  32. if(file_count > 0)
  33. return true;
  34. else
  35. return false;
  36. }
  37. void create_mark(double cx, double cy, pcl::PointCloud<pcl::PointXYZ>::Ptr &mark_cloud)
  38. {
  39. int width = 10;
  40. int length = 25;
  41. double resolution = 0.01;
  42. // mark_cloud->clear();
  43. for (int i = 0; i < width; i++)
  44. {
  45. pcl::PointXYZ t_point = pcl::PointXYZ((i - width / 2.0)*resolution + cx, cy, -1);
  46. mark_cloud->push_back(t_point);
  47. }
  48. for (int i = 0; i < length; i++)
  49. {
  50. pcl::PointXYZ t_point = pcl::PointXYZ(cx, (i - length / 2.0)*resolution + cy, -1);
  51. mark_cloud->push_back(t_point);
  52. }
  53. // std::cout<<"cx cy: "<<cx<<", "<<cy<<std::endl;
  54. }
  55. void save_cloud_txt(std::string txt, pcl::PointCloud<pcl::PointXYZ>::Ptr pCloud)
  56. {
  57. std::ofstream os;
  58. os.open(std::string("./").append(txt), std::ios::out);
  59. if(!os.is_open())
  60. {
  61. std::cout << "write, failed to open " << txt << std::endl;
  62. return;
  63. }
  64. for (int i = 0; i < pCloud->points.size(); i++)
  65. {
  66. pcl::PointXYZ point = pCloud->points[i];
  67. char buf[255];
  68. memset(buf, 0, 255);
  69. sprintf(buf, "%f %f %f\n", point.x, point.y, point.z);
  70. os.write(buf, strlen(buf));
  71. }
  72. char cwd[255];
  73. getcwd(cwd, 255);
  74. std::cout << "file write to " << cwd <<"/"<< txt << std::endl;
  75. os.close();
  76. }
  77. bool read_pointcloud(std::string filename, pcl::PointCloud<pcl::PointXYZ>::Ptr &pointcloud)
  78. {
  79. // std::lock_guard<std::mutex> lck(m_cloud_mutex);
  80. pointcloud->clear();
  81. std::ifstream in(filename);
  82. if (!in.is_open())
  83. {
  84. std::cout << "failed to open file " << filename << std::endl;
  85. return false;
  86. }
  87. while (!in.eof())
  88. {
  89. std::string t_linestr;
  90. if (getline(in, t_linestr))
  91. {
  92. std::vector<std::string> str_vector;
  93. std::stringstream ss(t_linestr);
  94. std::string num_str;
  95. while (getline(ss, num_str, ' '))
  96. {
  97. str_vector.push_back(num_str);
  98. }
  99. if (str_vector.size() != 3)
  100. {
  101. std::cout << "unsupported point cloud / cannot find point x y z value: " << filename << std::endl;
  102. return false;
  103. }
  104. pcl::PointXYZ t_cloud;
  105. t_cloud.x = stod(str_vector[0]);
  106. t_cloud.y = stod(str_vector[1]);
  107. t_cloud.z = stod(str_vector[2]);
  108. pointcloud->push_back(t_cloud);
  109. }
  110. }
  111. in.close();
  112. std::cout << "file read finished with points " << pointcloud->size() << std::endl;
  113. return true;
  114. }
  115. bool ReadProtoParam(std::string path, wj::wjLidarParams &params)
  116. {
  117. int fd = open(path.c_str(), O_RDONLY);
  118. if (fd == -1)
  119. return false;
  120. FileInputStream *input = new FileInputStream(fd);
  121. bool success = google::protobuf::TextFormat::Parse(input, &params);
  122. // std::cout<<m_global_param.data_path()<<std::endl;
  123. delete input;
  124. close(fd);
  125. return success;
  126. }
  127. bool ReadProtoParam(std::string path, wj::wjManagerParams &params)
  128. {
  129. int fd = open(path.c_str(), O_RDONLY);
  130. if (fd == -1)
  131. return false;
  132. FileInputStream *input = new FileInputStream(fd);
  133. bool success = google::protobuf::TextFormat::Parse(input, &params);
  134. // std::cout<<m_global_param.data_path()<<std::endl;
  135. delete input;
  136. close(fd);
  137. return success;
  138. }
  139. bool ReadProtoParam(std::string path, Hardware_limit::Hardware_parameter &params)
  140. {
  141. int fd = open(path.c_str(), O_RDONLY);
  142. if (fd == -1)
  143. return false;
  144. FileInputStream *input = new FileInputStream(fd);
  145. bool success = google::protobuf::TextFormat::Parse(input, &params);
  146. // std::cout<<m_global_param.data_path()<<std::endl;
  147. delete input;
  148. close(fd);
  149. return success;
  150. }
  151. void lidar_test()
  152. {
  153. Wj_lidar_encapsulation *lidar = new Wj_lidar_encapsulation();
  154. wj::wjLidarParams params;
  155. bool result = ReadProtoParam("../src/test/wj_lidar_settings.prototxt", params);
  156. LOG(INFO) << "读配置结果" << result;
  157. // params.mutable_net_config()->set_ip_address("192.168.0.2");
  158. // params.mutable_net_config()->set_port(2110);
  159. if (lidar != 0)
  160. {
  161. Error_manager code = lidar->initialize(params);
  162. LOG(INFO) << code.to_string();
  163. // usleep(1000 * 1);
  164. if (code == SUCCESS)
  165. {
  166. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  167. for (int i = 0; i < 10; i++)
  168. {
  169. LOG(INFO) << "connect status: " << lidar->get_connection_status();
  170. code = lidar->get_cloud(cloud, std::chrono::steady_clock::now(), 3000);
  171. if (code == SUCCESS)
  172. {
  173. char temp[100];
  174. memset(temp, 0, 100);
  175. sprintf(temp, "cloud_%d.txt", i);
  176. if (cloud->size() > 0)
  177. {
  178. save_cloud_txt(temp, cloud);
  179. LOG(INFO) << "cloud saved to " << std::string(temp);
  180. }
  181. }
  182. else
  183. {
  184. LOG(WARNING) << code.to_string();
  185. }
  186. usleep(1000 * 30);
  187. LOG(INFO) << "end of cycle";
  188. }
  189. }
  190. }
  191. delete lidar;
  192. }
  193. void measure_task(std::vector<Region_worker *> workers, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Wj_lidar_Task* task);
  194. void all_lidar_test()
  195. {
  196. std::string manager_path = "setting/wj_manager_settings.prototxt";
  197. std::string hardware_path = "setting/limit.prototxt";
  198. std::string cloud_name = "/home/youchen/data/puai_sample200624/fence_wj/combined/conb.txt";
  199. wj::wjManagerParams params;
  200. Hardware_limit::Hardware_parameter hardware_parameter;
  201. bool result = ReadProtoParam(manager_path, params);
  202. result &= ReadProtoParam(hardware_path, hardware_parameter);
  203. if(!result){
  204. LOG(INFO) << "读配置结果" << result;
  205. return;
  206. }
  207. // init lidar instances
  208. std::vector<Wj_lidar_encapsulation *> lidars_vector;
  209. for (int i = 0; i < params.wj_lidar_size(); ++i)
  210. {
  211. lidars_vector.push_back(new Wj_lidar_encapsulation());
  212. Error_manager code = lidars_vector[i]->initialize(params.wj_lidar(i));
  213. // 错误码信息已在内部打印
  214. if (code != SUCCESS)
  215. {
  216. LOG(WARNING) << Error_manager(Error_code::WJ_MANAGER_UNINITIALIZED,NORMAL,"万集雷达连接失败").to_string();
  217. return ;
  218. }
  219. }
  220. for (size_t j = 0; j < 20000; j++)
  221. {
  222. LOG(INFO) << "\ncycle " << std::to_string(j);
  223. pcl::PointCloud<pcl::PointXYZ>::Ptr total_cloud(new pcl::PointCloud<pcl::PointXYZ>);
  224. for (int i = 0; i < lidars_vector.size(); ++i)
  225. {
  226. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
  227. if (lidars_vector[i]->get_cloud(cloud, std::chrono::steady_clock::now()) == SUCCESS)
  228. {
  229. total_cloud->operator+=(*cloud);
  230. }
  231. }
  232. LOG(INFO) << "--------callback get cloud, size: " << total_cloud->size();
  233. }
  234. }
  235. void detect_test()
  236. {
  237. std::string manager_path = "setting/wj_manager_settings.prototxt";
  238. std::string hardware_path = "setting/limit.prototxt";
  239. std::string cloud_directory_name = "/home/youchen/Documents/measure/MainStructure/elecfence_ws/cloud";
  240. std::vector<std::string> cloud_filename_strs;
  241. wj::wjManagerParams params;
  242. Hardware_limit::Hardware_parameter hardware_parameter;
  243. bool result = ReadProtoParam(manager_path, params);
  244. result &= ReadProtoParam(hardware_path, hardware_parameter);
  245. result &= recursive_file_read(cloud_directory_name, cloud_filename_strs);
  246. if(!result){
  247. LOG(INFO) << "读配置结果" << result;
  248. return;
  249. }
  250. //创建limit模块
  251. Verify_result* p_verify_result_tool=new Verify_result(hardware_parameter);
  252. std::vector<Region_worker *> region_workers_vector;
  253. // init region_detector instances
  254. for (int j = 0; j < params.regions_size(); ++j)
  255. {
  256. region_workers_vector.push_back(new Region_worker(j, params.regions(j), p_verify_result_tool));
  257. }
  258. LOG(INFO) << "created wj region workers";
  259. for (size_t i = 0; i < cloud_filename_strs.size(); i++)
  260. {
  261. LOG(INFO) << "\ncycle "<<std::to_string(i);
  262. for (int j = 3; j < 4; j++)
  263. {
  264. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  265. bool read_result = read_pointcloud(cloud_filename_strs[i], cloud);
  266. if (!read_result)
  267. {
  268. LOG(WARNING) << "read cloud error";
  269. return;
  270. }
  271. Wj_lidar_Task* task = new Wj_lidar_Task();
  272. task->init();
  273. wj_command command;
  274. command.terminal_id = 5;//j*2-1;
  275. command.command_time = std::chrono::steady_clock::now();
  276. command.timeout_in_milliseconds = 1000;
  277. task->set_command(command);
  278. // LOG(WARNING) << "000 " << std::to_string(command.terminal_id);
  279. measure_task(region_workers_vector, cloud, task);
  280. // LOG(WARNING) << "2 cloud use count: " <<cloud.use_count();
  281. delete task;
  282. }
  283. usleep(1000*10);
  284. }
  285. // getchar();
  286. for (int i = 0; i < region_workers_vector.size(); ++i)
  287. {
  288. if(region_workers_vector[i] != nullptr)
  289. {
  290. delete region_workers_vector[i];
  291. }
  292. }
  293. }
  294. #include <pcl/common/transforms.h>
  295. void measure_task(std::vector<Region_worker *> workers, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, Wj_lidar_Task* task)
  296. {
  297. static int save_count = 0;
  298. if(task == nullptr)
  299. {
  300. LOG(WARNING) << " empty task";
  301. return;
  302. }
  303. wj_command command_temp;
  304. Error_manager code = task->get_command(command_temp);
  305. int term_id = command_temp.terminal_id;
  306. // LOG(INFO) << "measure task entered. " << std::to_string(command_temp.terminal_id);
  307. // 创建保存结果容器
  308. wj_measure_result wj_measure_temp;
  309. wj_measure_temp.terminal_id = term_id;
  310. wj_measure_temp.correctness = false;
  311. // LOG(WARNING) << "111 " << std::to_string(workers.size());
  312. for (int i = 0; i < workers.size(); ++i)
  313. {
  314. // LOG(WARNING) << (workers[i] == nullptr);
  315. if (workers[i] != nullptr && workers[i]->get_id() == term_id)
  316. {
  317. char cloud_txt_filename[255];
  318. memset(cloud_txt_filename, 0, 255);
  319. bool correctness = false;
  320. // LOG(INFO) << "--------callback find terminal------" << term_id;
  321. double x = 0, y = 0, c = 0, wheelbase = 0, width = 0, ftheta;
  322. if (cloud->size() <= 0)
  323. {
  324. LOG(INFO) << "empty cloud";
  325. return;
  326. }
  327. // 获取最新点云并保存到total_cloud中
  328. // LOG(INFO) << "--------callback get cloud, size: " << cloud->size();
  329. // 获取检测结果
  330. std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
  331. Error_manager code = workers[i]->get_wheel_result(cloud, x, y, c, wheelbase, width, ftheta);
  332. std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
  333. LOG(INFO) << "solve time: " << std::chrono::duration_cast<std::chrono::milliseconds>(t1-t0).count()<<"";
  334. // LOG(WARNING) << "1 cloud use count: " <<cloud.use_count();
  335. time_t tt = time(0);
  336. struct tm *tc = localtime(&tt);
  337. char buf[255] = {0};
  338. memset(buf, 0, 255);
  339. // sprintf(buf, "%d-%02d-%02d_%02d:%02d:%02d", tc->tm_year + 1900,
  340. // tc->tm_mon + 1, tc->tm_mday, tc->tm_hour, tc->tm_min, tc->tm_sec);
  341. sprintf(buf, "%03d", save_count);
  342. save_count++;
  343. // 根据是否成功生成对应文件名
  344. if (code == SUCCESS)
  345. {
  346. correctness = true;
  347. sprintf(cloud_txt_filename, "./result/%s_%d.txt", buf, term_id);
  348. }
  349. else
  350. {
  351. // LOG(WARNING) << "get wheel result failed: " << code.to_string();
  352. correctness = false;
  353. sprintf(cloud_txt_filename, "./result/%s%s_%d.txt", "failed_", buf, term_id);
  354. }
  355. // save cloud txt
  356. // 存入中心点与四轮中心(左前,左后,右前,右后)
  357. Eigen::Affine3f transform = Eigen::Affine3f::Identity();
  358. transform.translation() << x, y, 0.0;
  359. transform.rotate(Eigen::AngleAxisf(c/180.0*M_PI - M_PI_2, Eigen::Vector3f::UnitZ()));
  360. pcl::PointCloud<pcl::PointXYZ>::Ptr t_total_append_cloud=pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  361. pcl::PointCloud<pcl::PointXYZ>::Ptr t_append_cloud=pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>);
  362. create_mark(-(width-0.15)/2.0, -wheelbase/2.0, t_append_cloud);
  363. create_mark(-(width-0.15)/2.0, +wheelbase/2.0, t_append_cloud);
  364. create_mark(+(width-0.15)/2.0, -wheelbase/2.0, t_append_cloud);
  365. create_mark(+(width-0.15)/2.0, +wheelbase/2.0, t_append_cloud);
  366. pcl::PointXYZ center(0, 0, 0);
  367. t_append_cloud->push_back(center);
  368. pcl::transformPointCloud(*t_append_cloud, *t_append_cloud, transform);
  369. t_total_append_cloud->operator+=(*t_append_cloud);
  370. save_cloud_txt(cloud_txt_filename, (cloud->operator+=(*t_append_cloud)).makeShared());
  371. wj_measure_temp.x = x * 1000.0;
  372. wj_measure_temp.y = y * 1000.0;
  373. wj_measure_temp.angle = c;
  374. wj_measure_temp.wheel_base = wheelbase * 1000.0;
  375. wj_measure_temp.width = width * 1000.0;
  376. wj_measure_temp.correctness = correctness;
  377. if (wj_measure_temp.correctness)
  378. {
  379. task->set_result(wj_measure_temp);
  380. char description[255] = {0};
  381. sprintf(description, "WJ center(%.1f, %.1f) size:(%.1f, %.1f) angle:%.2f front_ang:%.2f",
  382. x * 1000.0, y * 1000.0, wheelbase * 1000.0, width * 1000.0, c, ftheta);
  383. LOG(INFO) << description;
  384. return;
  385. }else
  386. {
  387. LOG(INFO) << "term: "+ std::to_string(term_id) +" measure failed.";
  388. }
  389. LOG(INFO) << "==================================================";
  390. }
  391. }
  392. }
  393. int main(int argc, char *argv[])
  394. {
  395. // lidar_test();
  396. // usleep(1000 * 1000);
  397. // lidar_test();
  398. // usleep(1000 * 1000);
  399. // lidar_test();
  400. // usleep(1000 * 1000);
  401. // std::cout<<std::hex<<-2146828280<<std::endl;
  402. detect_test();
  403. LOG(INFO) << "end";
  404. // getchar();
  405. return 0;
  406. }