Çok sensörlü bir sistemde en çok vakit kaybettiren şey filtrenin matematiği değildir. Kamera, IMU ve LiDAR'ı tek bir durum kestirimine bağlayan hattın her düğümünde ölçümün yanına bir sayı yazılır; o sayının ne anlama geldiği ise çoğu zaman hiçbir yerde belgelenmemiştir. Hangi saatten okundu? Fiziksel olayın hangi anını gösteriyor? Boru hattının neresinde vuruldu? Bu üç soruya cevap veremeyen bir sistemde füzyon çıkışındaki hata, ekstrinsik kalibrasyon hatasından ayırt edilemez — ve pratikte oraya yazılır. Bu yazı zaman damgasını bir uygulama ayrıntısı olarak değil, alt sistemler arasında imzalanan bir sözleşme olarak ele alıyor. Yazıda Spikedge'in yaptığı bir senkronizasyon ölçümü yer almaz; ölçülmesi gerekenler ayrı bir bölümde listelenmiştir.
Zaman damgası neyi iddia eder?
Bir zaman damgası, "bu veri şu anda üretildi" demez. Şunu der: bu ölçümün karşılık geldiği fiziksel olay, şu saat alanında, şu ana denk gelir. Cümlenin üç bileşeni de ayrı ayrı yanlış olabilir.
- Saat alanı (clock domain).
CLOCK_MONOTONIC,CLOCK_REALTIME,CLOCK_TAI, NIC'in PHC'si, sensörün kendi osilatörü, varsa GNSS zamanı — hepsi ayrı saatlerdir. İki damgayı çıkarmak ancak aynı alandaysa anlamlıdır. - Olay tanımı. Kamera için pozlamanın başı mı, ortası mı, karenin okunmasının bitişi mi? IMU için örnekleme anı mı, FIFO'dan okunduğu an mı? Üreticiler bu tanımı çoğu zaman veri sayfasının başka bir bölümüne saklar.
- Damganın vurulduğu nokta. Olay ile damga arasında geçen her şey — kesme gecikmesi, sürücü kuyruğu, DMA tamamlanması, kullanıcı alanı zamanlaması — damgaya sessizce eklenir.
Bu üçünü ayırmayan her senkronizasyon tartışması yanlış katmanda çözüm arar.
Dört ayrı hata, dört ayrı çözüm
Pratikte "senkron değil" diye adlandırılan durum dört farklı arızanın toplamıdır ve her birinin çaresi başkadır:
| Hata | Ne yapar | Nereden gelir | Çaresi |
|---|---|---|---|
| Ofset | Sabit kayma | Farklı saat alanları, tanımlanmamış olay noktası | Ortak saat alanı, kalibrasyon ile kestirim |
| Kayma (drift) | Ofset zamanla büyür | Osilatör frekans farkı, sıcaklık | Sürekli disiplin (PTP/gPTP), frekans düzeltme |
| Jitter | Damga etrafında dağılım | Yazılım katmanında damgalama, zamanlayıcı gürültüsü | Damgayı donanıma indirmek |
| Modellenmemiş gecikme | Sistematik geç kalma | Sıkıştırma, kuyruk, ağ aktarımı | Damgayı kaynağa taşımak, gecikmeyi ölçüp modele koymak |
En tehlikelisi ofsettir; çünkü tutarlı davranır, filtreyi bozmaz görünür ve sessizce ekstrinsik parametrelere emilir.
Saat alanını kurmak: IEEE 1588 ve 802.1AS
Birden fazla karta yayılmış bir sistemde ortak zaman ölçeğini kuran şey PTP'dir. IEEE 1588 protokolün kendisini tanımlar; IEEE 802.1AS ise TSN bağlamında kullanılan gPTP profilidir. İkisi arasındaki fark akademik değildir:
- 802.1AS, gecikme ölçümü için peer delay mekanizmasını zorunlu kılar ve yoldaki her cihazın zaman-farkında (time-aware) olmasını bekler. Standardın kapsam bölümü hedefini, yedi köprü atlamasına kadar 1 µs'den iyi senkronizasyon olarak tanımlar.
- Genel amaçlı 1588 profilleri, transparan olmayan anahtarlar üzerinden end-to-end gecikme isteğiyle de çalışır; ağdaki kuyruklanma doğrudan hataya döner.
Karar kriteri: yoldaki anahtarları kontrol ediyorsanız ve TSN destekliyorlarsa gPTP; etmiyorsanız 1588 ile birlikte gerçekçi bir hata bütçesi. Linux tarafında işi linuxptp yürütür:
ethtool -T eth0 ## NIC donanım damgası vurabiliyor mu?
ptp4l -f /etc/linuxptp/gPTP.cfg -i eth0 -m ## gPTP profili
phc2sys -s eth0 -c CLOCK_REALTIME -w -m ## PHC -> sistem saati
ts2phc -f /etc/linuxptp/ts2phc.cfg -m ## GNSS PPS varsa PHC'yi disipline et
ethtool -T çıktısında aranacak satırlar bellidir: hardware-transmit, hardware-receive, hardware-raw-clock yetenekleri ve PTP Hardware Clock: 0 gibi geçerli bir indeks. PTP Hardware Clock: none görüyorsanız elinizde yalnızca yazılım damgası vardır ve gPTP kurmanın getirisi NIC'te kaybolur. phc2sys içindeki -w bayrağı, ptp4l'in Announce mesajından öğrendiği UTC farkını bekleyip uygular; elle sabit bir ofset yazmak artık saniyede sistemi bozar.
Buradaki en sık atlanan ayrıntı zaman ölçeğidir. PTP TAI üzerinden çalışır, CLOCK_REALTIME UTC üzerinden. BIPM/IERS'in ilan ettiği TAI–UTC farkı sabit bir sayı değildir; artık saniyelerle değişir. Sistem içinde tek bir ölçek seçin — çoğu füzyon hattı için CLOCK_TAI doğru cevaptır, çünkü artık saniye sıçraması yaşamaz.
Damga nerede vuruluyor: donanım, sürücü, kullanıcı alanı
Aynı paket için üç farklı damga alabilirsiniz ve üçü aynı şeyi ölçmez:
- PHY/MAC damgası. Paketin telden geçtiği an, NIC tarafından vurulur.
SO_TIMESTAMPINGileSOF_TIMESTAMPING_RX_HARDWAREveSOF_TIMESTAMPING_RAW_HARDWAREistenir; sürücü tarafındaSIOCSHWTSTAMPioctl'i ileHWTSTAMP_FILTER_PTP_V2_EVENTseçilir. - Çekirdek damgası. Paket soket katmanına ulaştığında vurulur; kesme gecikmesini ve NAPI zamanlamasını içerir.
- Kullanıcı alanı damgası.
clock_gettime()çağrıldığında; zamanlayıcı gürültüsünün tamamını taşır.
Kural nettir: damgayı olaya olabildiğince yaklaştırın, sonra bir daha yeniden damgalamayın. Hattın ilerisinde now() çağıran her satır, o noktaya kadar birikmiş gecikmeyi ölçümün içine yazar.
PHC ile sistem saati arasındaki ilişkiyi kurarken okuma gecikmesi de bir hata kaynağıdır. Donanım destekliyorsa PTP_SYS_OFFSET_PRECISE ioctl'i (PCIe PTM tabanlı çapraz damgalama) bu belirsizliği kaldırır; desteklemiyorsa PTP_SYS_OFFSET_EXTENDED en azından okuma penceresinin genişliğini bildirir.
Sensör tarafı: olay tanımını sabitlemek
Kamera
Bir görüntünün "ait olduğu an", global shutter için pozlamanın ortasıdır. Sahnede hareket varken bu tanım keyfi değildir: filtre, o karedeki geometrinin hangi ana karşılık geldiğini bilmek zorundadır.
V4L2 bunu açıkça belgeler ama varsayılan davranış tuzaklıdır. VIDIOC_DQBUF sonrası v4l2_buffer.flags alanında damga kaynağı bildirilir:
/* include/uapi/linux/videodev2.h */
switch (buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK) {
case V4L2_BUF_FLAG_TSTAMP_SRC_SOE:
/* Pozlamanın başlangıcı: t_orta = t + pozlama_suresi / 2 */
break;
case V4L2_BUF_FLAG_TSTAMP_SRC_EOF:
/* Karenin sonu: okuma (readout) suresi de icinde.
t_orta = t - okuma_suresi - pozlama_suresi / 2 */
break;
}
/* Ayrica: V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC mi,
V4L2_BUF_FLAG_TIMESTAMP_COPY mi? Ikincisi surucunun
damgayi baska bir yerden kopyaladigi anlamina gelir. */
SRC_EOF damgasını doğrudan füzyona vermek, pozlama artı okuma süresi kadar sistematik bir gecikme eklemek demektir; pozlama otomatikse bu gecikme sahne parlaklığıyla birlikte değişir. Rolling shutter'da ise tek bir "an" yoktur: her satırın kendi zamanı vardır ve hızlı dönen bir platformda bu geometrik bozulmaya döner.
Doğru mimari, kamerayı serbest koşan bir osilatöre değil PHC'den türetilen bir tetiğe bağlamaktır. Linux'ta API'si hazırdır:
/* include/uapi/linux/ptp_clock.h — PHC'den periyodik tetik uretmek */
struct ptp_perout_request perout = {0};
perout.index = 0; /* SoC'nin periodic-output kanali */
perout.start.sec = baslangic_tai_sn; /* PHC olceginde (TAI) */
perout.period.sec = 0;
perout.period.nsec = tetik_periyodu_ns;
ioctl(phc_fd, PTP_PEROUT_REQUEST2, &perout);
/* Ayni PHC ile disaridan gelen bir kenari damgalamak (IMU DRDY, GNSS PPS) */
struct ptp_extts_request extts = {
.index = 0,
.flags = PTP_ENABLE_FEATURE | PTP_RISING_EDGE,
};
ioctl(phc_fd, PTP_EXTTS_REQUEST2, &extts);
/* read(phc_fd, &olay, sizeof(struct ptp_extts_event)) */
Bu iki ioctl, "yazılımla hizalamaya çalışmak" ile "donanımda hizalı üretmek" arasındaki farkı temsil eder. GigE Vision tarafındaki karşılığı kameranın kendi IEEE 1588 desteğidir: kamera aynı alana katılıyorsa tetik ve damga zaten ortak ölçektedir.
IMU
IMU'nun kendi osilatörü vardır ve nominal ODR değeri bir vaat değil, bir etikettir. İki ayrı sorun çıkar:
- Kendi saatinin kayması. Ana bilgisayarın damgaladığı DRDY kenarlarını örnek indeksine karşı doğrusal oturtmak, gerçek örnekleme aralığını ve kayma oranını verir. Filtreye nominal aralığı beslemek, yavaşça büyüyen bir zaman hatası üretir.
- FIFO gruplama. Watermark ile toplu okumada okuma anı, örneklerin hiçbirinin zamanı değildir; geriye hesaplamak gerekir:
t_k = t_okuma − (N − k) · dt. Buradakidtde ölçülmüş aralıktır, katalog değeri değil.
Kamera ile IMU arasında donanım tetiği yoksa geriye kalan bilinmeyen, sabit bir zaman ofsetidir. Kalibrasyonda kestiren araçlar vardır (ETH Zürih'in Kalibr paketi kamera–IMU ofsetini bir durum olarak çözer); görsel-eylemsiz kestiriciler ise ofseti çevrimiçi bir durum değişkeni olarak taşır. İkisi de meşrudur, ama ikisi de gözlemlenebilirlik koşulu ister: platform yeterince uyarılmıyorsa ofset gözlemlenemez ve hata başka parametrelere kayar.
LiDAR
Bir tarama tek bir ana ait değildir; her nokta kendi zamanında ölçülür. Hareket bozulmasını (motion distortion) düzeltmek için nokta başına zaman alanı ve senkron bir IMU şarttır. Üreticinin damga sözleşmesini — taramanın başı mı, ortası mı, sonu mu — yanlış okumak, tarama periyodunun yarısı kadar sabit bir yanlılık üretir.
ROS 2'de hangi saat?
ROS 2, üç ayrı saat kaynağını açıkça ayırır: RCL_SYSTEM_TIME (CLOCK_REALTIME, atlayabilir), RCL_STEADY_TIME (monotonik, ama makineler arası karşılaştırılamaz) ve RCL_ROS_TIME (use_sim_time etkinken /clock konusundan beslenir). Üçünü karıştıran bir sistemde füzyon çıkışı simülasyonda çalışır, sahada çalışmaz.
Pratik kurallar:
- Mesajın
header.stampalanı yakalama anıdır, yayınlama anı değildir. Sürücüdenode->now()çağırıp damga basmak, hattaki bütün gecikmeyi ölçüme yazan en yaygın hatadır. - Makineler arası karşılaştırma yapılacaksa damga PTP ile disipline edilmiş sistem saatinde üretilmelidir; monotonik saat düğüm dışına çıkamaz.
message_filtersiçindekiApproximateTimedamgaların doğru olduğunu varsayar; yanlış damgalanmış bir akışı düzeltmez, sadece yanlış eşleşmeyi güvenilir kılar. Aynı şekildetf2ekstrapolasyon hataları çoğu zaman dönüşüm ağacının değil damganın sorunudur.- QoS uyumsuzluğu bir sensörü sessizce düşürdüğünde füzyon "çalışır" görünmeye devam eder; bunu ROS2 DDS QoS ayarları rehberimizde ayrıntılandırıyoruz.
Kaymanın füzyon çıkışına ne yaptığı
Mekanizma şudur: bir ölçüm, ait olduğu andan Δt kadar sapmış bir anla eşleştirildiğinde, platformun o Δt boyunca yaptığı hareket doğrudan hataya döner. Doğrusal hızda v · Δt kadar konum, açısal hızda ω · Δt kadar yönelim hatası.
Asıl tehlike burada başlar. Sabit bir Δt, kamera ile IMU arasındaki kol mesafesinden (lever arm) ayırt edilemez; filtre onu ekstrinsik parametrelere emer, artıklar küçülür, kovaryans daralır — yani kestirim tutarlı görünürken yanlıdır. Kayma varsa Δt zamanla büyür: filtre peşinden koşar, innovation dizisi otokorelasyonlu hale gelir, ki-kare kapısı iyi ölçümleri reddetmeye başlar. Sahada bu "belirli manevralarda tracking kopuyor" diye raporlanır ve saatlerce algoritma tarafında aranır.
Nerede yanlış gider
Sırasıyla en pahalıdan başlayarak:
- Damgayı boru hattının ilerisinde yeniden vurmak. Kodlayıcıdan, ağdan veya kuyruktan sonra
now()çağrılan her yer, gecikmeyi ölçümün içine gömer. Damga bir kez vurulur ve mesajla birlikte taşınır. - Kamera damgasının olay tanımını doğrulamamak.
SRC_EOFileSRC_SOEarasındaki fark, pozlama artı okuma süresidir ve otomatik pozlamada sabit bile değildir. - Nominal örnekleme aralığına güvenmek. Katalogdaki ODR ile gerçek aralık arasındaki fark, uzun çalışmalarda birikerek büyür.
- Yazılım damgasıyla gPTP kurmak.
ethtool -TçıktısındaPTP Hardware Clock: nonegörüyorsanız, protokolün getirdiği kesinlik NIC'te kayboluyor demektir. - TAI ile UTC'yi karıştırmak. İki alt sistem farklı ölçek kullanıyorsa aradaki fark sabit bir ofset olarak görünür; artık saniyede ise aniden değişir.
- Bir kez hizalayıp bir daha bakmamak. Senkronizasyon bir kurulum adımı değil sürekli bir durumdur.
ptp4lvephc2sysçıktısı telemetriye girmeli; grandmaster değişimi, senkron kaybı ve düzeltme büyüklüğü izlenmelidir. - Senkron kaybını sessiz geçmek. Saat alanı bozulduğunda füzyon çıkışı hâlâ üretilir ve hâlâ makul görünür. Sistem bunu bir arıza olarak raporlamıyorsa kaybı sahada müşteri keşfeder.
- Boştaki sistemde ölçmek. Ağ trafiği, model çıkarımı ve disk yazımı aynı anda koşarken damgalama davranışı ölçülmeden hiçbir sayının anlamı yoktur. Aynı disiplini EtherCAT ölçüm metodolojisi yazımızda anlatıyoruz.
Doğrulama planı: neye bakılır
Yayımlanmaya değer her senkronizasyon sayısı üç şeyle anlam kazanır: hangi kurulumda, hangi yöntemle, kim ölçtü. Asgari küme:
- Alanlar arası hizalama. İki kartın PPS veya periodic-output çıkışını aynı osiloskopta yan yana görün. Yazılımın raporladığı ofset değil, telin üzerindeki kenar farkı esastır.
ptp4lofset ve frekans düzeltmesi. Zaman serisi olarak kaydedin; sıcaklık değişimi altında ayrıca koşturun.- Uçtan uca olay testi. Bir LED darbesini kameraya, aynı darbeyi fotodiyot üzerinden IMU kartının damgalama girişine verin; iki damganın farkı kamera hattının gerçek gecikmesidir. Kontrollü bir titreşim veya dönüşte kamera–IMU çapraz korelasyonu aynı ofseti bağımsız olarak doğrular.
- Yük altında bozulma. Yukarıdakilerin tam yükte nasıl değiştiği. PREEMPT_RT yapılandırması burada belirleyicidir; yaklaşımı PREEMPT_RT çekirdek yapılandırması rehberinde topladık.
- Kurtarma davranışı. Grandmaster'ı ağdan çıkarın: sistem tanımlı bir duruma mı düşüyor, yoksa eski ofsetle çalışmaya devam mı ediyor?
Karar kriteri
Gereken senkronizasyon kesinliği bir tercih değil, bir türevdir. Kabul edilebilir durum hatasını ε, sistemin en hızlı değişim oranını max|ẋ| olarak alın; ihtiyacınız olan zaman kesinliği δt ≤ ε / max|ẋ| ile sınırlıdır. Bu bütçeyi çıkarmadan mekanizma seçmek, ya gereğinden pahalı bir TSN altyapısı ya da sahada çöken bir hat üretir.
Bütçe elinizdeyken seçim şu tabloya oturur:
| Durum | Mekanizma | Bedeli |
|---|---|---|
| Tek SoC, tek kart, tüm sensörler yerel | Ortak monotonik saat + donanım tetik (PTP_PEROUT_REQUEST2) |
En ucuzu; kartlar arası ölçeklenmez |
| Aynı ağdaki birden çok kart | gPTP (802.1AS) + donanım damgası + PHC güdümlü tetik | TSN yetenekli NIC ve anahtar gerekir |
| Ayrı ağlar, araçlar arası | GNSS disiplinli PPS + ts2phc |
GNSS görüşü ve tutunma (holdover) davranışı tasarlanmalı |
| Senkronize edilemeyen hazır sensör | Zaman ofsetini kalibrasyonda veya çevrimiçi durum olarak kestirmek | Gözlemlenebilirlik koşulu ve filtre karmaşıklığı |
Üç maddeyle kapatalım. Her sensör için olay tanımını (pozlama ortası, örnekleme anı, tarama başlangıcı) yazılı hale getirin; belgelenmemiş bir tanım, sonradan bulunan bir ofsettir. Damgayı olaya en yakın noktada vurun ve bir daha yeniden damgalamayın. Senkron durumunu bir telemetri sinyali yapın — senkron kaybı sessizce geçen bir sistemde füzyon çıkışına güvenilemez. Zaman damgası doğru değilse, filtrenin ne kadar iyi olduğunun önemi yoktur.
Kendi hattınızda saat alanlarını, damgalama noktalarını ve gecikme bütçesini birlikte çıkarmak istiyorsanız sensör füzyonu yetkinliğimiz tam olarak bu üç soruyla başlar; kapsamı belirlemek için gömülü sistem mimari denetimi planlayabilirsiniz.
Kaynaklar
- IEEE — IEEE 1588-2019, Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems — https://standards.ieee.org/ieee/1588/6825/
- IEEE — IEEE 802.1AS-2020, Timing and Synchronization for Time-Sensitive Applications — https://standards.ieee.org/ieee/802.1AS/7121/
- linuxptp — ptp4l, phc2sys, ts2phc kılavuz sayfaları — https://linuxptp.sourceforge.net/
- Linux çekirdek dokümantasyonu — PTP Hardware Clock Infrastructure — https://docs.kernel.org/driver-api/ptp.html
- Linux çekirdek dokümantasyonu — Timestamping (SO_TIMESTAMPING) — https://docs.kernel.org/networking/timestamping.html
- Linux çekirdek dokümantasyonu — V4L2 Buffers:
v4l2_bufferflags — https://docs.kernel.org/userspace-api/media/v4l/buffer.html - ROS 2 design — Clock and Time — https://design.ros2.org/articles/clock_and_time.html
- ETH Zürih ASL — Kalibr: camera–IMU calibration toolbox — https://github.com/ethz-asl/kalibr
- BIPM — TAI–UTC ilişkisi ve artık saniye duyuruları — https://www.bipm.org/en/time-ftp/
Kaynaklara erişim tarihi: 5 Eylül 2026. Standart sürümleri ve çekirdek API'leri değişir; hangi bayrağın hangi çekirdek sürümünde bulunduğu kullandığınız BSP'nin belgesinden doğrulanmalıdır.
