اگر آپ نے کبھی ایسا روبوٹک نظام بنایا ہے جو حقیقت میں اپنے اردگرد کی دنیا کو دیکھ سکتا ہے، ٹریک کر سکتا ہے اور اس پر ردعمل ظاہر کر سکتا ہے، تو آپ جانتے ہیں کہ سینسنگ ماڈل کی تربیت مشکل حصہ ہے۔ مشکل حصہ اس بات کو یقینی بنانا ہے کہ ماڈل حقیقی روبوٹ سافٹ ویئر اسٹیک کے اندر حقیقی وقت میں ہارڈ ویئر کی رکاوٹوں یا وقت کے مسائل پیدا ہونے کے وقت کو توڑے بغیر قابل اعتماد طریقے سے چلتا ہے۔
اس ٹیوٹوریل میں، ہم ROS 2 اور YOLOv11 کا استعمال کرتے ہوئے ایک مکمل ریئل ٹائم آبجیکٹ کا پتہ لگانے اور ٹریکنگ پائپ لائن بناتے ہیں۔ آپ سیکھیں گے کہ کیمرہ فریمز کو سمیلیٹر سے ROS 2 پر کیسے پوسٹ کیا جائے، YOLO انفرنس کو ایک وقف شدہ دھاگے پر چلائیں، تمام فریموں میں ملٹی آبجیکٹ ٹریکنگ کے لیے ByteTrack کو انٹیگریٹ کریں، اور محدود ہارڈ ویئر پر تیز تر اندازہ لگانے کے لیے ماڈلز کو ONNX پر ایکسپورٹ کریں۔
اس آرٹیکل کے اختتام تک، آپ نہ صرف یہ سمجھیں گے کہ یہ ٹولز ایک ساتھ کیسے فٹ ہوتے ہیں، بلکہ یہ بھی سمجھیں گے کہ ہر ایک آرکیٹیکچرل فیصلہ شناختی نظام کے لیے کیوں اہم ہے جس کا مقصد پیداواری ماحول کے ساتھ ساتھ لیپ ٹاپ پر بھی کام کرنا ہے۔
یہاں ہم کیا احاطہ کریں گے:
انڈیکس
شرطیں
جاری رکھنے سے پہلے، یقینی بنائیں کہ آپ درج ذیل سے واقف ہیں:
-
Python 3.10 اور اس سے زیادہ: اس ٹیوٹوریل میں تمام کوڈ Python میں لکھا گیا ہے۔
-
بنیادی ROS 2 علم: آپ کو یہ سمجھنے کی ضرورت ہے کہ نوڈ، موضوع، پبلشر، اور سبسکرائبر کیا ہیں۔ اگر آپ ROS 2 میں نئے ہیں تو، سرکاری ROS 2 دستاویزات ایک اچھا نقطہ آغاز ہے۔
-
PyTorch اور آبجیکٹ کا پتہ لگانے کے تصورات کا علم: آپ کو YOLO ماڈل کو خود تربیت دینے کی ضرورت نہیں ہے، لیکن آپ کو یہ سمجھنے کی ضرورت ہے کہ تخمینہ کا کیا مطلب ہے اور باؤنڈنگ باکس کا پتہ لگانے کا آؤٹ پٹ کیسا لگتا ہے۔
-
کام کرنے والی ROS 2 شائستہ تنصیب Ubuntu 22.04 پر۔
-
GPU کی سفارش کی جاتی ہے۔ ریئل ٹائم انفرنس کے لیے، پائپ لائن CPU پر کم فریم ریٹ پر چلتی رہتی ہے۔
-
CARLA سمیلیٹر (اختیاری): کیمرہ پبلشر سیکشن CARLA استعمال کرتا ہے۔ اگر آپ کے پاس CARLA انسٹال نہیں ہے، تو آپ ROS 2 کے موافق کیمرہ ماخذ جیسے کہ ویب کیم نوڈ یا بیک فائل پلے بیک کو تبدیل کر سکتے ہیں۔
ہم کیا بناتے ہیں اور کیوں
پرسیپشن پائپ لائن روبوٹک سسٹم کا وہ حصہ ہے جو روبوٹ کے ارد گرد کے ماحول میں کیا ہے اس کو سمجھنے کے لیے ذمہ دار ہے۔ یہ خام سینسر ڈیٹا لیتا ہے، عام طور پر کیمرے کے فریم، اور اسے ساختی معلومات میں تبدیل کرتا ہے: کوئی چیز کہاں ہے، کیا ہے، اور یہ کیسے حرکت کرتی ہے۔
اس ٹیوٹوریل میں، ہم چار الگ الگ تہوں کے ساتھ ایک شناختی پائپ لائن بناتے ہیں:
-
کیمرے مجموعہ سمیلیٹر سے خام تصویری فریموں کو کیپچر کریں اور انہیں ROS 2 پیغامات کے طور پر شائع کریں، انہیں باقی روبوٹ اسٹیک کے لیے دستیاب کرائیں۔
-
آبجیکٹ کا پتہ لگانا ہم اعتماد کے اسکور کے ساتھ اشیاء اور ان کے مقامات کی شناخت کے لیے ہر آنے والے فریم پر YOLOv11 چلاتے ہیں۔
-
ایک سے زیادہ آبجیکٹ ٹریکنگ ByteTrack کا استعمال کرتے ہوئے تمام فریموں میں پتہ لگانے کی زنجیر بنا کر، ہم ہر فریم کو ایک نئے منظر کے طور پر استعمال کرنے کے بجائے وقت کے ساتھ ساتھ ایک مستحکم ID فراہم کرتے ہیں۔
-
تصدیق اور اصلاح ایک ٹرسٹ گیٹنگ پرت شامل کریں جو کم معیار کی کھوجوں کو نیچے کی دھارے کی تلاش کی منطق تک پہنچنے سے روکتی ہے اور کنارے کے ہارڈ ویئر پر تیز تر اندازہ لگانے کے لیے ماڈلز کو ONNX کو برآمد کرتی ہے۔
ہم CARLA کو بطور سمیلیٹر استعمال کر رہے ہیں۔ CARLA حقیقت پسندانہ سینسر ڈیٹا، قابل کنٹرول ماحول، اور Python کے قابل رسائی کیمرہ اداکار فراہم کرتا ہے، جو اسے خود مختار گاڑی اور موبائل روبوٹ پرسیپشن ریسرچ کے لیے قدرتی فٹ بناتا ہے۔ اگر آپ ایک مختلف سینسر ذریعہ استعمال کرتے ہیں، تو ROS 2 فن تعمیر ایک جیسا ہے اور آپ کو صرف کیمرہ پبلشر نوڈ کو تبدیل کرنے کی ضرورت ہے۔
منصوبے کی ساخت
کوئی بھی کوڈ لکھنے سے پہلے پروجیکٹ کی مجموعی ترتیب کو دیکھنا مفید ہے۔ مکمل شدہ ورک اسپیس مندرجہ ذیل ہے۔
ros2_perception_ws/
├── src/
│ └── perception_stack/
│ ├── perception_stack/
│ │ ├── __init__.py
│ │ ├── camera_publisher.py # Publishes CARLA frames into ROS 2
│ │ ├── perception_node.py # Threaded YOLO inference node
│ │ ├── tracker.py # ByteTrack integration
│ │ ├── validator.py # Confidence gating layer
│ │ └── export_onnx.py # ONNX export script
│ ├── models/
│ │ └── yolov11n.pt # Downloaded YOLO weights
│ ├── package.xml
│ ├── setup.py
│ └── setup.cfg
├── requirements.txt
└── README.md
ہر فائل کی ایک ذمہ داری ہے۔ یہ علیحدگی روبوٹکس سافٹ ویئر کے لیے خاص طور پر اہم ہے کیونکہ شناخت، ٹریکنگ، اور توثیق مختلف شرحوں پر تیار ہوتی ہے اور اسے الگ سے جانچنے کے قابل ہونا چاہیے۔
ROS 2 ورک اسپیس کو کیسے ترتیب دیا جائے۔
ایک ورک اسپیس اور پیکیج بنائیں۔
mkdir -p ~/ros2_perception_ws/src
cd ~/ros2_perception_ws/src
ros2 pkg create --build-type ament_python perception_stack
cd ~/ros2_perception_ws
colcon build
source install/setup.bash
colcon build ورک اسپیس کو مرتب کریں۔ سورسنگ install/setup.bash اب جب کہ ROS 2 نئے پیکیج کو پہچانتا ہے، آپ نوڈ کو اس طرح چلا سکتے ہیں: ros2 run.
انحصار کو انسٹال کرنے کا طریقہ
pip install ultralytics opencv-python-headless cv_bridge \
torch torchvision onnx onnxruntime-gpu \
numpy supervision
فراہم کنندگان کے لیے نوٹ: یہ ٹیوٹوریل ONNX رن ٹائم کو GPU سپورٹ کے ساتھ استعمال کرتا ہے: onnxruntime-gpu. اگر آپ CUDA مطابقت پذیر GPU کے بغیر کسی مشین پر چل رہے ہیں، تو اسے اس سے تبدیل کریں: onnxruntime صرف CPU کے قیاس کے لیے۔ باقی پائپ لائن میں کوئی تبدیلی نہیں ہوئی، لیکن فریم کی شرح کم ہونے کی امید ہے۔
ROS 2 میں کیمرہ فریم کیسے پوسٹ کریں۔
پہلا نوڈ CARLA کے Python API اور ROS 2 ماحولیاتی نظام کے درمیان فرق کو ختم کرتا ہے۔ CARLA ایونٹ پر مبنی کال بیک سسٹم استعمال کرتا ہے۔ ROS 2 ٹائپ شدہ میسج فارمیٹ کے ساتھ پبلشر-سبسکرائبر ماڈل استعمال کرتا ہے۔ یہ نوڈ CARLA کی خام تصویر کی شکل کو تبدیل کرتا ہے۔ sensor_msgs/Image پیغام یہ ہے کہ تمام ROS 2 نوڈس سبسکرائب کر سکتے ہیں۔
بنانا camera_publisher.py:
import carla
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import numpy as np
class CARLACameraNode(Node):
def __init__(self):
super().__init__('carla_camera_node')
self.publisher = self.create_publisher(Image, '/carla/camera/rgb', 10)
self.bridge = CvBridge()
self.get_logger().info('CARLA camera node started.')
def camera_callback(self, image):
# CARLA raw data is BGRA, we convert to BGR for OpenCV compatibility
array = np.frombuffer(image.raw_data, dtype=np.uint8)
array = array.reshape((image.height, image.width, 4))
bgr = array[:, :, :3]
msg = self.bridge.cv2_to_imgmsg(bgr, encoding='bgr8')
# Stamp the message with the current ROS 2 clock time.
# This is critical. Downstream nodes like trackers and SLAM
# systems calculate velocity and displacement using time deltas
# between messages. Without an accurate timestamp, those
# calculations produce garbage and the tracker becomes unstable.
msg.header.stamp = self.get_clock().now().to_msg()
self.publisher.publish(msg)
def main():
rclpy.init()
node = CARLACameraNode()
client = carla.Client('localhost', 2000)
world = client.get_world()
blueprint_library = world.get_blueprint_library()
camera_bp = blueprint_library.find('sensor.camera.rgb')
camera_bp.set_attribute('image_size_x', '1280')
camera_bp.set_attribute('image_size_y', '720')
camera_bp.set_attribute('fov', '90')
spawn_point = world.get_map().get_spawn_points()[0]
camera = world.spawn_actor(camera_bp, spawn_point)
camera.listen(node.camera_callback)
rclpy.spin(node)
camera.destroy()
node.destroy_node()
rclpy.shutdown()
کہ cv_bridge لائبریری OpenCV arrays اور ROS 2 تصویری پیغامات کے درمیان تبادلوں کو سنبھالتی ہے۔ کہ bgr8 انکوڈنگ ڈاؤن اسٹریم سبسکرائبرز کو بتاتی ہے کہ کس رنگ کی شکل کی توقع کی جائے۔ اس کے بغیر، رنگین چینلز کو خود بخود تبدیل کیا جا سکتا ہے اور ڈیٹیکٹر بالکل درست ان پٹ کے لیے غلط نتائج پیدا کرے گا۔
تھریڈڈ انفرنس کا استعمال کرتے ہوئے علمی نوڈ کیسے بنایا جائے۔
یہ پائپ لائن میں ساختی لحاظ سے سب سے اہم نوڈ ہے، اور کوڈ کو دیکھنے سے پہلے اس کے ڈیزائن کو کچھ وضاحت کی ضرورت ہے۔
ROS 2 سبسکرائبر کال بیکس کو ایک ہی ایگزیکیوٹر تھریڈ میں بطور ڈیفالٹ ہینڈل کرتا ہے۔ جب YOLO انفرنس کال کال بیک کے اندر ہوتی ہے، تو یہ اس تھریڈ کو انفرنس کی مدت کے لیے بلاک کر دیتا ہے۔ جب تک اندازہ چل رہا ہو، سبسکرائبر نئے پیغامات وصول نہیں کر سکتے۔
قطار کے سائز اور فریم کی شرح پر منحصر ہے، اس کا مطلب ہے کہ جب تک اندازہ مکمل ہو جائے گا، یہ پرانے فریموں پر کارروائی شروع کر دے گا۔ ٹریکر پھر ایک ندی دیکھتا ہے جو ہموار ندی کے بجائے وقت کے ساتھ ساتھ فاسد اور متضاد ہے۔
حل یہ ہے کہ جمع کو پروسیسنگ سے الگ کیا جائے۔ کال بیک ایک کام کرتا ہے۔ اس کا مطلب یہ ہے کہ آنے والے فریموں کو ایک پابند قطار میں ڈالنا اور انہیں فوری طور پر واپس کرنا ہے۔ ایک الگ دھاگہ اس قطار سے کھینچتا ہے اور تخمینہ چلاتا ہے۔
قطار کا زیادہ سے زیادہ سائز ہے۔ اگر تخمینہ جاری نہیں رہتا ہے اور قطار بھری ہوئی ہے تو، نئے فریموں کو غیر معینہ مدت تک قطار میں لگانے کے بجائے رد کر دیا جاتا ہے۔ یہ جان بوجھ کر ڈیزائن کا انتخاب ہے۔ ریئل ٹائم سسٹمز میں، پرانے فریم جو دیر سے پروسیس ہوتے ہیں عام طور پر گرے ہوئے فریموں سے زیادہ خراب ہوتے ہیں۔ کیونکہ اس کی وجہ سے ٹریکر دنیا کو ویسا ہی دیکھتا ہے جیسا کہ یہ ہے، نہ کہ جیسا ہے۔
بنانا perception_node.py:
import threading
import queue
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from ultralytics import YOLO
import cv2
CONFIDENCE_THRESHOLD = 0.45
class PerceptionNode(Node):
def __init__(self):
super().__init__('perception_node')
self.bridge = CvBridge()
self.model = YOLO('models/yolov11n.pt')
# Bounded queue: maxsize=5 prevents stale frame accumulation.
# When the queue is full, image_callback drops the incoming frame
# rather than waiting, keeping the pipeline current.
self.frame_queue = queue.Queue(maxsize=5)
self.subscription = self.create_subscription(
Image,
'/carla/camera/rgb',
self.image_callback,
10
)
self.inference_thread = threading.Thread(
target=self.run_inference,
daemon=True
)
self.inference_thread.start()
self.get_logger().info('Perception node ready.')
def image_callback(self, msg):
# Drop the frame if inference is not keeping up.
# We never want to block the callback thread.
if not self.frame_queue.full():
self.frame_queue.put(msg)
def run_inference(self):
while rclpy.ok():
msg = self.frame_queue.get()
frame = self.bridge.imgmsg_to_cv2(msg, desired_encoding='bgr8')
results = self.model(frame, conf=CONFIDENCE_THRESHOLD, verbose=False)
detections = results[0].boxes
self.get_logger().info(
f'Detected {len(detections)} objects above threshold {CONFIDENCE_THRESHOLD}'
)
def main():
rclpy.init()
node = PerceptionNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
ملٹی آبجیکٹ ٹریکنگ کے لیے بائٹ ٹریک کو کیسے مربوط کیا جائے۔
اکیلے پتہ لگانا آپ کو بتاتا ہے کہ ایک فریم میں کیا ہے۔ ٹریکنگ آپ کو بتاتی ہے کہ وقت کے ساتھ کیا ہو رہا ہے۔ یہ آپ کو بتاتا ہے کہ یہ کون سی کار ہے، کہاں جا رہی ہے، اور آیا یہ وہی کار ہے جسے آپ نے دو سیکنڈ پہلے دیکھا تھا۔
بائٹ ٹریک انٹرسیکشن اوور-یونین (IoU) کا استعمال کرتے ہوئے موجودہ ٹریکس کے ساتھ نئی کھوجوں کو جوڑ کر کام کرتا ہے، جو پیش گوئی شدہ ٹریک پوزیشن اور آنے والی شناختوں کے درمیان باؤنڈنگ باکس اوورلیپ کی پیمائش کرتا ہے۔
یہ دو قدمی مماثلت کے عمل کا استعمال کرتا ہے جو اعلی اور کم اعتماد دونوں کی کھوجوں کو سنبھالتا ہے، یہ سادہ ٹریکرز کے مقابلے میں رکاوٹ کے خلاف زیادہ مضبوط بناتا ہے۔
تین پیرامیٹرز جو آپ اکثر ایڈجسٹ کریں گے وہ ہیں:
-
track_thresh: ٹریک شروع کرنے یا اس کی تصدیق کرنے کے لیے کم از کم پتہ لگانے کا اعتماد -
match_thresh: موجودہ ٹریکس سے مماثل پتہ لگانے کے لیے کم از کم IoU -
track_buffer: ان فریموں کی تعداد جو ٹریک کو ہٹائے جانے سے پہلے کسی میچ کا پتہ لگائے بغیر زندہ رہتا ہے۔
بنانا tracker.py:
from supervision import ByteTracker, Detections
import numpy as np
class RoboticsTracker:
def __init__(self):
# track_buffer controls how long a track survives
# without a matching detection. Higher values help
# during brief occlusions but can produce ghost tracks
# for objects that have genuinely left the scene.
self.tracker = ByteTracker(
track_thresh=0.45,
match_thresh=0.8,
track_buffer=30,
frame_rate=30
)
def update(self, yolo_results, frame_shape):
boxes = yolo_results[0].boxes
if len(boxes) == 0:
return []
xyxy = boxes.xyxy.cpu().numpy()
confidence = boxes.conf.cpu().numpy()
class_ids = boxes.cls.cpu().numpy().astype(int)
detections = Detections(
xyxy=xyxy,
confidence=confidence,
class_id=class_ids
)
tracked = self.tracker.update(
detections=detections,
frame_resolution_wh=(frame_shape[1], frame_shape[0])
)
# tracked.tracker_id gives each detection a stable integer ID
# that persists across frames as long as the track is alive.
return tracked
کہ tracker_id فیلڈز وہ ہیں جو نیویگیشن کے لیے ٹریکنگ کو کارآمد بناتے ہیں۔ ایک گمنام باؤنڈنگ باکس لسٹ کے بجائے، ڈاؤن اسٹریم سسٹم اب جانتا ہے کہ آبجیکٹ ID 7 ایک پیدل چلنے والا ہے جو پچھلے 12 فریموں کے دوران شمال مشرق میں چلا گیا ہے۔
قابل اعتبار تصدیقی پرت کو کیسے شامل کیا جائے۔
روبوٹ کے رویے کو تبدیل کرنے کے لیے ایک واحد، اعلیٰ اعتماد کا پتہ لگانا کافی بنیاد نہیں ہے۔ اعتماد کا اسکور اس بات کی پیمائش کرتا ہے کہ ماڈل اس کے بارے میں کتنا یقینی ہے جس کا پتہ چلا ہے۔ یہ اس بات کی پیمائش نہیں کرتا ہے کہ آیا پتہ عارضی طور پر مستحکم ہے، آیا پلیٹ فارم خود ہی مستحکم ہے، یا آس پاس کے حالات پتہ لگانے کو قابل فہم بناتے ہیں۔
اس توثیقی پرت کو ایک شناخت کو قابل عمل کے بطور نشان زد کرنے سے پہلے متعدد سگنلز کے اتفاق کی ضرورت ہوتی ہے۔ بنانا validator.py:
CONFIDENCE_THRESHOLD = 0.45
MIN_TRACK_AGE = 3 # frames a track must exist before being trusted
JITTER_THRESHOLD = 2.0 # maximum acceptable platform acceleration (m/s²)
def is_actionable_detection(detection, track_age: int, platform_acceleration: float):
"""
Returns True only when a detection passes all three checks:
1. Model confidence is above threshold (filters weak detections)
2. Track has existed long enough to be considered stable
(filters noise that triggers a detection in one or two frames but not more)
3. The platform carrying the sensor is not vibrating or accelerating
sharply enough to corrupt the sensor data itself
"""
if detection.confidence < CONFIDENCE_THRESHOLD:
return False, "low_confidence"
if track_age < MIN_TRACK_AGE:
return False, "track_not_stabilised"
if platform_acceleration > JITTER_THRESHOLD:
return False, "platform_unstable"
return True, "actionable"
یہ پیٹرن ماڈل آؤٹ پٹ کو سسٹم لیول ٹرسٹ سے الگ کرتا ہے۔ ماڈل کا کام پتہ لگانا ہے۔ توثیق کرنے والے کا کام یہ طے کرنا ہے کہ روبوٹ کی موجودہ آپریٹنگ حالت کو مدنظر رکھتے ہوئے ان میں سے کون سی کھوج محفوظ ہے۔
Edge کی تعیناتی کے لیے ماڈل کو ONNX پر کیسے برآمد کیا جائے۔
ONNX، اوپن نیورل نیٹ ورک ایکسچینج کے لیے مختصر، فریم ورک اور رن ٹائم کے درمیان پورٹیبل طریقے سے مشین لرننگ ماڈلز کی نمائندگی کرنے کے لیے ایک کھلا فارمیٹ ہے۔ PyTorch کے ذریعے اندازہ چلانے کے بجائے، اپنے ماڈل کو ایک بار ONNX فارمیٹ میں برآمد کریں اور پھر اسے ONNX رن ٹائم یا TensorRT کے ذریعے چلائیں۔ دونوں ایج ہارڈ ویئر پر بہت زیادہ موثر ہیں۔
TensorRT NVIDIA کی انفرنس آپٹیمائزیشن لائبریری ہے۔ ایک ONNX ماڈل لیں اور اسے خاص طور پر اپنے ٹارگٹ GPU کے لیے مرتب کریں، کرنل فیوژن، لیئر آپٹیمائزیشن، اور INT8 یا FP16 پر اختیاری درستگی میں کمی کا اطلاق کریں۔ نتیجہ ایک انفرنس انجن ہے جو اسی ہارڈ ویئر پر اصل PyTorch ماڈل سے زیادہ تیز چلتا ہے۔ یہ 30FPS ریئل ٹائم پائپ لائن میں قابل استعمال سسٹم اور ناقابل استعمال سسٹم کے درمیان فرق ہوسکتا ہے۔
بنانا export_onnx.py:
from ultralytics import YOLO
def export_perception_model(weights_path: str, output_path: str):
"""
Exports a YOLOv11 model to ONNX format for edge deployment.
The dynamic_axes setting on the batch dimension means the exported
model can accept single frames (batch=1) or batches of frames
without needing to be re-exported. This is useful for testing
with batched input during benchmarking.
"""
model = YOLO(weights_path)
# Export using Ultralytics' built-in ONNX export.
# opset=17 is the recommended version for compatibility
# with TensorRT 8.x and later.
model.export(
format="onnx",
imgsz=640,
opset=17,
dynamic=True, # enables dynamic batch size
simplify=True # runs onnx-simplifier to clean the graph
)
print(f"Model exported to {output_path}")
if __name__ == '__main__':
export_perception_model(
weights_path="models/yolov11n.pt",
output_path="models/perception.onnx"
)
PyTorch کے بجائے برآمد شدہ ONNX ماڈل کا استعمال کرتے ہوئے اندازہ چلانے کے لیے، YOLO انفرنس کال کو اس میں تبدیل کریں: perception_node.py ONNX رن ٹائم سیشن کا استعمال:
import onnxruntime as ort
import numpy as np
import cv2
session = ort.InferenceSession(
'models/perception.onnx',
providers=['CUDAExecutionProvider', 'CPUExecutionProvider']
)
def run_onnx_inference(frame: np.ndarray):
# Preprocess: resize, normalise, add batch dimension, convert to float32
img = cv2.resize(frame, (640, 640))
img = img.astype(np.float32) / 255.0
img = img.transpose(2, 0, 1) # HWC to CHW
img = np.expand_dims(img, axis=0) # add batch dimension
outputs = session.run(None, {'images': img})
return outputs
کہ providers فہرست ONNX رن ٹائم کو GPU ایکسلریشن کے لیے CUDA کو ترجیح دینے اور CUDA دستیاب نہ ہونے کی صورت میں CPU پر واپس آنے کی ہدایت کرتی ہے۔ یہ ایک ہی انفرنس کوڈ کو بغیر کوڈ کی تبدیلیوں کے ڈویلپمنٹ سسٹمز اور ایج ڈیوائسز کے درمیان پورٹ کرنے کی اجازت دیتا ہے۔
اپنی پوری پائپ لائن کی جانچ کیسے کریں۔
تمام نوڈس بننے کے بعد، دونوں ٹرمینلز پر پائپ لائن شروع کریں۔
پہلے ٹرمینل میں، کیمرہ پبلشر شروع کریں۔
cd ~/ros2_perception_ws
source install/setup.bash
ros2 run perception_stack camera_publisher
دوسرے ٹرمینل میں ریکگنیشن نوڈ شروع کریں۔
source install/setup.bash
ros2 run perception_stack perception_node
اس بات کو یقینی بنانے کے لیے کہ فریم نوڈس کے درمیان صحیح طریقے سے بہہ رہے ہیں، آپ تیسرے ٹرمینل میں اشیاء کا معائنہ کر سکتے ہیں۔
ros2 topic hz /carla/camera/rgb
یہ کمانڈ کیمرے کے موضوع کے لیے پیغام کی شرح پرنٹ کرتی ہے۔ 30FPS پر، آپ کو تقریباً 30 پیغامات فی سیکنڈ نظر آئیں گے۔ نمایاں طور پر کم تعداد سے پتہ چلتا ہے کہ CARLA کال بیکس فریم چھوڑ رہے ہیں یا نوڈس کے درمیان نیٹ ورک سیر ہو گیا ہے۔
اگر آپ بصری طور پر معائنہ کرنا چاہتے ہیں کہ شناختی نوڈ کس چیز کا پتہ لگا رہا ہے، تو آپ اندرونی طور پر تشریح شدہ تصویری عنوان کو شائع کرکے ایک سادہ تصور شامل کرسکتے ہیں۔ run_inference:
annotated = results[0].plot() # draws boxes and labels on the frame
annotated_msg = self.bridge.cv2_to_imgmsg(annotated, encoding='bgr8')
annotated_msg.header.stamp = self.get_clock().now().to_msg()
self.annotated_publisher.publish(annotated_msg)
پھر تشریح شدہ سلسلہ کھولیں۔ rqt_image_view:
ros2 run rqt_image_view rqt_image_view /perception/annotated
نتیجہ
اب ہم نے سینسرز سے تصدیق شدہ اور ٹریس ایبل پتہ لگانے کے لیے ایک حقیقی وقت کی روبوٹک پرسیپشن پائپ لائن بنائی ہے۔ آپ جو سسٹم بناتے ہیں وہ کیمرہ کلیکشن، تھریڈڈ انفرنس، ملٹی آبجیکٹ ٹریکنگ، اعتماد پر مبنی تصدیق، اور ایج آپٹمائزڈ ماڈل ایکسپورٹ کو ہینڈل کرتا ہے۔
ان تمام اجزاء کے لیے گہرا سبق ایک ہی ہے۔ روبوٹ پرسیپشن سسٹم کا مسئلہ ہے، ماڈل کا مسئلہ نہیں۔ ایک اچھی طرح سے تربیت یافتہ ماڈل ضروری ہے لیکن کافی نہیں ہے۔ پیداوار میں جو چیز اہمیت رکھتی ہے وہ یہ ہے کہ آیا پائپ لائن وقت کو صحیح طریقے سے ہینڈل کرتی ہے اور بوجھ کے نیچے خوبصورتی سے انحطاط کرتی ہے، آیا خرابی کی حالتوں کی وضاحت کی گئی ہے، اور آیا فن تعمیر مسائل کو واضح طور پر الگ کرتا ہے تاکہ فیلڈ میں ڈیبگ اور اعادہ کیا جا سکے۔
یہاں اگلا مرحلہ پتہ لگانے والے لاگ ان کو تبدیل کرنا ہے۔ perception_node.py ہم پتہ لگانے کے لیے ایک مناسب ROS 2 میسج پبلشر کا استعمال کرتے ہوئے آؤٹ پٹ کو Nav2 نیویگیشن اسٹیک میں ضم کرتے ہیں اور پوری پائپ لائن کو ٹارگٹ ہارڈ ویئر پر چلاتے ہیں تاکہ یہ یقینی بنایا جا سکے کہ ONNX کی اصلاح حقیقی دنیا کی تعیناتی کے حالات میں برقرار ہے۔
اگر آپ اس سے ملتی جلتی کوئی چیز بنا رہے ہیں یا اس کے بارے میں کوئی سوالات ہیں تو براہ کرم بلا جھجھک ہم سے رابطہ کریں۔ جب روبوٹ کی بات آتی ہے تو اس کے بارے میں بات کرنے کے لئے ہمیشہ بہت کچھ ہوتا ہے جو حقیقت میں کام کرتے ہیں۔