十二、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文件中均可:

相关推荐
网易独家音乐人Mike Zhou2 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
古月居GYH20 小时前
ROS一键安装脚本
人工智能·机器人·ros
DeepAlchemy20 小时前
ROSSERIAL与Arduino IDE交叉开发(UBUNTU环境,包含ESP32、arduino nano)
c++·单片机·ros·rosserial
jjyangyou2 天前
物联网核心安全系列——智能汽车安全防护的重要性
算法·嵌入式·产品经理·硬件·产品设计
FreakStudio2 天前
全网最适合入门的面向对象编程教程:59 Python并行与并发-并行与并发和线程与进程
python·单片机·嵌入式·面向对象·电子diy·电子计算机
憧憬一下3 天前
UART硬件介绍
arm开发·嵌入式硬件·串口·嵌入式·linux驱动开发
佳肴3 天前
BT04-E蓝牙模块
嵌入式
Mr.Winter`4 天前
轨迹优化 | 基于Savitzky-Golay滤波的无约束路径平滑(附ROS C++/Python仿真)
人工智能·算法·机器人·自动驾驶·ros·ros2·数值优化
huanggang9825 天前
在Ubuntu22.04上源码构建ROS noetic环境
ros·ubuntu 22.04
找不着地窖的皮险家6 天前
ROS Action
c++·机器人·ros