一、构建程序包
本人使用Qt5.12.8
创建ROS2工作环境
mkdir ros2_ws
cd ros2_ws
mkdir src
cd src
ros2 pkg create --build-type ament_cmake 项目名
创建Qt文件
(1)构建系统使用cmake
(2)取与ROS2包同名的Qt文件
二、合并文件夹
(1)将所有的Qt文件中的.h文件全部放在include文件夹中
(2)将所有的Qt文件中的.cpp文件全部放在src文件夹中
(3)创建新文件夹ui,放置Qt文件中的ui文件
(4)合并CMakelists
CMakelists.txt一般如下所示
cmake_minimum_required(VERSION 3.8)//cmake版本
project(文件名)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(Boost 1.71.0 REQUIRED COMPONENTS thread)
find_package(Qt5 COMPONENTS Widgets REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
file(GLOB PRO_SOURCE_DIR RELATIVE ${CMAKE_SOURCE_DIR} FOLLOW_SYMLINKS src/*.cpp)
file(GLOB PRO_UI_DIR RELATIVE ${CMAKE_SOURCE_DIR} FOLLOW_SYMLINKS ui/*.ui)
file(GLOB PRO_INCLUDE_DIR RELATIVE ${CMAKE_SOURCE_DIR} FOLLOW_SYMLINKS include/*.h *.hpp)
file(GLOB PRO_RESOURCE_DIR RELATIVE ${CMAKE_SOURCE_DIR} FOLLOW_SYMLINKS resource/*.qrc)
qt5_wrap_ui(QT_UI_HPP ${PRO_UI_DIR})
qt5_wrap_cpp(QT_MOC_HPP ${PRO_INCLUDE_DIR})
qt5_add_resources(QT_RESOUCE_HPP ${PRO_RESOURCE_DIR})
message(${CMAKE_CURRENT_BINARY_DIR})
#向工程添加多个特定的头文件搜索路径
include_directories(
include/
${CMAKE_CURRENT_BINARY_DIR}
)
#编译如下文件生成可执行文件PROJECT_NAME
add_executable(${PROJECT_NAME}
${PRO_SOURCE_DIR}
${PRO_INCLUDE_DIR}
${PRO_UI_DIR}
${PRO_RESOURCE_DIR}
${QT_UI_HPP}
${QT_MOC_HPP}
${QT_RESOUCE_HPP}
)
ament_target_dependencies(${PROJECT_NAME} rclcpp Boost std_msgs )
#为 target 添加需要链接的共享库
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
三、编译
(1)在CMakelists的同级目录下创建一个build文件夹
(2)进入文件夹执行cmake …
(3)使用make进行编译
(4)./可执行文件 运行文件
mkdir build
cd build
cmake ..
make
./可执行文件
四、添加自定义的msg
使用ROS2中用到的interfaces需要向CmakeList和xml文件中添加相关内容
(1)CMakelist
find_package(nest_interfaces REQUIRED)//查找包
ament_target_dependencies(${PROJECT_NAME} rclcpp Boost std_msgs nest_interfaces)//添加依赖
(2)package.xml
<depend>nest_interfaces</depend>
(3)使用interfaces需要在文件中添加头文件"xxx.hpp"
五、线程
要运行客户端/服务器,发布/订阅,需要在mainwindow的构造函数中添加线程,保证ROS2的spin和Qt的UI运行不会相互影响
(1)在mainwindow的构造函数中进行初始化init(命令行参数直接定义)
(2)线程中只执行spin
rclcomm::rclcomm()
{
this->start();//启动线程,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码
}
//发布者运行
void rclcomm::run()
{
rclcpp::spin(std::make_shared<Subscriber>());
}
(3)在mainwindow的析构函数中执行shutdown
六、获取ROS2的msg数据
定义全局变量
auto deviceState = nest_interfaces::msg::DeviceState();
在回调函数中使用get()函数
Subscriber::Subscriber():Node("device_state")
{
subscription_ = this->create_subscription<nest_interfaces::msg::DeviceState>("device_state_topic", 10, std::bind(&Subscriber::topic_callback, this, std::placeholders::_1));
}
void Subscriber::topic_callback(const nest_interfaces::msg::DeviceState::SharedPtr msg) const
{
RCLCPP_INFO(this->get_logger(), "I heard: '%d'", msg->drone_detected_state);
deviceState=*msg.get();
//qDebug() << deviceState.drone_detected_state;
}