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 )
add_message_files( FILES RobotPosition.msg )
generate_messages( DEPENDENCIES std_msgs )
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()