zoukankan      html  css  js  c++  java
  • CV学习日志:CV开发之常用库最简CMake配置及ROS2使用样例

             之前分两篇文章介绍了CV开发的常用开发库及其头文件。详见《CV学习日志:CV开发之常用库及其头文件》和《CV学习日志:CV开发之ROS2和Webots头文件及其自动提取》。

             本篇给出基于CV开发常用库的CMake配置模板,并给出使用了ROS2的样例。

             给出的CMake配置基于ubuntu20.04,开发库除Webots(Webots采用默认安装路径)外都是通过apt-get安装,详见《CV学习日志:CV开发之Ubuntu2004和WLS2环境搭建》。

             给出的CMake工程假设了一个自定义库,即基于ROS2自编译的库,colon编译安装路径是/root/app/ros2ex/out/install。

     

             以下是CMake模板的详细代码,尤其要注意配置了Threads和对QT5添加了特殊配置。

     1 ###I.Global####################################################################
     2 cmake_minimum_required(VERSION 3.5)
     3 project(aaron)
     4 set(CMAKE_CXX_STANDARD 14)
     5 set(CMAKE_CXX_STANDARD_REQUIRED True)
     6 set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/out)
     7 set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/out)
     8 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/header) #if header directory exists
     9 
    10 ###II.UNIX####################################################################
    11 if(UNIX)
    12 set(THREADS_PREFER_PTHREAD_FLAG ON)
    13 find_package(Threads REQUIRED)
    14 message("Platform: UNIX
    
    Platform: UNIX
    
    Platform: UNIX
    
    Platform: UNIX
    
    Platform: UNIX
    
    Platform: UNIX
    
    ")
    15 
    16 #1.Qt5
    17 include_directories(/usr/include/x86_64-linux-gnu/qt5)
    18 file(GLOB Qt5_LIBS /usr/lib/x86_64-linux-gnu/libQt5*.so.5) #remove Qt5Bootstrap and Qt5Debug if they exist
    19 add_compile_definitions(QT_WIDGETS_LIB) #Add QT_NO_VERSION_TAGGING if installing Qt manually
    20 add_compile_options(-fPIC)
    21 
    22 #2.OpenCV
    23 include_directories(/usr/include/opencv4)
    24 file(GLOB OpenCV_LIBS /usr/lib/x86_64-linux-gnu/libopencv*.so)
    25 
    26 #3.Eigen3 Gflags Glog Ceres Spdlog
    27 include_directories(/usr/include)
    28 include_directories(/usr/include/eigen3)
    29 file(GLOB Gflags_LIBS /usr/lib/x86_64-linux-gnu/libgflags*.so)
    30 file(GLOB Glog_LIBS /usr/lib/x86_64-linux-gnu/libglog*.so)
    31 file(GLOB Ceres_LIBS /usr/lib/libceres*.so)
    32 
    33 #4.ROS2 ROS2EX Webots
    34 include_directories(/opt/ros/foxy/include /root/app/ros2ex/out/install/include)
    35 include_directories(/usr/local/webots/include/controller/cpp /usr/local/webots/include/controller/c)
    36 file(GLOB ROS2_LIBS LIST_DIRECTORIES false /opt/ros/foxy/lib/*.so)
    37 file(GLOB ROS2EX_LIBS LIST_DIRECTORIES false /root/app/ros2ex/out/install/lib/*.so)
    38 file(GLOB Webots_LIBS LIST_DIRECTORIES false /usr/local/webots/lib/controller/*.so)
    39 
    40 #5.Octomap
    41 include_directories(/usr/include)
    42 file(GLOB Octomap_LIBS /usr/lib/x86_64-linux-gnu/liboctom*.so)#octomap&octomath
    43 set(Octomap_LIBS ${Octomap_LIBS} /usr/lib/x86_64-linux-gnu/liboctovis.so)
    44 set(Octomap_LIBS ${Octomap_LIBS} /usr/lib/x86_64-linux-gnu/libdynamicedt3d.so)
    45 
    46 #8.AllLibs
    47 set(ALL_LIBS ${Qt5_LIBS} ${OpenCV_LIBS} ${ROS2_LIBS} ${ROS2EX_LIBS} ${Webots_LIBS}
    48 ${Gflags_LIBS} ${Glog_LIBS} ${Ceres_LIBS} ${Octomap_LIBS})
    49 link_libraries(${ALL_LIBS})
    50 message("ALL_LIBS: ${ALL_LIBS}")
    51 
    52 ###9.2ROSTest
    53 set(rostestcpp ${CMAKE_SOURCE_DIR}/rostest.cpp)
    54 add_executable(rostest ${rostestcpp})
    55 target_link_libraries(rostest Threads::Threads)
    56 endif(UNIX)
    View Code

             以下是ROS2使用样例的详细代码,依赖于C++14、OpenCV4.x、Spdlog及Foxy

     1 #include "cvheaders.h" //write this file based on previous articles
     2 
     3 #ifndef ns1970
     4 #define ms1970 chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()).time_since_epoch().count()
     5 #define us1970 chrono::time_point_cast<chrono::microseconds>(chrono::system_clock::now()).time_since_epoch().count()
     6 #define ns1970 chrono::time_point_cast<chrono::nanoseconds>(chrono::system_clock::now()).time_since_epoch().count()
     7 #endif
     8 
     9 class RosTestCore
    10 {
    11 public:
    12     static void AirRobot(int argc = 0, char **argv = 0)
    13     {
    14         //0.InitROS
    15         rclcpp::init(argc, argv);
    16 
    17         //1.PreROS
    18         int64 nPubFrame = 0;
    19         rclcpp::Node::SharedPtr nodAirRobot = rclcpp::Node::make_shared("airRobot", "acv");
    20         rclcpp::Publisher<ssrmsg::Image>::SharedPtr pubRawFrame = nodAirRobot->create_publisher<ssrmsg::Image>("rawFrame", 2);
    21         rclcpp::TimerBase::SharedPtr TimerTimestamp = nodAirRobot->create_wall_timer(200ms, [&]()->void
    22             {
    23                 //1.PrepareData
    24                 int64 ts = ns1970;
    25                 ssrmsg::Image::UniquePtr ima = make_unique<ssrmsg::Image>();
    26                 ima->header.frame_id = std::to_string(++nPubFrame);
    27                 ima->header.stamp.sec = ts / 1000000000;
    28                 ima->header.stamp.nanosec = ts % 1000000000;
    29                 ima->width = 640;
    30                 ima->height = 480;
    31                 ima->step = 3 * ima->width;
    32                 ima->is_bigendian = 0;
    33                 ima->encoding = CV_8UC3;
    34                 ima->data.assign(ima->step * ima->height, 128);
    35                 cv::putText(Mat_<Vec3b>(ima->height, ima->width, (Vec3b*)ima->data.data()), ima->header.frame_id, Point(300, 220), FONT_HERSHEY_PLAIN, 4, Scalar(255, 0, 0), 4);
    36 
    37                 //2.PublishData
    38                 pubRawFrame->publish(std::move(ima));
    39 
    40                 //3.PrintDetails
    41                 spdlog::info("nPubFrame: {}", nPubFrame);
    42                 spdlog::info("	Node::get_name: {}", nodAirRobot->get_name());
    43                 spdlog::info("	Node::get_namespace: {}", nodAirRobot->get_namespace());
    44                 spdlog::info("	Node::get_sub_namespace: {}", nodAirRobot->get_sub_namespace());
    45                 spdlog::info("	Node::get_effective_namespace: {}", nodAirRobot->get_effective_namespace());
    46                 spdlog::info("	Node::get_fully_qualified_name: {}", nodAirRobot->get_fully_qualified_name());
    47             });
    48 
    49         //2.SpinROS
    50         rclcpp::spin(nodAirRobot);
    51 
    52         //3.StopROS
    53         rclcpp::shutdown();
    54     }
    55 
    56 public:
    57     static void LandRobot(int argc = 0, char **argv = 0)
    58     {
    59         //0.InitROS
    60         rclcpp::init(argc, argv);
    61 
    62         //1.PreROS
    63         int64 nSubRawFrame = 0;
    64         rclcpp::Node::SharedPtr nodLandRobot = rclcpp::Node::make_shared("landRobot", "acv");
    65         rclcpp::Subscription<ssrmsg::Image>::SharedPtr subRawFrame = nodLandRobot->create_subscription<ssrmsg::Image>("rawFrame", 2, [&](ssrmsg::Image::UniquePtr frame)
    66             {
    67                 cv::imshow("RawFrame", Mat_<Vec3b>(frame->height, frame->width, (Vec3b*)frame->data.data()));
    68                 cv::waitKey(10);
    69                 spdlog::info("nSubRawFrame: {}", ++nSubRawFrame);
    70                 spdlog::info("	Node::get_name: {}", nodLandRobot->get_name());
    71                 spdlog::info("	Node::get_namespace: {}", nodLandRobot->get_namespace());
    72                 spdlog::info("	Node::get_sub_namespace: {}", nodLandRobot->get_sub_namespace());
    73                 spdlog::info("	Node::get_effective_namespace: {}", nodLandRobot->get_effective_namespace());
    74                 spdlog::info("	Node::get_fully_qualified_name: {}", nodLandRobot->get_fully_qualified_name());
    75             });
    76 
    77         //2.SpinROS
    78         rclcpp::spin(nodLandRobot);
    79 
    80         //3.StopROS
    81         rclcpp::shutdown();
    82     }
    83 };
    84 
    85 int main(int argc, char** argv)
    86 {
    87     if (argc < 2){ spdlog::critical("appName nodeName(airRobot/landRobot)"); return -1; }
    88 
    89     if (strcmp(argv[1], "airRobot") == 0) RosTestCore::AirRobot(argc, argv);
    90     else if (strcmp(argv[1], "landRobot") == 0) RosTestCore::LandRobot(argc, argv);
    91 
    92     return 0;
    93 }
    View Code

             打开两个终端执行source /opt/ros/foxy/setup.bash后,再分别执行以下命令可查看效果。

             1)终端一:./rostest airRobot

             2)终端二:./rostest landRobot

     

  • 相关阅读:
    手机号码 正则表达式
    邮政编码的正则表达式
    对象为null,调用非静态方法产生空指针异常
    文件找不到异常(FileNotFoundException)
    数组下标越界异常解决方法
    空指针异常的解决方法
    需求:打印九九乘法表
    创建简单线程
    ·博客作业06--图
    博客作业05--查找
  • 原文地址:https://www.cnblogs.com/dzyBK/p/13894015.html
Copyright © 2011-2022 走看看