SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误

今天动手运行了高翔《视觉SLAM十四讲》第3讲“三维空间刚体运动”中的代码部分,前面的部分非常顺利,但是到了3.7节可视化演示的部分,出现了非常棘手的问题,大约画了3个小时的时间才解决。趁热乎记录一下,并且把最终实现的代码贴在本博客中,以便于后面踩坑的时候能及时解决。

坑1:undefined reference to symbol

最主要的坑就是标题所示的那个:

undefined reference to symbol ‘glTexImage2D‘

完整的报错类似:

undefined reference to symbol 'glTexImage2D'
error adding symbols: DSO missing from

搜了一下原因,这篇博客写的比较清楚。最终,我采用了他所说的“可能是因为make编译未找到链接的共享库 LibGL.so文件 ,我们可以在CMakeLists.txt文件中的 target_link_libraries 语句中添加 LibGL.so”这个方法,事实证明是很管用的。具体来说,就是在CMakeLists.txt中添加这一句话:

target_link_libraries(plotTrajectory GL)

坑2:findPackage没有找到package

可能是因为路径的问题,源代码中的findpackage没有找到pangolin的头文件和库文件,于是会报类似下的错误:

undefined reference to 'panbolin'::CreateWindowAndBind(std...........blabla)

这显然是引用失败,我自己写了findPangolin.cmake文件(详情见下方),并且按照截图的方式组织的工程结构如下。
SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误_第1张图片
./cmake/FindPangolin.cmake

find_path(PANGOLIN_INCLUDE_DIR
	NAMES pangolin.h
	PATHS "/usr/local/include/pangolin/"
	)

find_library(PANGOLIN_LIBRARY
	NAMES pangolin
	PATHS "/usr/local/lib/"
	)

MESSAGE("THIS IS A DEBUG INFO.")
MESSAGE("${PANGOLIN_INCLUDE_DIR}")
MESSAGE("${PANGOLIN_LIBRARY}")
IF (PANGOLIN_INCLUDE_DIR AND PANGOLIN_LIBRARY)
	SET(PANGOLIN_FOUND TRUE)
	MESSAGE("PANGOLIN FOUND = TRUE")
ENDIF (PANGOLIN_INCLUDE_DIR AND PANGOLIN_LIBRARY)

IF (PANGOLIN_FOUND)
	IF(NOT PANGOLIN_FIND_QUIETLY)
		MESSAGE(STATUS "FOUND PANGOLIN_LIB:${PANGOLIN_LIBRARY}")
	ENDIF(NOT PANGOLIN_FIND_QUIETLY)
ELSE (PANGOLIN_FOUND)
	IF(PANGOLIN_FIND_REQUIRED)
		MESSAGE(FATAL_ERROR "COULD NOT FIND PANGOLIN LIBRARY.")
	ENDIF(PANGOLIN_FIND_REQUIRED)
ENDIF(PANGOLIN_FOUND)

./CMakeLists.txt

cmake_minimum_required( VERSION 2.8 )
set( CMAKE_BUILD_TYPE "Debug")
project(plotTrajectory)
set(CMAKE_MODULE_PATH ~/slam/examplesInTheBook/Chapter3/plotTrajectory/cmake)
MESSAGE("IWUCH DEBUG PROJECT_MODULE_PATH:${CMAKE_MODULE_PATH}")

find_package(Pangolin REQUIRED)

if(PANGOLIN_FOUND)
	include_directories(${PANGOLIN_INCLUDE_DIR})
	add_executable(plotTrajectory plotTrajectory.cpp)
	target_link_libraries(plotTrajectory ${PANGOLIN_LIBRARY})
	target_link_libraries(plotTrajectory GL)
else(PANGOLIN_FOUND)
	message(FATAL_ERROR " PANGOLIN LIBRARY NOT FOUND.")
endif(PANGOLIN_FOUND)

include_directories("/usr/local/include/eigen3")

坑三:文件路径无法读取

源代码中给的trajectory.txt路径无法使用,我最终暴力给了绝对路径,当然也可以使用相对路径,这个地方可以研究一下,应该有简单的方法可以学一学。

string trajectory_file = "/home/robotlab1/slam/examplesInTheBook/Chapter3/plotTrajectory/trajectory.txt";

最终我使用的源代码如下,有些多余的代码是在调试过程中增加的。

plotTrajctory.cpp

#include 
#include 
#include 
#include 

// extern "C"{
// #include
// }

// 本例演示了如何画出一个预先存储的轨迹

using namespace std;
using namespace Eigen;
using namespace pangolin;

// path to trajectory file
string trajectory_file = "/home/robotlab1/slam/examplesInTheBook/Chapter3/plotTrajectory/trajectory.txt";

void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>>);

int main(int argc, char **argv) {

  vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;
  ifstream fin(trajectory_file);
  if (!fin) {
    cout << "cannot find trajectory file at " << trajectory_file << endl;
    return 1;
  }

  while (!fin.eof()) {
    double time, tx, ty, tz, qx, qy, qz, qw;
    fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw;
    Isometry3d Twr(Quaterniond(qw, qx, qy, qz));
    Twr.pretranslate(Vector3d(tx, ty, tz));
    poses.push_back(Twr);
  }
  cout << "read total " << poses.size() << " pose entries" << endl;

  // draw trajectory in pangolin
  DrawTrajectory(poses);
  return 0;
}

/*******************************************************************************************/
void DrawTrajectory(vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses) {
  // create pangolin window and plot the trajectory
  pangolin::CreateWindowAndBind("Trajectory Viewer", 1024, 768);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  pangolin::OpenGlRenderState s_cam(
    pangolin::ProjectionMatrix(1024, 768, 500, 500, 512, 389, 0.1, 1000),
    pangolin::ModelViewLookAt(0, -0.1, -1.8, 0, 0, 0, 0.0, -1.0, 0.0)
  );

  pangolin::View &d_cam = pangolin::CreateDisplay()
    .SetBounds(0.0, 1.0, 0.0, 1.0, -1024.0f / 768.0f)
    .SetHandler(new pangolin::Handler3D(s_cam));

  while (pangolin::ShouldQuit() == false) {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    d_cam.Activate(s_cam);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glLineWidth(2);
    for (size_t i = 0; i < poses.size(); i++) {
      // 画每个位姿的三个坐标轴
      Vector3d Ow = poses[i].translation();
      Vector3d Xw = poses[i] * (0.1 * Vector3d(1, 0, 0));
      Vector3d Yw = poses[i] * (0.1 * Vector3d(0, 1, 0));
      Vector3d Zw = poses[i] * (0.1 * Vector3d(0, 0, 1));
      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();
    }
    // 画出连线
    for (size_t i = 0; i < poses.size(); i++) {
      glColor3f(0.0, 0.0, 0.0);
      glBegin(GL_LINES);
      auto p1 = poses[i], p2 = poses[i + 1];
      glVertex3d(p1.translation()[0], p1.translation()[1], p1.translation()[2]);
      glVertex3d(p2.translation()[0], p2.translation()[1], p2.translation()[2]);
      glEnd();
    }
    pangolin::FinishFrame();
    usleep(5000);   // sleep 5 ms
  }
}

SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误_第2张图片
SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误_第3张图片

最终的结果如下,几个小时的努力没有白费,还是很开心的_
SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误_第4张图片
同样的,我们重新修改visualizeGeometry这个工程中的CMakeList.txt和cmake目录下的FindPangolin.cmake文件,我们可以运行得到相机位姿的可视化表达,以及其对应的ERAQ(Eulerangle、Rotationmatrix、Axisangle、Quaternion)数值。
SLAMBOOK2踩坑记之:plotTrajectory.cpp中的undefined reference to symbol ‘glTexImage2D‘错误_第5张图片

你可能感兴趣的:(SLAM)