主题是充当管道的通道,其他ROS节点可以在该通道上发布或读取信息。我们下面来进行ros2话题编程。
(运行环境Ubuntu18.04+ros2Dashing)
我们首先创建一个名为topic_publisher_pkg的新软件包。 创建程序包时,添加rclcpp和std_msgs作为依赖项。
为了创建一个具有roscpp和std_msgs作为依赖关系的包,您应该使用以下命令:
[ ]: ros2 pkg create topic_publisher_pkg --build-type ament_cmake --dependencies rclcpp std_msgs
在src文件夹下创建一个simple_topic_publisher.cpp
//导入必要的rclcpp库
#include "rclcpp/rclcpp.hpp"
//从std_msgs功能包导入int32消息类型
#include "std_msgs/msg/int32.hpp"
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
//创建一个名为simple_publisher的节点,返回句柄node
auto node = rclcpp::Node::make_shared("simple_publisher");
//创建publisher,发布名为counter的topic,消息类型为std_msgs::msg::Int32
auto publisher= node->create_publisher<std_msgs::msg::Int32>("counter",10);
//定义一个std_msgs::msg::Int32类型的消息
std_msgs::msg::Int32 message;
//初始化为0
message.data = 0;
//设置循环频率
rclcpp::WallRate loop_rate(2);
//创建一个循环直到有人打破它
while (rclcpp::ok()) {
//发布消息
publisher->publish(message);
//data自加一
message.data++;
rclcpp::spin_some(node);
//延时
loop_rate.sleep();
}
rclcpp::shutdown();
return 0;
}
在cmake文件添加
add_executable(simple_publisher_node src/simple_topic_publisher.cpp)
ament_target_dependencies(simple_publisher_node rclcpp std_msgs)
install(TARGETS
simple_publisher_node
DESTINATION lib/${PROJECT_NAME}
)
编译完成后运行
ros2 run topic_publisher_pkg simple_publisher_node
运行节点
虽然什么也没有发生,但是刚刚创建了一个名为“/counter”话题,我们可以用下面这条指令输出它:
ros2 topic echo /counter
data: 59
data: 60
data: 61
data: 62
data: 63
data: 64
...
但是,在ROS2中,上面这种编码风格将被弃用,这是因为Composition(组成)。在ROS2中,与ROS1的显着区别是引入了Composition(组合)的概念。从根本上讲,这意味着您将能够在单个进程中组合(执行)多个节点。您可以在这里阅读更多有关它的信息:https://index.ros.org/doc/ros2/Composition/
但是,为了能够使用节点组合,您将需要以更加面向对象的方式对脚本进行编程。因此,您检查的第一个脚本simple_topic_publisher.cpp将无法使用节点组成,在下面,您可以看一下执行完全相同的操作的脚本,但是该脚本是使用可组合的方法和类进行编码的。
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/int32.hpp"
#include <chrono>
using namespace std::chrono_literals;
//定义一个类,继承自rclcpp::Node
class SimplePublisher : public rclcpp::Node
{
public:
//构造函数调用基类构造函数初始化节点,幷初始化变量count_为0
SimplePublisher()
: Node("simple_publisher"), count_(0)
{
//创建publisher,发布名为counter的topic,消息类型为std_msgs::msg::Int32
publisher_ = this->create_publisher<std_msgs::msg::Int32>("counter",10);
//创建timer对象,绑定到timer_callback函数,该timer对象将眉500ms被触发
timer_ = this->create_wall_timer(
500ms, std::bind(&SimplePublisher::timer_callback, this));
}
private:
//上述的timer_callback函数
void timer_callback()
{
//同样的创建一个message,并将count赋给他,然后count自加
auto message = std_msgs::msg::Int32();
message.data = count_;
count_++;
//发布message
publisher_->publish(message);
}
//定义上面用到的发布者和计时器(timer)的对象
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr publisher_;
size_t count_;
};
int main(int argc, char *argv[])
{
rclcpp::init(argc, argv);
//创建一个SimplePublisher的对象,并使其运行直到有人关闭它(例如ctrl+c)
rclcpp::spin(std::make_shared<SimplePublisher>());
rclcpp::shutdown();
return 0;
}
同样在cmake文件添加
add_executable(simple_topic_publisher_composable src/simple_topic_publisher_composable.cpp)
ament_target_dependencies(simple_topic_publisher_composable rclcpp std_msgs)
install(TARGETS
simple_publisher_node
simple_topic_publisher_composable #在install原来的基础上添加这一句
DESTINATION lib/${PROJECT_NAME}
)
使用colcon build编译后运行:
ros2 run topic_publisher_pkg simple_topic_publisher_composable
同样使用ros2 topic echo counter可以看到和上面那个节点一样的输出。
(文章主要翻译自ROS2-IN-5-DAYS-e-book,并在其基础上根据版本修改了一些东西)
git
https://github.com/DylanLN/oryxbot_ws-ros2后续会慢慢更新。