|
@@ -1,598 +0,0 @@
|
|
|
-
|
|
|
-
|
|
|
-#include <csignal>
|
|
|
-
|
|
|
-
|
|
|
-#include "lio/Estimator.h"
|
|
|
-#include "lio/mapper.h"
|
|
|
-
|
|
|
-#include "lddc.h"
|
|
|
-#include "lds_hub.h"
|
|
|
-#include "lds_lidar.h"
|
|
|
-#include "lds_lvx.h"
|
|
|
-#include "livox_sdk.h"
|
|
|
-
|
|
|
-#include <pangolin/var/var.h>
|
|
|
-#include <pangolin/var/varextra.h>
|
|
|
-#include <pangolin/gl/gl.h>
|
|
|
-#include <pangolin/gl/gldraw.h>
|
|
|
-#include <pangolin/display/display.h>
|
|
|
-#include <pangolin/display/view.h>
|
|
|
-#include <pangolin/display/widgets.h>
|
|
|
-#include <pangolin/display/default_font.h>
|
|
|
-#include <pangolin/handler/handler.h>
|
|
|
-#include "segment/LidarFeatureExtractor.h"
|
|
|
-
|
|
|
-#include "../dijkstra/dijkstra.h"
|
|
|
-#include "time_data.h"
|
|
|
-
|
|
|
-//雷达相关
|
|
|
-livox_ros::Lddc *lddc= nullptr;
|
|
|
-//特征提取相关
|
|
|
-LidarFeatureExtractor* lidarFeatureExtractor;
|
|
|
-pcl::PointCloud<PointType>::Ptr laserCloud;
|
|
|
-int Lidar_Type=0;
|
|
|
-int N_SCANS = 6;
|
|
|
-bool Feature_Mode = false;
|
|
|
-bool Use_seg = false;
|
|
|
-
|
|
|
-//slam 地图相关
|
|
|
-Mapper* pMaper= nullptr;
|
|
|
-
|
|
|
-//路径相关
|
|
|
-std::mutex pathMutex;
|
|
|
-std::vector<int> shortestPath;
|
|
|
-PathMap DijkstraMap;
|
|
|
-int node_beg=1;
|
|
|
-int node_end=5;
|
|
|
-
|
|
|
-
|
|
|
-void SigHandle(int sig) {
|
|
|
- printf("catch sig %d\n", sig);
|
|
|
- TimerRecord::PrintAll();
|
|
|
-}
|
|
|
-
|
|
|
-class LockCloud
|
|
|
-{
|
|
|
- public:
|
|
|
- LockCloud()
|
|
|
- {
|
|
|
- cloud_.reset(new pcl::PointCloud<PointType>);
|
|
|
- }
|
|
|
- void Lock(){
|
|
|
- lock_.lock();
|
|
|
- }
|
|
|
- void unlock(){
|
|
|
- lock_.unlock();
|
|
|
- }
|
|
|
- pcl::PointCloud<PointType>::Ptr Get()
|
|
|
- {
|
|
|
- return cloud_;
|
|
|
- }
|
|
|
- void Set(pcl::PointCloud<PointType>::Ptr cloud)
|
|
|
- {
|
|
|
- lock_.lock();
|
|
|
- cloud_=cloud;
|
|
|
- lock_.unlock();
|
|
|
- }
|
|
|
-
|
|
|
- protected:
|
|
|
- std::mutex lock_;
|
|
|
- pcl::PointCloud<PointType>::Ptr cloud_;
|
|
|
-};
|
|
|
-
|
|
|
-LockCloud scan_cloud;
|
|
|
-LockCloud localmap_cloud;
|
|
|
-Eigen::Matrix4d cur_pose;
|
|
|
-double pose_line_length=2.0;
|
|
|
-double final_cost=0;
|
|
|
-
|
|
|
-void CloudFullCallback(pcl::PointCloud<PointType>::Ptr cloud,double timebase)
|
|
|
-{
|
|
|
- scan_cloud.Set(cloud);
|
|
|
-}
|
|
|
-
|
|
|
-void CloudLocalCallback(pcl::PointCloud<PointType>::Ptr cloud,double timebase)
|
|
|
-{
|
|
|
- localmap_cloud.Set(cloud);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void OdometryCallback(Eigen::Matrix4d tranform,double timebase)
|
|
|
-{
|
|
|
- cur_pose=tranform;
|
|
|
-}
|
|
|
-
|
|
|
-void FinalCostCallback(double cost)
|
|
|
-{
|
|
|
- final_cost=cost;
|
|
|
-}
|
|
|
-
|
|
|
-void CloudCallback(TimeCloud tc,int handle)
|
|
|
-{
|
|
|
- double timeSpan =tc.cloud->points.back().normal_x;
|
|
|
- laserCloud.reset(new pcl::PointCloud<PointType>);
|
|
|
- laserCloud->reserve(15000*N_SCANS);
|
|
|
-
|
|
|
- PointType point;
|
|
|
- for(const auto& p : tc.cloud->points)
|
|
|
- {
|
|
|
-
|
|
|
- //std::cout<<point.normal_y<<" "<<point.normal_x<<" "<<timeSpan<<std::endl;
|
|
|
- if (p.normal_y > N_SCANS - 1) continue;
|
|
|
- if (p.x < 0.01) continue;
|
|
|
- if (!pcl_isfinite(p.x) ||
|
|
|
- !pcl_isfinite(p.y) ||
|
|
|
- !pcl_isfinite(p.z))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- point.x=p.x;
|
|
|
- point.y=p.y;
|
|
|
- point.z=p.z;
|
|
|
- point.normal_x = p.normal_x / timeSpan; //normao_x time
|
|
|
- point.intensity=p.intensity;
|
|
|
- int line=int(p.normal_y);
|
|
|
- point.normal_y=LidarFeatureExtractor::_int_as_float(line);
|
|
|
- laserCloud->push_back(point);
|
|
|
- /*std::cout<<" x:"<<point.x<<" y:"<<point.y<<" z:"<<point.z
|
|
|
- <<" intnesity:"<<point.intensity<<" normal_x:"<<point.normal_x
|
|
|
- <<" normal_y:"<<point.normal_y<<std::endl;*/
|
|
|
- }
|
|
|
-
|
|
|
- tc.cloud=laserCloud;
|
|
|
- pMaper->AddCloud(tc);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-void ImuDataCallback(ImuData imu,int handle){
|
|
|
- pMaper->AddImu(imu);
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-bool InitLidar(double freq);
|
|
|
-bool InitMap(std::string config_file);
|
|
|
-bool InitDijkstraMap();
|
|
|
-void DrawPose(Eigen::Matrix4d pose);
|
|
|
-void DrawMap(PathMap& map,std::vector<int> path,pangolin::GlFont* text_font);
|
|
|
-void DrawCloud(pcl::PointCloud<PointType>::Ptr cloud,
|
|
|
- double r,double g,double b,double psize,double alpha=1.0);
|
|
|
-
|
|
|
-int main(int argc, char** argv)
|
|
|
-{
|
|
|
-
|
|
|
- //reg参数
|
|
|
- std::string config_file="../config/horizon_config.yaml";
|
|
|
- if(InitMap(config_file)==false)
|
|
|
- return -1;
|
|
|
-
|
|
|
-
|
|
|
- signal(SIGINT, SigHandle);
|
|
|
-
|
|
|
- pangolin::GlFont *text_font = new pangolin::GlFont("../config/tt0102m_.ttf", 30.0);
|
|
|
- pangolin::CreateWindowAndBind("Main", 1280, 960);
|
|
|
-
|
|
|
- // 3D Mouse handler requires depth testing to be enabled
|
|
|
- glEnable(GL_DEPTH_TEST);
|
|
|
- glEnable(GL_BLEND); // 启用混合
|
|
|
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
-
|
|
|
- pangolin::OpenGlRenderState s_cam(
|
|
|
- pangolin::ProjectionMatrix(1280, 960, 840, 840, 640, 480, 0.1, 1000),
|
|
|
- pangolin::ModelViewLookAt(25, 25, 70, 25, 25, 5, pangolin::AxisY)
|
|
|
- );
|
|
|
-
|
|
|
- const int UI_WIDTH = 30 * pangolin::default_font().MaxWidth();
|
|
|
- pangolin::View &d_cam = pangolin::CreateDisplay()
|
|
|
- .SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, 1280.0f / 960.0f)
|
|
|
- .SetHandler(new pangolin::Handler3D(s_cam));
|
|
|
-
|
|
|
- pangolin::CreatePanel("ui")
|
|
|
- .SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH));
|
|
|
-
|
|
|
- pangolin::Var<bool> lvx_checkbox("ui.lvx_Checkbox", true, true);
|
|
|
- pangolin::Var<std::string> lvx_file("ui.lvx_file_String", "../map/lidarbag/start1.lvx");
|
|
|
-
|
|
|
- pangolin::Var<bool> start_button("ui.start_Button", false, false);
|
|
|
- pangolin::Var<bool> stop_button("ui.stop_Button", false, false);
|
|
|
- pangolin::Var<double> freq_double("ui.Freq_Double", 10, 1, 15);
|
|
|
- /*pangolin::Var<int> an_int("ui.An_Int", 2, 0, 5);
|
|
|
- pangolin::Var<double> a_double_log("ui.Log_scale", 3, 1, 1E4, true);*/
|
|
|
- pangolin::Var<std::string> timequeue_string("ui.tq_String", "timequeue_string");
|
|
|
- pangolin::Var<std::string> xyz_string("ui.xyz_String", "xyz");
|
|
|
- pangolin::Var<std::string> rpy_string("ui.rpy_String", "rpy");
|
|
|
- pangolin::Var<std::string> cost_string("ui.final_cost", "cost");
|
|
|
-
|
|
|
- pangolin::Var<int> beg_Int("ui.beg", 1, 1, 7);
|
|
|
- pangolin::Var<int> end_Int("ui.end", 5, 1, 7);
|
|
|
- pangolin::Var<std::string> path_string("ui.path", "cost");
|
|
|
- pangolin::Var<std::string> distance_string("ui.distance", "distance");
|
|
|
-
|
|
|
- if(!InitDijkstraMap())
|
|
|
- return -2;
|
|
|
-
|
|
|
- pangolin::Var<std::function<void(void)>> solve_view("ui.Solve", [&]() {
|
|
|
-
|
|
|
- auto start_tm = std::chrono::system_clock::now();
|
|
|
-
|
|
|
- node_beg = beg_Int.Get();
|
|
|
- node_end = end_Int.Get();
|
|
|
-
|
|
|
-
|
|
|
- float distance = 0;
|
|
|
- pathMutex.lock();
|
|
|
- shortestPath.clear();
|
|
|
- DijkstraMap.GetShortestPath(node_beg, node_end, shortestPath, distance);
|
|
|
- pathMutex.unlock();
|
|
|
-
|
|
|
- char path_str[64] = {0};
|
|
|
- sprintf(path_str, "%d-%d:", node_beg, node_end);
|
|
|
-
|
|
|
- for (int i = shortestPath.size() - 1; i >= 0; --i)
|
|
|
- {
|
|
|
- sprintf(path_str + strlen(path_str), "%d-", shortestPath[i]);
|
|
|
- }
|
|
|
- sprintf(path_str + strlen(path_str), "%d", node_end);
|
|
|
- path_string = path_str;
|
|
|
-
|
|
|
- char cost[62] = {0};
|
|
|
- sprintf(cost, "d(%d-%d):%.3f", node_beg, node_end, distance);
|
|
|
- distance_string = cost;
|
|
|
-
|
|
|
- auto end_tm = std::chrono::system_clock::now();
|
|
|
- auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_tm - start_tm);
|
|
|
- double time = double(duration.count()) * std::chrono::microseconds::period::num / std::chrono::microseconds::period::den;
|
|
|
- char tm[32] = {0};
|
|
|
- sprintf(tm, "time:%.5fs", time);
|
|
|
- timequeue_string = tm;
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- // Demonstration of how we can register a keyboard hook to alter a Var
|
|
|
- pangolin::RegisterKeyPressCallback(pangolin::PANGO_CTRL + 'b', [&]() {
|
|
|
- //a_double = 3.5;
|
|
|
-
|
|
|
- });
|
|
|
-
|
|
|
- // Default hooks for exiting (Esc) and fullscreen (tab).
|
|
|
-
|
|
|
- //初始化雷达
|
|
|
- double publish_freq = freq_double.Get(); /* Hz */
|
|
|
- if(!InitLidar(publish_freq))
|
|
|
- return -3;
|
|
|
-
|
|
|
-
|
|
|
- double zoom = 1.0;
|
|
|
- while (!pangolin::ShouldQuit())
|
|
|
- {
|
|
|
- // Clear entire screen
|
|
|
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
-
|
|
|
- if (pangolin::Pushed(start_button))
|
|
|
- {
|
|
|
- if (lvx_checkbox)
|
|
|
- {
|
|
|
- std::string file = lvx_file.Get();
|
|
|
- lddc->Start(file);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- lddc->Start();
|
|
|
- }
|
|
|
- }
|
|
|
- if (pangolin::Pushed(stop_button))
|
|
|
- {
|
|
|
- lddc->Stop();
|
|
|
- }
|
|
|
-
|
|
|
- Eigen::Matrix3d rotation=cur_pose.topLeftCorner(3,3);
|
|
|
- Eigen::Vector3d eulerAngle=rotation.eulerAngles(0,1,2);
|
|
|
- Eigen::Vector3d t=cur_pose.topRightCorner(3,1);
|
|
|
- char rpy[64]={0};
|
|
|
- sprintf(rpy,"%.3f,%.3f,%.3f",eulerAngle[0]*180.0/M_PI,eulerAngle[1]*180.0/M_PI,eulerAngle[2]*180.0/M_PI);
|
|
|
- char translation[64]={0};
|
|
|
- sprintf(translation,"%.3f,%.3f,%.3f",t[0],t[1],t[2]);
|
|
|
- xyz_string=translation;
|
|
|
- rpy_string=rpy;
|
|
|
-
|
|
|
- char cost[64]={0};
|
|
|
- sprintf(cost,"cost:%f",final_cost);
|
|
|
- cost_string=cost;
|
|
|
-
|
|
|
-
|
|
|
- if (freq_double.GuiChanged())
|
|
|
- {
|
|
|
- publish_freq=freq_double.Get();
|
|
|
- lddc->SetPublishFrq(publish_freq);
|
|
|
- }
|
|
|
-
|
|
|
- char info_str[64]={0};
|
|
|
- sprintf(info_str,"time:%.5fs queue:%d",pMaper->frame_tm_,pMaper->_lidarMsgQueue.size());
|
|
|
- timequeue_string=info_str;
|
|
|
-
|
|
|
- if (d_cam.IsShown())
|
|
|
- {
|
|
|
- d_cam.Activate(s_cam);
|
|
|
- pangolin::glDrawAxis(3);//三维坐标轴,红——x轴,绿——y轴,蓝——z轴
|
|
|
-
|
|
|
- DrawPose(cur_pose);
|
|
|
-
|
|
|
- //绘制变换后的扫描点
|
|
|
- double ptSize=1;
|
|
|
- double alpha=1;
|
|
|
- scan_cloud.Lock();
|
|
|
- DrawCloud(scan_cloud.Get(),1,1,1,ptSize,alpha);
|
|
|
- scan_cloud.unlock();
|
|
|
-
|
|
|
- //地图点
|
|
|
- ptSize=0.1;
|
|
|
- alpha=0.2;
|
|
|
- DrawCloud(pMaper->GetMapCorner(),1,0,0,ptSize,alpha);
|
|
|
- DrawCloud(pMaper->GetMapSurf(),0.1,1,0,ptSize,alpha);
|
|
|
- DrawCloud(pMaper->GetMapNonf(),0.1,0,1,ptSize,alpha);
|
|
|
-
|
|
|
- //绘制dijkstra地图及最短路径
|
|
|
- pathMutex.lock();
|
|
|
- std::vector<int> solve_path=shortestPath;
|
|
|
- pathMutex.unlock();
|
|
|
- std::reverse(solve_path.begin(),solve_path.end());
|
|
|
- solve_path.push_back(node_end);
|
|
|
- DrawMap(DijkstraMap, solve_path,text_font);
|
|
|
-
|
|
|
- }
|
|
|
- pangolin::FinishFrame();
|
|
|
- std::this_thread::sleep_for(std::chrono::microseconds(10));
|
|
|
- }
|
|
|
-
|
|
|
- lddc->Stop();
|
|
|
- pMaper->completed();
|
|
|
- delete pMaper;
|
|
|
- delete lddc;
|
|
|
- delete text_font;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-bool InitMap(std::string config_file)
|
|
|
-{
|
|
|
- cv::FileStorage fsSettings(config_file, cv::FileStorage::READ);
|
|
|
- if (!fsSettings.isOpened())
|
|
|
- {
|
|
|
- std::cout << "config_file error: cannot open " << config_file << std::endl;
|
|
|
- return false;
|
|
|
- }
|
|
|
- Lidar_Type = static_cast<int>(fsSettings["Lidar_Type"]);
|
|
|
- N_SCANS = static_cast<int>(fsSettings["Used_Line"]);
|
|
|
- Feature_Mode = static_cast<int>(fsSettings["Feature_Mode"]);
|
|
|
- Use_seg = static_cast<int>(fsSettings["Use_seg"]);
|
|
|
-
|
|
|
- int NumCurvSize = static_cast<int>(fsSettings["NumCurvSize"]);
|
|
|
- float DistanceFaraway = static_cast<float>(fsSettings["DistanceFaraway"]);
|
|
|
- int NumFlat = static_cast<int>(fsSettings["NumFlat"]);
|
|
|
- int PartNum = static_cast<int>(fsSettings["PartNum"]);
|
|
|
- float FlatThreshold = static_cast<float>(fsSettings["FlatThreshold"]);
|
|
|
- float BreakCornerDis = static_cast<float>(fsSettings["BreakCornerDis"]);
|
|
|
- float LidarNearestDis = static_cast<float>(fsSettings["LidarNearestDis"]);
|
|
|
- float KdTreeCornerOutlierDis = static_cast<float>(fsSettings["KdTreeCornerOutlierDis"]);
|
|
|
-
|
|
|
- int ivox_nearby_type = static_cast<int>(fsSettings["ivox_nearby_type"]);
|
|
|
- int max_ivox_node = static_cast<int>(fsSettings["max_ivox_node"]);
|
|
|
- float ivox_resolution = static_cast<float>(fsSettings["ivox_node_solution"]);
|
|
|
-
|
|
|
- laserCloud.reset(new pcl::PointCloud<PointType>);
|
|
|
-
|
|
|
- lidarFeatureExtractor = new LidarFeatureExtractor(N_SCANS,
|
|
|
- NumCurvSize,
|
|
|
- DistanceFaraway,
|
|
|
- NumFlat,
|
|
|
- PartNum,
|
|
|
- FlatThreshold,
|
|
|
- BreakCornerDis,
|
|
|
- LidarNearestDis,
|
|
|
- KdTreeCornerOutlierDis);
|
|
|
-
|
|
|
- //map 参数
|
|
|
- std::string map_dir="../map/";
|
|
|
- float filter_parameter_corner = 0.2;
|
|
|
- float filter_parameter_surf = 0.4;
|
|
|
- int IMU_Mode = 2;
|
|
|
-
|
|
|
- double vecTlb[]={1.0, 0.0, 0.0, -0.05512,
|
|
|
- 0.0, 1.0, 0.0, -0.02226,
|
|
|
- 0.0, 0.0, 1.0, 0.0297,
|
|
|
- 0.0, 0.0, 0.0, 1.0};
|
|
|
-
|
|
|
- // set extrinsic matrix between lidar & IMU
|
|
|
- Eigen::Matrix3d R;
|
|
|
- Eigen::Vector3d t;
|
|
|
- R << vecTlb[0], vecTlb[1], vecTlb[2],
|
|
|
- vecTlb[4], vecTlb[5], vecTlb[6],
|
|
|
- vecTlb[8], vecTlb[9], vecTlb[10];
|
|
|
- t << vecTlb[3], vecTlb[7], vecTlb[11];
|
|
|
- Eigen::Quaterniond qr(R);
|
|
|
- R = qr.normalized().toRotationMatrix();
|
|
|
-
|
|
|
-
|
|
|
- int WINDOWSIZE = 0;
|
|
|
- if (IMU_Mode < 2)
|
|
|
- WINDOWSIZE = 1;
|
|
|
- else
|
|
|
- WINDOWSIZE = 20;
|
|
|
-
|
|
|
- pMaper = new Mapper(WINDOWSIZE, lidarFeatureExtractor,Use_seg,filter_parameter_corner, filter_parameter_surf,
|
|
|
- ivox_nearby_type, max_ivox_node, ivox_resolution);
|
|
|
- pMaper->InitRT(R, t);
|
|
|
- pMaper->SetOdomCallback(OdometryCallback);
|
|
|
- pMaper->SetCloudMappedCallback(CloudFullCallback);
|
|
|
- pMaper->SetLocalMapCloudCallback(CloudLocalCallback);
|
|
|
- pMaper->SetFinalCostCallback(FinalCostCallback);
|
|
|
- pMaper->LoadMap(map_dir + "/featurebbt_transformed.txt");
|
|
|
-
|
|
|
- double RPI = M_PI / 180.0;
|
|
|
- Eigen::Vector3d eulerAngle(0 * RPI, 0 * RPI, 11.5 * RPI);
|
|
|
- Eigen::AngleAxisd rollAngle(Eigen::AngleAxisd(eulerAngle(0), Eigen::Vector3d::UnitX()));
|
|
|
- Eigen::AngleAxisd pitchAngle(Eigen::AngleAxisd(eulerAngle(1), Eigen::Vector3d::UnitY()));
|
|
|
- Eigen::AngleAxisd yawAngle(Eigen::AngleAxisd(eulerAngle(2), Eigen::Vector3d::UnitZ()));
|
|
|
-
|
|
|
- Eigen::Matrix3d rotation_matrix;
|
|
|
- rotation_matrix = yawAngle * pitchAngle * rollAngle;
|
|
|
- Eigen::Matrix4d transform;
|
|
|
- transform.topLeftCorner(3, 3) = rotation_matrix;
|
|
|
- transform.topRightCorner(3, 1) = Eigen::Vector3d(0.46, 0.48, 0.73);
|
|
|
- pMaper->SetInitPose(transform);
|
|
|
-
|
|
|
- printf(" window size :%d\n--------------", WINDOWSIZE);
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool InitDijkstraMap()
|
|
|
-{
|
|
|
- DijkstraMap.AddVertex(1, 2.3, 3.1);
|
|
|
- DijkstraMap.AddVertex(2, 19.2, 3.1);
|
|
|
- DijkstraMap.AddVertex(3, 59.7, 3.3);
|
|
|
- DijkstraMap.AddVertex(4, 98.4, 3.3);
|
|
|
- DijkstraMap.AddVertex(5, 98.5, -13);
|
|
|
- DijkstraMap.AddVertex(6, 59.5, -13);
|
|
|
- DijkstraMap.AddVertex(7, 20, 18);
|
|
|
-
|
|
|
- bool ret=true;
|
|
|
- ret=ret&&DijkstraMap.AddEdge(1, 2, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(2, 3, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(2, 7, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(3, 4, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(3, 6, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(4, 5, false);
|
|
|
- ret=ret&&DijkstraMap.AddEdge(5, 6, false);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-bool InitLidar(double publish_freq)
|
|
|
-{
|
|
|
- LivoxSdkVersion _sdkversion;
|
|
|
- GetLivoxSdkVersion(&_sdkversion);
|
|
|
- const int32_t kSdkVersionMajorLimit = 2;
|
|
|
- if (_sdkversion.major < kSdkVersionMajorLimit) {
|
|
|
- printf("The SDK version[%d.%d.%d] is too low\n", _sdkversion.major,
|
|
|
- _sdkversion.minor, _sdkversion.patch);
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (publish_freq > 100.0) {
|
|
|
- publish_freq = 100.0;
|
|
|
- } else if (publish_freq < 0.1) {
|
|
|
- publish_freq = 0.1;
|
|
|
- } else {
|
|
|
- publish_freq = publish_freq;
|
|
|
- }
|
|
|
- lddc= new livox_ros::Lddc(publish_freq);
|
|
|
-
|
|
|
- lddc->SetCloudCallback(CloudCallback);
|
|
|
- lddc->SetImuCallback(ImuDataCallback);
|
|
|
- return true;
|
|
|
-}
|
|
|
-void DrawPose(Eigen::Matrix4d pose)
|
|
|
-{
|
|
|
- double l=pose_line_length<0.1?0.1:pose_line_length;
|
|
|
- Eigen::Vector3d Ow=pose.topRightCorner(3, 1);
|
|
|
- Eigen::Vector3d Xw=pose.topLeftCorner(3,3)*(l*Eigen::Vector3d(1,0,0))+Ow;
|
|
|
- Eigen::Vector3d Yw=pose.topLeftCorner(3,3)*(l*Eigen::Vector3d(0,1,0))+Ow;
|
|
|
- Eigen::Vector3d Zw=pose.topLeftCorner(3,3)*(l*Eigen::Vector3d(0,0,1))+Ow;
|
|
|
-
|
|
|
- glLineWidth(5);
|
|
|
- glBegin(GL_LINES);
|
|
|
- glColor3f(1.0, 0.0, 0.0);
|
|
|
- glVertex3d(Ow[0], Ow[1], Ow[2]);
|
|
|
- glVertex3d(Xw[0], Xw[1], Xw[2]);
|
|
|
- glColor3f(0.0, 1.0, 0.0);
|
|
|
- glVertex3d(Ow[0], Ow[1], Ow[2]);
|
|
|
- glVertex3d(Yw[0], Yw[1], Yw[2]);
|
|
|
- glColor3f(0.0, 0.0, 1.0);
|
|
|
- glVertex3d(Ow[0], Ow[1], Ow[2]);
|
|
|
- glVertex3d(Zw[0], Zw[1], Zw[2]);
|
|
|
- glEnd();
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-void DrawMap(PathMap& map,std::vector<int> path,pangolin::GlFont* text_font)
|
|
|
-{
|
|
|
-
|
|
|
- //绘制顶点
|
|
|
- std::map<int,PathMap::MapNode> nodes=map.GetNodes();
|
|
|
- std::map<int,PathMap::MapNode>::iterator it=nodes.begin();
|
|
|
- float z=3.6;
|
|
|
-
|
|
|
- glPointSize(20.0);
|
|
|
-// 开始画点
|
|
|
- glBegin ( GL_POINTS );
|
|
|
- glColor3f(1, 0, 1);
|
|
|
- for(it;it!=nodes.end();it++)
|
|
|
- {
|
|
|
- PathMap::MapNode node=it->second;
|
|
|
- // 设置点颜色,rgb值,float类型
|
|
|
- glVertex3f(node.x, node.y, z);
|
|
|
- }
|
|
|
- glEnd();
|
|
|
-
|
|
|
- glLineWidth(5);
|
|
|
- glBegin(GL_LINES);
|
|
|
- //绘制边
|
|
|
- glColor3f(1.0, 0.9, 0.0);
|
|
|
- std::vector<PathMap::MapEdge> edges=map.GetEdges();
|
|
|
- for(int i=0;i<edges.size();++i)
|
|
|
- {
|
|
|
- PathMap::MapEdge edge=edges[i];
|
|
|
- float x1,y1,x2,y2;
|
|
|
- map.GetVertexPos(edge.id1,x1,y1);
|
|
|
- map.GetVertexPos(edge.id2,x2,y2);
|
|
|
-
|
|
|
- glVertex3d(x1,y1, z);
|
|
|
- glVertex3d(x2,y2,z);
|
|
|
- }
|
|
|
-
|
|
|
- glEnd();
|
|
|
-
|
|
|
- if(path.size()>0)
|
|
|
- {
|
|
|
- glLineWidth(10);
|
|
|
- glBegin(GL_LINE_STRIP);
|
|
|
- glColor3f(0, 0, 1);
|
|
|
- for (int i = 0; i < path.size() ; ++i)
|
|
|
- {
|
|
|
- float x1, y1;
|
|
|
- if (map.GetVertexPos(path[i], x1, y1))
|
|
|
- {
|
|
|
- glVertex3d(x1, y1, z);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- glEnd();
|
|
|
- }
|
|
|
-
|
|
|
- glColor3f(1,1,1);
|
|
|
- it=nodes.begin();
|
|
|
- for(it;it!=nodes.end();it++)
|
|
|
- {
|
|
|
- PathMap::MapNode node=it->second;
|
|
|
-
|
|
|
- char idx[16]={0};
|
|
|
- sprintf(idx,"%d",it->first);
|
|
|
- text_font->Text(idx).Draw(node.x,node.y,z);
|
|
|
- }
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-void DrawCloud(pcl::PointCloud<PointType>::Ptr cloud,
|
|
|
- double r,double g,double b,double psize,double alpha)
|
|
|
-{
|
|
|
- glPointSize(psize);
|
|
|
- glBegin(GL_POINTS);
|
|
|
- glColor4f(r, g, b, alpha);
|
|
|
- for (int i = 0; i < cloud->size(); ++i)
|
|
|
- {
|
|
|
- PointType pt = cloud->points[i];
|
|
|
- glVertex3d(pt.x , pt.y , pt.z );
|
|
|
-
|
|
|
- }
|
|
|
- glEnd();
|
|
|
-}
|