瓜大无人船使用踩坑记
目錄libusb解決方案geographic_msgs解決方案libgps解決方案自定義消息編譯時提示找不到.h頭文件PS3 Controller & usb.h解決方案CMakeList編寫bluetooth.h解決方案cwiid.h解決方案1解決方案2后記
Don't get suckered in by the comments - they can be terribly misleading. Debug only the code. —— Dave Storer
libusb
Checking for one of the modules 'libusb' CMake Error at /usr/share/cmake-3.5
None of the required 'libusb' found
解決方案
下載libusb
https://github.com/libusb/libusb
編譯及安裝
進入目錄,shell下依次執行下列命令。
執行:./configure
提示:
configure: error: “udev support requested but libudev not installed”
解決:
sudo apt-get install libudev-dev
執行:make
提示:
‘aclocal-1.14’ is missing on your system.
解決:
sudo apt-get install automake
sudo apt-get install libtool
sudo autoreconf -ivf
make
安裝:sudo make install
libusb-1.0.a 和 libusb-1.0.so 被安裝到 /usr/local/lib/ 目錄
libusb.h 被安裝到 /usr/local/include/libusb-1.0/ 目錄
確認安裝libusb包后,xxx包空間,catkin_make還是找不到libusb???
主要原因如下:
查看/usr/local/lib,安裝的libusb的二進制文件名稱為 libusb-1.0.so
查看joystick_drivers中的CMakeLists.txt中pkg_search_module(LIBUSB REQUIRED libusb),libusb應該修改成libusb-1.0,這樣才能與/usr/local/lib相符
geographic_msgs
【Debug】:ros :Could not find a package configuration file provided by "geographic_msgs"
詳細描述:
Could not find the required component 'geographic_msgs'. The following CMake error indicates that you either need to install the package with the same name or change your environment so that it can be found.
CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cmake:83 (find_package):
Could not find a package configuration file provided by "geographic_msgs"
with any of the following names:
geographic_msgsConfig.cmake
geographic_msgs-config.cmake
Add the installation prefix of "geographic_msgs" to CMAKE_PREFIX_PATH or
set "geographic_msgs_DIR" to a directory containing one of the above files.
If "geographic_msgs" provides a separate development package or SDK, be
sure it has been installed.
解決方案
sudo apt-get install ros-kinetic-geographic-msgs
libgps
ros No package 'libgps' found‘
解決方案
sudo apt-get install libgps-dev
自定義消息編譯時提示找不到.h頭文件
在我們擁有多個package的時候,我們定義了一個消息或者服務,并在代碼中使用了這個消息或者服務。如果是單獨編譯這個包,編譯通過。但是如果是多個包一起編譯,就會出現找不到相關頭文件的錯誤。
原因: 編譯時未按照嚴格順序進行編譯
解決辦法:在使用自定義消息或者服務的包中,修改CMakeLists.txt,增加如下內容
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
作用:讓編譯器知道,編譯some_target時,需要注意編譯順序
PS3 Controller & usb.h
sixpair.c:23:17: fatal error: usb.h: No such file or directory.
include <usb.h>
Compilation terminated
解決方案
sudo apt-get install libusb-dev
CMakeList編寫
一、 概述
CMake構建系統通過ROS包中的CMakeList.txt來構建軟件包?;ハ嘁蕾嚨陌及粋€或者多個CMakeList.txt來描述如何編譯代碼和如何安裝。在catkin 項目中,CMakeList.txt 符合標準的vanilla CMakeList.txt 格式,但稍微有點不同。
二、 整體結構和命令一覽
在編寫CMakeLists.txt時必須遵循特定的格式,否則軟件包將無法正確構建和編譯。一個完整的ROS下CMakeList.txt由下面內容組成
所需CMake版本(cmake_minimum_required)
軟件包名稱(project())
查找構建所需的其他CMake / Catkin軟件包(find_package())
啟用Python模塊支持(catkin_python_setup())
消息/服務/動作生成器(add_message_files(),add_service_files(),add_action_files())
生成消息/服務/動作等自定義消息(generate_messages())
指定包的構建信息輸出(catkin_package())
要建立的庫/可執行文件(add_library()/ add_executable()/ target_link_libraries())
測試(catkin_add_gtest())
安裝規則(install())
三、 CMake版本
CMakeLists.txt文件必須以CMake的版本開頭。下面表示的是Catkin需要2.8.3或更高的版本。
cmake_minimum_required(VERSION 2.8.3)
四、 軟件包名稱
繼而需要指定CMake工程名,一般取作包名。例如我們的項目名叫做robot_brain
project(robot_brain)
而在CMake中,可以在CMake文本中使用變量${PROJECT_NAME}來引用項目名稱。
五、 查找相關的CMake包
接下來我們要用find_package指令來指定在構建項目過程中依賴了哪些其他的包,在ROS中,catkin必備依賴,所以雷打不打地我們寫上catkin REQUIRED:
find_package(catkin REQUIRED)
在此基礎上,如果我們還需要依賴其他包(或者組件),我們就在 上述的包后面繼續添加包(組件)名即可:
find_package(catkin REQUIRED COMPONENTS nodelet)
或者可以寫成
find_package(catkin REQUIRED)
find_package(nodelet REQUIRED)
值得注意一點的是:這里添加的包用于構建包使用,而不是添加運行時依賴項。
你也可以做:
find_package(catkin REQUIRED)
find_package(nodelet REQUIRED)
如何寫,看個人習慣吧,如果不考慮篇幅,其實我更喜歡把所有包(組件)列成一列,直觀。在普通的CMakeLists.txt中是沒有find_package()的,那么,catkin中的這個語句有啥作用呢?
5.1 那find_package()作何用?
如果CMake通過find_package找到一個包,則會自動生成有關包所在路徑的CMake環境變量,環境變量描述了包中頭文件的位置,源文件的位置,包所依賴的庫以及這些庫的路徑。
這些變量名稱以< PACKAGE NAME >_< PROPERTY >的形式出現:
- < NAME >_FOUND - 如果找到庫,則設置為true,否則為false
- < NAME > _INCLUDE_DIRS或<NAME> _INCLUDES - 包導出的包含路徑
- < NAME > _LIBRARIES或<NAME> _LIBS - 由包導出的庫
- < NAME > _DEFINITIONS - ?
- ...
5.2為啥Catkin包是組件形式?
實際上,Catkin的包并不是catkin的真正組成部分。而catkin采用CMake的組件功能,主要是為了節省打字時間。
將Catkin的包作為一種組件看待是很有好處的,當你找到包的時候,各種以catkin為前綴的添加到CMakeLists.txt中了。以前述nodelet包為例:
find_package(catkin REQUIRED COMPONENTS nodelet)
catkin執行到這個語句時,就會導出的nodelet的include路徑,庫等也添加到catkin前綴的變量中。例如,catkin_INCLUDE_DIRS不僅包含catkin的include路徑,還包含了nodelet,這在后面會用到。
當然,我們可以只選擇找nodelet的:
find_package(nodelet)
很可惜這樣的做法會令nodelet路徑,庫等不會被添加到catkin變量中,從而生成了例如nodelet_INCLUDE_DIRS,nodelet_LIBRARIES這樣的變量等。
5.3Boost庫
如果使用C ++和Boost,則需要用find_package()來找Boost庫,并指定Boost中的組件。 舉個栗子,如果想使用Boost線程,就可以寫成:
find_package(Boost REQUIRED COMPONENTS thread)
六、catkin_package()
catkin_package()是一個catkin提供的CMake宏,用于將catkin特定的信息信息輸出到構建系統上,用于生成pkg配置文件以及CMake文件。
這個命令必須在add_library()或者add_executable()之前調用,該函數有5個可選參數:
INCLUDE_DIRS - 導出包的include路徑
LIBRARIES - 導出項目中的庫
CATKIN_DEPENDS - 該項目依賴的其他catkin項目
DEPENDS - 該項目所依賴的非catkin CMake項目。
CFG_EXTRAS - 其他配置選項
舉個栗子:
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
CATKIN_DEPENDS roscpp nodelet
DEPENDS eigen opencv)
這表示包文件夾中的文件夾“include”是導出頭文件的地方。 ${PROJECT_NAME}根據project中的內容生成,此處是rrobot_brain?!皉oscpp”+“nodelet”是用來構建/運行此程序包的catkin包,而“eigen”+“opencv”是用于構建/運行此程序包的非catkin包。
七、指定構建目標
構建目標可以有多種形式,但通常主要有以下兩種:
執行文件目標 - 可以運行的程序
庫目標 - 可在構建和/或運行時給可執行目標使用的庫
7.1目標命名
值得重點關注的是,catkin中的構建目標的名稱必須是唯一的,但是,但構建目標命名的唯一性只能在CMake內部進行。可以使用set_target_properties()函數將目標重命名為其他目標:
再舉個栗子:
set_target_properties(rviz_image_view
PROPERTIES OUTPUT_NAME image_view
PREFIX "")
這時就將rviz_image_view的名稱更改為image_view了。
7.2自定義輸出目錄
一般情況下,令輸出目標目錄保持默認就可以了,但有時遇到一些特定情況就得因地制宜。再再舉個栗子,一個包含了Python bindings的庫必須防止在不同的文件夾,才能夠被導入Python中,因此可以通過下述方式進行:
set_target_properties(python_module_library
PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_PYTHON_DESTINATION})
7.3包含路徑和庫路徑
在生成目標之前,請記得先寫好包含路徑和庫路徑,不然編譯會失敗。
包括路徑 - 頭文件
庫路徑 - 構建對象需要用到的庫
include_directories(<dir1>,<dir2>,...,<dirN>)
link_directories(<dir1>,<dir2>,...,<dirN>)
7.3.1 include_directories()
include_directories()中的參數應該是調用find_package調用時生成的* _INCLUDE_DIRS變量。 如果使用catkin和Boost,那么include_directories()調用應該如下所示:
include_directories(include ${Boost_INCLUDE_DIRS} ${catkin_INCLUDE_DIRS})
第一個參數“include”表示包中的include /目錄也是路徑的一部分。
7.3.2 link_directories()
link_directories()函數可用于添加額外的庫路徑,但通常不推薦這樣做,因為 所有catkin和CMake軟件包在find_packaged時都會自動添加鏈接信息。 只需寫target_link_libraries()中就可以了。但真要寫,就按照下面那樣來寫:
link_directories(~/my_libs)
7.4 可執行目標
要指定必須構建的可執行目標,我們必須使用add_executable()CMake函數。
add_executable(myProgram
src/main.cpp
src/some_file.cpp)
構建myProgram的目標可執行文件,3個源文件構建:src / main.cpp,src / some_file.cpp和src / another_file.cpp。
7.5 庫目標
add_library() 用于指定要構建的庫。
add_library(${PROJECT_NAME} ${${PROJECT_NAME}_SRCS})
7.6 target_link_libraries()
target_link_libraries()來指定可執行目標鏈接的庫。 通常在add_executable()調用之后完成。 如果找不到ros,則添加$ {catkin_LIBRARIES}。
target_link_libraries(<executableTargetName>, <lib1>, <lib2>, ... <libN>)
add_executable(foo src/foo.cpp)
add_library(moo src/moo.cpp)
target_link_libraries(foo moo) -- This links foo against libmoo.so
請注意,在大多數情況中不需要使用link_directories(),因為find_package()自動拉入。
八、消息、服務和響應
消息(.msg),服務(.srv)和響應(.action)文件在ROS包構建和使用之前需要一個特殊的預處理器構建步驟。 這些宏的要點是生成編程語言特定的文件,以便可以利用其選擇的編程語言中的消息,服務和動作。 構建系統將使用生成器(例如gencpp,genpy,genlisp等)生成綁定。
提供了三個宏來分別處理消息,服務和響應:
add_message_files
add_service_files
add_action_files
而在之后必須在下面寫下面宏,catkin時候會在devel的include文件夾中生成對應的頭文件:
generate_messages()
8.1 使用條件
為了能夠正常生成相應的文件,這些宏必須在catkin_package()宏之前,
find_package(catkin REQUIRED COMPONENTS ...)
add_message_files(...)
add_service_files(...)
add_action_files(...)
generate_messages(...)
catkin_package(...)`
在catkin_package()宏中寫上CATKIN_DEPENDS message_runtime
catkin_package(
...
CATKIN_DEPENDS message_runtime ...
...)
并且在find_package()寫上message_generation組件:
find_package(catkin REQUIRED COMPONENTS message_generation)
package.xml文件中加上
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
如果構建的對象依賴于其他需要構建消息/服務/響應的構建對象,則需要向目標catkin_EXPORTED_TARGETS添加明確的依賴關系,以便它們以正確的順序構建。 這種情況比較常用,除非您的包真的不使用ROS的任何部分。 但這種依賴關系不能自動傳遞。 (some_target是由add_executable()設置的目標的名稱):
add_dependencies(some_target${catkin_EXPORTED_TARGETS})
如果需要構建消息或服務的包以及使用這些消息和/或服務的可執行文件,則需要為自動生成的消息目標創建明確的依賴關系,以便以正確的順序構建它們。 (some_target是由add_executable()設置的目標的名稱):
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS})
如果您的catkin包滿足上述兩個條件,則需要添加以下兩個依賴關系,即:
add_dependencies(some_target ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
8.2 例子
現在有兩個依賴于std_msgs和sensor_msgs的消息MyMessage1.msg和MyMessage2.msg,還有一個自定義服務MyService.srv, message_program是使用這些消息和服務的指令,以及生成不使用自定義消息、服務的程序do_not_use_local_messages_programcatkin包,那么CMakeLists.txt應該寫成:
######## 構建時依賴項 find_package(catkin REQUIRED COMPONENTS message_generation std_msgs######## 聲明要構建哪些消息
add_message_files(FILES
MyMessage1.msg
MyMessage2.msg)######## 聲明構建哪些服務
add_service_files(FILES
MyService.srv)######## 聲明生成上述消息、服務需要依賴的消息以及服務
generate_messages(DEPENDENCIES
std_msgs
sensor_msgs)######## 聲明運行時依賴項
catkin_package(CATKIN_DEPENDS
message_runtime
std_msgs sensor_msgs)######## 聲明構建生成的可執行文件名稱以及依賴項
add_executable(message_program src/main.cpp)
add_dependencies(message_program ({){PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
######## 聲明構建不需要使用自定義消息、服務的可執行文件
add_executable(does_not_use_local_messages_program src/main.cpp)
add_dependencies(does_not_use_local_messages_program ${catkin_EXPORTED_TARGETS})
如果要構建響應,則在包中“action”目錄中創建有一個名為“MyAction.action”的文件,則必須將actionlib_msgs添加到使用catkin進行find_package的組件列表中,然后在CMakeList.txt中加上下面兩行:
add_action_files(FILES
MyAction.action)
此外,該包必須具有對actionlib_msgs的構建依賴。
九、啟用Python模塊支持
如果catkin包使用一些Python模塊,您應該創建一個setup.py文件,并在調用catkin_python_setup()之后調用generate_messages()和catkin_package()。
十、單位測試
有一個catkin-specific宏用于處理名為catkin_add_gtest()的基于gtest的單元測試。
catkin_add_gtest(myUnitTest test / utest.cpp)
十一、可選步驟:指定可安裝的目標
構建后,構建目標通常被放置在catkin工作區中。但有時候我們希望將目標安裝到系統其他地方(有關安裝路徑的信息可以在REP 122中找到),以便其他人或本地文件夾可以使用它們來測試。換句話說,如果你想要做一個“make install”的代碼,你需要指定目標應該生成到哪里。
這是使用CMake install()函數作為參數完成的:
目標 - 目標是安裝
ARCHIVE DESTINATION - 靜態庫和DLL(Windows).lib存根
LIBRARY DESTINATION - 非DLL共享庫和模塊
RUNTIME DESTINATION - 可執行目標和DLL(Windows)樣式共享庫
舉個栗子:
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
除了這些標準目標,一些文件必須安裝到特殊文件夾。即一個包含Python綁定的庫必須安裝到不同的文件夾中才能在Python中導入:
install(TARGETS python_module_library
ARCHIVE DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_PYTHON_DESTINATION}
)
11.1 安裝Python可執行腳本
對于Python代碼,安裝規則看起來是不同的,因為沒有使用add_library()和add_executable()函數,以便CMake確定哪些文件是目標以及它們是什么類型的目標。 而是在您的CMakeLists.txt文件中使用以下內容:
catkin_install_python(PROGRAMS scripts/myscript
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
有關安裝python腳本和模塊的詳細信息以及文件夾布局的最佳做法,請參見catkin手冊。
如果您只安裝Python腳本并且不提供任何模塊,則不需要創建上述setup.py文件,也不需要調用catkin_python_setup()。
11.2 安裝頭文件
標題文件也必須安裝到“include”文件夾中,這通常是通過安裝整個文件夾的文件來完成的(可選地,按文件名模式過濾,不包括SVN子文件夾)。 這可以通過如下所示的安裝規則完成:
install(DIRECTORY include/{CATKIN_PACKAGE_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)
或者如果包含的子文件夾與包名稱不匹配:
install(DIRECTORY include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
PATTERN ".svn" EXCLUDE
)
11.3 安裝roslaunch文件或其他資源
其他資源(如啟動文件)可以安裝到
$ {CATKIN_PACKAGE_SHARE_DESTINATION
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch
PATTERN ".svn" EXCLUDE)
參考文章:
1.ROS中的CMakeLists.txt
2.catkinCMakeLists.txt
bluetooth.h
.../joystick_drivers-master/wiimote/include/wiimote/wiimote_controller.h:49:10: fatal error: bluetooth/bluetooth.h: No such file or directory
#include <bluetooth/bluetooth.h> // libbluetooth.so
^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/build.make:62: recipe for target 'turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/src/wiimote_controller.cpp.o' failed
make[2]: *** [turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/src/wiimote_controller.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
解決方案
sudo apt-get install libbluetooth-dev
cwiid.h
/joystick_drivers-master/wiimote/include/wiimote/wiimote_controller.h:52:10: fatal error: cwiid.h: No such file or directory
#include <cwiid.h> // libcwiid.so
^~~~~~~~~
compilation terminated.
turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/build.make:62: recipe for target 'turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/src/wiimote_controller.cpp.o' failed
make[2]: *** [turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/src/wiimote_controller.cpp.o] Error 1
CMakeFiles/Makefile2:44715: recipe for target 'turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/all' failed
make[1]: *** [turtlebot2/joystick_drivers-master/wiimote/CMakeFiles/wiimote_node.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
解決方案1
(未測試的解決方案)
sudo apt-get install libcwiid-dev
解決方案2
【已測試但效果未知(報錯,但多次重復后編譯結束)】
下載
https://github.com/abstrakraft/cwiid/tree/master
編譯安裝
aclocal
autoconf
./configure
make
sudo make install
注意:
當執行./configure時,出現如下錯誤configure: error: flex not found
$ ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gawk... no
checking for mawk... mawk
checking for flex... no
checking for lex... no
configure: error: flex not found
應安裝flex:
sudo apt-get install flex
提示error: bison not found
應安裝bison
sudo apt-get install bison byacc
aclocal與autoconf
下載三個包:autoconf-2.68.tar.bz2、automake-1.11.1.tar.bz2、m4-1.4.14.tar.bz2,注意安裝順序。
su - root
tar xjf XXXXX.tar.bz2
cd m4/
./configure make make install
cd autoconf/
./configure make make install
cd automake/
./configure make make install
exit
特別注意:
編譯安裝m4-1.4.16.tar.gz,出現問題:
./configure
make
報錯提示:
error: 'gets' undeclared here (not in a function)
解決辦法:
gedit lib/stdio.in.h
查找字段:gets is a security hole
將_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); 字段和他之前的注釋 /* 一塊注釋掉,如下
/* It is very rare that the developer ever has full control of stdin,
so any use of gets warrants an unconditional warning. Assume it is
always declared, since it is required by C89.
#undef gets
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); */
再添加如下內容:
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !__GLIBC_PREREQ(2, 16)
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
#endif
再重新編譯安裝
make
make install
附注:
查看是否安裝成功cwiid.h的方法:
$ whereis cwiid.h
cwiid: /usr/local/etc/cwiid /usr/local/lib/cwiid
后記
在苦逼實驗中,爛慫無人船上發生的奇葩問題都會被記錄在此。
現在的淚就是當年腦袋進的水。
總結
以上是生活随笔為你收集整理的瓜大无人船使用踩坑记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ABAP Business switc和
- 下一篇: 获取application server