// // Created by zx on 22-12-2. // #include "pangolinViewer.h" PangolinViewer* PangolinViewer::viewer_= nullptr; PangolinViewer* PangolinViewer::CreateViewer() { if (viewer_== nullptr) { viewer_=new PangolinViewer(); } return viewer_; } PangolinViewer::~PangolinViewer() { if(thread_!= nullptr) { if (thread_->joinable()) thread_->join(); delete thread_; thread_= nullptr; } } PangolinViewer::PangolinViewer() { thread_=new std::thread(&PangolinViewer::loop,this); } void PangolinViewer::Join() { if(thread_!= nullptr) { if (thread_->joinable()) thread_->join(); } } void PangolinViewer::SetAutoTestNavCallback(AutoTestBtnCallback callback) { navigation_AutoBtn_callback_=callback; } void PangolinViewer::SetNavigationCallbacks(StartBtnCallback startBtn, PauseBtnCallback pauseBtn, StopBtnCallback stopBtn) { naviagtion_startBtn_callback_=startBtn; naviagtion_pauseBtn_callback_=pauseBtn; navigation_stopBtn_callback_=stopBtn; } void PangolinViewer::SetCallbacks(ViewerSpinOnceCallback spinOnce,DijkstraBtnCallback dijkstra) { spinOnce_callback_=spinOnce; dijkstraBtn_callback_=dijkstra; } void PangolinViewer::ResetPathInfo(int beg,int end,float distance) { *beg_Int_=beg; *end_Int_=end; char cost[64]={0}; sprintf(cost, "d(%d-%d):%f", beg, end, distance); *distance_string_=cost; } void PangolinViewer::Init() { pangolin::CreateWindowAndBind("Main", 1280, 760); // 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); text_font_ = new pangolin::GlFont("../config/tt0102m_.ttf", 30.0); s_cam_=new pangolin::OpenGlRenderState( pangolin::ProjectionMatrix(1480, 760, 840, 840, 480, 380, 0.1, 1000), pangolin::ModelViewLookAt(25, 0, 90, 25, 0, 20, pangolin::AxisY) ); const int UI_WIDTH = 30 * pangolin::default_font().MaxWidth(); d_cam_ = &pangolin::CreateDisplay() .SetBounds(0.0, 1.0, pangolin::Attach::Pix(UI_WIDTH), 1.0, 1280.0f / 760.0f) .SetHandler(new pangolin::Handler3D(*s_cam_)); pangolin::CreatePanel("ui") .SetBounds(0.0, 1.0, 0.0, pangolin::Attach::Pix(UI_WIDTH)); timequeue_string_=new pangolin::Var("ui.tq_String", "timequeue_string"); xyz_string_=new pangolin::Var("ui.xyz_String", "xyz"); rpy_string_=new pangolin::Var("ui.rpy_String", "rpy"); velocity_string_=new pangolin::Var("ui.velocity", ""); beg_Int_=new pangolin::Var("ui.beg", 1, 0, 11); end_Int_=new pangolin::Var("ui.end", 10, 0, 11); v_=new pangolin::Var("ui.v", 1.0, -2.0,2.0 ); a_=new pangolin::Var("ui.a", 1.0, -10.0, 10.0); path_string_=new pangolin::Var("ui.path", "cost"); distance_string_=new pangolin::Var("ui.distance", "distance"); pangolin::Var> solve_view("ui.Solve", [&]() { if(dijkstraBtn_callback_!= nullptr) { auto start_tm = std::chrono::system_clock::now(); int node_beg = beg_Int_->Get(); int node_end = end_Int_->Get(); float distance=std::numeric_limits().max(); std::vector shortestPath; if(dijkstraBtn_callback_(node_beg,node_end,distance,shortestPath)) { shortest_path_=shortestPath; 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):%f", node_beg, node_end, distance); *distance_string_ = cost; auto end_tm = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(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; } } }); pangolin::Var> navigation_beg("ui.nav_Beg", [&]() { if(naviagtion_startBtn_callback_!= nullptr) naviagtion_startBtn_callback_(); }); pangolin::Var> navigation_pause("ui.nav_PAUSE", [&]() { if(naviagtion_pauseBtn_callback_!= nullptr) naviagtion_pauseBtn_callback_(); }); pangolin::Var> navigation_end("ui.nav_End", [&]() { if(navigation_stopBtn_callback_!= nullptr) navigation_stopBtn_callback_(); }); pangolin::Var> navigation_auto_test("ui.nav_auto_test", [&]() { if(navigation_AutoBtn_callback_!= nullptr) navigation_AutoBtn_callback_(); }); } void PangolinViewer::DrawCloud(PointCloud::Ptr cloud,double r,double g,double b, double alpha,double psize) { 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(); } void PangolinViewer::DrawTrajectory(const Trajectory& traj, double r,double g,double b,double ptsize) { glPointSize(ptsize); glBegin(GL_POINTS); glColor4f(r, g, b, 1); for (int i = 0; i < traj.size(); ++i) { Pose2d pt =traj[i]; glVertex3d(pt.x() , pt.y() , 0); } glEnd(); } void PangolinViewer::DrawDijkastraMap(PathMap& map,std::vector path) { //绘制顶点 std::map nodes=map.GetNodes(); std::map::iterator it=nodes.begin(); float z=0; glPointSize(10.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 edges=map.GetEdges(); for(int i=0;i0) { 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 PangolinViewer::ShowBrotherStatu(Eigen::Matrix4d pose,double velocity,double angular) { double l=2; 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); glVertex3d(Ow[0], Ow[1], Ow[2]); glVertex3d(Xw[0], Xw[1], Xw[2]); glColor3f(1.0, 1.0, 1.0); glVertex3d(Ow[0], Ow[1], Ow[2]); glVertex3d(Yw[0], Yw[1], Yw[2]); glColor3f(0, 1.0, 1.0); glVertex3d(Ow[0], Ow[1], Ow[2]); glVertex3d(Zw[0], Zw[1], Zw[2]); glEnd(); } void PangolinViewer::ShowRealtimeStatu(Eigen::Matrix4d pose,double velocity,double angular) { double l=10; 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(); Eigen::Matrix3d rotation = pose.topLeftCorner(3, 3); Eigen::Vector3d eulerAngle = rotation.eulerAngles(0, 1, 2); Eigen::Vector3d t = 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 twist[64]={0}; sprintf(twist,"vel:%.5f, \tagl:%.5f\n",velocity,angular); *velocity_string_=twist; } void PangolinViewer::loop(PangolinViewer* p) { if(p== nullptr) return ; p->Init(); while (!pangolin::ShouldQuit()) { // Clear entire screen glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*if (pangolin::Pushed(*p->start_button_)) { if (*p->lvx_checkbox_) { std::string file = p->lvx_file_->Get(); } else { } } if (pangolin::Pushed(*p->stop_button_)) { } if (p->freq_double_->GuiChanged()) { double publish_freq=p->freq_double_->Get(); }*/ if (p->d_cam_->IsShown()) { p->d_cam_->Activate(*p->s_cam_); pangolin::glDrawAxis(3);//三维坐标轴,红——x轴,绿——y轴,蓝——z轴 if(p->spinOnce_callback_!= nullptr) p->spinOnce_callback_(p); } pangolin::FinishFrame(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }