Bir Jetson Nano MQTT hattı, GPU hızlandırmalı görüyü uçta çalıştırmanıza ve buluta yalnızca sonuçları göndermenize olanak tanır. Bu eğitimde bir NVIDIA Jetson üzerinde nesne tespiti çalıştıracak, tespitleri ve cihaz sağlığını TLS ile MQTT üzerinden JSON olarak yayınlayacak ve betiği açılışta başlayan ve kendi kendine yeniden bağlanan bir servise dönüştüreceksiniz.
Neden Jetson Artı MQTT
NVIDIA Jetson kartları, küçük ve düşük güç tüketen bir modülde bir Arm CPU ile CUDA destekli bir GPU'yu bir araya getirir. Bu da onları, veri merkezine video göndermeden kişileri, araçları veya hataları gerçek zamanlı tespit etmesi gereken kameralar için popüler bir seçim hâline getirir.
Böyle bir kameranın asıl ilginç kısmı çıktısıdır: nesne etiketleri, konumlar, sayımlar ve uyarılar. MQTT bu çıktıyı iletmenin doğal bir yoludur, çünkü hafiftir, güvenilmez bağlantıları zarif şekilde yönetir ve istenen sayıda tüketicinin abone olmasına izin verir. Jetson bir kez yayınlar; dashboard'lar, uyarı araçları, historian'lar ve diğer yapay zeka servislerinin hepsi aynı mesajları alır.
Jetson ve Yazılım Yığını Seçimi
| Kart | JetPack nesli | Varsayılan Python | paho-mqtt 2.x desteği | Notlar |
|---|---|---|---|---|
| Jetson Nano (orijinal, 4 GB) | JetPack 4.x | 3.6 | Hayır, 1.6.x kullanın | Hâlâ yaygın olarak kullanılıyor, daha yeni JetPack yok |
| Jetson Orin Nano | JetPack 5 veya 6 | 3.8 veya 3.10 | Evet | Güncel giriş seviyesi seçim |
| Jetson Orin NX / AGX Orin | JetPack 5 veya 6 | 3.8 veya 3.10 | Evet | Daha büyük modeller için daha fazla GPU |
Bu sürüm farkı en yaygın tuzaktır. paho-mqtt 2.x, Python 3.7 veya üstünü gerektirir; bu yüzden JetPack 4.6 çalıştıran orijinal bir Jetson Nano'da ya paho-mqtt 1.6.1'i kurarsınız (ve CallbackAPIVersion argümanını ile properties callback parametresini kaldırırsınız) ya da kodunuzu daha yeni bir Python'a sahip bir container içinde çalıştırırsınız. Aşağıdaki örnekler paho-mqtt 2.x ile JetPack 5 veya 6'yı hedefler.
Çıkarım için bu eğitim, TensorRT ile optimize edilmiş tespit modellerini kısa bir Python API'sinin arkasında sunan ve CSI ile USB kameraları yöneten NVIDIA'nın açık kaynaklı jetson-inference kütüphanesini kullanır. MQTT kısmı, Ultralytics üzerinden YOLO dahil diğer tüm çıkarım framework'leriyle aynı şekilde çalışır.
Adım 1: Jetson'ı Hazırlamak
jetson-inference'ı dokümantasyonunu izleyerek kurun (kaynaktan derleyerek veya Docker container'ını kullanarak), ardından MQTT client'ını ekleyin:
sudo apt update
sudo apt install -y python3-pip mosquitto-clients
pip3 install "paho-mqtt>=2.0"
Kameranın çalıştığını doğrulayın. jetson-inference kuruluyken:
video-viewer csi://0 # CSI camera such as a Raspberry Pi Camera Module v2
video-viewer /dev/video0 # USB webcam
Ardından Jetson'ın broker'a ulaşabildiğini kontrol edin. İlk test için broker.connectmq.com'un genel alanını TLS üzerinden kullanın:
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-i jetson-test-7d1e -t "connectmq/demo/jet-7d1e/hello" -m "jetson online"
Bu başarısız olursa 8883 portu için giden güvenlik duvarı kurallarını ve sistem saatinin doğru olup olmadığını kontrol edin; saati yıllarca geride olan bir Jetson'da TLS başarısız olur.
Adım 2: Tespit Yayıncısı
jetson_mqtt.py olarak kaydedin. Kareleri yakalar, detectNet'i GPU üzerinde çalıştırır, hızı sınırlandırılmış tespitleri, sınıf başına retained sayımları ve kare hızı ile GPU tarafı performansını içeren bir heartbeat yayınlar.
import json
import ssl
import time
import uuid
import paho.mqtt.client as mqtt
from jetson_inference import detectNet
from jetson_utils import videoSource
BROKER, PORT = "broker.connectmq.com", 8883
PREFIX = "connectmq/demo/jet-7d1e/site1/gate/cam1"
USERNAME, PASSWORD = None, None # özel bir broker için "YOUR_USERNAME", "YOUR_PASSWORD" olarak ayarlayın
CLIENT_ID = f"jetson-cam1-{uuid.uuid4().hex[:6]}" # özel bir broker'da YOUR_CLIENT_ID kullanın
PUBLISH_EVERY = 0.5
HEARTBEAT_EVERY = 30
net = detectNet("ssd-mobilenet-v2", threshold=0.5)
camera = videoSource("csi://0") # veya "/dev/video0" ya da "rtsp://..."
def on_connect(client, userdata, flags, reason_code, properties):
print("connected:", reason_code)
client.publish(f"{PREFIX}/status",
json.dumps({"online": True, "model": "ssd-mobilenet-v2"}),
qos=1, retain=True)
def on_disconnect(client, userdata, flags, reason_code, properties):
print("disconnected:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID,
protocol=mqtt.MQTTv5)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.will_set(f"{PREFIX}/status", json.dumps({"online": False}), qos=1, retain=True)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.reconnect_delay_set(min_delay=1, max_delay=60)
client.connect_async(BROKER, PORT, keepalive=30)
client.loop_start()
last_pub = last_beat = 0.0
last_counts = None
frames = 0
while True:
img = camera.Capture()
if img is None: # yakalama zaman aşımı
continue
detections = net.Detect(img, overlay="none")
frames += 1
objects, counts = [], {}
for d in detections:
label = net.GetClassDesc(d.ClassID)
counts[label] = counts.get(label, 0) + 1
objects.append({
"label": label,
"conf": round(d.Confidence, 2),
"box": [round(d.Left / img.width, 3), round(d.Top / img.height, 3),
round(d.Right / img.width, 3), round(d.Bottom / img.height, 3)],
})
now = time.time()
if now - last_pub >= PUBLISH_EVERY:
last_pub = now
client.publish(f"{PREFIX}/detections",
json.dumps({"ts": now, "objects": objects}), qos=0)
if counts != last_counts:
last_counts = counts
client.publish(f"{PREFIX}/counts", json.dumps({"ts": now, **counts}),
qos=1, retain=True)
if now - last_beat >= HEARTBEAT_EVERY:
fps = frames / (now - last_beat) if last_beat else 0.0
client.publish(f"{PREFIX}/health", json.dumps({
"ts": now, "fps": round(fps, 1),
"networkFps": round(net.GetNetworkFPS(), 1)}), qos=0)
last_beat, frames = now, 0
Sonuçları dizüstü bilgisayarınızdan izleyin:
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
-i jet-watch-7d1e -t "connectmq/demo/jet-7d1e/#" -v
connect_async ile loop_start birlikte kullanıldığında betik, ağ kesik olsa bile çıkarım yapmaya devam eder; paho arka planda yeniden bağlanır, retained status topic'i ve Last Will de kameranın erişilebilir olup olmadığını herkese bildirir.
Adım 3: Cihaz Sağlığı Eklemek
Sessizce aşırı ısınan veya performansını kısan (throttling) bir kamera, sahada yaygın bir arızadır. Jetson kartları sıcaklıkları sysfs üzerinden raporlar; bunları heartbeat ile birlikte yayınlayabilirsiniz:
import glob
def read_temps():
temps = {}
for zone in glob.glob("/sys/class/thermal/thermal_zone*"):
try:
with open(f"{zone}/type") as t, open(f"{zone}/temp") as v:
temps[t.read().strip()] = int(v.read()) / 1000
except OSError:
pass
return temps
Sağlık payload'una "temps": read_temps() ekleyin. Özel bir broker'da, bir sıcaklık alanı üzerindeki eşik tabanlı uyarı kuralı, kart performansını kısmaya başlamadan önce sizi uyarır.
Adım 4: Servis Olarak Çalıştırmak
/etc/systemd/system/jetson-mqtt.service dosyasını oluşturun:
[Unit]
Description=Jetson vision to MQTT
After=network-online.target
Wants=network-online.target
[Service]
User=jetson
WorkingDirectory=/home/jetson/vision
ExecStart=/usr/bin/python3 /home/jetson/vision/jetson_mqtt.py
Restart=always
RestartSec=5
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now jetson-mqtt
journalctl -u jetson-mqtt -f
Çok Sayıda Kamera için Topic Tasarımı
Tek bir Jetson kolaydır; üç sahaya yayılmış yirmi tanesi ise bir plan gerektirir. Tüketicilerin doğru seviyede abone olabilmesi için konum hiyerarşisini topic'e yerleştirin: site/area/line-or-gate/camera/.... Bir güvenlik dashboard'u site1/+/+/alerts topic'ine, bir operasyon raporu +/+/+/counts topic'ine, tek bir kamerada hata ayıklayan bir mühendis ise yalnızca o kameraya abone olur. Bu, ISA-95 tabanlı bir Unified Namespace ile aynı fikirdir ve ConnectMQ bu tür topic yapılarını cihaz görünümünde tanır.
Mesaj türlerini betikte gösterildiği gibi ayrı tutun: yüksek hızlı tespitler, değişime bağlı retained sayımlar, düşük hızlı sağlık mesajları ve Last Will ile retained bir status. Bunları tek bir topic'te karıştırmak her tüketiciyi her şeyi ayrıştırıp filtrelemeye zorlar ve farklı mesaj türlerine farklı QoS seviyeleri vermeyi imkânsız hâle getirir.
Performans İpuçları
Jetson'daki kare hızının büyük kısmı Python'dan veya MQTT'den değil, çıkarım motorundan gelir. Birkaç alışkanlık hattı hızlı tutar:
- TensorRT ile optimize edilmiş modeller kullanın; jetson-inference motoru ilk çalıştırmada derler ve önbelleğe alır, bu yüzden ilk başlatma yavaş, sonrakiler hızlıdır.
- Videoyu izleyen kimse yokken katman çizmekten kaçının (
overlay="none"). - Yayın hızını betikteki gibi sınırlandırın; 30 fps'de her kare için JSON kodlamak hiçbir fayda sağlamadan CPU yükü ekler.
sudo jetson_clockskomutunu yalnızca yeterli soğutmanız olduğunda kullanın ve sıcaklıkları sağlık topic'i üzerinden izleyin.
Jetson Nano MQTT Sorun Giderme Kontrol Listesi
CallbackAPIVersionile ilgiliTypeError. paho-mqtt 1.x kullanıyorsunuz; yükseltin ya da orijinal Nano'da 1.6 API'sini kullanın.- TLS el sıkışma hataları. Sistem tarihini (
timedatectl) veca-certificatespaketinin kurulu olduğunu kontrol edin. - Aynı nedenle tekrarlanan bağlantı kopmaları. İki cihaz aynı client ID'yi paylaşıyor; her client'ın benzersiz bir ID'si olmalıdır ve ConnectMQ'da client ID verilen kimlik bilgilerine bağlıdır.
- Bir süre sonra düşük kare hızı. Yayınlanan sıcaklıkları kontrol edin; bir fan ekleyin veya
nvpmodelile bilinçli olarak daha düşük bir güç modu seçin. - Mesaj seli. Tespitlerin hızını sınırlandırın; genel alanda sınır client başına saniyede 10 mesajdır.
- systemd altında kamera bulunamıyor. Servis kullanıcısının
videogrubunda olması gerekir.
Prototipten Filoya
Bir kamera çalıştığında sorular operasyonel hâle gelir: cihaz başına kimlik bilgileri, şifreleme ve hangi kameraların çevrimiçi olduğunu görmek. Gerçek görüntüler veya konumlar söz konusu olduğu anda genel MQTT test broker'ından özel bir barındırılan MQTT broker'a geçin. ConnectMQ her Jetson'a kendi oluşturulmuş kimlik bilgilerini verir, 8883 portunda TLS kabul eder, cihazları ISA-95 seviyesine göre listeler ve her tespiti canlı topic gezgininde gösterir. Farklı sahalardaki çok sayıda Jetson tek bir yere raporladığında, bir bulut MQTT broker hiçbir sahada gelen bağlantılar için port açma ihtiyacını ortadan kaldırır.
Bu hattın modelden bağımsız bir sürümü için MQTT ile YOLO nesne tespiti yazısına, mikrodenetleyici boyutunda bir alternatif için ESP32-CAM ile kişi tespiti yazısına, Jetson, Coral ve diğer hızlandırıcılar arasında seçim yapmak için ise uç yapay zeka donanımı yazısına bakın. Yapay zeka ve IoT rehberi büyük resmi ele alıyor.
Jetson'ınızı ConnectMQ'ya Bağlayın
app.connectmq.com adresinde ücretsiz Serverless planında kredi kartı gerektirmeden bir broker oluşturun, ardından betikteki BROKER, USERNAME, PASSWORD ve CLIENT_ID değerlerini oluşturulan değerlerle ayarlayın. Jetson'ınızın tespitleri saniyeler içinde portalda görünecek.
Sık Sorulan Sorular
paho-mqtt orijinal Jetson Nano'da çalışır mı?
Evet, ancak JetPack 4.x Python 3.6 ile gelir; bu yüzden paho-mqtt 1.6.1'i ve onun eski callback API'sini kullanın ya da paho-mqtt 2.x için Python 3.7 veya üstüne sahip bir container çalıştırın.
Jetson video karelerini MQTT üzerinden yayınlamalı mı?
Genellikle hayır. Tespitleri, sayımları ve mesaj boyutu sınırı içinde ara sıra anlık görüntüleri yayınlayın; canlı videoya ihtiyacınız varsa bir akış protokolü kullanın.
Jetson MQTT için hangi portu kullanmalı?
Hızlı bir testin ötesindeki her şey için TLS ile 8883 portunu kullanın. 1883 portu şifresizdir ve sentetik veriyle geliştirmeyle sınırlı tutulmalıdır.
MQTT ve çıkarımı aynı Python sürecinde çalıştırabilir miyim?
Evet. paho ağ döngüsü loop_start aracılığıyla arka plandaki bir thread'de çalışır; bu yüzden ana döngüdeki çıkarım ağ işlemleri tarafından bloke edilmez.



