İçeriğe geç

ROS (Robot İşletim Sistemi) hızlı başlangıç kılavuzu

ROS Tanıtımı (altyazılı) from Open Robotics on Vimeo.

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üphaneler ve araçlar koleksiyonu sağlar. ROS, çeşitli robotik platformlarla çalışacak şekilde tasarlanmıştır, bu da onu robotikçiler için esnek ve güçlü bir araç haline getirir.

ROS'un Temel Özellikleri

  1. 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.

  2. İletişim Ara Yazılımı: 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ınla-abone ol modeli ve hizmet çağrıları için bir istek-cevap modeli aracılığıyla gerçekleştirilir.

  3. 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 olanak tanıyarak daha kolay entegrasyon ve denemeyi kolaylaştırır.

  4. 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.

  5. Kapsamlı Ekosistem: ROS ekosistemi, navigasyon, manipülasyon, algılama ve daha fazlası dahil olmak üzere farklı robotik uygulamalar için mevcut olan çok sayıda paket ile geniş ve sürekli büyümektedir. Topluluk, bu paketlerin geliştirilmesine ve bakımına aktif olarak katkıda bulunur.

ROS Sürümlerinin Evrimi

Geliştirildiği 2007 yılından bu yana ROS, her biri robotik topluluğunun artan ihtiyaçlarını karşılamak için yeni özellikler ve iyileştirmeler sunan birden fazla sürümle gelişmiştir. ROS'un gelişimi iki ana seri olarak kategorize edilebilir: Bu kılavuz, ROS Noetic Ninjemys olarak bilinen ROS 1'in Uzun Süreli Destek (LTS) sürümüne odaklanmaktadır, kod daha önceki sürümlerle de çalışmalıdır.

ROS 1 vs. ROS 2

ROS 1 robotik geliştirme için sağlam bir temel oluştururken, ROS 2 bu eksiklikleri gidermektedir:

  • Gerçek Zamanlı Performans: Gerçek zamanlı sistemler ve deterministik davranış için geliştirilmiş destek.
  • Güvenlik: Çeşitli ortamlarda güvenli ve güvenilir çalışma için geliştirilmiş 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 dışındaki ç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önderildiği ve alındığı adlandırılmış bir kanaldır. Düğümler bir konuya mesaj yayınlayabilir veya bir konudan gelen mesajlara abone olarak birbirleriyle iletişim kurabilirler. Bu yayınlama-abone olma modeli, eşzamansız iletişime ve düğümler arasında ayrışmaya 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ına ve kamera konularına odaklanacağız.

ROS ile Ultralytics YOLO Kurulumu

Bu kılavuz, ROSbot ROS deposunun bir çatalı olan bu ROS ortamı kullanılarak test edilmiştir. 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, hem simülasyon hem de gerçek dünya dahil olmak üzere herhangi bir ROS Noetic/Melodic ortamında çalışacaktır.

Husarion ROSbot 2 PRO

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 Paket:

    pip install ultralytics
    

ROS ile Ultralytics adresini kullanın sensor_msgs/Image

Bu sensor_msgs/Image mesaj türü ROS'ta görüntü verilerini temsil etmek için yaygın olarak 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 görevler için robotik uygulamalarda yaygın olarak kullanılmaktadır, nesne algılamave navigasyon.

ROS Gazebo'da Algılama ve Segmentasyon

Adım Adım Görüntü 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 tespit edilen nesneleri algılama ve segmentasyon için yeni konulara yayınlıyoruz.

İlk olarak, gerekli kütüphaneleri içe aktarın ve iki modeli örnekleyin: biri segmentasyon ve bir tane de tespit. Bir ROS düğümünü başlatın (adı 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 tanıyan 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 konusunu başlatın: biri tespit ve bir tane de 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 şu şekilde 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, aşağıdaki iletileri dinleyen bir abone oluşturun /camera/color/image_raw konusuna yönlendirir ve her yeni mesaj için bir geri arama işlevi çağırır. Bu geri arama işlevi şu türdeki iletileri alır sensor_msgs/Imagekullanarak bunları bir numpy dizisine dönüştürür. ros_numpygörüntüleri daha önce anlık hale getirilmiş YOLO modelleri ile işler, görüntülere açıklama ekler 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()
Kodu tamamlayın
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ıklama, sistemin dağıtılmış yapısı nedeniyle zor olabilir. Bu süreçte çeşitli araçlar yardımcı olabilir:

  1. 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.
  2. rostopic list: ROS sistemindeki mevcut tüm konuları listelemek için bu komutu kullanın ve aktif veri akışlarına genel bir bakış sağlayın.
  3. 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ğlı olduğu ve nasıl etkileşimde bulundukları hakkında bilgi sağlar.
  4. 3B gösterimler gibi daha karmaşık görselleştirmeler için RViz. RViz (ROS Visualization), 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, robotik sisteminizin davranışında hata ayıklamayı ve anlamayı kolaylaştırır.

Algılanan Sınıfları Yayınla ile std_msgs/String

Standart ROS mesajları ayrıca şunları içerir std_msgs/String mesajlar. 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 mesajlar üzerinde tespit edilen sınıfları yeniden yayınlamak için /ultralytics/detection/classes konu. Bu mesajlar daha hafiftir ve temel bilgileri sağlar, bu da onları çeşitli uygulamalar için değerli kılar.

Örnek Kullanım Örneği

Bir kamera ve nesne ile donatılmış bir depo robotu düşünün algılama modeli. Ağ üzerinden büyük açıklamalı görüntüler göndermek yerine, robot tespit edilen 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ı /ultralytics/detection/classes konu. Bu bilgiler daha sonra merkezi bir izleme sistemi tarafından envanteri gerçek zamanlı olarak izlemek, engellerden kaçınmak için robotun yol planlamasını optimize etmek veya tespit edilen 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.

String Adım Adım Kullanım

Bu örnekte Ultralytics YOLO paketinin ROS ile nasıl kullanılacağı gösterilmektedir. Bu örnekte, bir kamera konusuna abone oluyoruz, gelen görüntüyü YOLO kullanarak işliyoruz ve tespit edilen nesneleri yeni konuya yayınlıyoruz /ultralytics/detection/classes kullanarak std_msgs/String Mesajlar. Bu mesajlar ros_numpy paketi, ROS Image 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("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()

ROS Derinlik Görüntüleri ile Ultralytics adresini kullanın

RGB görüntülere ek olarak ROS, nesnelerin kameraya olan uzaklığı hakkında bilgi sağlayan derinlik görüntülerini de 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 3D yapısını algılamalarını sağlar.

Derinlik Görüntüleri Elde Etme

Derinlik görüntüleri çeşitli sensörler kullanılarak elde edilebilir:

  1. Stereo Kameralar: Görüntü eşitsizliğine dayalı olarak derinliği hesaplamak için iki kamera kullanın.
  2. Uçuş Süresi (ToF) Kameraları: Işığın bir nesneden geri dönmesi için geçen süreyi ölçer.
  3. Yapılandırılmış Işık Sensörleri: Bir desen yansıtın ve yüzeylerdeki deformasyonunu ölçün.

YOLO adresini Derinlik Görüntüleriyle Kullanma

ROS'ta derinlik görüntüleri şu şekilde temsil edilir 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 format kullanır ve her değerin nesneye olan mesafeyi temsil ettiği piksel başına 16 bitlik işaretsiz bir tamsayı belirtir. Derinlik görüntüleri, çevrenin daha kapsamlı bir görünümünü sağlamak için genellikle RGB görüntülerle birlikte kullanılır.

YOLO adresini 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ündeki nesneleri tespit edebilir ve bu tespit, derinlik görüntüsündeki ilgili bölgeleri belirlemek için kullanılabilir. Bu, tespit edilen nesneler için kesin derinlik bilgilerinin çıkarılmasına olanak tanıyarak robotun çevresini üç boyutlu olarak 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 ç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, bir görüntüyü bölümlere ayırmak için YOLO adresini kullanıyoruz ve çıkarılan maskeyi derinlik görüntüsündeki nesneyi bölümlere ayırmak için uyguluyoruz. Bu, ilgilenilen nesnenin her bir pikselinin kameranın odak merkezine olan uzaklığını belirlememizi sağlar. Bu mesafe bilgisini elde ederek, kamera ile sahnedeki belirli nesne arasındaki mesafeyi hesaplayabiliriz. Gerekli kütüphaneleri içe aktararak, bir ROS düğümü oluşturarak ve bir segmentasyon modeli ile bir ROS konusunu örnekleyerek 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 arama fonksiyonu tanımlayın. Fonksiyon, 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 tespit edilen her nesne için segmentasyon maskesini çıkarır ve derinlik görüntüsünü kullanarak nesnenin kameradan ortalama uzaklığını hesaplar. Çoğu sensörün klip mesafesi olarak bilinen ve ötesindeki değerlerin inf olarak temsil edildiği maksimum bir mesafesi vardır (np.inf). İşlemeden önce, bu null değerleri filtrelemek ve onlara bir değer atamak önemlidir. 0. Son olarak, tespit edilen nesneleri ortalama uzaklıkları ile birlikte /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 tamamlayın
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()

ROS ile Ultralytics adresini kullanın sensor_msgs/PointCloud2

ROS Gazebo'da Algılama ve Segmentasyon

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 mümkün kılar.

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 bir sahnenin dış yüzeyini temsil eder. Buluttaki her nokta şu özelliklere sahiptir X, Yve Z koordinatları, uzaydaki konumuna karşılık gelir ve ayrıca renk ve yoğunluk gibi ek bilgiler de içerebilir.

Referans çerçevesi

İle çalışırken sensor_msgs/PointCloud2nokta 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, sensörün /tf_static konusunu ele alır. Ancak, özel uygulama gereksinimlerinize bağlı olarak, nokta bulutunu başka bir referans çerçevesine dönüştürmeniz gerekebilir. Bu dönüşüm şu şekilde gerçekleştirilebilir tf2_ros paketi, koordinat çerçevelerini yönetmek ve bunlar arasında veri dönüştürmek için araçlar sağlar.

Nokta bulutlarının elde edilmesi

Nokta Bulutları çeşitli sensörler kullanılarak elde edilebilir:

  1. LIDAR (Işık Algılama ve Uzaklık Ölçme): Nesnelere olan mesafeleri ölçmek ve yüksek hassasiyetli 3D haritalar oluşturmak için lazer darbeleri kullanır.
  2. Derinlik Kameraları: Her piksel için derinlik bilgisini yakalayarak sahnenin 3D olarak yeniden oluşturulmasını sağlar.
  3. Stereo Kameralar: Üçgenleme yoluyla derinlik bilgisi elde etmek için iki veya daha fazla kamera kullanın.
  4. 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.

Nokta Bulutları ile YOLO adresini kullanma

YOLO ile entegre etmek için sensor_msgs/PointCloud2 tipi mesajlarda, derinlik haritaları için kullanılana benzer bir yöntem kullanabiliriz. Nokta bulutunda gömülü olan renk bilgisinden yararlanarak, 2 boyutlu bir görüntü çıkarabilir, YOLO kullanarak bu görüntü üzerinde segmentasyon yapabilir ve ardından ilgilenilen 3 boyutlu nesneyi izole etmek için elde edilen maskeyi üç boyutlu noktalara uygulayabiliriz.

Nokta bulutlarını işlemek için Open3D (pip install open3d), kullanıcı dostu bir Python kütüphanesidir. 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 kütüphane, süreci önemli ölçüde basitleştirebilir ve YOLO tabanlı segmentasyon ile birlikte 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 örnekleyin.

import time

import rospy

from ultralytics import YOLO

rospy.init_node("ultralytics")
time.sleep(1)
segmentation_model = YOLO("yolov8m-seg.pt")

Bir işlev oluşturun pointcloud2_to_arraydönüştüren bir sensor_msgs/PointCloud2 mesajını iki numpy dizisine dönüştürür. Bu sensor_msgs/PointCloud2 mesajlar şunları içerir n puanlarına göre width ve height elde edilen görüntünün. Örneğin, bir 480 x 640 görüntünün sahip olacağı 307,200 noktalar. Her nokta üç uzamsal koordinat içerir (xyz) ve karşılık gelen renk RGB biçimi. Bunlar iki ayrı bilgi kanalı olarak düşünülebilir.

Fonksiyon şu değeri döndürür xyz koordinatları ve RGB değerlerini orijinal kamera çözünürlüğü biçiminde (width x height). Çoğu sensörün klip mesafesi olarak bilinen ve ötesindeki değerlerin inf olarak gösterildiği bir maksimum mesafesi vardır (np.inf). İşlemeden önce, bu null değerleri filtrelemek ve onlara 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, şu adrese abone olun /camera/depth/points konusunu nokta bulutu mesajını almak ve sensor_msgs/PointCloud2 mesajını, XYZ koordinatlarını ve RGB değerlerini içeren numpy dizilerine (XYZ pointcloud2_to_array fonksiyonu). Bölümlere ayrılmış nesneleri çıkarmak için YOLO modelini kullanarak RGB görüntüsünü 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.

İkili değerlerden oluştuğu için maskenin işlenmesi basittir. 1 nesnenin varlığını gösterir ve 0 yokluğunu 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 bölümlere ayrılmış nesneyi ilişkili renklerle 3D 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])
Kodu tamamlayın
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])

ile Nokta Bulutu Segmentasyonu Ultralytics

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 :

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 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:

rospy.Subscriber("/camera/color/image_raw", Image, callback)

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/Imageengellerden kaçınma, 3B haritalama ve konum belirleme 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:

  1. Dönüştür sensor_msgs/PointCloud2 mesajlarını numpy dizilerine dönüştürür.
  2. RGB görüntüleri bölümlere ayırmak için YOLO adresini kullanın.
  3. 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.

📅5 ay önce oluşturuldu ✏️ 2 ay önce güncellendi

Yorumlar