(五)ROS2学习--创建调用其它包接口的一个发布者

一、背景

主机:Ubuntu20.04
介绍:基于上一篇(四)ROS2学习–第一个ROS2项目(创建一个客制化接口),本片教程将会在新的包里面创建新的发布者publisher,发布到上一篇文章创建的topic,另外创建新的接收者subscriber也可以参考本篇文章。

二、构建步骤

1. 构建项目包

  • 首先打开上一篇文章所用到的源码目录
cd <Your project path>/ros2_01/src
  • 创建ROS2项目包及msg
ros2 pkg create --build-type ament_cmake car_publish_test
mkdir car_publish_test/msg

创建完成后项目目录结构如下

.
├── build.sh
└── src
    ├── car_publish_test
    │   ├── CMakeLists.txt
    │   ├── include
    │   │   └── car_publish_test
    │   ├── msg
    │   ├── package.xml
    │   └── src
    └── smart_car
        ├── CMakeLists.txt
        ├── include
        │   └── smart_car
        ├── msg
        │   └── Car.msg
        ├── package.xml
        └── src
            ├── publish_car.cpp
            └── subscriber_car.cpp

11 directories, 8 files

2. 创建消息接口

  • 创建msg文件
    既然要用到上一篇文章创建的接口,就必然与上一个包里的msg文件有所关联,所以我们在路径“ros2_01/src/car_publish_test/msg/”目录下创建一个.msg文件,命名为Car.msg,内容如下:
smart_car/Car[] car

3. 修改“package.xml”

在"package.xml"中添加项目编译时依赖rosidl_default_generators及运行时依赖rosidl_default_runtime及依赖所在的组别。同时,此包依赖上一篇文章中生成的"smart_car", 也要添加编译和运行依赖。添加后的文件内容如下(需要自行修改项目描述description,作者信息maintainer ,以及遵从的license) :

<?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>car_publish_test</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="your email address">Your name</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>
  
  <buildtool_depend>rosidl_default_generators</buildtool_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>
  
  <build_depend>smart_cat</build_depend>
  <exec_depend>smart_cat</exec_depend>

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

4. 修改"src/smart_car/CMakeLists.txt"

将添加以下内容:

  • 配置msg文件到保存 msg文件列表 的变量中。
  • 添加编译对“smart_car” 包的依赖
  • 通过配置的msg_files变量,rosidl_generate_interfaces接口 将消息列表添加到项目中
  • 添加运行时依赖rosidl_default_runtime
  • find_package(rclcpp REQUIRED)查找编译发布者程序依赖的“rclcpp”包。
  • 最终添加发布者程序编译及安装操作,切记添加"rosidl_target_interfaces"的接口,确保可以使用自定义的接口
set(msg_files
  "msg/Car.msg"
)

find_package(smart_car REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  DEPENDENCIES smart_car
)

ament_export_dependencies(rosidl_default_runtime)

find_package(rclcpp REQUIRED)

add_executable(publish_car_test src/publish_car_test.cpp)
ament_target_dependencies(publish_car_test rclcpp)

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

rosidl_target_interfaces(publish_car_test 
  ${PROJECT_NAME} "rosidl_typesupport_cpp")

5. 创建发布者程序

发布者程序“ros2_01/src/car_publish_test/src/publish_car_test.cpp”。
示例代码内容如上篇文章中发布者程序一致:

#include <chrono>
#include <memory>

#include "rclcpp/rclcpp.hpp"
#include "smart_car/msg/car.hpp" //包含信息列表的头文件, 规则举例Car.msg->car.h;CarAbc.msg->car_abc.h

using namespace std::chrono_literals;
//以下创建一个节点及一个 smart_car TOPIC的发布者
class CarPublisher : public rclcpp::Node
{
public:
  CarPublisher()
  : Node("smart_car_publisher")
  {
    smart_car_publisher_ =
      this->create_publisher<smart_car::msg::Car>("smart_car", 100);

//以下创建一个定时回调函数
    auto publish_msg = [this]() -> void {
        auto message = smart_car::msg::Car();

        message.direction = message.D_DOWN;
        message.note = "this is for test 2 ! ";

        RCLCPP_INFO(this->get_logger(), "Direction: '%d' note: '%s'", message.direction, message.note.c_str());

        this->smart_car_publisher_->publish(message);
      };
    //创建一个定时器,使每秒调用一次publish_msg函数
    timer_ = this->create_wall_timer(1s, publish_msg);
  }

private:
  //变量声明
  rclcpp::Publisher<smart_car::msg::Car>::SharedPtr smart_car_publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
};


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

  return 0;
}

三、编译及验证

首先回到项目的根目录ros2_01

1. 编译

  • 编译依赖包
    注意,因为本篇所生成的包依赖上篇文章生成的"smart_car"的包,因此需要先编译及使能“smart_car”,但如果已经编译及使能则可以忽略
colcon build --packages-up-to smart_car
source install/local_setup.bash
  • 编译 “car_publish_test”包
colcon build --packages-up-to car_publish_test

2. 验证

执行以下命令使发布者程序运行如下:

source install/local_setup.bash
ros2 run car_publish_test publish_car_test

结果如下:
在这里插入图片描述
在新的窗口打开上一篇文章"smart_car"包中的接收者节点,结果如下:
在这里插入图片描述
同时打开"smart_car"中的发布者程序和"car_publish_test"中的发布者程序结果会出现有意思的事情,接收者可以同时接收两个发布者所发布的不同信息如下:
在这里插入图片描述

代码已附

最近更新

  1. TCP协议是安全的吗?

    2024-04-03 21:54:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-03 21:54:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-03 21:54:01       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-03 21:54:01       20 阅读

热门阅读

  1. 2_C语言分支与循环

    2024-04-03 21:54:01       13 阅读
  2. SCG K8S(Spring Cloud Gateway Kubernetes)一直报503错误

    2024-04-03 21:54:01       16 阅读
  3. 蓝桥杯-跳石头

    2024-04-03 21:54:01       11 阅读
  4. Linux Shell,遍历数组或文件的几种不同写法

    2024-04-03 21:54:01       13 阅读
  5. 执行SQL分析打印

    2024-04-03 21:54:01       11 阅读
  6. 人工智能常用的编程语言有哪些?

    2024-04-03 21:54:01       14 阅读
  7. 蓝桥杯_阅读魔法书(字符串匹配)

    2024-04-03 21:54:01       12 阅读
  8. 01---webpack的基础篇

    2024-04-03 21:54:01       11 阅读
  9. 蓝桥杯软件测试赛项--自动化测试

    2024-04-03 21:54:01       11 阅读