话题的发布者
- 导入消息类型,ros自带的消息类型在
std_msgs/msg/
下面,有string等类型 - 定义一个类,里面声明一个发布者话题的共享指针,指针标注发布的数据类型
- 在构造函数中使用
create_publisher
创建声明的这个发布者对象,也可以在声明时创建对象。
- 声明一个发布者的类(发布者对象、发布数据的函数)
#include "rclcpp/rclcpp.hpp"
// 1. 导入消息类型
#include "std_msgs/msg/string.hpp"
// 定义一个有发布者的类,里面包含发布者对象
class publisher: public rclcpp::Node
{
private:
// 2.声明一个发布者用于发布消息,这里只是定义,也可以在这里对其进行初始化,我这里在构造函数里面进行初始化
// 发布者名称为pub_er,用共性指针声明对象,<std_msgs::msg::String>表示要发布的数据类型
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_er;
public:
// 定义一个发布话题的函数,声明类对象调用该函数发布数据。
publisher(std::string name);
~publisher();
void publish_data();
};
publisher::publisher(std::string name):Node(name)
{
//发布者的构造函数
RCLCPP_INFO(this->get_logger(),"create publisher");
// 3. 创造一个发布者
// 使用create_publisher这个函数创建发布者对象,并声明一下他的发布的数据类型
// 两个参数,一个是发布的话题名称,参数是队列长度,暂时填一个数字10
pub_er = this->create_publisher<std_msgs::msg::String>("topic_name",10);
}
// 析构函数,该函数在释放对象后调用,或者按CTRL+C后调用
publisher::~publisher()
{RCLCPP_INFO(this->get_logger(),"delete publisher");}
// 调用该函数,使用发布者把数据发布出去
void publisher::publish_data()
{
// 声明一个存储数据的对象
std_msgs::msg::String text_data;
// 向对象中存储数据要调用该数据类型对象的data
text_data.data="abcdefg";
pub_er->publish(text_data);
}
- 主函数调用发布者独享
int main(int argc, char ** argv)
{
rclcpp::init(argc,argv);
// 声明一个节点对象,该节点的类型是我们是声明的 发布者类
auto node = std::make_shared<publisher>("my_publishr");
while(1)
{
sleep(3);
node->publish_data();
}
rclcpp::spin(node);
rclcpp::shutdown();
}
话题的订阅者
- 声明一个订阅者的类
// 创建一个订阅者的类
class subscriber : public rclcpp::Node
{
private:
// 声明一个话题的订阅者,发布者为sub_er
// clcpp::Subscription是一个模板类,要订阅的话题类型为std_msgs::msg::String
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr sub_er;
// 声明一个订阅者的回调函数,回调函数用于当我们接收到发布者的数据后做的反应
// 参数是一个共享指针,指针的类型就是发布者发布的类型
void callback(const std_msgs::msg::String::SharedPtr publish_data)
{
//收到数据后的处理逻辑
// 这里只是把订阅到的数据打印输出一下
RCLCPP_INFO(this->get_logger(),"data:%s",publish_data->data.c_str());
}
public:
subscriber(std::string name);
~subscriber();
};
subscriber::subscriber(std::string name):Node(name)
{
//订阅者的构造函数
RCLCPP_INFO(this->get_logger(),"create subscriber");
//构造函数里面创建订阅者
//使用create_subscription这个来给声明的订阅者来创建一个实体
//create_subscriptionde第一个参数是:订阅的话题名称,第二个参数是队列长度
//成员函数不能只用当做参数进行回调,成员函数需要一个对象来调用,可以使用bind
sub_er = this->create_subscription<std_msgs::msg::String>("topic_name",10,std::bind(&subscriber::callback,this,_1));
}
subscriber::~subscriber()
{ RCLCPP_INFO(this->get_logger(),"delete subscriber"); }
- 主函数声明这个订阅者对象
int main(int argc, char ** argv)
{
rclcpp::init(argc,argv);
auto node = std::make_shared<subscriber>("my_subscriber");
rclcpp::spin(node);
rclcpp::shutdown();
}
自定义话题的接口类型
-
在包的src的同级目录下,不是工程目录的src同级目录下创建msg文件夹
-
在msg文件夹下创建Xxx.msg文件(文件首字母大写,不能包含_下划线等符号)
-
在Xxx.msg文件中添加消息类型
-
在CmakeList.txt文件和package.xml文件中添加依赖、msg文件的目录
-
创建一个msg文件,文件名为Novel.msg
# 添加一个string类型和图片类型
# 调用原有的string类型
string content
# 调用以后的图片类型
sensor_msgs/Image image
# 数组的话直接在数据类型后面加数组的中括号,例如:
# string[] content
- 修改CMakeLists.txt文件
主要是添加依赖(find_package和rosidl_generate_interfaces)
# 添加我们要引入数据类型的依赖包
find_package(sensor_msgs REQUIRED) # sensor_msgs/Image
# 自定义数据类型还需要一个rosidl_default_generators
find_package(rosidl_default_generators REQUIRED)
# 自定义数据类型还需要添加一个rosidl_generate_interfaces
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Novel.msg" #这里是指明msg文件的目录和名称
DEPENDENCIES sensor_msgs) # 这里需要填上这个类型所需的依赖
- 修改package.xml文件
<depend>sensor_msgs</depend> <!-- 这个是数据类型的依赖 -->
<!-- 下面三项是需要添加的东西 -->
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
将自定义的话题引入到程序中
- 代码中引入头文件和声明一个订阅者
// 引入自定义话题接口的头文件
// 表示在ros2_publisher包或目录下的msg目录下,文件名为Novel
#include <ros2_publisher/msg/Novel.hpp>
// 定义一个自定义话题数据类型的对象
ros2_publisher::msg::Novel publish_data_interface;
// 声明一个自定义数据类型的发布者
rclcpp::Publisher<ros2_publisher::msg::Novel>::SharedPtr num_publisher=this->create_publisher<ros2_publisher::msg::Novel>("topic_name",20);
- 修改CMakeLists.txt文件
添加自定义数据类型的包依赖
find_package(ros2_publisher REQUIRED)
在ament_target_dependencies中添加包依赖名
ament_target_dependencies(
my_publisher
"std_msgs"
"rclcpp"
ros2_publisher
)
- 修改package.xml文件
添加定义数据类型的包
<depend>ros2_publisher</depend>