8. Tạo một ROS Subscriber

Search for a command to run...

Em cảm ơn anh
các hàm như subscriber() thì mình có thể coi ở doc nào vậy anh em tra mà ko có mong anh có thể trả lời
E tra Google "Ros + tên hàm" là nó ra. Ví dụ https://docs.ros.org/en/melodic/api/rospy/html/rospy.topics.Subscriber-class.html
Trong series này, mình sẽ giúp các bạn tìm hiểu và thực hành những khái niệm cơ bản của ROS (Robot Operating System) bằng cách tự tạo ra một con robot và cách điều khiển nó. Cùng bắt đầu nhé!
Hy vọng bạn vẫn nhớ một trong những lý do rất quan trọng mà chúng ta tìm hiểu ROS: "Don't reinvent the wheel", nghĩa là có rất nhiều package (hoặc project) thú vị có sẵn mà bạn có thể ứng dụng ngay hoặc không tốn nhiều công sức để triển khai trong RO...
As said in the previous post, I will not wait until the robot is complete and then make tutorials. This project log contains all the newest updates (ideas, changes, problems, etc.) that I encounter during this project from the start to the end. As al...

After the ROS 101 series, I am now planning to bring the mobile robot to life. Below are my rough idea and plan, but they will be updated regularly as the project grows. So stay tuned! The Idea The goal of this project is simple: to understand how al...

Trong chương cuối cùng của sê-ri ROS Cơ Bản này, chúng ta sẽ kết hợp mọi thứ đã học được cho đến nay để hoàn thành một nhiệm vụ cuối cùng: di chuyển robot bằng cử chỉ tay. Ý tưởng Ý tưởng để làm phần này thật ra rất đơn giản và cũng không có gì mới. ...

In this final chapter of the series ROS 101, we are going to combine everything we have learned so far to finish one last challenge: moving the robot with our hand signs. The idea The idea is pretty simple and there is actually nothing new. In the pr...

Hãy cùng tiếp tục chương trước bằng việc dùng Xacro để cải tiến mô tả robot (URDF) và thêm nhiều thuộc tính hơn để mô phỏng và điều khiển robot trong Gazebo. Code ở phần này nhìn có vẻ dài dòng (vì XML luôn yêu cầu các thẻ mở và đóng) nhưng thực ra r...

Trong phần này, mình sẽ hướng dẫn bạn tạo một image subscriber đơn giản (hay "Người In Ấn" trong ví dụ từ phần trước). Subscriber này sẽ liên tục đọc hình ảnh từ topic image_raw (mà bạn đã tạo từ chương 7) và hiển thị chúng. Tất nhiên, bạn có thể làm được nhiều thứ hơn là chỉ hiển thị ảnh (chẳng hạn như đưa ảnh vào một số thuật toán học máy (Machine Learning) mà bạn sẽ thực hiện trong chương tiếp theo) hoặc thậm chí bạn có thể show ảnh ngay từ publisher bẳng OpenCV nhưng hãy bắt đầu thật cơ bản. Subscriber này chỉ là một ví dụ để bạn thấy được các chương trình trong ROS giao tiếp với nhau như thế nào.
Tạo một tập lệnh Python mới trong thư mục my_cam và đặt tên cho nó là image_subscriber.py. Nếu bạn đã đọc và làm chương 7 thì code bên dưới sẽ thấy quen vì cấu trúc khá giống với publisher. Mình vẫn khuyên bạn nên làm theo phần giải thích bên dưới và tự code thay vì copy&paste.
#!/usr/bin/python3
import rospy
import cv2
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
def callback(image_msg):
"""This function is called to handle the subscribed messages
Args:
image_msg (Image): message type Image from sensor_msgs
"""
try:
cv_image = bridge.imgmsg_to_cv2(image_msg)
cv2.imshow('ROS Image Subscriber', cv_image)
cv2.waitKey(10)
except CvBridgeError as error:
print(error)
if __name__=="__main__":
bridge = CvBridge()
rospy.init_node("image_subscriber", anonymous=True)
print("Subscribe images from topic /image_raw ...")
image_subcriber = rospy.Subscriber("image_raw", Image, callback)
try:
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
except KeyboardInterrupt:
print("Shutting down!")
Phần đầu tiên giống hệt như trong image_publisher.py và về cơ bản là để import tất cả các thư viện cần thiết.
#!/usr/bin/python3
import rospy
import cv2
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
Tiếp theo, một hàm callback được định nghĩa nhưng mình muốn giải thích hàm main trước và đến với hàm callback này sau. Tương tự như publisher, trong main bạn cần tạo một đối tượng CvBridge và khởi tạo một Node có tên image_subscriber.
if __name__=="__main__":
bridge = CvBridge()
rospy.init_node("image_subscriber", anonymous=True)
print("Subscribe images from topic /image_raw ...")
Sau đó, một subscriber được khởi tạo bằng cách sử dụng hàm rospy.Subscriber("image_raw", Image, callback) trong đó image_raw là topic mà bạn muốn subscribe, Image là kiểu dữ liệu của image_raw và callback là một hàm sẽ luôn được gọi khi subscriber nhận message mới. Cuối cùng, rospy.spin() được gọi để giữ Node của bạn chạy liên tục cho đến khi nó bị dừng (ví dụ: bằng Ctrl + C).
image_subcriber = rospy.Subscriber("image_raw", Image, callback)
try:
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
except KeyboardInterrupt:
print("Shutting down!")
Hàm callback luôn được định nghĩa với message là tham số (argument) đầu tiên.
def callback(image_msg):
Bên trong callback, trước hết bạn cần chuyển ROS message image_msg sang định dạng của OpenCV (mình đặt tên nó ở đây là cv_image) bằng cách sử dụng hàm imgmsg_to_cv2. Sau đó, bạn có thể hiển thị hình ảnh bằng cách sử dụng hàm cv2.imshow. Hàm này có hai tham số: thứ nhất là tên cửa sổ (ở đây là ROS Image Subscriber) và thứ hai là hình ảnh (cv_image). Cuối cùng, cv2.waitKey(10) được sử dụng để delay trong một phần nghìn giây (ms) nhất định (ở đây là 10 mili giây) trước khi chuyển sang khung hình tiếp theo.
try:
cv_image = bridge.imgmsg_to_cv2(image_msg)
cv2.imshow('ROS Image Subscriber', cv_image)
cv2.waitKey(10)
except CvBridgeError as error:
print(error)
Để chạy file Python này từ terminal, thì bạn cũng cần làm cho nó executable (có thể thực thi được) bằng cách nhấp chuột phải vào file và chọn Properties > Permissions và tích Allow executing file as program hoặc sử dụng lệnh sudo chmod +x image_subscriber.py. Sau đó, mở 3 terminal hoặc một terminator với 3 terminal nhỏ như bên dưới.

Trong terminal thứ nhất, chạy ROS Master:
roscore
Trong cái thứ hai, chạy image publisher (nhớ kết nối webcam với máy ảo nếu bạn dùng VMware):
rosrun my_cam image_publisher.py
Trong terminal thứ ba, chạy subscriber:
rosrun my_cam image_subscriber.py
Sau đó, bạn sẽ thấy một cửa sổ có tiêu đề ROS Image Subscriber hiện lên với hình ảnh truyền trực tiếp từ webcam của bạn giống như của mình trong ảnh trên.
Sau khi hoàn thành chương 7 và 8, giờ bạn đã biết cách code ROS publisher và subscriber. Bạn cũng biết cách lấy hình ảnh từ camera, một trong những cảm biến phổ biến nhất trong chế tạo robot. Trong chương tiếp theo, như đã hứa, mình sẽ giúp bạn sử dụng một trong những công cụ có sẵn để khai thác hình ảnh subscribed được thành những thông tin hữu ích thay vì chỉ xem chúng trên màn hình.