1) Generator kodu ROS 2 emituje rosidl::Buffer<uint8_t> zamiast std::vector<uint8_t> dla pol uint8[]. 2) Buffer<T> stosuje wzorzec PIMPL i deleguje do BufferImplBase<T>; domyslnie tworzy CpuBufferImpl<T> opakowujacy std::vector<T>. 3) Backend ustawia sie raz przy konstrukcji (brak settera po konstrukcji, aby unikac wyscigow). 4) Na CPU dostepne jest pelne API std::vector i niejawna konwersja; na backendach innych niz CPU dostep do elementow rzuca std::runtime_error, a kopie na hosta uzyskuje sie przez to_vector(). 5) Backendy dostawcow (BufferBackend) sa odkrywane i ladowane przez pluginlib (BufferBackendRegistry). 6) Podczas komunikacji warstwa serializacji wola create_descriptor_with_endpoint(); przy zgodnym backendzie po obu stronach przesylany jest deskryptor (<= 4096 B, np. uchwyt IPC pamieci GPU) i odtwarzany przez from_descriptor_with_endpoint() bez kopiowania danych; gdy peer nie wspiera backendu, deskryptor jest nullptr i nastepuje fallback do serializacji CPU. Endpointy oglaszaja obslugiwane backendy i negocjuja zgodnosc (on_creating_endpoint / on_discovering_endpoint).
W ROS 2 pola binarne wiadomosci (uint8[]) byly reprezentowane jako std::vector<T> w pamieci hosta, co przy duzych danych (obrazy, chmury punktow, tensory) wymuszalo kosztowne kopie miedzy CPU a akceleratorem i uniemozliwialo natywny, zero-copy transport pamieci GPU miedzy wezlami bez rozwiazan spoza rdzenia.
Szablonowy kontener zastepujacy std::vector<T> dla pol uint8[]. Dla backendu CPU udostepnia pelne API std::vector i niejawna konwersje do std::vector<T>&; API dla wszystkich backendow: size(), get_backend_type(), get_impl(), to_vector(). Semantyka wartosci: gleboka kopia przez clone().
Minimalna klasa bazowa (get_backend_type(), size(), to_cpu(), clone()). Konkretne backendy: CpuBufferImpl, CUDA, ROCm itd.
Oficjalna
Implementacja opakowujaca std::vector<T>; domyslny backend zapewniajacy pelna zgodnosc wsteczna.
Oficjalna
Abstrakcyjny interfejs (pakiet rosidl_buffer_backend). Tworzy i odczytuje deskryptory (create_descriptor_with_endpoint / from_descriptor_with_endpoint, <= 4096 B), obsluguje hooki odkrywania/negocjacji endpointow (on_creating_endpoint, on_discovering_endpoint) i pozostaje niezalezny od RMW.
Oficjalna
Pakiet rosidl_buffer_backend_registry. Dynamicznie odkrywa i tworzy instancje backendow przez pluginlib (create_backend_instance, get_backend_names).
operator[], at(), iteratory i inne operacje std::vector rzucaja std::runtime_error dla backendow innych niz CPU.
to_vector() to escape hatch zwracajacy kopie na CPU, co niweczy korzysc z zero-copy.
Kazdy deskryptor tworzony przez backend musi zserializowac sie do najwyzej kMaxBufferDescriptorSize (4096 B).
Gdy peer nie obsluguje backendu, create_descriptor_with_endpoint() zwraca nullptr i transport przechodzi na standardowa serializacje CPU (utrata zero-copy).
Watek na ROS Discourse przedstawiajacy dzialajacy prototyp zero-copy transportu pamieci akceleratora dla pol uint8[], prowadzony przez inzynierow NVIDIA.
PR #941 (scalony 2026-03-31) wprowadza rosidl::Buffer<T>, BufferImplBase<T>, CpuBufferImpl<T> i BufferBackend jako podstawowe typy natywnego bufora.
Wydanie rosidl_buffer 5.1.4 (2026-04-09): sciezka generatora C++ zaczyna emitowac rosidl::Buffer dla pol typu uint8[] (PR #942).
Typ backendu buforowania okreslany przy konstrukcji: 'cpu' (domyslny), 'cuda', 'rocm', 'demo'. Ustawiany raz, bez settera po konstrukcji.
Parametr szablonu Buffer<T>. Generator C++ emituje rosidl::Buffer<uint8_t> dla pol uint8[].
Gorne ograniczenie zserializowanego deskryptora backendu: 4096 bajtow.
Backend CUDA pozwala trzymac i transportowac pamiec GPU bez kopii na hosta (zero-copy przez deskryptory), co jest glownym celem funkcji.
Domyslny backend CPU i architektura pluggable sprawiaja, ze sam kontener nie zalezy od konkretnego sprzetu.