Tạo và Sử Dụng Tin Nhắn Tùy Chỉnh Trong ROS

Trong giao thức truyền thông của ROS, dữ liệu được truyền theo cấu trúc đã định nghĩa trước, chẳng hạn như các loại tin nhắn (msg) cho Topic hoặc dịch vụ (srv). Các loại dữ liệu cơ bản trong std_msgs của ROS thường không đáp ứng đủ nhu cầu phức tạp, do đó ta có thể sử dụng tin nhắn tùy chỉnh.

Tạo RobotPosition.msg

Tạo thư mục `msg` ở cùng cấp với thư mục `src`, sau đó tạo tệp `RobotPosition.msg` bên trong thư mục `msg`:

string robot_id
float64 pos_x
float64 pos_y
float64 orientation

Cấu Hình Tệp CMakeLists.txt

Cần thực hiện một số thay đổi để đảm bảo msg được xử lý đúng cách:

  • Thêm gói `message_generation` vào phần tìm kiếm gói:
  • find_package(catkin REQUIRED COMPONENTS
      roscpp
      rospy
      std_msgs
      message_generation
    )
    
  • Thêm file msg mới:
  • add_message_files(
      FILES
      RobotPosition.msg
    )
    
  • Định nghĩa các phụ thuộc cần thiết và tạo các tệp giao diện:
  • generate_messages(
      DEPENDENCIES
      std_msgs
    )
    
  • Thêm phụ thuộc thời gian chạy:
  • catkin_package(
      CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
    )
    

Thực Hiện Publisher Và Subscriber (Phiên Bản C++)

Tạo hai tệp `robot_pub.cpp` và `robot_sub.cpp` trong thư mục `src`:

// robot_pub.cpp
#include <ros/ros.h>
#include "your_pkg/RobotPosition.h"

int main(int argc, char **argv) {
    ros::init(argc, argv, "robot_publisher");
    ros::NodeHandle nh;
    ros::Publisher pub = nh.advertise<your_pkg::RobotPosition>("/robot_position", 10);
    
    your_pkg::RobotPosition pose;
    pose.robot_id = "bot_1";
    pose.pos_x = 25.5;
    pose.pos_y = 17.8;
    pose.orientation = 45.0;

    while(ros::ok()) {
        pub.publish(pose);
        ROS_INFO("Publishing robot: %s, position(%lf, %lf, %lf)", pose.robot_id.c_str(), pose.pos_x, pose.pos_y, pose.orientation);
        ros::Duration(1).sleep();
        ros::spinOnce();
    }
}
// robot_sub.cpp
#include <ros/ros.h>
#include "your_pkg/RobotPosition.h"

void robotCallback(const your_pkg::RobotPosition::ConstPtr &pose) {
    ROS_INFO("Subscribed robot: %s, position(%lf, %lf, %lf)", pose->robot_id.c_str(), pose->pos_x, pose->pos_y, pose->orientation);
}

int main(int argc, char **argv) {
    ros::init(argc, argv, "robot_subscriber");
    ros::NodeHandle nh;
    ros::Subscriber sub = nh.subscribe<your_pkg::RobotPosition>("/robot_position", 10, robotCallback);
    ros::spin();
}

Thực Hiện Publisher Và Subscriber (Phiên Bản Python)

Tạo hai tập lệnh `robot_pub.py` và `robot_sub.py` trong thư mục `scripts`:

# robot_pub.py
#!/usr/bin/env python

import rospy
from your_pkg.msg import RobotPosition

def main():
    rospy.init_node('robot_publisher')
    pub = rospy.Publisher('/robot_position', RobotPosition, queue_size=10)
    msg = RobotPosition()
    msg.robot_id = "bot_2"
    msg.pos_x = 30.0
    msg.pos_y = 20.0
    msg.orientation = 90.0

    while not rospy.is_shutdown():
        pub.publish(msg)
        rospy.loginfo("Publishing robot: {}, position({}, {}, {})".format(msg.robot_id, msg.pos_x, msg.pos_y, msg.orientation))
        rospy.sleep(1)

if __name__ == '__main__':
    main()
# robot_sub.py
#!/usr/bin/env python

import rospy
from your_pkg.msg import RobotPosition

def robot_callback(msg):
    rospy.loginfo("Subscribed robot: {}, position({}, {}, {})".format(msg.robot_id, msg.pos_x, msg.pos_y, msg.orientation))

def main():
    rospy.init_node('robot_subscriber')
    rospy.Subscriber('/robot_position', RobotPosition, robot_callback, queue_size=10)
    rospy.spin()

if __name__ == '__main__':
    main()

Thẻ: ROS message_customization C++ python topic_communication

Đăng vào ngày 6 tháng 7 lúc 14:51