main.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #include <csignal>
  2. #include "lio/Estimator.h"
  3. #include "lio/mapper.h"
  4. #include "lddc.h"
  5. #include "lds_hub.h"
  6. #include "lds_lidar.h"
  7. #include "lds_lvx.h"
  8. #include "livox_sdk.h"
  9. #include "pangolinViewer.h"
  10. #include "segment/LidarFeatureExtractor.h"
  11. #include "dijkstra/dijkstra.h"
  12. #include "define/timedlockdata.hpp"
  13. #include "MPC/navigation.h"
  14. //雷达相关
  15. livox_ros::Lddc *lddc= nullptr;
  16. //特征提取相关
  17. LidarFeatureExtractor* lidarFeatureExtractor;
  18. pcl::PointCloud<PointType>::Ptr laserCloud;
  19. int Lidar_Type=0;
  20. int N_SCANS = 6;
  21. bool Feature_Mode = false;
  22. bool Use_seg = false;
  23. //slam 地图相关
  24. Mapper* pMaper= nullptr;
  25. //路径相关
  26. int node_beg=1,node_end=6;
  27. std::mutex pathMutex;
  28. std::vector<int> shortest_path;
  29. PathMap DijkstraMap;
  30. //控制相关
  31. Navigation* navigator=nullptr;
  32. TimedLockData<PointCloud> scan_cloud;
  33. TimedLockData<PointCloud::Ptr> localmap_cloud;
  34. TimedLockData<Eigen::Matrix4d> cur_pose;
  35. double final_cost=0;
  36. void CloudFullCallback(pcl::PointCloud<PointType>::Ptr cloud,double timebase)
  37. {
  38. scan_cloud.reset(*cloud,0.1);
  39. }
  40. void CloudLocalCallback(pcl::PointCloud<PointType>::Ptr cloud,double timebase)
  41. {
  42. localmap_cloud.reset(cloud,0.1);
  43. }
  44. void OdometryCallback(Eigen::Matrix4d tranform,double timebase)
  45. {
  46. cur_pose.reset(tranform);
  47. //Eigen::Vector3d eulerAngle=tranform.topLeftCorner(3,3).eulerAngles(2,1,0);
  48. Pose2d pose(tranform(0,3),tranform(1,3),0);
  49. Navigation::GetInstance()->ResetPose(pose);
  50. }
  51. void FinalCostCallback(double cost)
  52. {
  53. final_cost=cost;
  54. }
  55. void CloudCallback(TimeCloud tc,int handle)
  56. {
  57. double timeSpan =tc.cloud->points.back().normal_x;
  58. laserCloud.reset(new pcl::PointCloud<PointType>);
  59. laserCloud->reserve(15000*N_SCANS);
  60. PointType point;
  61. for(const auto& p : tc.cloud->points)
  62. {
  63. //std::cout<<point.normal_y<<" "<<point.normal_x<<" "<<timeSpan<<std::endl;
  64. if (p.normal_y > N_SCANS - 1) continue;
  65. if (p.x < 0.01) continue;
  66. if (!pcl_isfinite(p.x) ||
  67. !pcl_isfinite(p.y) ||
  68. !pcl_isfinite(p.z))
  69. {
  70. continue;
  71. }
  72. point.x=p.x;
  73. point.y=p.y;
  74. point.z=p.z;
  75. point.normal_x = p.normal_x / timeSpan; //normao_x time
  76. point.intensity=p.intensity;
  77. int line=int(p.normal_y);
  78. point.normal_y=LidarFeatureExtractor::_int_as_float(line);
  79. laserCloud->push_back(point);
  80. /*std::cout<<" x:"<<point.x<<" y:"<<point.y<<" z:"<<point.z
  81. <<" intnesity:"<<point.intensity<<" normal_x:"<<point.normal_x
  82. <<" normal_y:"<<point.normal_y<<std::endl;*/
  83. }
  84. tc.cloud=laserCloud;
  85. pMaper->AddCloud(tc);
  86. }
  87. void ImuDataCallback(ImuData imu,int handle){
  88. pMaper->AddImu(imu);
  89. }
  90. bool InitLidar(double freq);
  91. bool InitMap(std::string config_file);
  92. bool InitDijkstraMap();
  93. void pangolinSpinOnce(PangolinViewer* viewer)
  94. {
  95. if(cur_pose.timeout()==false)
  96. viewer->ShowRealtimePose(cur_pose.Get());
  97. //绘制变换后的扫描点
  98. double ptSize=1;
  99. double alpha=1;
  100. PointCloud scan=scan_cloud.Get();
  101. if(scan.size()>0)
  102. viewer->DrawCloud(scan.makeShared(),1,1,1,alpha,ptSize);
  103. //地图点
  104. ptSize=0.1;
  105. alpha=0.2;
  106. viewer->DrawCloud(pMaper->GetMapCorner(),1,0,0,alpha,ptSize);
  107. viewer->DrawCloud(pMaper->GetMapSurf(),0.1,1,0,alpha,ptSize);
  108. viewer->DrawCloud(pMaper->GetMapNonf(),0.1,0,1,alpha,ptSize);
  109. viewer->ShowSlamCost(final_cost);
  110. if(pMaper!= nullptr)
  111. viewer->ShowSlamQueueTime(pMaper->_lidarMsgQueue.size(),pMaper->frame_tm_);
  112. //绘制dijkstra地图及最短路径
  113. pathMutex.lock();
  114. std::vector<int> solve_path=shortest_path;
  115. pathMutex.unlock();
  116. std::reverse(solve_path.begin(),solve_path.end());
  117. solve_path.push_back(node_end);
  118. viewer->DrawDijkastraMap(DijkstraMap, solve_path);
  119. }
  120. void OnStartBtn(std::string lvxfile)
  121. {
  122. if(lddc!= nullptr)
  123. {
  124. if (lvxfile=="")
  125. lddc->Start();
  126. else
  127. lddc->Start(lvxfile);
  128. }
  129. }
  130. void OnStopBtn()
  131. {
  132. if(lddc!= nullptr)
  133. lddc->Stop();
  134. }
  135. void OnFreqChanged(int freq)
  136. {
  137. if(lddc!= nullptr)
  138. lddc->SetPublishFrq(freq);
  139. }
  140. bool OnDijkstraBtn(int beg,int end,float& distance,
  141. std::vector<int>& shortestPath)
  142. {
  143. bool ret= DijkstraMap.GetShortestPath(beg, end, shortestPath, distance);
  144. if(ret)
  145. {
  146. node_beg=beg;
  147. node_end=end;
  148. pathMutex.lock();
  149. shortest_path = shortestPath;
  150. pathMutex.unlock();
  151. }
  152. return ret;
  153. }
  154. int main(int argc, char** argv)
  155. {
  156. //reg参数
  157. std::string config_file="../config/horizon_config.yaml";
  158. if(InitMap(config_file)==false)
  159. return -1;
  160. if(!InitDijkstraMap())
  161. {
  162. printf("Dijkstra Map load failed\n");
  163. return -2;
  164. }
  165. //初始化雷达
  166. double publish_freq = 10.0;
  167. if(!InitLidar(publish_freq))
  168. return -3;
  169. PangolinViewer* viewer=PangolinViewer::CreateViewer();
  170. viewer->SetCallbacks(pangolinSpinOnce,OnStartBtn,OnStopBtn,OnFreqChanged,OnDijkstraBtn);
  171. viewer->Join();
  172. TimerRecord::PrintAll();
  173. lddc->Stop();
  174. pMaper->completed();
  175. delete pMaper;
  176. delete lddc;
  177. delete viewer;
  178. return 0;
  179. }
  180. bool InitMap(std::string config_file)
  181. {
  182. cv::FileStorage fsSettings(config_file, cv::FileStorage::READ);
  183. if (!fsSettings.isOpened())
  184. {
  185. std::cout << "config_file error: cannot open " << config_file << std::endl;
  186. return false;
  187. }
  188. Lidar_Type = static_cast<int>(fsSettings["Lidar_Type"]);
  189. N_SCANS = static_cast<int>(fsSettings["Used_Line"]);
  190. Feature_Mode = static_cast<int>(fsSettings["Feature_Mode"]);
  191. Use_seg = static_cast<int>(fsSettings["Use_seg"]);
  192. int NumCurvSize = static_cast<int>(fsSettings["NumCurvSize"]);
  193. float DistanceFaraway = static_cast<float>(fsSettings["DistanceFaraway"]);
  194. int NumFlat = static_cast<int>(fsSettings["NumFlat"]);
  195. int PartNum = static_cast<int>(fsSettings["PartNum"]);
  196. float FlatThreshold = static_cast<float>(fsSettings["FlatThreshold"]);
  197. float BreakCornerDis = static_cast<float>(fsSettings["BreakCornerDis"]);
  198. float LidarNearestDis = static_cast<float>(fsSettings["LidarNearestDis"]);
  199. float KdTreeCornerOutlierDis = static_cast<float>(fsSettings["KdTreeCornerOutlierDis"]);
  200. int ivox_nearby_type = static_cast<int>(fsSettings["ivox_nearby_type"]);
  201. int max_ivox_node = static_cast<int>(fsSettings["max_ivox_node"]);
  202. float ivox_resolution = static_cast<float>(fsSettings["ivox_node_solution"]);
  203. laserCloud.reset(new pcl::PointCloud<PointType>);
  204. lidarFeatureExtractor = new LidarFeatureExtractor(N_SCANS,
  205. NumCurvSize,
  206. DistanceFaraway,
  207. NumFlat,
  208. PartNum,
  209. FlatThreshold,
  210. BreakCornerDis,
  211. LidarNearestDis,
  212. KdTreeCornerOutlierDis);
  213. //map 参数
  214. std::string map_dir="../map/";
  215. float filter_parameter_corner = 0.2;
  216. float filter_parameter_surf = 0.4;
  217. int IMU_Mode = 2;
  218. double vecTlb[]={1.0, 0.0, 0.0, -0.05512,
  219. 0.0, 1.0, 0.0, -0.02226,
  220. 0.0, 0.0, 1.0, 0.0297,
  221. 0.0, 0.0, 0.0, 1.0};
  222. // set extrinsic matrix between lidar & IMU
  223. Eigen::Matrix3d R;
  224. Eigen::Vector3d t;
  225. R << vecTlb[0], vecTlb[1], vecTlb[2],
  226. vecTlb[4], vecTlb[5], vecTlb[6],
  227. vecTlb[8], vecTlb[9], vecTlb[10];
  228. t << vecTlb[3], vecTlb[7], vecTlb[11];
  229. Eigen::Quaterniond qr(R);
  230. R = qr.normalized().toRotationMatrix();
  231. int WINDOWSIZE = 0;
  232. if (IMU_Mode < 2)
  233. WINDOWSIZE = 1;
  234. else
  235. WINDOWSIZE = 20;
  236. pMaper = new Mapper(WINDOWSIZE, lidarFeatureExtractor,Use_seg,filter_parameter_corner, filter_parameter_surf,
  237. ivox_nearby_type, max_ivox_node, ivox_resolution);
  238. pMaper->InitRT(R, t);
  239. pMaper->SetOdomCallback(OdometryCallback);
  240. pMaper->SetCloudMappedCallback(CloudFullCallback);
  241. pMaper->SetLocalMapCloudCallback(CloudLocalCallback);
  242. pMaper->SetFinalCostCallback(FinalCostCallback);
  243. pMaper->LoadMap(map_dir + "/featurebbt_transformed.txt");
  244. double RPI = M_PI / 180.0;
  245. Eigen::Vector3d eulerAngle(0 * RPI, 0 * RPI, 11.5 * RPI);
  246. Eigen::AngleAxisd rollAngle(Eigen::AngleAxisd(eulerAngle(0), Eigen::Vector3d::UnitX()));
  247. Eigen::AngleAxisd pitchAngle(Eigen::AngleAxisd(eulerAngle(1), Eigen::Vector3d::UnitY()));
  248. Eigen::AngleAxisd yawAngle(Eigen::AngleAxisd(eulerAngle(2), Eigen::Vector3d::UnitZ()));
  249. Eigen::Matrix3d rotation_matrix;
  250. rotation_matrix = yawAngle * pitchAngle * rollAngle;
  251. Eigen::Matrix4d transform;
  252. transform.topLeftCorner(3, 3) = rotation_matrix;
  253. transform.topRightCorner(3, 1) = Eigen::Vector3d(0.46, 0.48, 0.73);
  254. pMaper->SetInitPose(transform);
  255. printf(" window size :%d\n--------------", WINDOWSIZE);
  256. return true;
  257. }
  258. bool InitDijkstraMap()
  259. {
  260. DijkstraMap.AddVertex(1, 2.3, 3.1);
  261. DijkstraMap.AddVertex(2, 19.2, 3.1);
  262. DijkstraMap.AddVertex(3, 59.7, 3.3);
  263. DijkstraMap.AddVertex(4, 98.4, 3.3);
  264. DijkstraMap.AddVertex(5, 98.5, -13);
  265. DijkstraMap.AddVertex(6, 59.5, -13);
  266. DijkstraMap.AddVertex(7, 20, 18);
  267. bool ret=true;
  268. ret=ret&&DijkstraMap.AddEdge(1, 2, false);
  269. ret=ret&&DijkstraMap.AddEdge(2, 3, false);
  270. ret=ret&&DijkstraMap.AddEdge(2, 7, false);
  271. ret=ret&&DijkstraMap.AddEdge(3, 4, false);
  272. ret=ret&&DijkstraMap.AddEdge(3, 6, false);
  273. ret=ret&&DijkstraMap.AddEdge(4, 5, false);
  274. ret=ret&&DijkstraMap.AddEdge(5, 6, false);
  275. return ret;
  276. }
  277. bool InitLidar(double publish_freq)
  278. {
  279. LivoxSdkVersion _sdkversion;
  280. GetLivoxSdkVersion(&_sdkversion);
  281. const int32_t kSdkVersionMajorLimit = 2;
  282. if (_sdkversion.major < kSdkVersionMajorLimit) {
  283. printf("The SDK version[%d.%d.%d] is too low\n", _sdkversion.major,
  284. _sdkversion.minor, _sdkversion.patch);
  285. return false;
  286. }
  287. if (publish_freq > 100.0) {
  288. publish_freq = 100.0;
  289. } else if (publish_freq < 0.1) {
  290. publish_freq = 0.1;
  291. } else {
  292. publish_freq = publish_freq;
  293. }
  294. lddc= new livox_ros::Lddc(publish_freq);
  295. lddc->SetCloudCallback(CloudCallback);
  296. lddc->SetImuCallback(ImuDataCallback);
  297. return true;
  298. }