c++ Cmake工程(4) opevslam ros工程模式
0 自己编写ros节点引用opemvslam
0-1 首先将openvslam 正常cmake编译一遍 得到build文件夹
0-2 进入自带的ros文件夹例子 cakin_make,这一步要用到上一步的build的库


openvslam 节点 测试建图和定位(后期拷贝到自己的ros工程里当基准用来改造)


publisher是图像发布和视频发布节点 非必须

0-3 自己任意地方创建一个ros工程 假设ros_cgg
拷贝openvslam 的文件同级目录

这个目录是由cmakelist决定的 可以修改 相当于cmakelist上面三级目录地址
message(STATUS " 当前编译编译目录: ${PROJECT_SOURCE_DIR}")
get_filename_component(DEFAULT_OpenVSLAM_DIR ${PROJECT_SOURCE_DIR} DIRECTORY)
get_filename_component(DEFAULT_OpenVSLAM_DIR ${DEFAULT_OpenVSLAM_DIR} DIRECTORY)
get_filename_component(DEFAULT_OpenVSLAM_DIR ${DEFAULT_OpenVSLAM_DIR} DIRECTORY)
set(OpenVSLAM_ROOT ${DEFAULT_OpenVSLAM_DIR} CACHE STRING "Root directory of OpenVSLAM")
message(STATUS "Root directory of OpenVSLAM: ${OpenVSLAM_ROOT}")
ros_cgg/src下创建使用节点 拷贝原工程openvslam的ros测试节点

(其他俩文件夹是其他项目 和这个没有关系 没有也可以)

原版本自带的直接拷贝过来

编译


最后
简单一点 的,不要这么多拷贝,直接在原工程自带的ros文件里修改新增自己编写的文件就完事了,或者把camkalist路径改一下引导过去。
上面这几个方法是完全重新创建了一个,为了理解ros工程结构,都依赖了哪些源文件和组织关系。
关键点
1 -1 openvslamde 源码部分是如何被CMakeLists引用的?

引用的ros节点

编译的CMakeLists

通过get_filename_component 指令连续三次上一级目录,找到相对位置的总工程根目录
get_filename_component 是 CMake 的一个命令,用于从路径字符串中提取特定的组件。它可以提取以下内容: 目录(DIRECTORY):从路径中获取目录部分。 文件名(NAME):从路径中获取文件名部分。 扩展名(EXT):从路径中获取文件扩展名部分。 基本名(NAME_WE):从路径中获取不带扩展名的文件名部分。 例如,如果你有一个路径 "/home/user/project/file.txt",使用 get_filename_component 可以分别提取 "/home/user/project/" 作为目录、"file.txt" 作为文件名、".txt" 作为扩展名,以及 "file" 作为基本名。

1-2 openvslamde 源码部分是如何被调用文件引用的

openvslam先编译安装到 usr/local/include/ 然后再是编译ros节点。
ros节点文件直接从系统目录找的"openvslam/system.h"。 然后才是从CMakeLists给定的目录查找。
#include <ros/ros.h> //#include "openvslam/system.h" // 优先从 usr/local/include/下查找 然后才是自己指定的目录

2 相对路径

# 自己写的依赖库文件目录
message(STATUS "当前CMakeLists路径: ${PROJECT_SOURCE_DIR}")
set(VSLAM_ROOT "${PROJECT_SOURCE_DIR}/../../../src" )
message(STATUS "自己写的依赖库文件目录: ${VSLAM_ROOT}")
include_directories(
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
"/usr/local/include/eigen3"
${VSLAM_ROOT} #自己写的依赖库文件目录
)
从而可以直接使用
#include "vslam/system.h" // 等同于 ${VSLAM_ROOT}/vslam/system.h
其中
set(VSLAM_ROOT "${PROJECT_SOURCE_DIR}/../../../src" )
可以参考openvslam类似写法代替
# digging into the root directory of OpenVSLAM
get_filename_component(DEFAULT_OpenVSLAM_DIR ${PROJECT_SOURCE_DIR} DIRECTORY)
get_filename_component(DEFAULT_OpenVSLAM_DIR ${DEFAULT_OpenVSLAM_DIR} DIRECTORY)
get_filename_component(DEFAULT_OpenVSLAM_DIR ${DEFAULT_OpenVSLAM_DIR} DIRECTORY)
set(OpenVSLAM_ROOT "${DEFAULT_OpenVSLAM_DIR}/src" CACHE STRING "Root directory of OpenVSLAM")
message(STATUS "Root directory of OpenVSLAM: ${OpenVSLAM_ROOT}")




CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(test_node)
find_package(catkin REQUIRED COMPONENTS
roscpp
geometry_msgs
sensor_msgs
cv_bridge
message_filters # 消息同步
image_transport
)
find_package(OpenCV REQUIRED)
find_package(Boost REQUIRED COMPONENTS filesystem)
find_package(Eigen3 REQUIRED)
catkin_package(
CATKIN_DEPENDS roscpp geometry_msgs sensor_msgs cv_bridge
DEPENDS Boost
)
# 自己写的依赖库文件目录
message(STATUS "当前CMakeLists路径: ${PROJECT_SOURCE_DIR}")
set(VSLAM_ROOT "${PROJECT_SOURCE_DIR}/../../../src" )
message(STATUS "自己写的依赖库文件目录: ${VSLAM_ROOT}")
include_directories(
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
"/usr/local/include/eigen3"
${VSLAM_ROOT} #自己写的依赖库文件目录
)
# 编译自己写的依赖库
add_library(openvslam_system
${VSLAM_ROOT}/vslam/system.cc
)
# 编译发布节点
add_executable(run_slam src/run_slam.cc)
target_link_libraries(run_slam
${catkin_LIBRARIES}
${OpenCV_LIBRARIES}
${Boost_LIBRARIES}
openvslam_system)
package.xml

<?xml version="1.0"?>
<package format="2">
<name>test_node</name>
<version>0.0.1</version>
<description>
A package to publish and subscribe to images and GPS data using ROS.
</description>
<!-- Maintainer of the package -->
<maintainer email="your_email@example.com">Your Name</maintainer>
<!-- License of the package -->
<license>MIT</license>
<!-- Build tool required to build this package -->
<buildtool_depend>catkin</buildtool_depend>
<!-- Dependencies of the package during build and runtime -->
<build_depend>roscpp</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>cv_bridge</build_depend>
<build_depend>eigen</build_depend>
<build_depend>geometry_msgs</build_depend>
<build_depend>message_filters</build_depend>
<build_depend>image_transport</build_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>sensor_msgs</exec_depend>
<exec_depend>cv_bridge</exec_depend>
<exec_depend>eigen</exec_depend>
<exec_depend>geometry_msgs</exec_depend>
<exec_depend>message_filters</exec_depend>
<exec_depend>image_transport</exec_depend>
<!-- Declare additional dependencies required for building this package -->
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>sensor_msgs</build_export_depend>
<build_export_depend>cv_bridge</build_export_depend>
<build_export_depend>eigen</build_export_depend>
<build_export_depend>geometry_msgs</build_export_depend>
<build_export_depend>message_filters</build_export_depend>
<build_export_depend>image_transport</build_export_depend>
<!-- Export information, can be used by other packages -->
<export>
<!-- Export any specific information here -->
</export>
</package>

run_slam.cc
#include <ros/ros.h>
//#include "openvslam/system.h" // 优先从 usr/local/include/下查找 然后才是自己指定的目录
#include "vslam/system.h" // 等同于 ${VSLAM_ROOT}/vslam/system.h
int main(int argc, char** argv) {
ros::init(argc, argv, "run_slam_node");
ros::NodeHandle nh;
// Create an instance of SLAMSystem
SLAMSystem slam_system;
slam_system.initialize();
ros::spin(); // Enter a loop, waiting for callbacks
return 0;
}
依赖库




system.h
#ifndef OPENVSLAM_SYSTEM_H
#define OPENVSLAM_SYSTEM_H
#include <iostream>
class SLAMSystem {
public:
SLAMSystem();
void initialize();
};
#endif // OPENVSLAM_SYSTEM_H
system.cc
#include "system.h"
SLAMSystem::SLAMSystem() {
// Constructor implementation
}
void SLAMSystem::initialize() {
std::cout << "SLAMSystem initialized." << std::endl;
}