在ROS 2中,使用C++来构建和调用自定义消息类型的步骤与Python版本相似。下面是如何使用C++版构建自定义消息类型并调用它的详细过程。
一、构建自定义消息类型
1. 创建ROS 2包
首先,创建一个ROS 2包来存放自定义消息,并声明其依赖于rosidl_default_generators
ros2 pkg create my_custom_msgs --build-type ament_cmake --dependencies rosidl_default_generators
2. 定义自定义消息类型
在my_custom_msgs
包中创建msg
目录并定义.msg
文件
mkdir -p my_custom_msgs/msg
例如,创建MyCustomMsg.msg
文件:
# my_custom_msgs/msg/MyCustomMsg.msg
int32 id
string name
float32 value
3. 修改CMakeLists.txt
在CMakeLists.txt
文件中,添加对自定义消息类型生成的支持:
find_package(rosidl_default_generators REQUIRED)
# 定义消息文件
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/MyCustomMsg.msg"
)
4. 修改package.xml
在package.xml
文件中,声明对rosidl_default_generators
的依赖:
<build_depend>rosidl_default_generators</build_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
5. 编译自定义消息
编写完消息文件后,使用colcon
进行编译:
colcon build --packages-select my_custom_msgs
source install/setup.bash
二、调用自定义消息(C++版)
1. 编写发布节点
创建一个发布自定义消息的C++节点:
// my_custom_msgs_pub.cpp
#include <rclcpp/rclcpp.hpp>
#include "my_custom_msgs/msg/my_custom_msg.hpp"
class CustomMsgPublisher : public rclcpp::Node {
public:
CustomMsgPublisher() : Node("custom_msg_publisher") {
publisher_ = this->create_publisher<my_custom_msgs::msg::MyCustomMsg>("custom_topic", 10);
timer_ = this->create_wall_timer(
std::chrono::seconds(1),
std::bind(&CustomMsgPublisher::publish_message, this)
);
}
private:
void publish_message() {
auto message = my_custom_msgs::msg::MyCustomMsg();
message.id = 1;
message.name = "example";
message.value = 42.0;
RCLCPP_INFO(this->get_logger(), "Publishing: id=%d, name=%s, value=%f",
message.id, message.name.c_str(), message.value);
publisher_->publish(message);
}
rclcpp::Publisher<my_custom_msgs::msg::MyCustomMsg>::SharedPtr publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};
int main(int argc, char * argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<CustomMsgPublisher>());
rclcpp::shutdown();
return 0;
}
2. 编写订阅节点
创建一个订阅自定义消息的C++节点:
// my_custom_msgs_sub.cpp
#include <rclcpp/rclcpp.hpp>
#include "my_custom_msgs/msg/my_custom_msg.hpp"
class CustomMsgSubscriber : public rclcpp::Node {
public:
CustomMsgSubscriber() : Node("custom_msg_subscriber") {
subscription_ = this->create_subscription<my_custom_msgs::msg::MyCustomMsg>(
"custom_topic", 10, std::bind(&CustomMsgSubscriber::topic_callback, this, std::placeholders::_1));
}
private:
void topic_callback(const my_custom_msgs::msg::MyCustomMsg::SharedPtr msg) const {
RCLCPP_INFO(this->get_logger(), "Received: id=%d, name=%s, value=%f",
msg->id, msg->name.c_str(), msg->value);
}
rclcpp::Subscription<my_custom_msgs::msg::MyCustomMsg>::SharedPtr subscription_;
};
int main(int argc, char * argv[]) {
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<CustomMsgSubscriber>());
rclcpp::shutdown();
return 0;
}
3. 修改CMakeLists.txt
文件
在CMakeLists.txt
中,添加对这两个节点的编译规则:
# 添加可执行文件和依赖
add_executable(my_custom_msgs_pub src/my_custom_msgs_pub.cpp)
ament_target_dependencies(my_custom_msgs_pub rclcpp my_custom_msgs)
add_executable(my_custom_msgs_sub src/my_custom_msgs_sub.cpp)
ament_target_dependencies(my_custom_msgs_sub rclcpp my_custom_msgs)
# 安装可执行文件
install(TARGETS
my_custom_msgs_pub
my_custom_msgs_sub
DESTINATION lib/${PROJECT_NAME}
)
4. 编译代码
编译整个包,包括发布和订阅节点:
colcon build --packages-select my_custom_msgs
source install/setup.bash
三、运行节点
1. 运行发布节点
首先运行发布节点,开始发布自定义消息:
ros2 run my_custom_msgs my_custom_msgs_pub
2. 运行订阅节点
然后运行订阅节点,接收并打印自定义消息:
ros2 run my_custom_msgs my_custom_msgs_sub
这样,你就成功使用C++构建并调用了自定义消息类型。