主页 > IT业界  > 

在已安装二进制movit2的情况下使用自编译moveit2

在已安装二进制movit2的情况下使用自编译moveit2
在已安装二进制movit2的情况下,想使用自编译moveit2,只要引入一下自编译moveit2库的环境变量即可。主要是想搞明白这个过程发生了什么,也就是引入环境后有什么变化,以及如何对编译过程产生影响 一、setup.bash流程 所有资料上都说setup.bash作用就是添加环境,其实就是将对应的地址添加到不同的环境变量当中了,这里主要想分析一下这个过程是如何实现的主要 关注的环境变量是LD_LIBRARY_PATH、CMAKE_PREFIX_PATH、AMENT_PREFIX_PATH 1、运行source ./install/setup.bash效果 ==========运行source ./install/setup.bash前========== ~/ws_moveit2$ echo $LD_LIBRARY_PATH /usr/local/etherlab/lib:/opt/ros/humble/opt/rviz_ogre_vendor/lib:/opt/ros/humble/lib/x86_64-linux-gnu:/opt/ros/humble/lib ~/ws_moveit2$ echo $CMAKE_PREFIX_PATH ~/ws_moveit2$ echo $AMENT_PREFIX_PATH /opt/ros/humble 运行后自己包中的所有lib文件就添加到LD_LIBRARY_PATH变量中,类似~/ws_moveit2/install/moveit_ros_planning_interface/lib的地址CMAKE_PREFIX_PATH和AMENT_PREFIX_PATH变量添加了很多类似~/ws_moveit2/install/moveit_ros_planning_interface的地址 2、./install/setup.bash文件分析 文件中用的是shell语言,跟命令行中用的一样。不过两个语法略有不同,属于不同的shell类型,大部分差不多 (1)定义_colcon_prefix_chain_bash_source_script()函数 _colcon_prefix_chain_bash_source_script() { if [ -f "$1" ]; then if [ -n "$COLCON_TRACE" ]; then echo "# . \"$1\"" fi . "$1" else echo "not found: \"$1\"" 1>&2 fi } (2)加载基础ros环境 COLCON_CURRENT_PREFIX="/opt/ros/humble" #系统中ros的安装位置 _colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" #运行对应的bash文件 每个工作空间都默认加载了基础的环境变量 (3)加载当前工作空间的环境 COLCON_CURRENT_PREFIX="$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)" _colcon_prefix_chain_bash_source_script "$COLCON_CURRENT_PREFIX/local_setup.bash" 这里比较复杂的就是第一行,测试一下就可以那段命令就是运行 builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd

结果就是返回了当前路径

~/ws_moveit2/install 具体语法解读 builtin cd : 使用内置命令cd ${BASH_SOURCE[0]} : 这个变量显示此脚本的位置包括文件名 dirname : 取出地址,即取出文件名 ‘ ’ : 先执行反引号内部的命令 /dev/null : 把输出放入黑洞设备,也就是不输出 上面命令一起就是cd到当前,然后再用pwd输出即可传递给COLCON_CURRENT_PREFIX (4)删除定义的变量和函数 unset COLCON_CURRENT_PREFIX unset _colcon_prefix_chain_bash_source_script 删除定义的变量和函数 3、./install/local_setup.bash文件分析 (1)添加地址到环境变量 _colcon_prefix_bash_prepend_unique_value() { # arguments _listname="$1" _value="$2" # get values from variable eval _values=\"\$$_listname\" # backup the field separator _colcon_prefix_bash_prepend_unique_value_IFS="$IFS" IFS=":" # start with the new value _all_values="$_value" _contained_value="" # iterate over existing values in the variable for _item in $_values; do # ignore empty strings if [ -z "$_item" ]; then continue fi # ignore duplicates of _value if [ "$_item" = "$_value" ]; then _contained_value=1 continue fi # keep non-duplicate values _all_values="$_all_values:$_item" done unset _item if [ -z "$_contained_value" ]; then if [ -n "$COLCON_TRACE" ]; then if [ "$_all_values" = "$_value" ]; then echo "export $_listname=$_value" else echo "export $_listname=$_value:\$$_listname" fi fi fi unset _contained_value # restore the field separator IFS="$_colcon_prefix_bash_prepend_unique_value_IFS" unset _colcon_prefix_bash_prepend_unique_value_IFS # export the updated variable eval export $_listname=\"$_all_values\" unset _all_values unset _values unset _value unset _listname } (2)添加前缀地址到COLCON_PREFIX_PATH _colcon_prefix_bash_prepend_unique_value COLCON_PREFIX_PATH "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX" unset _colcon_prefix_bash_prepend_unique_value (3)检查python环境变量 if [ -n "$COLCON_PYTHON_EXECUTABLE" ]; then if [ ! -f "$COLCON_PYTHON_EXECUTABLE" ]; then echo "error: COLCON_PYTHON_EXECUTABLE '$COLCON_PYTHON_EXECUTABLE' doesn't exist" return 1 fi _colcon_python_executable="$COLCON_PYTHON_EXECUTABLE" else # try the Python executable known at configure time _colcon_python_executable="/usr/bin/python3" # if it doesn't exist try a fall back if [ ! -f "$_colcon_python_executable" ]; then if ! /usr/bin/env python3 --version > /dev/null 2> /dev/null; then echo "error: unable to find python3 executable" return 1 fi _colcon_python_executable=`/usr/bin/env python3 -c "import sys; print(sys.executable)"` fi fi (4)加载另外的bash脚本,并根据COLCON_TRACE决定是否输出调试信息 下面这个代码不是原版,有一些调试信息 echo "===========================" echo "2" echo $1 echo "3" echo $COLCON_TRACE _colcon_prefix_sh_source_script() { if [ -f "$1" ]; then if [ -n "$COLCON_TRACE" ]; then echo "# . \"$1\"" fi echo "source \"$1\"" . "$1" else echo "not found: \"$1\"" 1>&2 fi } echo "===========================1" echo "${_colcon_ordered_commands}" # get all commands in topological order _colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" echo "===========================1.5" echo "${_colcon_ordered_commands}" unset _colcon_python_executable if [ -n "$COLCON_TRACE" ]; then echo "$(declare -f _colcon_prefix_sh_source_script)" echo "# Execute generated script:" echo "# <<<" echo "${_colcon_ordered_commands}" echo "# >>>" echo "unset _colcon_prefix_sh_source_script" fi echo "===========================2" echo $AMENT_PREFIX_PATH echo "===========================3" echo "${_colcon_ordered_commands}" eval "${_colcon_ordered_commands}" unset _colcon_ordered_commands unset _colcon_prefix_sh_source_script unset _colcon_prefix_bash_COLCON_CURRENT_PREFIX echo "===========================" echo $AMENT_PREFIX_PATH 下面这行运行了_local_setup_util_sh.py文件,生成了添加地址到指定环境变量的命令将其存到_colcon_ordered_commands _colcon_ordered_commands="$($_colcon_python_executable "$_colcon_prefix_bash_COLCON_CURRENT_PREFIX/_local_setup_util_sh.py" sh bash)" 下面这步则是直接执行_colcon_ordered_commands eval "${_colcon_ordered_commands}" 二、find_package流程

相关资料:

blog.csdn.net/weixin_41652700/article/details/128914776?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522a7d6f436d89e18bbe78a29bb97f8df50%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=a7d6f436d89e18bbe78a29bb97f8df50&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-128914776-null-null.nonecase&utm_term=cmake&spm=1018.2226.3001.4450 blog.csdn.net/m0_73640344/article/details/144246881 1、 find_package搜索地址 find_package实际上是在找对应的.cmake文件,这些文件会生成对应的_DIR、_LIB、_INCLUDE环境变量名。我在写一个moveit相关代码时,cmakelist中有如下内容 find_package(moveit_ros_planning_interface REQUIRED) 这个搜索的地址是~/ws_moveit2/install/moveit_ros_planning_interface/share/moveit_ros_planning_interface/cmake 2、正常编译结果 message("==============find_package前=========") message("moveit_ros_planning_interface_FOUND: ${moveit_ros_planning_interface_FOUND}") message("moveit_ros_planning_interface_INCLUDE_DIRS: ${moveit_ros_planning_interface_INCLUDE_DIRS}") message("moveit_ros_planning_interface_LIBRARIES: ${moveit_ros_planning_interface_LIBRARIES}") message("moveit_ros_planning_interface_LIBRARY_DIRS: ${moveit_ros_planning_interface_LIBRARY_DIRS}") message("moveit_ros_planning_interface_VERSION: ${moveit_ros_planning_interface_VERSION}") message("moveit_ros_planning_interface_DIR: ${moveit_ros_planning_interface_DIR}") find_package(moveit_ros_planning_interface REQUIRED) message("==============find_package后=========") message("moveit_ros_planning_interface_FOUND: ${moveit_ros_planning_interface_FOUND}") message("moveit_ros_planning_interface_INCLUDE_DIRS: ${moveit_ros_planning_interface_INCLUDE_DIRS}") message("moveit_ros_planning_interface_LIBRARIES: ${moveit_ros_planning_interface_LIBRARIES}") message("moveit_ros_planning_interface_LIBRARY_DIRS: ${moveit_ros_planning_interface_LIBRARY_DIRS}") message("moveit_ros_planning_interface_VERSION: ${moveit_ros_planning_interface_VERSION}") message("moveit_ros_planning_interface_DIR: ${moveit_ros_planning_interface_DIR}") 在find_package前这些变量都不存在没有引入手动编译moveit的工作空间的环境变量,所以在find_package后的环境变量都是在/opt/ros/humle中的,以下是其中的一部分 moveit_ros_planning_interface_FOUND: 1 #找到包 moveit_ros_planning_interface_INCLUDE_DIRS: /opt/ros/humble/include/geometry_msgs;/opt/ros/humble/include/moveit_msgs;/usr/include/bullet;/opt/ros/humble/include; #头文件地址 moveit_ros_planning_interface_LIBRARIES: /opt/ros/humble/lib/libbuiltin_interfaces__rosidl_generator_c.so;/opt/ros/humble/lib/libbuiltin_interfaces__rosidl_typesupport_fastrtps_c.so; #库文件 moveit_ros_planning_interface_LIBRARY_DIRS: #空 moveit_ros_planning_interface_VERSION: 2.5.8 #版本 moveit_ros_planning_interface_DIR: /opt/ros/humble/share/moveit_ros_planning_interface/cmake #cmake地址 3、使用手动编译moveit2 关键就是添加set(moveit_ros_planning_interface_DIR “~/ws_moveit2/install/moveit_ros_planning_interface/share/moveit_ros_planning_interface/cmake”)然后将缺失的so文件添加到LD_LIBRARY_PATH环境变量,这一步也可以用cmake中连接器的相关语法,根本原因在于虽然告诉用find_package告诉了编译器怎么编译(比如CMAKE_CURRENT_SOURCE_DIR等变量),但是和环境变量相关的连接过程还是没有变化,所以要手动添加环境或者在连接器上给出具体位置(最简单的还是直接source运行一下手动编译moveit的bash文件) 4、自写库使用find_package()

资料: zhuanlan.zhihu /p/669872914 blogs /linxmouse/p/16778116.html

find_packagge()有模块和配置两种模式。模块模式一般就是自己写的cmake文件,一般是Find<package_name>.cmake文件格式。配置模式就是第三方库官方提供的cmake文件,一般是<package_name>Config.cmake格式。 (1)自写库 cpp文件、h头文件和CMakeList文件都跟一般代码一样,只是生成库文件。关键就是在cmake文件中添加一些变量。 src/MyLibrary.cpp #include "MyLibrary.h" #include <iostream> namespace MyLibrary { void printMessage() { std::cout << "Hello from MyLibrary!" << std::endl; } } include/MyLibrary.h #ifndef MYLIBRARY_H #define MYLIBRARY_H namespace MyLibrary { void printMessage(); } #endif // MYLIBRARY_H CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(MyLibrary VERSION 1.0) # 添加库 add_library(MyLibrary src/MyLibrary.cpp) # 包含头文件目录 target_include_directories(MyLibrary PUBLIC include) cmake/FindMyLibrary.cmake set(MyLibrary_FOUND true) set(MyLibrary_INCLUDE_DIR /home/wangyuanhao/communication_with_thread/find_package_test/include/) set(MyLibrary_LIBRARIES_DIR /home/wangyuanhao/communication_with_thread/find_package_test/build/) (2)调用自写库 find_package只是调用了cmake文件,只是会再一些特定路径下搜索,用include直接调用cmake即可。 src/main.cpp #include <MyLibrary.h> int main() { MyLibrary::printMessage(); return 0; } CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(MyApp) # 查找 MyLibrary set(CMAKE_MODULE_PATH /home/wangyuanhao/communication_with_thread/find_package_test/cmake) #将cmake路径添加到模块路径CMAKE_MODULE_PATH,这样find_package才能找到 message(CMAKE_MODULE_PATH:${CMAKE_MODULE_PATH}) find_package(MyLibrary REQUIRED) #include(/home/wangyuanhao/communication_with_thread/find_package_test/cmake/FindMyLibrary.cmake)#跟find_package效果一样 message(MyLibrary_INCLUDE_DIR:${MyLibrary_INCLUDE_DIR}) # 添加可执行文件 add_executable(MyApp src/main.cpp) # 链接 MyLibrary target_link_libraries(MyApp PRIVATE /home/wangyuanhao/communication_with_thread/find_package_test/build/libMyLibrary.a) if (MyLibrary_INCLUDE_DIR) target_include_directories(MyApp PRIVATE ${MyLibrary_INCLUDE_DIR}) endif()
标签:

在已安装二进制movit2的情况下使用自编译moveit2由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“在已安装二进制movit2的情况下使用自编译moveit2