跳转至

自定义msg

1. 自定义topic消息

1.1 创建package

ros2 pkg create --build-type ament_cmake msg_srv

可以修改package.xml文件如下信息

<description>C++ client server tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

1.2 在工程下创建msg文件夹,创建Num.msg文件并填写如下内容

int64 num

1.3 配置cmake

find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/Num.msg"
)

出现如下问题

Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES OPENSSL_INCLUDE_DIR) 

执行如下命令即可

sudo apt-get install libssl-dev

1.4 配置package.xml文件

<build_depend>rosidl_default_generators</build_depend>

<exec_depend>rosidl_default_runtime</exec_depend>

<member_of_group>rosidl_interface_packages</member_of_group>

1.5 编译工程

colcon build --packages-select msg_srv

1.6 显示消息详情

ros2 interface show msg_srv/msg/Num

2. 使用自定义的topic消息

2.1 c++使用

publisher和subscriber代码实现

publisher

#include <iostream>
#include "rclcpp/rclcpp.hpp"
#include <msg_srv/msg/num.hpp>
using namespace std;

class MyNode : public rclcpp::Node {
private:
    rclcpp::Publisher<msg_srv::msg::Num>::SharedPtr publisher;
    int size;
public:
    MyNode():Node("publisher_node"),size(0){
        publisher = this->create_publisher<msg_srv::msg::Num>(
                "cpp_topic", 10);
        rclcpp::Rate rate(1);
        while (rclcpp::ok()) {
            msg_srv::msg::Num msg;
            msg.num = size;
            publisher->publish(msg);
            rate.sleep();
            size += 1;
        }
    }
};

int main(int argc,char*argv[]){
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<MyNode>());
    rclcpp::shutdown();
    return 0;
}

subscriber

#include <iostream>
#include "rclcpp/rclcpp.hpp"
#include "msg_srv/msg/num.hpp"
using namespace std;

class MyNode : public rclcpp::Node {
private:
    rclcpp::Subscription<msg_srv::msg::Num>::SharedPtr subscription;
public:
    MyNode():Node("subscriber_node"){
        subscription = this->create_subscription<msg_srv::msg::Num>("cpp_topic",10,
                             std::bind(&MyNode::topic_call_back,this,std::placeholders::_1));
    }
    void topic_call_back(msg_srv::msg::Num ::SharedPtr msg){
        RCLCPP_INFO(this->get_logger(), "I heard: '%d'", msg->num);
    }
};

int main(int argc,char*argv[]){
    rclcpp::init(argc, argv);
    rclcpp::spin(std::make_shared<MyNode>());
    rclcpp::shutdown();
    return 0;
}

配置cmake

find_package(msg_srv REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
...
add_executable(publisher_msg src/publisher_msg.cpp)
add_executable(subscriber_msg src/subscriber_msg.cpp)

...
ament_target_dependencies(publisher_msg rclcpp std_msgs msg_srv)
ament_target_dependencies(subscriber_msg rclcpp std_msgs msg_srv)

install(TARGETS
        ...
        publisher_msg
        subscriber_msg
        DESTINATION lib/${PROJECT_NAME})

package.xml配置

<depend>msg_srv</depend>

编译工程

colcon build

运行节点

ros2 run cpp_pubsub publisher_msg 
ros2 run cpp_pubsub subscriber_msg

2.2 python使用

publisher和subscriber代码实现

publisher

import rclpy
from rclpy.node import Node
from msg_srv.msg import Num


class MyNode(Node):
    def __init__(self):
        super(MyNode, self).__init__('publisher_py')
        self.publisher = self.create_publisher(Num, 'py_topic', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = Num()
        msg.num = self.i
        self.publisher.publish(msg)
        self.get_logger().info('Publishing: "%d"' % msg.num)
        self.i += 1


def main():
    rclpy.init()
    node = MyNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

subscriber

import rclpy
from rclpy.node import Node
from msg_srv.msg import Num


class MyNode(Node):
    def __init__(self):
        super(MyNode, self).__init__('subscriber_node')
        self.subscription = self.create_subscription(Num, 'py_topic', self.msg_call_back, 10)

    def msg_call_back(self, msg):
        self.get_logger().info(f'msg:{msg.num}')


def main():
    rclpy.init()
    node = MyNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()


if __name__ == '__main__':
    main()

package.xml配置

<exec_depend>msg_srv</exec_depend>

setup.py配置

entry_points={
        'console_scripts': [
            ...
            'publisher_msg = py_pubsub.publisher_msg:main',
            'subscriber_msg = py_pubsub.subscriber_msg:main',
        ],
    },

编译工程

colcon build

运行节点

ros2 run py_pubsub publisher_msg 
ros2 run py_pubsub subscriber_msg