1创建自定义消息
1.1. 创建工作空间
mkdir -p ros2_ws/src
1.2.创建功能包
cd ros2_ws/src
ros2 pkg create msg_pkg --build-type ament_cmake --dependencies rclcpp std_msgs
1.3.创建消息
在功能包msg_pkg中创建msg文件夹,并在msg目录中创建消息文件.类型.msg. 如Student.msg和Class.msg(切记消息类型首字母大写)
cd msg_pkg
mkdir msg
Student.msg中内容如下:
string name
int16 age
Class.msg中内容如下:
int16 id
Student[] students #当引用同一包中的消息时不需要加包名.如果在其他中中引用需要加上包名msg_pkg/Student[] students
1.4.修改CMakeLists.txt
添加如下代码段
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
#========================================
# 自定义消息
find_package(geometry_msgs REQUIRED)
find_package(rosidl_default_generators REQUIRED)
set(msg_files
"msg/Student.msg"
"msg/Class.msg"
)
rosidl_generate_interfaces(${PROJECT_NAME}
${msg_files}
DEPENDENCIES std_msgs geometry_msgs
)
ament_export_dependencies(rosidl_default_runtime)
#========================================
1. 5.修改package.xml
添加如下代码段
<!--添加自定义消息-->
<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
<!--添加自定义消息-->
1.6.编译并查看
1.6.1.编译
返回到工作空间目录下.这里是ros2_ws目录下,执行如下命令进行编译
colcon build --packages-up-to objectsDetection
1.6.2.查看
. install/local_setup.bash
ros2 interface package msg_pkg
出现如下消息类型,则成功
2.同一个包下使用自定义消息(简单的发布者和订阅者)
注意点:在同一个包中使用自定义消息在CMakeLists.txt中必须添加如下代码段,不然找不的自定义消息的头文件
rosidl_target_interfaces(classPlush
${PROJECT_NAME} "rosidl_typesupport_cpp")
2.1 发布者(在msg_pkg功能包的src中添加push.cpp)
#include <sys/time.h>
#include <algorithm>
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <msg_pkg/msg/class.hpp>
#include <msg_pkg/msg/student.hpp>
#include <rclcpp/rclcpp.hpp>
#include <vector>
static volatile int keepRunning = 1;
void signal_handler(int signum) {
printf("signal_handler: caught signal %d\n", signum);
if (signum == SIGINT) {
keepRunning = 0;
// SLAM.Shutdown();
}
}
int main(int argc, char const *argv[]) {
if (signal(SIGINT, signal_handler) == SIG_ERR) {
printf("Failed to caught signal\n");
} else {
std::cout << "signal_handler ok" << std::endl;
}
/* 初始化rclcpp */
rclcpp::init(argc, argv);
/*产生一个节点*/
auto node = std::make_shared<rclcpp::Node>("classPlus");
RCLCPP_INFO(node->get_logger(), "RosNode_1节点已经启动.");
rclcpp::Publisher<msg_pkg::msg::Class>::SharedPtr clss_pub =
node->create_publisher<msg_pkg::msg::Class>("classMesag", 1);
int i = 0;
msg_pkg::msg::Class cl;
while (keepRunning) {
msg_pkg::msg::Student stu;
stu.age = i * 10 + 1;
stu.name = "stu" + std::to_string(i);
cl.students.push_back(stu);
if (i % 5 == 0) {
cl.id = i;
clss_pub->publish(cl);
std::cout << "publish end" << std::endl;
}
i++;
}
rclcpp::shutdown();
return 0;
}
2.1.1 修改CMakeLists.txt
添加如下代码段
#=========================================
#发布者
add_executable(classPlush src/push.cpp)
target_link_libraries(classPlush rclcpp::rclcpp )
rosidl_target_interfaces(classPlush
${PROJECT_NAME} "rosidl_typesupport_cpp")
#注册可执行文件
install(TARGETS classPlush
DESTINATION lib/${PROJECT_NAME}
)
#=========================================
2.1.2 编译并查看可执行文件
2.1.2.1 编译(同上)
colcon build --packages-up-to objectsDetection
2.1.2.2 查看可执行文件
ros2 pkg executables msg_pkg
若没有对应可执行文件classPlush出现或者运行报出如下错误,那是因为在CMakeLists.txt中没有加入install(TARGETS classPlush DESTINATION lib/${PROJECT_NAME} )
进行注册.
No executable found
2.1.3 执行并订阅查看
2.1.3.1 执行
ros2 run msg_pkg classPlush
2.1.3.2 查看
2.2 订阅者(编译修改同上)
#include <memory>
#include <msg_pkg/msg/class.hpp>
#include <msg_pkg/msg/student.hpp>
#include "rclcpp/rclcpp.hpp"
using std::placeholders::_1;
class MinimalSubscriber : public rclcpp::Node {
public:
MinimalSubscriber() : Node("classSub") {
subscription_ = this->create_subscription<msg_pkg::msg::Class>(
"classMesag", 10,
std::bind(&MinimalSubscriber::topic_callback, this, _1));
}
private:
void topic_callback(const msg_pkg::msg::Class::SharedPtr msg) const {
std::cout << "clssid: " << msg->id << std::endl;
for (int i = 0; i < msg->students.size(); i++) {
msg_pkg::msg::Student std = msg->students[i];
std::cout << "age: " << std.age << std::endl;
}
}
rclcpp::Subscription<msg_pkg::msg::Class>::SharedPtr subscription_;
};
int main(int argc, char* argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<MinimalSubscriber>());
rclcpp::shutdown();
return 0;
}