ROS (Robot İşletim Sistemi) hızlı başlangıç kılavuzu
ROS Giriş (altyazılı) itibaren Open Robotics on Vimeo.
ROS nedir?
Robot İşletim Sistemi (ROS), robotik araştırma ve endüstride yaygın olarak kullanılan açık kaynaklı bir çerçevedir. ROS, geliştiricilerin robot uygulamaları oluşturmasına yardımcı olacak bir kitaplık ve araç koleksiyonu sağlar. ROS, çeşitli robotik platformlarla çalışmak üzere tasarlanmıştır, bu da onu robotikçiler için esnek ve güçlü bir araç haline getirir.
ROS'un Temel Özellikleri
-
Modüler Mimari: ROS, geliştiricilerin düğüm adı verilen daha küçük, yeniden kullanılabilir bileşenleri birleştirerek karmaşık sistemler oluşturmasına olanak tanıyan modüler bir mimariye sahiptir. Her düğüm tipik olarak belirli bir işlevi yerine getirir ve düğümler, konular veya hizmetler üzerinden mesajlar kullanarak birbirleriyle iletişim kurar.
-
İletişim Ara Yazılımı: ROS, süreçler arası iletişimi ve dağıtılmış hesaplamayı destekleyen sağlam bir iletişim altyapısı sunar. Bu, veri akışları (konular) için bir yayımlama-abone olma modeli ve hizmet çağrıları için bir istek-yanıt modeli aracılığıyla elde edilir.
-
Donanım Soyutlaması: ROS, donanım üzerinde bir soyutlama katmanı sağlayarak geliştiricilerin cihazdan bağımsız kod yazmasına olanak tanır. Bu, aynı kodun farklı donanım kurulumlarıyla kullanılmasına izin vererek daha kolay entegrasyon ve denemeyi kolaylaştırır.
-
Araçlar ve Yardımcı Programlar: ROS, görselleştirme, hata ayıklama ve simülasyon için zengin bir araç ve yardımcı program seti ile birlikte gelir. Örneğin, RViz, sensör verilerini ve robot durum bilgilerini görselleştirmek için kullanılırken, Gazebo, algoritmaları ve robot tasarımlarını test etmek için güçlü bir simülasyon ortamı sağlar.
-
Kapsamlı Ekosistem: ROS ekosistemi, navigasyon, manipülasyon, algılama ve daha fazlası dahil olmak üzere farklı robotik uygulamalar için çok sayıda paketle çok geniştir ve sürekli büyümektedir. Topluluk, bu paketlerin geliştirilmesine ve sürdürülmesine aktif olarak katkıda bulunur.
ROS Sürümlerinin Evrimi
2007'deki geliştirilmesinden bu yana ROS, robotik topluluğunun artan ihtiyaçlarını karşılamak için her biri yeni özellikler ve iyileştirmeler sunan birden fazla sürümle gelişti. ROS'un gelişimi iki ana seriye ayrılabilir: ROS 1 ve ROS 2. Bu kılavuz, ROS Noetic Ninjemys olarak bilinen ROS 1'in Uzun Süreli Destek (LTS) sürümüne odaklanır, kod önceki sürümlerle de çalışmalıdır.
ROS 1 ve ROS 2
ROS 1, robotik geliştirme için sağlam bir temel sağlarken, ROS 2 aşağıdakileri sunarak eksikliklerini giderir:
- Gerçek Zamanlı Performans: Gerçek zamanlı sistemler ve deterministik davranışlar için geliştirilmiş destek.
- Güvenlik: Çeşitli ortamlarda güvenli ve güvenilir çalışma için gelişmiş güvenlik özellikleri.
- Ölçeklenebilirlik: Çok robotlu sistemler ve büyük ölçekli dağıtımlar için daha iyi destek.
- Çapraz Platform Desteği: Windows ve macOS dahil olmak üzere Linux'un ötesindeki çeşitli işletim sistemleriyle genişletilmiş uyumluluk.
- Esnek İletişim: Süreçler arası daha esnek ve verimli iletişim için DDS kullanımı.
ROS Mesajları ve Konuları
ROS'ta düğümler arasındaki iletişim, mesajlar ve konular aracılığıyla kolaylaştırılır. Mesaj, düğümler arasında değiş tokuş edilen bilgileri tanımlayan bir veri yapısıdır, konu ise mesajların gönderildiği ve alındığı adlandırılmış bir kanaldır. Düğümler, bir konuya mesaj yayınlayabilir veya bir konudaki mesajlara abone olarak birbirleriyle iletişim kurmalarını sağlayabilir. Bu yayımlama-abone olma modeli, düğümler arasında zaman uyumsuz iletişime ve ayrıştırmaya olanak tanır. Bir robotik sistemdeki her sensör veya aktüatör tipik olarak bir konuya veri yayınlar ve bu veriler daha sonra işleme veya kontrol için diğer düğümler tarafından tüketilebilir. Bu kılavuzun amacı doğrultusunda, Görüntü, Derinlik ve PointCloud mesajları ve kamera konularına odaklanacağız.
Ayarlama Ultralytics YOLO ROS ile
Bu kılavuz, ROSbot ROS deposunun bir çatalı olan bu ROS ortamı kullanılarak test edilmiştir. Bu ortam şunları içerir:Ultralytics YOLO paketi, kolay kurulum için bir Docker konteyneri, kapsamlı ROS paketleri ve hızlı test için Gazebo dünyaları. Husarion ROSbot 2 PRO ile çalışmak üzere tasarlanmıştır. Sağlanan kod örnekleri, hem simülasyon hem de gerçek dünya dahil olmak üzere herhangi bir ROS Noetic/Melodic ortamında çalışacaktır.
Bağımlılıklar Yükleme
ROS ortamının yanı sıra, aşağıdaki bağımlılıkları yüklemeniz gerekir:
-
ROS Numpy paketi: Bu, ROS Görüntü mesajları ve numpy dizileri arasında hızlı dönüşüm için gereklidir.
-
Ultralytics Paketi:
Kullanmak Ultralytics ROS ile sensor_msgs/Image
Bu sensor_msgs/Image
Mesaj Türü is commonly used in ROS for representing image data. It contains fields for encoding, height, width, and pixel data, making it suitable for transmitting images captured by cameras or other sensors. Image messages are widely used in robotic applications for tasks such as visual perception, object detection, and navigation.
Görselin Adım Adım Kullanımı
Aşağıdaki kod parçacığı, Ultralytics YOLO ROS ile paket. Bu örnekte, bir kamera konusuna abone oluyoruz, gelen görüntüyü kullanarak işliyoruz. YOLOtıklatın ve algılanan nesneleri algılama ve segmentasyon için yeni konulara yayımlayın.
İlk olarak, gerekli kitaplıkları içe aktarın ve iki model oluşturun: biri Segmentasyon ve bir tane Algılama. Bir ROS düğümü başlatın (adıyla ultralytics
) ROS master ile iletişimi etkinleştirmek için. İstikrarlı bir bağlantı sağlamak için, düğüme devam etmeden önce bağlantıyı kurması için yeterli zaman veren kısa bir duraklama ekliyoruz.
import time
import rospy
from ultralytics import YOLO
detection_model = YOLO("yolov8m.pt")
segmentation_model = YOLO("yolov8m-seg.pt")
rospy.init_node("ultralytics")
time.sleep(1)
İki ROS konusu başlatın: biri Algılama ve bir tane Segmentasyon. Bu konular, açıklamalı görüntüleri yayınlamak için kullanılacak ve daha sonraki işlemler için erişilebilir hale getirilecektir. Düğümler arasındaki iletişim kullanılarak kolaylaştırılır. sensor_msgs/Image
Ileti.
from sensor_msgs.msg import Image
det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)
seg_image_pub = rospy.Publisher("/ultralytics/segmentation/image", Image, queue_size=5)
Son olarak, ekrandaki mesajları dinleyen bir abone oluşturun. /camera/color/image_raw
konu ve her yeni mesaj için bir geri arama işlevi çağırır. Bu geri çağırma işlevi, şu türdeki iletileri alır sensor_msgs/Image
, kullanarak bunları bir numpy dizisine dönüştürür ros_numpy
, görüntüleri daha önce başlatılan görüntülerle işler YOLO modeller, görüntülere açıklama ekler ve ardından bunları ilgili konulara geri yayınlar: /ultralytics/detection/image
algılama ve /ultralytics/segmentation/image
segmentasyon için.
import ros_numpy
def callback(data):
"""Callback function to process image and publish annotated images."""
array = ros_numpy.numpify(data)
if det_image_pub.get_num_connections():
det_result = detection_model(array)
det_annotated = det_result[0].plot(show=False)
det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))
if seg_image_pub.get_num_connections():
seg_result = segmentation_model(array)
seg_annotated = seg_result[0].plot(show=False)
seg_image_pub.publish(ros_numpy.msgify(Image, seg_annotated, encoding="rgb8"))
rospy.Subscriber("/camera/color/image_raw", Image, callback)
while True:
rospy.spin()
Kodu tamamla
import time
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from ultralytics import YOLO
detection_model = YOLO("yolov8m.pt")
segmentation_model = YOLO("yolov8m-seg.pt")
rospy.init_node("ultralytics")
time.sleep(1)
det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)
seg_image_pub = rospy.Publisher("/ultralytics/segmentation/image", Image, queue_size=5)
def callback(data):
"""Callback function to process image and publish annotated images."""
array = ros_numpy.numpify(data)
if det_image_pub.get_num_connections():
det_result = detection_model(array)
det_annotated = det_result[0].plot(show=False)
det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))
if seg_image_pub.get_num_connections():
seg_result = segmentation_model(array)
seg_annotated = seg_result[0].plot(show=False)
seg_image_pub.publish(ros_numpy.msgify(Image, seg_annotated, encoding="rgb8"))
rospy.Subscriber("/camera/color/image_raw", Image, callback)
while True:
rospy.spin()
Hata ayıklama
ROS (Robot İşletim Sistemi) düğümlerinde hata ayıklamak, sistemin dağıtılmış yapısı nedeniyle zor olabilir. Bu süreçte birkaç araç yardımcı olabilir:
rostopic echo <TOPIC-NAME>
: Bu komut, belirli bir konuda yayınlanan mesajları görüntülemenizi sağlayarak veri akışını incelemenize yardımcı olur.rostopic list
: ROS sistemindeki mevcut tüm konuları listelemek için bu komutu kullanın ve size aktif veri akışlarına genel bir bakış sağlayın.rqt_graph
: Bu görselleştirme aracı, düğümler arasındaki iletişim grafiğini görüntüleyerek düğümlerin birbirine nasıl bağlandığına ve nasıl etkileşime girdiğine dair içgörüler sağlar.- 3B gösterimler gibi daha karmaşık görselleştirmeler için şunları kullanabilirsiniz: RViz (Karavan). RViz (ROS Görselleştirme), ROS için güçlü bir 3D görselleştirme aracıdır. Robotunuzun ve çevresinin durumunu gerçek zamanlı olarak görselleştirmenizi sağlar. RViz ile sensör verilerini görüntüleyebilirsiniz (örn.
sensors_msgs/Image
), robot modeli durumları ve diğer çeşitli bilgi türleri, hata ayıklamayı ve robotik sisteminizin davranışını anlamayı kolaylaştırır.
Algılanan Sınıfları Yayımla std_msgs/String
Standart ROS mesajları ayrıca şunları içerir std_msgs/String
Ileti. Birçok uygulamada, açıklamalı görüntünün tamamını yeniden yayınlamak gerekli değildir; bunun yerine, yalnızca robotun görünümünde bulunan sınıflara ihtiyaç vardır. Aşağıdaki örnekte nasıl kullanılacağı gösterilmektedir std_msgs/String
Ileti Algılanan sınıfları yeniden yayımlamak için /ultralytics/detection/classes
konu. Bu mesajlar daha hafiftir ve temel bilgileri sağlayarak onları çeşitli uygulamalar için değerli kılar.
Örnek Kullanım Durumu
Kamera ve nesne ile donatılmış bir depo robotu düşünün Algılama modeli. Robot, ağ üzerinden büyük açıklamalı görüntüler göndermek yerine, algılanan sınıfların bir listesini şu şekilde yayınlayabilir: std_msgs/String
Ileti. Örneğin, robot "kutu", "palet" ve "forklift" gibi nesneleri algıladığında bu sınıfları /ultralytics/detection/classes
konu. Bu bilgiler daha sonra envanteri gerçek zamanlı olarak izlemek, engellerden kaçınmak için robotun yol planlamasını optimize etmek veya algılanan bir kutuyu almak gibi belirli eylemleri tetiklemek için merkezi bir izleme sistemi tarafından kullanılabilir. Bu yaklaşım, iletişim için gereken bant genişliğini azaltır ve kritik verilerin iletilmesine odaklanır.
Dize adım adım kullanımı
Bu örnekte nasıl kullanılacağı gösterilmektedir. Ultralytics YOLO ROS ile paket. Bu örnekte, bir kamera konusuna abone oluyoruz, gelen görüntüyü kullanarak işliyoruz. YOLOtıklatın ve algılanan nesneleri yeni konuya yayımlayın /ultralytics/detection/classes
Kullan -arak std_msgs/String
Ileti. bu ros_numpy
paketi, ROS Görüntü mesajını ile işlenmek üzere bir numpy dizisine dönüştürmek için kullanılır. YOLO.
import time
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import String
from ultralytics import YOLO
detection_model = YOLO("yolov8m.pt")
rospy.init_node("ultralytics")
time.sleep(1)
classes_pub = rospy.Publisher("/ultralytics/detection/classes", String, queue_size=5)
def callback(data):
"""Callback function to process image and publish detected classes."""
array = ros_numpy.numpify(data)
if classes_pub.get_num_connections():
det_result = detection_model(array)
classes = det_result[0].boxes.cls.cpu().numpy().astype(int)
names = [det_result[0].names[i] for i in classes]
classes_pub.publish(String(data=str(names)))
rospy.Subscriber("/camera/color/image_raw", Image, callback)
while True:
rospy.spin()
Kullanmak Ultralytics ROS Derinlik Görüntüleri ile
RGB görüntülere ek olarak, ROS, nesnelerin kameradan uzaklığı hakkında bilgi sağlayan derinlik görüntülerini destekler. Derinlik görüntüleri, engellerden kaçınma, 3D haritalama ve yerelleştirme gibi robotik uygulamalar için çok önemlidir.
Derinlik görüntüsü, her pikselin kameradan bir nesneye olan mesafeyi temsil ettiği bir görüntüdür. Renkleri yakalayan RGB görüntülerin aksine, derinlik görüntüleri uzamsal bilgileri yakalayarak robotların çevrelerinin 3B yapısını algılamasını sağlar.
Derinlik Görüntülerinin Elde Edilmesi
Derinlik görüntüleri çeşitli sensörler kullanılarak elde edilebilir:
- Stereo Kameralar: Görüntü eşitsizliğine göre derinliği hesaplamak için iki kamera kullanın.
- Uçuş Süresi (ToF) Kameraları: Işığın bir nesneden dönmesi için geçen süreyi ölçün.
- Yapılandırılmış Işık Sensörleri: Bir desen yansıtın ve yüzeylerdeki deformasyonunu ölçün.
Kullan -arak YOLO Derinlik Görüntüleri ile
ROS'ta derinlik görüntüleri sensor_msgs/Image
Kodlama, yükseklik, genişlik ve piksel verileri için alanları içeren mesaj türü. Derinlik görüntüleri için kodlama alanı genellikle "16UC1" gibi bir biçim kullanır ve piksel başına 16 bitlik işaretsiz bir tamsayıyı belirtir ve burada her değer nesneye olan mesafeyi temsil eder. Derinlik görüntüleri, ortamın daha kapsamlı bir görünümünü sağlamak için genellikle RGB görüntülerle birlikte kullanılır.
Kullan -arak YOLO, hem RGB hem de derinlik görüntülerinden bilgi çıkarmak ve birleştirmek mümkündür. Örneğin YOLO bir RGB görüntüsündeki nesneleri algılayabilir ve bu algılama, derinlik görüntüsündeki karşılık gelen bölgeleri tam olarak belirlemek için kullanılabilir. Bu, algılanan nesneler için kesin derinlik bilgilerinin çıkarılmasına olanak tanıyarak robotun çevresini üç boyutlu olarak anlama yeteneğini geliştirir.
RGB-D Fotoğraf Makineleri
Derinlik görüntüleriyle çalışırken, RGB ve derinlik görüntülerinin doğru şekilde hizalandığından emin olmak çok önemlidir. Intel RealSense serisi gibi RGB-D kameralar, senkronize RGB ve derinlik görüntüleri sağlayarak her iki kaynaktan gelen bilgilerin birleştirilmesini kolaylaştırır. Ayrı RGB ve derinlik kameraları kullanılıyorsa, doğru hizalamayı sağlamak için bunları kalibre etmek çok önemlidir.
Derinlik Adım Adım Kullanım
Bu örnekte şunu kullanırız: YOLO tıklayarak bir görüntüyü parçalara ayırın ve nesneyi derinlik görüntüsünde parçalara ayırmak için ayıklanan maskeyi uygulayın. Bu, ilgilenilen nesnenin her pikselinin kameranın odak merkezinden uzaklığını belirlememizi sağlar. Bu mesafe bilgisini elde ederek kamera ile sahnedeki belirli nesne arasındaki mesafeyi hesaplayabiliriz. Gerekli kitaplıkları içe aktararak, bir ROS düğümü oluşturarak ve bir segmentasyon modeli ve bir ROS konusu örneği oluşturarak başlayın.
import time
import rospy
from std_msgs.msg import String
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolov8m-seg.pt")
classes_pub = rospy.Publisher("/ultralytics/detection/distance", String, queue_size=5)
Ardından, gelen derinlik görüntüsü mesajını işleyen bir geri çağırma işlevi tanımlayın. İşlev, derinlik görüntüsü ve RGB görüntü mesajlarını bekler, bunları numpy dizilerine dönüştürür ve segmentasyon modelini RGB görüntüsüne uygular. Daha sonra algılanan her nesne için segmentasyon maskesini çıkarır ve derinlik görüntüsünü kullanarak nesnenin kameradan ortalama mesafesini hesaplar. Çoğu sensör, klip mesafesi olarak bilinen ve değerlerin inf (np.inf
). İşlemeden önce, bu null değerleri filtrelemek ve bunlara bir değer atamak önemlidir. 0
. Son olarak, algılanan nesneleri, ortalama mesafeleriyle birlikte yayınlar. /ultralytics/detection/distance
konu.
import numpy as np
import ros_numpy
from sensor_msgs.msg import Image
def callback(data):
"""Callback function to process depth image and RGB image."""
image = rospy.wait_for_message("/camera/color/image_raw", Image)
image = ros_numpy.numpify(image)
depth = ros_numpy.numpify(data)
result = segmentation_model(image)
for index, cls in enumerate(result[0].boxes.cls):
class_index = int(cls.cpu().numpy())
name = result[0].names[class_index]
mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
obj = depth[mask == 1]
obj = obj[~np.isnan(obj)]
avg_distance = np.mean(obj) if len(obj) else np.inf
classes_pub.publish(String(data=str(all_objects)))
rospy.Subscriber("/camera/depth/image_raw", Image, callback)
while True:
rospy.spin()
Kodu tamamla
import time
import numpy as np
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import String
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolov8m-seg.pt")
classes_pub = rospy.Publisher("/ultralytics/detection/distance", String, queue_size=5)
def callback(data):
"""Callback function to process depth image and RGB image."""
image = rospy.wait_for_message("/camera/color/image_raw", Image)
image = ros_numpy.numpify(image)
depth = ros_numpy.numpify(data)
result = segmentation_model(image)
for index, cls in enumerate(result[0].boxes.cls):
class_index = int(cls.cpu().numpy())
name = result[0].names[class_index]
mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
obj = depth[mask == 1]
obj = obj[~np.isnan(obj)]
avg_distance = np.mean(obj) if len(obj) else np.inf
classes_pub.publish(String(data=str(all_objects)))
rospy.Subscriber("/camera/depth/image_raw", Image, callback)
while True:
rospy.spin()
Kullanmak Ultralytics ROS ile sensor_msgs/PointCloud2
Bu sensor_msgs/PointCloud2
Mesaj Türü ROS'ta 3B nokta bulutu verilerini temsil etmek için kullanılan bir veri yapısıdır. Bu mesaj türü, robotik uygulamaların ayrılmaz bir parçasıdır ve 3B haritalama, nesne tanıma ve yerelleştirme gibi görevleri etkinleştirir.
Nokta bulutu, üç boyutlu bir koordinat sistemi içinde tanımlanan veri noktalarının bir koleksiyonudur. Bu veri noktaları, 3D tarama teknolojileri aracılığıyla yakalanan bir nesnenin veya sahnenin dış yüzeyini temsil eder. Buluttaki her nokta X
, Y
ve Z
uzaydaki konumuna karşılık gelen koordinatlar ve ayrıca renk ve yoğunluk gibi ek bilgileri de içerebilir.
Referans çerçevesi
Birlikte çalışırken sensor_msgs/PointCloud2
, nokta bulutu verilerinin alındığı sensörün referans çerçevesini dikkate almak önemlidir. Nokta bulutu başlangıçta sensörün referans çerçevesinde yakalanır. Bu referans çerçevesini dinleyerek belirleyebilirsiniz. /tf_static
konu. Ancak, özel uygulama gereksinimlerinize bağlı olarak, nokta bulutunu başka bir referans çerçevesine dönüştürmeniz gerekebilir. Bu dönüşüm, tf2_ros
paketi, koordinat çerçevelerini yönetmek ve bunlar arasında verileri dönüştürmek için araçlar sağlar.
Nokta bulutlarını elde etme
Nokta Bulutları çeşitli sensörler kullanılarak elde edilebilir:
- LIDAR (Light Detection and Ranging): Uses laser pulses to measure distances to objects and create high-precision 3D maps.
- Derinlik Kameraları: Her piksel için derinlik bilgilerini yakalayarak sahnenin 3D yeniden yapılandırılmasına olanak tanır.
- Stereo Kameralar: Nirengi yoluyla derinlik bilgisi elde etmek için iki veya daha fazla kamera kullanın.
- Yapılandırılmış Işık Tarayıcıları: Bilinen bir deseni bir yüzeye yansıtın ve derinliği hesaplamak için deformasyonu ölçün.
Kullan -arak YOLO Nokta Bulutları ile
Entegrasyon için YOLO ile sensor_msgs/PointCloud2
Mesaj yazın, derinlik haritaları için kullanılana benzer bir yöntem kullanabiliriz. Nokta bulutuna gömülü renk bilgilerinden yararlanarak, bir 2D görüntü çıkarabilir, bu görüntü üzerinde segmentasyon gerçekleştirebiliriz. YOLOtıklatın ve sonra elde edilen maskeyi üç boyutlu noktalara uygulayarak ilgilenilen 3B nesneyi yalıtın.
Nokta bulutlarını işlemek için Open3D (pip install open3d
), kullanıcı dostu bir Python kütüphane. Open3D, nokta bulutu veri yapılarını yönetmek, görselleştirmek ve karmaşık işlemleri sorunsuz bir şekilde yürütmek için sağlam araçlar sağlar. Bu kitaplık, süreci önemli ölçüde basitleştirebilir ve nokta bulutlarını aşağıdakilerle birlikte manipüle etme ve analiz etme yeteneğimizi geliştirebilir: YOLO-tabanlı segmentasyon.
Nokta Bulutları Adım Adım Kullanımı
Gerekli kitaplıkları içe aktarın ve YOLO segmentasyon modeli.
import time
import rospy
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolov8m-seg.pt")
İşlev oluşturma pointcloud2_to_array
, bu da bir sensor_msgs/PointCloud2
mesajını iki numpy dizisine dönüştürün. bu sensor_msgs/PointCloud2
Mesajlar şunları içerir: n
puanlara göre width
ve height
elde edilen görüntünün. Örneğin, bir 480 x 640
Görüntüde olacak 307,200
nokta. Her nokta üç uzamsal koordinat içerir (xyz
) ve karşılık gelen renk RGB
biçim. Bunlar iki ayrı bilgi kanalı olarak düşünülebilir.
İşlev şunu döndürür: xyz
koordinatlar ve RGB
orijinal kamera çözünürlüğü biçimindeki değerler (width x height
). Çoğu sensör, klip mesafesi olarak bilinen ve değerlerin inf (np.inf
). İşlemeden önce, bu null değerleri filtrelemek ve bunlara bir değer atamak önemlidir. 0
.
import numpy as np
import ros_numpy
def pointcloud2_to_array(pointcloud2: PointCloud2) -> tuple:
"""
Convert a ROS PointCloud2 message to a numpy array.
Args:
pointcloud2 (PointCloud2): the PointCloud2 message
Returns:
(tuple): tuple containing (xyz, rgb)
"""
pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
nan_rows = np.isnan(xyz).all(axis=2)
xyz[nan_rows] = [0, 0, 0]
rgb[nan_rows] = [0, 0, 0]
return xyz, rgb
Ardından, abone olun /camera/depth/points
Nokta bulutu mesajını almak ve sensor_msgs/PointCloud2
XYZ koordinatlarını ve RGB değerlerini içeren numpy dizilerine mesaj gönderin ( pointcloud2_to_array
işlevi). kullanarak RGB görüntüsünü işleyin YOLO Parçalı nesneleri ayıklamak için model. Algılanan her nesne için, segmentasyon maskesini çıkarın ve nesneyi 3B alanda izole etmek için hem RGB görüntüsüne hem de XYZ koordinatlarına uygulayın.
Maskenin işlenmesi, ikili değerlerden oluştuğu için basittir. 1
nesnenin varlığını gösteren ve 0
yokluğu gösterir. Maskeyi uygulamak için orijinal kanalları maske ile çarpmanız yeterlidir. Bu işlem, ilgilenilen nesneyi görüntü içinde etkili bir şekilde izole eder. Son olarak, bir Open3D nokta bulutu nesnesi oluşturun ve parçalanmış nesneyi ilişkili renklerle 3B alanda görselleştirin.
import sys
import open3d as o3d
ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)
if not len(result[0].boxes.cls):
print("No objects detected")
sys.exit()
classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
mask_expanded = np.stack([mask, mask, mask], axis=2)
obj_rgb = rgb * mask_expanded
obj_xyz = xyz * mask_expanded
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((ros_cloud.height * ros_cloud.width, 3)))
pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((ros_cloud.height * ros_cloud.width, 3)) / 255)
o3d.visualization.draw_geometries([pcd])
Kodu tamamla
import sys
import time
import numpy as np
import open3d as o3d
import ros_numpy
import rospy
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolov8m-seg.pt")
def pointcloud2_to_array(pointcloud2: PointCloud2) -> tuple:
"""
Convert a ROS PointCloud2 message to a numpy array.
Args:
pointcloud2 (PointCloud2): the PointCloud2 message
Returns:
(tuple): tuple containing (xyz, rgb)
"""
pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
nan_rows = np.isnan(xyz).all(axis=2)
xyz[nan_rows] = [0, 0, 0]
rgb[nan_rows] = [0, 0, 0]
return xyz, rgb
ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)
if not len(result[0].boxes.cls):
print("No objects detected")
sys.exit()
classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
mask_expanded = np.stack([mask, mask, mask], axis=2)
obj_rgb = rgb * mask_expanded
obj_xyz = xyz * mask_expanded
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((ros_cloud.height * ros_cloud.width, 3)))
pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((ros_cloud.height * ros_cloud.width, 3)) / 255)
o3d.visualization.draw_geometries([pcd])
SSS
Robot İşletim Sistemi (ROS) nedir?
Robot İşletim Sistemi (ROS), geliştiricilerin sağlam robot uygulamaları oluşturmalarına yardımcı olmak için robotikte yaygın olarak kullanılan açık kaynaklı bir çerçevedir. Robotik sistemler oluşturmak ve bunlarla arayüz oluşturmak için bir kütüphaneler ve araçlar koleksiyonu sağlayarak karmaşık uygulamaların daha kolay geliştirilmesini sağlar. ROS, konular veya hizmetler üzerinden mesajlar kullanarak düğümler arasındaki iletişimi destekler.
Gerçek zamanlı nesne algılama için Ultralytics YOLO adresini ROS ile nasıl entegre edebilirim?
Ultralytics YOLO adresini ROS ile entegre etmek, bir ROS ortamı kurmayı ve sensör verilerini işlemek için YOLO adresini kullanmayı içerir. Aşağıdaki gibi gerekli bağımlılıkları yükleyerek başlayın ros_numpy
ve Ultralytics YOLO :
Ardından, bir ROS düğümü oluşturun ve gelen verileri işlemek için bir görüntü konusuna abone olun. İşte minimal bir örnek:
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from ultralytics import YOLO
detection_model = YOLO("yolov8m.pt")
rospy.init_node("ultralytics")
det_image_pub = rospy.Publisher("/ultralytics/detection/image", Image, queue_size=5)
def callback(data):
array = ros_numpy.numpify(data)
det_result = detection_model(array)
det_annotated = det_result[0].plot(show=False)
det_image_pub.publish(ros_numpy.msgify(Image, det_annotated, encoding="rgb8"))
rospy.Subscriber("/camera/color/image_raw", Image, callback)
rospy.spin()
ROS konuları nelerdir ve Ultralytics YOLO adresinde nasıl kullanılırlar?
ROS konuları, bir yayınla-abone ol modelini kullanarak bir ROS ağındaki düğümler arasındaki iletişimi kolaylaştırır. Bir konu, düğümlerin eşzamansız olarak mesaj göndermek ve almak için kullandığı adlandırılmış bir kanaldır. Ultralytics YOLO bağlamında, bir düğümü bir görüntü konusuna abone yapabilir, algılama veya segmentasyon gibi görevler için YOLO kullanarak görüntüleri işleyebilir ve sonuçları yeni konulara yayınlayabilirsiniz.
Örneğin, bir kamera konusuna abone olun ve gelen görüntüyü algılama için işleyin:
Neden ROS'ta Ultralytics YOLO ile derinlik görüntüleri kullanılmalı?
ile temsil edilen ROS'taki derinlik görüntüleri sensor_msgs/Image
engellerden kaçınma, 3B haritalama ve yerelleştirme gibi görevler için çok önemli olan nesnelerin kameradan uzaklığını sağlar. Tarafından derinlik bilgisini kullanma RGB görüntülerle birlikte robotlar 3D ortamlarını daha iyi anlayabilir.
YOLO ile RGB görüntülerden segmentasyon maskeleri çıkarabilir ve bu maskeleri derinlik görüntülerine uygulayarak hassas 3D nesne bilgileri elde edebilir, robotun gezinme ve çevresiyle etkileşim kurma becerisini geliştirebilirsiniz.
ROS'ta YOLO ile 3B nokta bulutlarını nasıl görselleştirebilirim?
ROS'ta 3D nokta bulutlarını YOLO ile görselleştirmek için:
- Dönüştür
sensor_msgs/PointCloud2
mesajlarını numpy dizilerine dönüştürür. - RGB görüntüleri bölümlere ayırmak için YOLO adresini kullanın.
- Segmentasyon maskesini nokta bulutuna uygulayın.
İşte görselleştirme için Open3D kullanan bir örnek:
import sys
import open3d as o3d
import ros_numpy
import rospy
from sensor_msgs.msg import PointCloud2
from ultralytics import YOLO
rospy.init_node("ultralytics")
segmentation_model = YOLO("yolov8m-seg.pt")
def pointcloud2_to_array(pointcloud2):
pc_array = ros_numpy.point_cloud2.pointcloud2_to_array(pointcloud2)
split = ros_numpy.point_cloud2.split_rgb_field(pc_array)
rgb = np.stack([split["b"], split["g"], split["r"]], axis=2)
xyz = ros_numpy.point_cloud2.get_xyz_points(pc_array, remove_nans=False)
xyz = np.array(xyz).reshape((pointcloud2.height, pointcloud2.width, 3))
return xyz, rgb
ros_cloud = rospy.wait_for_message("/camera/depth/points", PointCloud2)
xyz, rgb = pointcloud2_to_array(ros_cloud)
result = segmentation_model(rgb)
if not len(result[0].boxes.cls):
print("No objects detected")
sys.exit()
classes = result[0].boxes.cls.cpu().numpy().astype(int)
for index, class_id in enumerate(classes):
mask = result[0].masks.data.cpu().numpy()[index, :, :].astype(int)
mask_expanded = np.stack([mask, mask, mask], axis=2)
obj_rgb = rgb * mask_expanded
obj_xyz = xyz * mask_expanded
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(obj_xyz.reshape((-1, 3)))
pcd.colors = o3d.utility.Vector3dVector(obj_rgb.reshape((-1, 3)) / 255)
o3d.visualization.draw_geometries([pcd])
Bu yaklaşım, navigasyon ve manipülasyon gibi görevler için yararlı olan bölümlere ayrılmış nesnelerin 3D görselleştirmesini sağlar.