Qt+ROS2项目构建

一、构建程序包

本人使用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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值