十二、Yocto集成ROS2 app程序(package)

文章目录

  • [Yocto集成ROS2 app程序](#Yocto集成ROS2 app程序)
    • [1. 添加一个ros2 package应用程序](#1. 添加一个ros2 package应用程序)
    • [2. 添加bb文件集成app应用程序](#2. 添加bb文件集成app应用程序)

Yocto集成ROS2 app程序

本篇文章为基于raspberrypi 4B单板的yocto实战系列的第十二篇文章:
一、yocto 编译raspberrypi 4B并启动
二、yocto 集成ros2(基于raspberrypi 4B)
三、Yocto创建自定义的layer和image
四、Yocto创建静态IP和VLAN
五、Yocto集成QT5
六、Yocto给组件分组(packagegroups)
七、Yocto使用systemd设置开机自启动程序
八、Yocto 创建自定义的conf文件
九、Yocto创建SDK,给Makefile/CMake使用
十、使用repo管理yocto各个layer
十一、Yocto集成tcpdump等网络工具

在前面的第二章节中我们很早就在image中集成了ros-core的运行环境,但是一只没有编写过测试程序来验证ros通信,然后就下载了官方的ros example程序,在ubuntu中是直接使用colcon编译即可完成编译和通信验证,但是当我尝试添加example到yocto编译时发现居然找不到一个现成可用的模板,所以本章节记录一下如何在yocto中集成ros 应用程序。

1. 添加一个ros2 package应用程序

这里我们拿两个简单的topic通信来验证,一个负责publish消息,一个负责subcribe消息。

涉及到的四个文件如下:

publisher_member_function.cpp

#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

/* This example creates a subclass of Node and uses std::bind() to register a
 * member function as a callback from the timer. */

class MinimalPublisher : public rclcpp::Node
{
public:
  MinimalPublisher()
  : Node("minimal_publisher"), count_(0)
  {
    publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
    timer_ = this->create_wall_timer(
      1500ms, std::bind(&MinimalPublisher::timer_callback, this));
  }

private:
  void timer_callback()
  {
    auto message = std_msgs::msg::String();
    message.data = "Hello, Swiftlane! " + std::to_string(count_++);
    RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
    publisher_->publish(message);
  }
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  size_t count_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalPublisher>());
  rclcpp::shutdown();
  return 0;
}

subscriber_member_function.cpp:

#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
using std::placeholders::_1;

class MinimalSubscriber : public rclcpp::Node
{
public:
  MinimalSubscriber()
  : Node("minimal_subscriber")
  {
    subscription_ = this->create_subscription<std_msgs::msg::String>(
      "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
  }

private:
  void topic_callback(const std_msgs::msg::String::SharedPtr msg) const
  {
    RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
  }
  rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};

int main(int argc, char * argv[])
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalSubscriber>());
  rclcpp::shutdown();
  return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(ros2-topic-sample)

# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()

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)

add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)

add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)

install(TARGETS
  talker
  DESTINATION lib/${PROJECT_NAME})

install(TARGETS
  listener
  DESTINATION lib/${PROJECT_NAME})  

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # uncomment the line when a copyright and license is not present in all source files
  #set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # uncomment the line when this package is not in a git repo
  #set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

package.xml:

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>ros2-topic-sample</name>
  <version>0.1.0</version>
  <description>Examples of minimal publisher/subscriber using rclcpp</description>
  <maintainer email="tangtaoqaq@gmail.com">tangtao</maintainer>
  <license>Apache License 2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>std_msgs</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

2. 添加bb文件集成app应用程序

然后就需要编写一个bb文件集成上面的ros应用,主要注意的就是在DEPENDS里面指明当前的程序依赖的package包名:

ros2-topic-sample.bb

DESCRIPTION = "Example of minimal publisher/subscriber using rclcpp."
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://package.xml \
    file://CMakeLists.txt \
    file://src/publisher_member_function.cpp \
    file://src/subscriber_member_function.cpp \
    "

S = "${WORKDIR}/"

DEPENDS = "rclcpp std-msgs ament-cmake-native"

# NOTE: unable to map the following CMake package dependencies: rclcpp ament_lint_auto std_msgs ros_ament_cmake
inherit ros_ament_cmake

然后执行如下指令编译该文件:

bitbake ros2-topic-sample

编译成功以后别忘了添加到image里面打包,可以直接加在image的bb文件或者packagegroup的bb文件中均可:

相关推荐
TENET-1 天前
计算机组成原理
嵌入式·数字电路·计算机组成原理
KINO321 天前
51单片机外部中断(按键识别)
单片机·51单片机·嵌入式
Curious!2 天前
launch 中可执行文件 type
ros
几度春风里2 天前
嵌入式Linux系统编程 — 6.2 signal和 sigaction信号处理函数
嵌入式·linux系统编程·信号处理函数
Hello Mr.Z2 天前
Cortex-A510——SMMU
嵌入式·arm·smmu
EQUINOX13 天前
【Chapter4】汇编语言及其程序设计,《微机系统》第一版,赵宏伟
开发语言·嵌入式
正点原子3 天前
【正点原子K210连载】 第十二章 跑马灯实验 摘自【正点原子】DNK210使用指南-CanMV版指南
c语言·嵌入式
万俟淋曦3 天前
[ROS 系列学习教程] 建模与仿真 - 使用 ros_control 控制差速轮式机器人
人工智能·ai·机器人·ros·ros_control
TENET-3 天前
计算机组成原理——寄存器
嵌入式·数字电路·计算机组成原理
Mr.Winter`5 天前
ROS2从入门到精通2-2:详解机器人3D可视化工具Rviz2与案例分析
3d·机器人·自动驾驶·ros·ros2