你ROS2的第一个Hello world项目

忙活了一中午,基本上摸清了如何使用colcon等工具编译一个自己的ROS2的项目。本文中,首先介绍了这么几个概念:节点(node)、主题(topic)、服务(services)。然后介绍了如何使用colcon来构建自己的包。本人的使用环境:ubuntu22.04,ROS2 Iron。我会提供源码给大家。本文参考:coze,ros2官网教程

1、激励实例

这一部分,我们提供了两个激励实例,先给大家看一看结果,一方面激发兴趣,另一方面明确这篇文章具体完成了什么任务。具体如何构建将会在后续详细介绍。

1.1 ROS2 初体验——使用绿毛龟(turtlesim)玩一玩

在这里插入图片描述
这里开了两个节点,一个是绿毛龟节点,另一一个是控制绿毛龟的节点。开启控制节点之后,键盘上下左右即可控制绿毛龟。这里的节点实际上就是执行特定任务的独立单元,节点之间可以进行通信。目前这个实例就是控制节点捕捉我们的键盘动作,然后将命令传递给绿毛龟节点,即完成控制。

1.2 ROS2 再体验——编译自己的包(talker & listener)

这里构建了两个节点:talker和listener。talker每1s发布一个topic,然后listener监听到topic之后打印下来。这就是经典的ROS2中的Hello word。
在这里插入图片描述

2、ROS2中的一些基本概念

  • 节点(node):就是一个执行特定任务的独立单元。你可以把它想象成一个程序或一个进程。在一个典型的ROS 2系统中,可能会有多个节点同时运行,每个节点都负责执行一个特定的任务。节点与节点之间可以进行通信。简单来说,节点是ROS 2系统中执行任务和处理数据的基本单位。

  • 话题(topic):异步通信方式,发出去就不管了,可以多对多。

  • 服务(service):同步通信方式,发出去之后要等待回应,可以一对多。
    在这里插入图片描述

  • 动作(action):是 ROS 2 中的通信类型之一,适用于长时间运行的任务。底层的三个话题和服务组成:一个任务目标(Goal,服务),一个执行结果(Result,服务),周期数据反馈(Feedback,话题)。

3、如何构建自己的包

3.1 玩绿毛龟

ros2 run turtlesim turtlesim_node    #运行绿毛龟节点
ros2 run turtlesim turtle_teleop_key #运行控制绿毛龟的节点

3.2 编译自己的包

3.2.1 新建包

ROS2中提供了一个colcon工具来管理构建。使用ros2 pkg create命令创建新包。这里的--build-type需要指定构建的类型:ament_pythonament_cmake--dependencies xxx xxx表示需要依赖的包。

ros2 pkg create --build-type ament_cmake note_communication --dependencies rclcpp std_msgs
3.2.2 查看新建包的结果

上述创建包之后,生成两个文件CMakeLists.txtpackage.xml。在ROS2中,package.xml文件是一个包的清单文件,它包含了关于包的元数据,例如包的名称、版本、作者、许可证信息,以及它与其他ROS软件包的依赖关系等。这个文件是用XML格式编写的,每个包必须有一个这样的文件。它的主要作用是帮助ROS的构建系统理解包的结构和依赖关系,以便正确地构建和链接它们。

3.2.3 编写talker和listener节点代码并且将至添加到CMakeLists.txt中

在src中,添加节点的实现代码(具体代码后续提供)。然后将两个节点添加到CMakeLists.txt中。

add_executable(talker ./src/talker.cpp)
ament_target_dependencies(talker rclcpp std_msgs)				#添加节点的依赖

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

install(TARGETS												    #添加安装路径
  talker
  listener
  DESTINATION lib/${PROJECT_NAME})

note_communication目录执行编译命令:

colcon build
3.2.4 运行节点
source ./install/setup.bash
ros2 run note_communication talker	# 跑talker节点

开一个新的终端:

source ./install/setup.bash
ros2 run note_communication listener	# 跑listener节点

搞定

4、代码分享

talker.cpp

#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>

int main(int argc, char const *argv[]){
  rclcpp::init(argc, argv);
  // 创建名字为talker的节点
  auto node = rclcpp::Node::make_shared("talker");
  
  // 在"chatter"这个主题上创建一个发布者,队列大小设为10
  auto chatter_pub = node->create_publisher<std_msgs::msg::String>("chatter", 10);
  rclcpp::Rate loop_rate(1); //控制主循环的频率,这里设定为每秒10次

  auto msg = std_msgs::msg::String();

  int index = 0;
  //主循环,只要ROS 2没有被关闭,就一直执行。
  while (rclcpp::ok()){
    msg.data = "Hello, world. " + std::to_string(index);
    RCLCPP_INFO(node->get_logger(), "Publishing: '%s'", msg.data.c_str());
    chatter_pub->publish(msg);//发布消息

    //循环等待回调函数
    rclcpp::spin_some(node);
    loop_rate.sleep();  //等待一段时间
    ++index;
  }
  rclcpp::shutdown();
  return 0;
}

listener.cpp

#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>

void chatterCallback(const std_msgs::msg::String::SharedPtr msg)
{
  RCLCPP_INFO(rclcpp::get_logger("listener"), "I heard: [%s]", msg->data.c_str());
}

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);
  // 创建名字为listener的节点
  auto node = rclcpp::Node::make_shared("listener");
  auto sub = node->create_subscription<std_msgs::msg::String>("chatter", 10, chatterCallback);
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

5、ROS2市场与安装已有包

ros资源网址,看清楚自己的ros2版本,以及是否可以通过apt指令安装。这里以rqt_robot_steering为例。

sudo apt-get install ros-iron-rqt-robot-steering #安装包
ros2 run rqt_robot_steering rqt_robot_steering   #启动包
ros2 run turtlesim turtlesim_node 				#启动绿毛龟节点

然后需要在rqt_robot_steering的最上面节点名称添加加上turtle1/cmd_vel,用来指示我们要控制turtle1。然后设定速度和角速度即可。

6、总结与反思

本人在好几年前接触过ROS1,我记得那时候在执行某个节点时,还需要首先开启一个ros::core节点。本人当时就在想,如果这个core节点挂掉,整个系统就会挂掉。在接触ROS2这两天之后,看来ROS2已经更改了这个特性,每个节点执行都有一定的独立性,类似于去中心化的分布的那个想法。但可以预见的一个疑问是,去中心化意味着整个系统不知道这些节点执行的先后顺序,对于一些注重执行步骤的任务,ROS2中是否存在一些机制能够胜任。

这篇博客,基本上都是标准化的流程,要弄清楚如何创建、编译、执行一个现有的/自己创建的包。其中,还添加了一些ROS2的一些基本概念,topic、service、action等。

### ROS 2 示例项目与教程 #### 安装和设置 ROS 2 为了开始使用 ROS 2,首先需要按照官方文档中的说明完成安装过程[^1]。这包括选择合适的操作系统版本以及遵循特定于操作系统的安装指南。 #### 创建第一个 ROS 2 包 创建一个新的工作空间,并初始化一个名为 `my_first_ros2_package` 的包: ```bash mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src ros2 pkg create my_first_ros2_package --build-type ament_python ``` 编辑 `setup.py` 文件来添加依赖项和其他元数据信息。接着,在新创建的 Python 文件夹内编写简单的发布者和订阅者的脚本。 对于发布者 (`talker_node.py`) 可能如下所示: ```python import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalPublisher(Node): def __init__(self): super().__init__('minimal_publisher') self.publisher_ = self.create_publisher(String, 'topic', 10) timer_period = 0.5 # seconds self.timer = self.create_timer(timer_period, self.timer_callback) def timer_callback(self): msg = String() msg.data = f'Hello World: {self.get_clock().now()}' self.publisher_.publish(msg) def main(args=None): rclpy.init(args=args) minimal_publisher = MinimalPublisher() rclpy.spin(minimal_publisher) minimal_publisher.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` 而对于订阅者 (`listener_node.py`) 则可以这样实现: ```python import rclpy from rclpy.node import Node from std_msgs.msg import String class MinimalSubscriber(Node): def __init__(self): super().__init__('minimal_subscriber') self.subscription = self.subscribe(String, 'topic', self.listener_callback, 10) def listener_callback(self, msg): self.get_logger().info('I heard: "%s"' % msg.data) def main(args=None): rclpy.init(args=args) minimal_subscriber = MinimalSubscriber() rclpy.spin(minimal_subscriber) minimal_subscriber.destroy_node() rclpy.shutdown() if __name__ == '__main__': main() ``` #### 使用启动文件运行多个节点 在实际应用中,经常需要同时启动多个节点。可以在 `launch` 文件夹里创建 `.launch.py` 文件来进行批量启动。例如,通过修改 `ros2_execution/` 下面的启动文件[^3] 来组合不同的功能模块一起运作。 #### 配置 Cartographer 地图构建工具 如果涉及到 SLAM 或导航任务,则可能需要用到像 Cartographer 这样的高级组件。此时应该查阅相应的配置文件位置及其作用[^4],以便调整参数以满足具体需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值