在ARM板上编译RGBDSLAM_V2 时出现如下错误:
/home/ninetripod/rgbdslam_catkin_ws/src/rgbdslam_v2-hydro/src/glviewer.cpp: In member function 'void GLViewer::drawOneCloud(int)':
/home/ninetripod/rgbdslam_catkin_ws/src/rgbdslam_v2-hydro/src/glviewer.cpp:341:75: error: invalid static_cast from type 'qreal* {aka float*}' to type 'GLdouble* {aka double*}'
/home/ninetripod/rgbdslam_catkin_ws/src/rgbdslam_v2-hydro/src/glviewer.cpp: In member function 'void GLViewer::drawClouds(float)':
/home/ninetripod/rgbdslam_catkin_ws/src/rgbdslam_v2-hydro/src/glviewer.cpp:377:64: error: invalid static_cast from type 'qreal* {aka float*}' to type 'GLdouble* {aka double*}'
/home/ninetripod/rgbdslam_catkin_ws/src/rgbdslam_v2-hydro/src/glviewer.cpp:416:75: error: invalid static_cast from type 'qreal* {aka float*}' to type 'GLdouble* {aka double*}'
make[2]: *** [rgbdslam_v2-hydro/CMakeFiles/rgbdslam.dir/src/glviewer.o] Error 1
make[1]: *** [rgbdslam_v2-hydro/CMakeFiles/rgbdslam.dir/all] Error 2
make: *** [all] Error 2
关于qreal与double不对应的问题,百思不得其解,后来在一位大神的帮助下终于得到了解决。
首先我们在QT的手册中看一下关于qreal关键字的说明:
Typedef for double unless Qt is configured with the-qreal float option.
意思是说,除非用户自己配置qreal为float,否则qreal将默认为double。
看到这,猜想或者头文件中代码中肯定有qreal的选项配置。
利用source insight将 /usr/include/qt4 目录下的所有头文件建立为一个工程,
接着在工程中搜索qreal关键字,最后在 /usr/include/qt4/Qt/qglobal.h 中找到了关于qreal的定义。
如下:
// This logic must match the one in qmetatype.h
#if defined(QT_COORD_TYPE)
typedef QT_COORD_TYPE qreal;
#elif defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) || defined(QT_ARCH_SYMBIAN)
typedef float qreal;
#else
typedef double qreal;
#endif
看到这就很清晰了,原来在arm中,qreal被定义为float类型,所以在编译的时候,类型为double的数据或者函数,就会与qreal关键字不匹配了。
这也就能解释为什么在电脑中编译的没问题(电脑中定义为double),但是在arm板中就会报一推错误。
经过后来的测试,发现下面这种方法无法从根本上解决问题。
我的解决办法是将上述头文件中的
typedef float qreal;
typedef double qreal;
这样在arm开发板中,qreal也会被定义为double,于是报错消失。
但是我不确定板子的是否能处理的过来这么多double类型的数据,想必qreal在qt中这样定义的目的也是为了避开arm处理能力有限的不足。
以下为正确解决方法
在源码的github的Issues中,我找到了维护者的答复,见下图:
大致意思为:将CMakelist.txt文件中的glviewer.cpp改为glviewer2.cpp,并且在glviewer2.cpp的第20行将
GLViewer::GLViewer(QWidget *parent) :QWidget(parent) { } 改为 GLViewer::GLViewer(QWidget *parent) :QGLWidget(parent) { }
按照这个方法操作一遍,问题解除。