• 在OpenCV-3.4.9的环境中编译 Prometheus 和prometheus_px4(填坑实录)


    从 opencv-3.2.0 到 opencv-3.4.9 的代码更改

    0. 相关依赖安装

    ROS(省略)、mavros包、建图模块、激光SLAM依赖项、NLopt、OMPL等

    ### mavros
    sudo apt-get install ros-melodic-mavros ros-melodic-mavros-extras
    wget https://raw.githubusercontent.com/mavlink/mavros/master/mavros/scripts/install_geographiclib_datasets.sh
    sudo chmod 777 ./install_geographiclib_datasets.sh
    sudo ./install_geographiclib_datasets.sh
    ### 建图模块 RTAB-map, OCTO-map
    sudo apt-get install ros-melodic-rtabmap*
    sudo apt-get install ros-melodic-octomap-*
    ### 激光SLAM依赖项 cartographer
    sudo apt-get install ros-melodic-cartographer*
    ### 优化相关模块
    git clone git://github.com/stevengj/nlopt  
    cd nlopt  
    mkdir build  
    cd build  
    cmake -D CMAKE_BUILD_TYPE=release \
          -D CMAKE_INSTALL_PREFIX=/usr/local/nlopt \
    	  ..
    make  
    sudo make install
    ### 规划相关模块
    sudo apt install ros-melodic-ompl*
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2. 编译 complie_detection.sh 中的问题

    1.1 问题1

    ~/Prometheus/Modules/object_detection/src/ellipse_lib/spire_ellipsedetector.cpp:1182:25: error: conversion from ‘cv::Mat’ to non-scalar type ‘CvMat’ requested
      CvMat temp = src;
    
    • 1
    • 2

    更改代码:

    	CvMat c_src = src;
        CvMat c_dst = _edges.getMat();
        CvMat c_dx = _sobel_x.getMat();
        CvMat c_dy = _sobel_y.getMat();
    
    • 1
    • 2
    • 3
    • 4

    为新的标准方式:

    	CvMat c_src = cvMat(src);
    	CvMat c_dst = cvMat(_edges.getMat());
    	CvMat c_dx = cvMat(_sobel_x.getMat());
    	CvMat c_dy = cvMat(_sobel_y.getMat());
    
    • 1
    • 2
    • 3
    • 4

    相应的,如果有 IplImage Ipi_z = z 则需要更改为 IplImage Ipi_z = cvIplImage(z)

    1.2 问题2

    ~/Prometheus/Modules/object_detection/src/darknet_ros/src/YoloObjectDetector.cpp:579:49: error: no matching function for call to ‘_IplImage::_IplImage(cv::Mat&)’
       IplImage* ROS_img = new IplImage(camImageCopy_);       
    
    • 1
    • 2

    更改代码:

      IplImage* ROS_img = new IplImage(camImageCopy_);
    
    • 1

    为新的标准方式:

      // IplImage* ROS_img = &cvIplImage(camImageCopy_);   	// ERROR: taking address of temporary [-fpermissive]
      IplImage tmp_img = cvIplImage(camImageCopy_);
      IplImage* ROS_img = &tmp_img;
    
    • 1
    • 2
    • 3

    1.3 问题3

    ~/Prometheus/Modules/planning/FastPlanner/plan_env/ThirdParty/sdf_tools/src/sdf_tools/sdf_builder.cpp: In member function ‘bool sdf_tools::SDF_Builder::BuildInternalPlanningScene()’:
    ~/Prometheus/Modules/planning/FastPlanner/plan_env/ThirdParty/sdf_tools/src/sdf_tools/sdf_builder.cpp:87:134: error: no matching function for call to ‘planning_scene::PlanningScene::PlanningScene(boost::shared_ptr<urdf::Model>&, boost::shared_ptr<srdf::Model>&)’
             planning_scene_ptr_ = std::shared_ptr<planning_scene::PlanningScene>(new planning_scene::PlanningScene(urdf_model, srdf_model));
                                                                                                                                          ^
    
    • 1
    • 2
    • 3
    • 4

    解决办法,更改代码:

            boost::shared_ptr<urdf::Model> urdf_model(new urdf::Model());
            urdf_model->initString(GenerateSDFComputeBotURDFString());
            // Make the SRDF model
            boost::shared_ptr<srdf::Model> srdf_model(new srdf::Model());
            srdf_model->initString(*urdf_model, GenerateSDFComputeBotSRDFString());
            // Make the planning scene
            planning_scene_ptr_.reset();
            planning_scene_ptr_ = std::shared_ptr<planning_scene::PlanningScene>(new planning_scene::PlanningScene(urdf_model, srdf_model));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    为新的标准方式:

        	auto urdf_model = std::make_shared<urdf::Model>();
        	urdf_model->initString(GenerateSDFComputeBotURDFString());
        	// Make the SRDF model
        	auto srdf_model = std::make_shared<srdf::Model>();
        	srdf_model->initString(*urdf_model, GenerateSDFComputeBotSRDFString());
    		// Make the planning scene
    		planning_scene_ptr_ = std::make_shared<planning_scene::PlanningScene>(urdf_model, srdf_model);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    总结1~3问题:

    (1)由于OpenCV的版本从 opencv2 到 opencv3 再到 opencv4 的升级过程中,对于 cv::Mat, CvMatIplImage 之间的相互转换关系操作一直在变化中。源码编译的时候,需要根据实际的编译环境 opencv 的版本来调整相应的代码。
    (2)由于C++语言的标准一直变化中,一些与之相关的代码也可能需要调整。例如关于指针尤其是指针模板的定义和使用。

    1.4 问题4

    又再次遇到奇葩的问题。

    ~/Prometheus/Modules/swarm_control/src/ego_traj_to_cmd.cpp:21:10: fatal error: quadrotor_msgs/PositionCommand.h: No such file or directory
     #include "quadrotor_msgs/PositionCommand.h"
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    
    • 1
    • 2
    • 3
    • 4

    网络上的方式是重新编译相关的功能包。但是,对于我来讲还是非常的迷惑!
    https://www.freesion.com/article/76371450240/

    cd ~/fast-planer_ws  //fast-planer_ws为我存放该工程的工作空间
    catkin_make
    source devel/setup.bash 
    
    • 1
    • 2
    • 3

    重新在另外一个网页上找到了看起来比较靠谱的办法。
    https://www.freesion.com/article/16841452429/

    step 1:在CMakeList.txt文件中,find_package() 里添加quadrotor_msgs如下

    find_package( #...
      quadrotor_msgs # 添加的
    )
    
    • 1
    • 2
    • 3

    step 2:同样在此CMakeList.txt中,include_directories里添加${catkin_INCLUDE_DIRS}如下:

    include_directories(include ${catkin_INCLUDE_DIRS})
    
    • 1

    在更改这个 CMakeList.txt 的时候发现,他的一些依赖与ego_planner 有关,于是事先编译一下 ego_planner.

    ~/Prometheus$ ./complie_ego.sh
    
    • 1

    然后再次编译 swarm 模块。

    ~/Prometheus$ ./complie_swarm.sh
    
    • 1

    结果得到一个新的错误提示。

    CMake Error at  ~/Prometheus/devel/share/quadrotor_msgs/cmake/quadrotor_msgsConfig.cmake:173 (message):
      Project 'prometheus_swarm_control' tried to find library 'encode_msgs'.
      The library is neither a target nor built/installed properly.  Did you
      compile project 'quadrotor_msgs'? Did you find_package() it before the
      subdirectory containing its code is included?
    
    • 1
    • 2
    • 3
    • 4
    • 5

    很迷的一个错误提示。然后再次编译 ego 模块。
    也可能是期间,同时在安装的 ompl 功能模块起作用了。

    sudo apt install ros-melodic-ompl*
    
    • 1

    不管他,继续了。

    ~/Prometheus$ ./complie_ego.sh
    
    • 1

    出现了一个错误提示如下。

    [ 86%] Building CXX object ego-planner-swarm/src/uav_simulator/Utils/rviz_plugins/CMakeFiles/rviz_plugins.dir/src/probmap_display.cpp.o
    [ 87%] Building CXX object ego-planner-swarm/src/uav_simulator/Utils/rviz_plugins/CMakeFiles/rviz_plugins.dir/src/aerialmap_display.cpp.o
    ego-planner-swarm/src/planner/traj_utils/CMakeFiles/traj_utils.dir/build.make:94: recipe for target 'ego-planner-swarm/src/planner/traj_utils/CMakeFiles/traj_utils.dir/src/polynomial_traj.cpp.o' failed
    make[2]: *** [ego-planner-swarm/src/planner/traj_utils/CMakeFiles/traj_utils.dir/src/polynomial_traj.cpp.o] Error 1
    CMakeFiles/Makefile2:5100: recipe for target 'ego-planner-swarm/src/planner/traj_utils/CMakeFiles/traj_utils.dir/all' failed
    make[1]: *** [ego-planner-swarm/src/planner/traj_utils/CMakeFiles/traj_utils.dir/all] Error 2
    make[1]: *** Waiting for unfinished jobs....
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    暂时忽略它,继续编译 swarm 模块。

    ~/Prometheus$ ./complie_swarm.sh
    
    • 1

    完美通过。

    总结4问题:

    此过程中由于 prometheus 编译过程中有相互的关联需求,而且其中还夹杂着因为缺少相应的功能包而出现的一些问题。总体思路是(1)调整编译的顺序;(2)安装相关依赖。

    1.5 问题5

    使用阿木实验室的Prometheus项目专用的PX4仓库来安装 prometheus_px4,安装方法如下:

    git clone https://gitee.com/amovlab/prometheus_px4.git
    cd prometheus_px4
    git submodule update --init --recursive
    pip3 install --user toml empy jinja2 packaging
    make amovlab_sitl_default gazebo
    
    cd prometheus_px4/Tools/setup
    source ./ubuntu.sh
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    其中,在进行到 make amovlab_sitl_default gazebo 的时候可能有报错(实际没有碰到),解决办法:

    make clean
    make px4_sitl gazebo
    
    sudo apt-get install libprotobuf-dev libprotoc-dev protobuf-compiler libeigen3-dev libxml2-utils python-rospkg python-jinja2
    sudo apt-get install libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-bad gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly -y
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在运行 cd prometheus_px4/Tools/setup && source ./ubuntu.sh 的时候可能会遇到找不到 cc1 等库文件的问题。解决办法:
    首先,通过gcc -v查看 gcc 的路径。

    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/8/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 8.4.0-1ubuntu1~18.04' --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-8 --program-prefix=x86_64-linux-gnu- --enable-shared 
    Thread model: posix
    gcc version 8.4.0 (Ubuntu 8.4.0-1ubuntu1~18.04) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    ~/.bash.bashrc 中添加

    export LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/8:$LIBRARY_PATH
    
    • 1

    然后再次运行 source ./ubuntu.sh 即可。
    另外,
    还需要在 ~/.bash.bashrc 中添加如下指令(以下若存在已添加过的命令,请勿重复添加),其中${your prometheus path}为Prometheus项目路径,${your px4 path}为安装PX4固件即prometheus_px4的路径。

    source ${your prometheus path}/Prometheus/devel/setup.bash
    export GAZEBO_PLUGIN_PATH=$GAZEBO_PLUGIN_PATH:${your prometheus path}/Prometheus/devel/lib
    export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:${your prometheus path}/Prometheus/Simulator/gazebo_simulator/models
    export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:${your prometheus path}/Prometheus/Simulator/gazebo_simulator/amov_models
    source ${your px4 path}/prometheus_px4/Tools/setup_gazebo.bash ${your px4 path}/prometheus_px4 ${your px4 path}/prometheus_px4/build/amovlab_sitl_default
    export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:${your px4 path}/prometheus_px4
    export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:${your px4 path}/prometheus_px4/Tools/sitl_gazebo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后可以继续安装 gazebo 中仿真所需的 3Dlidaroctomap 以及 Turtlebot3 等插件。

    sudo apt-get install ros-melodic-velodyne-gazebo-plugins
    sudo apt-get install ros-melodic-octomap-rviz-plugins
    sudo apt-get install ros-melodic-turtlebot3-*
    
    • 1
    • 2
    • 3

    Gazebo仿真运行测试:

    roslaunch prometheus_gazebo sitl.launch
    
    • 1

    一共启动了三个终端。
    第一个终端同时运行了gazeboMavrospx4_pos_estimatorpx4_pos_controller四个节点,第二个终端则运行了ground_station节点,第三个终端则运行了pos_estimator 节点。因此,若第一个终端无报错,第二个终端显示[Connected]并能够查看到飞机状态,且Gazebo成功运行,代表成功运行。

    NODES
      /
        gazebo (gazebo_ros/gzserver)
        gazebo_gui (gazebo_ros/gzclient)
        ground_station (prometheus_station/ground_station)
        ground_station_msg (prometheus_station/ground_station_msg)
        mavros (mavros/mavros_node)
        px4_pos_estimator (prometheus_control/px4_pos_estimator)
        px4_sender (prometheus_control/px4_sender)
        sitl (px4/px4)
        tf_2Dlidar (tf/static_transform_publisher)
        tf_3Dlidar (tf/static_transform_publisher)
        tf_realsense_camera (tf/static_transform_publisher)
        tf_slam2map (tf/static_transform_publisher)
        tf_world_map (tf/static_transform_publisher)
        vehicle_spawn_UX303L_3799_8995328815101938340 (gazebo_ros/spawn_model)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    运行如下指令启动终端控制节点,并根据终端提示输入指令:

    rosrun prometheus_control terminal_control
    
    • 1

    到这就成功了。也可以在第一个终端中,使用 help 以及 commander help 来学习使用命令操控无人机。
    不用重启系统而关闭 gazebo 的命令。

    killall gzserver
    killall gzclient
    
    • 1
    • 2
  • 相关阅读:
    管理器注册类方法和调用类函数方法
    Python面试宝典
    浅谈选择示波器时的“5倍法则”
    【SaaS应用程序】上海道宁为您提供研究数据管理-库存管理-调度工具——LabArchives
    Unity shader内置standard代码解析
    ubuntu1804配置OAK-D相机的ROS以及depthai_ros环境
    《分布式服务架构:原理,设计与实战》
    算法秘籍-王一博 | 数据结构与算法
    fastDFS单节点部署(2台服务器)
    商业模式,淘宝,拼多多,京东,短视频商业模式
  • 原文地址:https://blog.csdn.net/BeeGreen/article/details/126149444