ROS (Robot İşletim Sistemi) hızlı başlangıç kılavuzu
ROS Tanıtımı (altyazılı), Open Robotics tarafından Vimeo üzerinde.
ROS nedir?
Robot İşletim Sistemi (ROS), robotik araştırma ve endüstrisinde yaygın olarak kullanılan açık kaynaklı bir çerçevedir. ROS, geliştiricilerin robot uygulamaları oluşturmasına yardımcı olmak için bir kütüphane ve araç koleksiyonu sağlar. ROS, çeşitli robotik platformlarla çalışmak üzere tasarlanmıştır ve bu da onu robot uzmanları için esnek ve güçlü bir araç haline getirir.
ROS'un Temel Özellikleri
-
Modüler Mimari: ROS, modüler bir mimariye sahiptir ve geliştiricilerin düğümler adı verilen daha küçük, yeniden kullanılabilir bileşenleri birleştirerek karmaşık sistemler oluşturmasına olanak tanır. Her düğüm genellikle belirli bir işlevi yerine getirir ve düğümler konular veya hizmetler üzerinden mesajlar kullanarak birbirleriyle iletişim kurar.
-
İletişim Ara Katmanı: ROS, süreçler arası iletişimi ve dağıtık hesaplamayı destekleyen sağlam bir iletişim altyapısı sunar. Bu, veri akışları (konular) için bir yayınlama-abonelik modeli ve hizmet çağrıları için bir istek-yanıt modeli aracılığıyla sağlanır.
-
Donanım Soyutlaması: ROS, donanım üzerinde bir soyutlama katmanı sağlayarak geliştiricilerin aygıttan bağımsız kod yazmasına olanak tanır. Bu, aynı kodun farklı donanım kurulumlarıyla kullanılmasını sağlayarak 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 setiyle 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 geniştir ve sürekli olarak büyümektedir; navigasyon, manipülasyon, algılama ve daha fazlası dahil olmak üzere farklı robotik uygulamalar için çok sayıda paket mevcuttur. Topluluk, bu paketlerin geliştirilmesine ve bakımına aktif olarak katkıda bulunur.
ROS Sürümlerinin Evrimi
ROS, 2007'deki gelişiminden bu yana, robotik topluluğunun artan ihtiyaçlarını karşılamak için her biri yeni özellikler ve iyileştirmeler sunan birden çok sürümden geçti. ROS'un geliştirilmesi 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 odaklanmaktadır, kod önceki sürümlerle de çalışmalıdır.
ROS 1 - ROS 2 karşılaştırması
ROS 1 robotik geliştirme için sağlam bir temel sağlarken, ROS 2 aşağıdaki özellikleri sunarak eksikliklerini giderir:
- Gerçek Zamanlı Performans: Gerçek zamanlı sistemler ve deterministik davranış için iyileştirilmiş destek.
- Güvenlik: Çeşitli ortamlarda güvenli ve güvenilir çalışma için gelişmiş güvenlik özellikleri.
- Ölçeklenebilirlik: Çoklu robot sistemleri 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 ötesinde çeşitli işletim sistemleriyle genişletilmiş uyumluluk.
- Esnek İletişim: Daha esnek ve verimli süreçler arası 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önderilip alındığı adlandırılmış bir kanaldır. Düğümler bir konuya mesaj yayınlayabilir veya bir konudan mesajlara abone olabilir, bu da birbirleriyle iletişim kurmalarını sağlar. Bu yayınlama-abonelik modeli, düğümler arasında eşzamansız iletişime ve ayrışmaya olanak tanır. Bir robotik sistemdeki her sensör veya aktüatör tipik olarak bir konuya veri yayınlar ve bu da diğer düğümler tarafından işleme veya kontrol için tüketilebilir. Bu kılavuzun amacı doğrultusunda, Görüntü, Derinlik ve Nokta Bulutu mesajlarına ve kamera konularına odaklanacağız.
ROS ile Ultralytics YOLO Kurulumu
Bu kılavuz, bu ROS ortamı kullanılarak test edilmiştir; bu ortam, ROSbot ROS deposunun bir çatallanmış halidir. Bu ortam, Ultralytics YOLO paketini, kolay kurulum için bir Docker konteynerini, kapsamlı ROS paketlerini ve hızlı test için Gazebo dünyalarını içerir. Husarion ROSbot 2 PRO ile çalışmak üzere tasarlanmıştır. Sağlanan kod örnekleri, simülasyon ve gerçek dünya dahil olmak üzere herhangi bir ROS Noetic/Melodic ortamında çalışacaktır.
Bağımlılıkların Kurulumu
ROS ortamının yanı sıra, aşağıdaki bağımlılıkları da yüklemeniz gerekecektir:
-
ROS Numpy paketi: Bu, ROS Görüntü mesajları ve numpy dizileri arasında hızlı dönüşüm için gereklidir.
pip install ros_numpy
-
Ultralytics paketi:
pip install ultralytics
Ultralytics'i ROS ile kullanın sensor_msgs/Image
sensor_msgs/Image
mesaj türü genellikle ROS'ta görüntü verilerini temsil etmek için kullanılır. Kodlama, yükseklik, genişlik ve piksel verileri için alanlar içerir, bu da onu kameralar veya diğer sensörler tarafından yakalanan görüntüleri iletmek için uygun hale getirir. Görüntü mesajları, görsel algılama gibi robotik uygulamalarda yaygın olarak kullanılır, nesne tespiti, ve navigasyon.
Görüntü Adım Adım Kullanım
Aşağıdaki kod parçacığı, Ultralytics YOLO paketinin ROS ile nasıl kullanılacağını göstermektedir. Bu örnekte, bir kamera konusuna abone oluyoruz, gelen görüntüyü YOLO kullanarak işliyoruz ve algılanan nesneleri algılama ve segmentasyon için yeni konulara yayınlıyoruz.
İlk olarak, gerekli kitaplıkları içe aktarın ve iki model örneği oluşturun: biri segmentasyon ve biri de tespit. Bir ROS düğümü başlatın (şu adla: ultralytics
), ROS master ile iletişimi etkinleştirmek için. Kararlı bir bağlantı sağlamak için, düğüme devam etmeden önce bağlantıyı kurması için yeterli zaman tanıyan kısa bir duraklama ekliyoruz.
import time
import rospy
from ultralytics import YOLO
detection_model = YOLO("yolo11m.pt")
segmentation_model = YOLO("yolo11m-seg.pt")
rospy.init_node("ultralytics")
time.sleep(1)
İki ROS konusunu başlat: biri tespit ve biri de segmentasyon. Bu konular, etiketli görüntüleri yayınlamak için kullanılacak ve bu görüntülerin daha fazla işlenmesi için erişilebilir hale getirilmesini sağlayacaktır. Düğümler arasındaki iletişim şu kullanılarak kolaylaştırılır: sensor_msgs/Image
mesajları.
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, üzerinde mesajları dinleyen bir abone oluşturun /camera/color/image_raw
konuyu dinler ve her yeni mesaj için bir geri çağırma fonksiyonunu tetikler. Bu geri çağırma fonksiyonu, türünde mesajlar alır sensor_msgs/Image
, kullanarak bunları bir numpy dizisine dönüştürür. ros_numpy
, görüntüleri önceden örneklendirilmiş YOLO modelleriyle işler, görüntüleri etiketler ve ardından bunları ilgili konulara geri yayınlar: /ultralytics/detection/image
tespit için 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()
Tam kod
import time
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from ultralytics import YOLO
detection_model = YOLO("yolo11m.pt")
segmentation_model = YOLO("yolo11m-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ık yapısı nedeniyle zorlu olabilir. Bu süreçte yardımcı olabilecek çeşitli araçlar bulunmaktadır:
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 ve size aktif veri akışlarına genel bir bakış sunmak için bu komutu kullanın.rqt_graph
: Bu görselleştirme aracı, düğümler arasındaki iletişim grafiğini görüntüleyerek düğümlerin nasıl birbirine bağlı olduğu ve nasıl etkileşimde bulunduğu hakkında bilgi sağlar.- 3D gösterimler gibi daha karmaşık görselleştirmeler için şunları kullanabilirsiniz: RViz. RViz (ROS Görselleştirme), ROS için güçlü bir 3D görselleştirme aracıdır. Robotunuzun ve ortamının durumunu gerçek zamanlı olarak görselleştirmenizi sağlar. RViz ile sensör verilerini (örneğin,
sensors_msgs/Image
), robot modeli durumları ve diğer çeşitli bilgi türleri dahil olmak üzere robotik sisteminizin davranışını hata ayıklamayı ve anlamayı kolaylaştırır.
Algılanan Sınıfları Şununla Yayınla std_msgs/String
Standart ROS mesajları da şunları içerir: std_msgs/String
mesajları. Birçok uygulamada, tüm açıklamalı görüntüyü yeniden yayınlamak gerekli değildir; bunun yerine, yalnızca robotun görüş alanında bulunan sınıflara ihtiyaç vardır. Aşağıdaki örnek, nasıl kullanılacağını gösterir: std_msgs/String
mesajları algılanan sınıfları şurada yeniden yayınlamak için /ultralytics/detection/classes
konusunu dinler. Bu mesajlar daha hafiftir ve çeşitli uygulamalar için değerli olan temel bilgileri sağlar.
Örnek Kullanım Durumu
Bir kamera ve nesne ile donatılmış bir depo robotu düşünün tespit modeli. Robot, ağ üzerinden büyük etiketli görüntüler göndermek yerine, algılanan sınıfların bir listesini şu şekilde yayınlayabilir: std_msgs/String
mesajları. Örneğin, robot "kutu", "palet" ve "forklift" gibi nesneleri algıladığında, bu sınıfları şuraya yayınlar: /ultralytics/detection/classes
konusunu dinler. Bu bilgiler daha sonra merkezi bir izleme sistemi tarafından envanteri gerçek zamanlı olarak izlemek, robotun engellerden kaçınmak için yol planlamasını optimize etmek veya algılanan bir kutuyu almak gibi belirli eylemleri tetiklemek için kullanılabilir. Bu yaklaşım, iletişim için gereken bant genişliğini azaltır ve kritik verilerin iletilmesine odaklanır.
Adım Adım Dize Kullanımı
Bu örnek, Ultralytics YOLO paketinin ROS ile nasıl kullanılacağını gösterir. Bu örnekte, bir kamera konusuna abone oluyor, gelen görüntüyü YOLO kullanarak işliyor ve tespit edilen nesneleri yeni bir konuya yayınlıyoruz. /ultralytics/detection/classes
kullanarak std_msgs/String
mesajları. Şunun ros_numpy
paketi, ROS Görüntü mesajını YOLO ile işlenmek üzere bir numpy dizisine dönüştürmek için kullanılır.
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("yolo11m.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()
Ultralytics'i ROS Derinlik Görüntüleri ile kullanın
RGB görüntülerine ek olarak, ROS, nesnelerin kameradan uzaklığı hakkında bilgi sağlayan derinlik görüntülerini de destekler. Derinlik görüntüleri, engelden kaçınma, 3B haritalama ve konumlandırma gibi robotik uygulamalar için çok önemlidir.
Bir derinlik görüntüsü, her pikselin kameradan bir nesneye olan uzaklığı temsil ettiği bir görüntüdür. Rengi yakalayan RGB görüntülerinin aksine, derinlik görüntüleri uzamsal bilgileri yakalar ve robotların çevrelerinin 3B yapısını algılamasını sağlar.
Derinlik Görüntüleri Elde Etme
Derinlik görüntüleri çeşitli sensörler kullanılarak elde edilebilir:
- Stereo Kameralar: Görüntü farklılığına dayalı olarak derinliği hesaplamak için iki kamera kullanın.
- Uçuş Süresi (ToF) Kameraları: Işığın bir nesneden geri dönmesinin ne kadar sürdüğünü ölçün.
- Yapılandırılmış Işık Sensörleri: Bir desen yansıtın ve yüzeylerdeki deformasyonunu ölçün.
Derinlik Görüntüleri ile YOLO Kullanımı
ROS'ta, derinlik görüntüleri şu şekilde temsil edilir: sensor_msgs/Image
mesaj türü, kodlama, yükseklik, genişlik ve piksel verileri için alanlar içerir. Derinlik görüntüleri için kodlama alanı genellikle piksel başına 16 bit işaretsiz bir tamsayıyı gösteren "16UC1" gibi bir format kullanır; burada her değer nesneye olan uzaklığı 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üleriyle birlikte kullanılır.
YOLO kullanarak, 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ü içindeki nesneleri algılayabilir ve bu algılama, derinlik görüntüsündeki karşılık gelen bölgeleri belirlemek için kullanılabilir. Bu, algılanan nesneler için hassas derinlik bilgilerinin çıkarılmasına olanak tanıyarak robotun çevresini üç boyutta anlama yeteneğini geliştirir.
RGB-D Kameralar
Derinlik görüntüleriyle çalışırken, RGB ve derinlik görüntülerinin doğru şekilde hizalandığından emin olmak önemlidir. Intel RealSense serisi gibi RGB-D kameralar, senkronize RGB ve derinlik görüntüleri sağlayarak her iki kaynaktan gelen bilgileri birleştirmeyi kolaylaştırır. Ayrı RGB ve derinlik kameraları kullanılıyorsa, doğru hizalama sağlamak için bunları kalibre etmek çok önemlidir.
Derinlik Adım Adım Kullanım
Bu örnekte, bir görüntüyü bölümlere ayırmak ve çıkarılan maskeyi derinlik görüntüsündeki nesneyi bölümlere ayırmak için YOLO'yu kullanıyoruz. 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 örneklendirerek 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("yolo11m-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 RGB görüntüsüne segmentasyon modelini 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ün, değerlerin sonsuz (inf) olarak temsil edildiği, klip mesafesi olarak bilinen maksimum bir mesafesi vardır (np.inf
). İşlemden önce, bu boş değerleri filtrelemek ve bunlara bir değer atamak önemlidir: 0
. Son olarak, algılanan nesneleri ortalama mesafeleriyle birlikte yayınlar. /ultralytics/detection/distance
konusu.
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)
all_objects = []
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
all_objects.append(f"{name}: {avg_distance:.2f}m")
classes_pub.publish(String(data=str(all_objects)))
rospy.Subscriber("/camera/depth/image_raw", Image, callback)
while True:
rospy.spin()
Tam kod
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("yolo11m-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)
all_objects = []
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
all_objects.append(f"{name}: {avg_distance:.2f}m")
classes_pub.publish(String(data=str(all_objects)))
rospy.Subscriber("/camera/depth/image_raw", Image, callback)
while True:
rospy.spin()
Ultralytics'i ROS ile kullanın sensor_msgs/PointCloud2
sensor_msgs/PointCloud2
mesaj türü , ROS'ta 3D nokta bulutu verilerini temsil etmek için kullanılan bir veri yapısıdır. Bu mesaj türü, 3D haritalama, nesne tanıma ve lokalizasyon gibi görevleri etkinleştirerek robotik uygulamalar için ayrılmaz bir öneme sahiptir.
Nokta bulutu, üç boyutlu bir koordinat sistemi içinde tanımlanan veri noktaları koleksiyonudur. Bu veri noktaları, 3D tarama teknolojileri aracılığıyla yakalanan bir nesnenin veya sahnenin dış yüzeyini temsil eder. Buluttaki her noktanın şunları vardır: X
, Y
ve Z
uzaydaki konumuna karşılık gelen koordinatlar ve ayrıca renk ve yoğunluk gibi ek bilgiler içerebilir.
Referans çerçevesi
Şununla çalışırken: sensor_msgs/PointCloud2
, nokta bulutu verilerinin elde edildiği 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 şurayı dinleyerek belirleyebilirsiniz: /tf_static
konusu. 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
koordinat çerçevelerini yönetmek ve verileri bunlar arasında dönüştürmek için araçlar sağlayan paket.
Nokta bulutları elde etme
Nokta Bulutları çeşitli sensörler kullanılarak elde edilebilir:
- LIDAR (Işık Algılama ve Menzil Belirleme): Nesnelere olan mesafeleri ölçmek ve yüksek hassasiyetli 3B haritalar oluşturmak için lazer darbeleri kullanır.
- Derinlik Kameraları: Her piksel için derinlik bilgisini yakalar ve sahnenin 3B rekonstrüksiyonuna olanak tanır.
- Stereo Kameralar: Üçgenleme yoluyla derinlik bilgisi elde etmek için iki veya daha fazla kamera kullanın.
- Yapılandırılmış Işık Tarayıcıları: Bir yüzeye bilinen bir desen yansıtın ve derinliği hesaplamak için deformasyonu ölçün.
Nokta Bulutları ile YOLO Kullanımı
YOLO'yu entegre etmek için sensor_msgs/PointCloud2
tipi mesajlar için, derinlik haritaları için kullanılan yönteme benzer bir yöntem kullanabiliriz. Nokta bulutuna gömülü renk bilgilerinden yararlanarak, 2B bir görüntü çıkarabilir, YOLO kullanarak bu görüntü üzerinde segmentasyon gerçekleştirebilir ve ardından ortaya çıkan maskeyi üç boyutlu noktalara uygulayarak ilgilenilen 3B nesneyi izole edebiliriz.
Nokta bulutlarını işlemek için Open3D'yi kullanmanızı öneririz (pip install open3d
), kullanıcı dostu bir python kütüphanesi. 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 güçlü araçlar sağlar. Bu kütüphane, süreci önemli ölçüde basitleştirebilir ve YOLO tabanlı segmentasyonla bağlantılı olarak nokta bulutlarını manipüle etme ve analiz etme yeteneğimizi geliştirebilir.
Nokta Bulutları Adım Adım Kullanımı
Gerekli kütüphaneleri içe aktarın ve segmentasyon için YOLO modelini örneklendirin.
import time
import rospy
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolo11m-seg.pt")
Bir fonksiyon oluşturun pointcloud2_to_array
, bir öğesini dönüştüren sensor_msgs/PointCloud2
mesajı iki numpy dizisine dönüştürür. Şunun sensor_msgs/PointCloud2
mesajları içerir n
temel alan noktalar width
ve height
elde edilen görüntünün. Örneğin, bir 480 x 640
görüntüye sahip olacak 307,200
noktaları. Her nokta üç uzamsal koordinat içerir (xyz
) ve karşılık gelen renk RGB
biçimindedir. Bunlar, iki ayrı bilgi kanalı olarak düşünülebilir.
Fonksiyon şunu döndürür: xyz
koordinatlar ve RGB
değerleri orijinal kamera çözünürlüğü biçiminde (width x height
). Çoğu sensörün, değerlerin inf (sonsuz) olarak temsil edildiği, klip mesafesi olarak bilinen maksimum bir mesafesi vardır.np.inf
). İşlemden önce, bu boş 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, şuna abone olun: /camera/depth/points
nokta bulutu mesajını almak ve dönüştürmek için. sensor_msgs/PointCloud2
XYZ koordinatlarını ve RGB değerlerini içeren numpy dizilerine mesaj (kullanarak pointcloud2_to_array
fonksiyonu). Bölümlere ayrılmış nesneleri çıkarmak için RGB görüntüsünü YOLO modelini kullanarak işleyin. Algılanan her nesne için, segmentasyon maskesini çıkarın ve nesneyi 3B uzayda izole etmek için hem RGB görüntüsüne hem de XYZ koordinatlarına uygulayın.
Maskeyi işlemek basittir, çünkü maske ikili değerlerden oluşur, 1
nesnenin varlığını gösterir ve 0
nesnenin varlığını ve yokluğunu belirtir. Maskeyi uygulamak için orijinal kanalları maskeyle çarpmanız yeterlidir. Bu işlem, görüntüdeki ilgi nesnesini etkili bir şekilde izole eder. Son olarak, bir Open3D nokta bulutu nesnesi oluşturun ve bölümlenmiş nesneyi ilişkili renklerle 3B uzayda 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])
Tam kod
import sys
import time
import numpy as np
import open3d as o3d
import ros_numpy
import rospy
from sensor_msgs.msg import PointCloud2
from ultralytics import YOLO
rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolo11m-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şturmasına yardımcı olmak için robotikte yaygın olarak kullanılan açık kaynaklı bir çerçevedir. Karmaşık uygulamaların daha kolay geliştirilmesini sağlayarak, robotik sistemler oluşturmak ve bunlarla arayüz oluşturmak için bir kütüphane ve araç koleksiyonu 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'yu ROS ile nasıl entegre ederim?
Ultralytics YOLO'yu ROS ile entegre etmek, bir ROS ortamı kurmayı ve sensör verilerini işlemek için YOLO'yu kullanmayı içerir. Aşağıdaki gibi gerekli bağımlılıkları yükleyerek başlayın: ros_numpy
ve Ultralytics YOLO:
pip install ros_numpy ultralytics
Ardından, bir ROS düğümü oluşturun ve gelen verileri işlemek için bir görüntü konusuna (image topic) abone olun. İşte минима bir örnek:
import ros_numpy
import rospy
from sensor_msgs.msg import Image
from ultralytics import YOLO
detection_model = YOLO("yolo11m.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'da nasıl kullanılır?
ROS konuları, bir ROS ağındaki düğümler arasında yayınlama-abonelik modeli kullanarak iletişimi kolaylaştırır. Bir konu, düğümlerin mesajları eşzamansız olarak 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, görüntüleri algılama veya segmentasyon gibi görevler için YOLO kullanarak 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:
rospy.Subscriber("/camera/color/image_raw", Image, callback)
ROS'ta Ultralytics YOLO ile derinlik görüntüleri neden kullanılır?
ROS'ta derinlik görüntüleri, şu şekilde temsil edilir: sensor_msgs/Image
, engelden kaçınma, 3B haritalama ve konumlandırma gibi görevler için çok önemli olan nesnelerin kameraya olan uzaklığını sağlar. Şunu yaparak: derinlik bilgisini kullanarak RGB görüntülerle birlikte robotlar, 3D ortamlarını daha iyi anlayabilir.
YOLO ile, RGB görüntülerinden segmentasyon maskeleri çıkarabilir ve bu maskeleri derinlik görüntülerine uygulayarak hassas 3B nesne bilgileri elde edebilir, böylece robotun çevresiyle etkileşim ve navigasyon yeteneği geliştirilebilir.
ROS'ta YOLO ile 3B nokta bulutlarını nasıl görselleştirebilirim?
YOLO ile ROS'ta 3B nokta bulutlarını 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ülerini bölümlere ayırmak için YOLO'yu 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("yolo11m-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, robotik uygulamalarda gezinme ve manipülasyon gibi görevler için yararlı olan bölümlenmiş nesnelerin 3B görselleştirmesini sağlar.