本篇主要介绍开发过程中的一些注意事项,具体代码没有涉及
一、 版本说明
在后续的项目进展中,由于使用到pcl、vtk等三方库,查阅了各方资料,发现pyqt和pcl和vtk库总是报各种版本不兼容,或者缺失某文件的错误。所以最终还是采用c++去整体开发,这里归总一下所使用的各种库的版本:opencv4.5.5、pcl1.11.0、vtk8.2.0、qt5 5.12.8、boost1.71.0 。
注意:opencv下载的时候一定要记得将对应版本的contrib一起下载,然后一起编译。contrib是opencv里的一些没有版权的算法,比如我这儿所用到的pdf算法,所以opencv官方没有在release版本中包含contrib,即使你可能用不到某些算法,但是也建议你一块儿下载。
我是单独重新下载的contrib,但是在编译的时候,总是会报错,最终是卸载了opencv,重装,编译,然后成功的。(opencv编译极其繁琐,建议多看看相应的教程,一步步对照着来)
需要单独说明一下的是qt,本项目依然和上一篇文章一样,用qt designer写一个界面,然后把.ui .qrc文件拖入文件根目录下,引入vtk是为了在界面中显示点云结果,并实现拖拽,放大等操作,所以qt的版本和vtk的版本必须兼容,经常尝试发现vtk8.2.0、qt5 5.12.8可以兼容,但是会有警告即vtk版本过低,一些函数不再使用等,如果有其他的同学发现了更好的版本选择欢迎留言。
二、 开发说明
2.1 dlp4500开发说明
二次开发中比较麻烦的就是dlp4500,因为官方给的api是windows的,Linux需要自己写,但是查看dlp4500的源码会发现,其中使用的接口如:libusb、qt这些都是支持Linux版本的,所以dlp4500是可以支持Linux直接开发的。我们采用的依然是usb接口,i2c尝试过,但是通过c++代码在寄存器写入值的时候会报错,python下写入却不会报错,这个问题困扰了很久,最终决定采用usb。
第一次通过usb开发dlp4500的时候,Linux里会报找不到dlp4500这个设备的错误,这个时候需要改写对应的.rules文件。首先进入/etc/udev/rules.d创建一个dlp4500.rules文件,内容如下
# for libusb, kernel v < 2.6.24
SUBSYSTEM=="usb_device", ACTION=="add", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="6401", GROUP="plugdev", MODE="0666"
# for libusb, kernel v > 2.6.24
SUBSYSTEM=="usb", ACTION=="add", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="6401", GROUP="plugdev", MODE="0666"
# for hidraw version of hidapi
KERNEL=="hidraw*", ATTRS{busnum}=="1", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="6401", GROUP="plugdev", MODE="0666"
保存之后,插拔dlp4500的usb接口线,如果依然报找不到,重启系统即可。
然后就是usb接口函数。当初在这儿卡顿了很久,一直报找不到库函数的错误,开始以为是库函数链接的问题,后来发现是hidapi库的hid.c文件在三个平台上都叫这名儿,但是Linux下要用源码Linux文件夹下的hid.c文件,其他平台下的hid.c不可以。(这儿这个错误发生原因是因为搞dlp4500代码移植的时候,是从Windows上移植的,一个粗心结果造成了大麻烦)
简单的介绍一下,hidapi是一个控制hid设备的库函数,使用起来也很简单,将libhidapi-hidraw.so和libhidapi-libusb.so文件复制到lib文件夹下,hid.c、dlpc350_usb.cpp、dlpc350_common.cpp 、dlpc350_api.cpp复制到src文件夹下(2.2节有说明),将以下头文件复制到include文件夹下,有关dlpc350的代码文件都可以直接在Windows上给出的源码文件夹下找到。具体控制代码可以参考给出的Windows的gui源码进行模仿更改。(不是很难,但是需要花一定的时间)
然后就是大恒相机的开发,在接口上没什么注意的,只是需要看一看,你的开发板上的usb接口是不是3.0的,如果不是,运行代码会报找不到相机的错。
比较麻烦的一点是,大恒相机的库函数在Linux上不是很方便,因为给的示例是windows的,唯一给的Linux示例也是在qt上直接开发。由于我们采用的是jetson orin nano开发板,完整的qt占用内存太大,而且qt上写c++代码也不是很舒服,因此摸索了一套在vscode里面通过cmake添加大恒库函数的方法。这里需要注意一下,大恒给的支持Linux的库函数只有c开发的那一个,即GXIAPI,但用来写c++问题也不大。
2.2 链接三方库函数
为了方便管理,创建include文件夹放头文件,src文件夹放源代码,lib文件夹放三方库,build文件夹放编译文件。
首先将对应的头文件,gxiapi.h和dximageproc.h移动到对应的目录下,我是放在了和src源代码同级的include文件夹下,然后将gxiapi.so放在lib文件夹下(三方库文件在Windows是lib后缀文件,Linux是.so文件),接着创建CmakeLists.txt文件。
注意:vscode上链接三方库有两种方法,第一种是通过vscode创建task.json、launch.json、c_cpp_properties.json文件,第二种是通过cmake。第一种建议去看第一个链接的帖子,写的很详细,只是没有涉及到多个三方库的链接办法,具体的用法可以在第二个官方文档上学习。我这儿贴出我用这种方法写的task.json配置文件和c_cpp_properties.json文件
"args": [
"-fdiagnostics-color=always",
"-g",
"${fileDirname}/*.cpp",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"-I","${workspaceFolder}/",
"-I","${workspaceFolder}/src/","-I","${workspaceFolder}/lib/",
"-L","${workspaceFolder}/lib/",
"${workspaceFolder}/lib/libgxiapi.so",
{
"configurations": [
{
"name": "linux-gcc-arm64",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "linux-gcc-arm64",
"compilerPath": "/usr/bin/gcc"
}
],
"version": 4
}
Get Started with C++ and MinGW-w64 in Visual Studio Code
到这儿大恒相机在Linux上的配置也就完成了。
第二种方法的学习建议去camke官网上下载给出的cmake指令学习压缩包,跟着每一个step做一遍,cmake也就基本上没问题了(第一个链接),有不懂的可以跟着b站的无限十三,对照的做一遍(强推这个up,讲的很好)。我这儿也推荐使用cmake方式去链接三方库,虽然cmake指令学习起来很繁琐,但是在大型项目中,第一种方法太冗杂了,并且cmake三方平台都支持,后续的代码移植也方便一点,第二种方法对比下来就方便的多。
CMake Tutorial — CMake 3.30.0 Documentation
简单来说cmake编译、链接代码的一个工具,这个工具又通过CmakeLists.txt文件去具体的控制代码的一些操作。这儿用vs studio链接库和包含头文件目录来做一个简单的类比,vs studio通过属性管理器的链接器,vc++目录等具体的链接三方lib库、引入头文件,而Linux下的cmake是通过指令实现的(例如find_package(OpenCV 4.5.5 REQUIRED)),推荐在大型项目的库引用中,用find_package指令,具体用法以及含义推荐参考
“轻松搞定CMake”系列之find_package用法详解_findpackage 环境变量-CSDN博客
这儿给出CmakeLists.txt文件的常规写法
# 1、 给出版本需求和需要编译的项目名称
cmake_minimum_required(VERSION 3.10)
project(binpicking)
# 2、设置头文件目录(如果没有include文件夹就没有这句代码)
include_directories(${CMAKE_SOURCE_DIR}/include)
# 3、添加库前缀路径(这是为了保证cmake在查找默认路径找不到库文件的时候,额外再去这个路径找)
#由于我们使用的是jetson nano开发板,官方预先安装的一些库就在"/usr/lib/aarch64-linux-gnu"下
list(APPEND CMAKE_PREFIX_PATH "/usr/lib/aarch64-linux-gnu")
# 4、搜索src目录下的所有cpp和c文件
file(GLOB_RECURSE SOURCES "src/*.c" "src/*.cpp")
file(GLOB_RECURSE FORMS "src/*.ui")
file(GLOB_RECURSE RESOURCES "src/*.qrc")
# 5、添加可执行文件
add_executable(binpicking ${SOURCES} ${FORMS} ${RESOURCES})
# 6、查找并配置所需的库(一般来说,主流的一些库函数都会给出xxxConfig.cmake文件,find_package函数其实
# 也就是找的这个文件,这个文件可以简单的理解成,库函数官方帮你配置链接环境,这就为linux下的开发提供# 了很大的便利
find_package(OpenCV 4.5.5 REQUIRED)
find_package(PCL 1.11.0 REQUIRED)
#7、包含头文件目录
target_include_directories(binpicking PRIVATE ${OpenCV_INCLUDE_DIRS}
${VTK_INCLUDE_DIRS})
# 8、链接库
target_link_libraries(binpicking PRIVATE
${OpenCV_LIBS} # 第一种方法
"${CMAKE_SOURCE_DIR}/lib/libgxiapi.so" # 第二种方法
)
其他的三方库引用也类似,除了版本兼容问题,其他问题都可以通过这种方式去链接三方库。