Skip to content

feat(LibCarla/ros2): [5/7] add unified CDR serialization and GenericCdrPubSubType - #9643

Merged
LuisPovedaCano merged 8 commits into
carla-simulator:ue4-devfrom
JArmandoAnaya:feature/ros2-cdr-serialization
Apr 8, 2026
Merged

feat(LibCarla/ros2): [5/7] add unified CDR serialization and GenericCdrPubSubType#9643
LuisPovedaCano merged 8 commits into
carla-simulator:ue4-devfrom
JArmandoAnaya:feature/ros2-cdr-serialization

Conversation

@JArmandoAnaya

@JArmandoAnaya JArmandoAnaya commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Description

Relates to #9294 - DDS middleware decoupling PR series. Blocked on #9620.

What this PR does

Introduces a vendor-agnostic CDR serialization layer that bridges the 31
carla::ros2::msg::* POD structs to the DDS wire format used by ROS2.

New files (4):

File Purpose
LibCarla/source/carla/ros2/types/CdrSerialization.h serialize_to_cdr<T>() / deserialize_from_cdr<T>() for all 31 msg types. Uses Fast-CDR XCDR1 LE with DDS encapsulation header. Handles primitives, strings, arrays, vectors, and nested structs.
LibCarla/source/carla/ros2/types/CdrTopicInfo.h CdrTopicInfo<T> template specializations: type_name() (ROS2-compatible DDS type name) and max_serialized_size() (conservative CDR payload bound without encapsulation).
LibCarla/source/test/server/test_dds_middleware.cpp +14 CDR tests: cdr_topic_info (2) + cdr_serialization (12 round-trips).
LibCarla/cmake/test/CMakeLists.txt Add FastCDR include path, libfastcdr.a link, and -fexceptions to the server test binary (Fast-CDR templates use try/catch).

Serialization architecture

carla::ros2::msg::X  (vendor-agnostic POD struct)
         |
         v
  CdrSerialization.h — serialize_to_cdr() / deserialize_from_cdr()
         |
    CDR byte buffer (XCDR1 LE, wire-compatible with all ROS2 distros)
         |
    +----+----+
    |         |
    v         v
FastDDS    CycloneDDS
write()    dds_writecdr()
(Pending PR)      (Pending PR)

Tests

  • Server: 97 to 111 tests (all pass)
  • Client: 56/56 (unchanged)

Run CDR tests only:

./Build/libcarla-server-build.debug/test/libcarla_test_server_debug \
  --gtest_filter='*cdr_*'

PR series

This PR is part of the DDS middleware decoupling series (#9294). Each PR in the chain inherits the commits of all prior PRs. The Commits column lists only the commits introduced by that PR, and the Files column counts only the files changed by those new commits.

# PR Title Branch Commits Files
1/7 #9608 DDS middleware abstraction layer feature/dds-middleware-abstraction-layer 0ab35ee6 10
2/7 #9612 POD message types, FastDDS conversions, and TypeMap specializations feature/ros2-pod-types-and-fastdds-conversions e665d2af 39
3/7 #9619 Migrate publishers and subscribers to POD message types feature/ros2-publishers-pod-types-migration 98b6f7aa 27
4/7 #9620 CycloneDDS enum, factory, stubs, and tests feature/ros2-cyclonedds-enum-factory 2a4a8db3 5
5/7 #9643 Unified CDR serialization + GenericCdrPubSubType (this PR) feature/ros2-cdr-serialization 5a9dd3b4, 0a9ca585 8
6/7 #9644 CycloneDDS CDR middleware, UE4 runtime selection, and correctness fixes feature/ros2-cyclonedds-cdr-middleware d3f2a45b, 2d80046b 26
7/7 #9645 Remove legacy FastDDS-generated type files feature/ros2-remove-fastdds-generated-types eea4e0a4 125

Checklist

  • File count: 4 files added, 0 files modified, 0 files deleted
  • make LibCarla ARGS="--ros2" passes
  • make check.LibCarla passes (111 server + 56 client)

This change is Reviewable

…ackend support

Introduce a strategy-pattern abstraction that decouples PublisherImpl and
SubscriberImpl from the FastDDS API, enabling future integration of
additional DDS middleware implementations (e.g. CycloneDDS).

New abstraction layer (LibCarla/source/carla/ros2/dds/):
- DDSMiddleware enum and string conversion utilities
- IDDSPublisherMiddleware / IDDSSubscriberMiddleware pure virtual interfaces
- DDSMiddlewareFactory with thread-safe middleware selection and creation
- FastDDSPublisherMiddleware<T> / FastDDSSubscriberMiddleware<S> template
  implementations behind the new interfaces
- FastDDSTypeMap<T> identity-mapping type traits (to be replaced with real
  conversions when POD message types are introduced)

Modified files:
- PublisherImpl.h: replaced direct FastDDS inheritance and members with
  delegation to IDDSPublisherMiddleware via the factory (public API unchanged)
- SubscriberImpl.h: same pattern for subscriber side
- cmake/fast_dds/CMakeLists.txt: added CARLA_ROS2_DDS_FASTDDS compile
  definition, new header globs, and fixed missing include directories in
  the debug build target

No behavior change — FastDDS remains the only compiled middleware.
Concrete publishers and subscribers are unaffected.
…real TypeMap specializations

Introduce backend-neutral POD message structs and to_fastdds/from_fastdds
conversion functions, completing the type abstraction layer started in PR carla-simulator#1
without touching any concrete publisher or subscriber.

New files (LibCarla/source/carla/ros2/types/):
- 31 plain C++ structs in types/msg/ - one per ROS2 message type, no DDS
  dependency, standard library headers only, all members value-initialized
- FastDDSConversions.h: inline to_fastdds/from_fastdds overload pairs for all
  31 type pairs, ordered bottom-up so composites call primitives; move overloads
  for msg::Image and msg::PointCloud2 to avoid copying large data vectors

New test file (LibCarla/source/test/server/test_dds_middleware.cpp):
- 45 unit tests across 10 groups covering the middleware enum, factory,
  interfaces, PublisherImpl, and SubscriberImpl using hand-written mocks;
  no DDS daemon required (CARLA_ROS2_DDS_TESTING suppresses real includes)

Modified files:
- FastDDSTypeMap.h: 28 real specializations mapping msg::X to FastDDS types,
  coexisting with the existing identity specializations (different key types,
  no ODR conflict)
- DDSMiddleware.h: add ToROS2DDSTypeName() for use in PR carla-simulator#3
- DDSMiddlewareFactory.h: add CARLA_ROS2_DDS_TESTING guard to FastDDS
  include/create blocks so test binary compiles without real DDS headers
- PublisherImpl.h / SubscriberImpl.h: LIBCARLA_WITH_GTEST test seams for
  middleware injection and message simulation
- cmake/fast_dds/CMakeLists.txt: added glob for types/msg/*.h install

No behavior change - identity TypeMap specializations remain active; all
concrete publishers and subscribers compile and work unchanged.
…e types

Switch all concrete publishers and subscribers from FastDDS-generated
types to middleware-neutral POD structs (carla::ros2::msg::*). Remove
identity TypeMap specializations and generic identity converters from
FastDDSTypeMap, leaving only real POD-to-FastDDS mappings. Convert
FastDDS accessor syntax (.field(val) / .field()) to direct member
access (.field = val / .field). Fix DVS descriptor4 bug where fields
were set on descriptor3. Add log_warning on Init failure for all
publishers and subscribers. Add missing copyright headers to subscriber
CPP files.
…tests

Register CycloneDDS as a recognized middleware option in DDSMiddleware
enum, DDSMiddlewareToString, DDSMiddlewareFromString, and
GetAvailableMiddlewareString. Add CycloneDDS case to
DDSMiddlewareFactory for IsMiddlewareAvailable, CreatePublisher, and
CreateSubscriber, all guarded by CARLA_ROS2_DDS_CYCLONEDDS. Add stub
CycloneDDSPublisherMiddleware and CycloneDDSSubscriberMiddleware that
compile and satisfy the factory interface but return failure on all
operations until the real implementation lands. Add 7 new unit tests
for CycloneDDS enum parsing, availability checks, and factory routing
when the middleware is not compiled in.
…d-trip tests

Add CdrSerialization.h with serialize_to_cdr() / deserialize_from_cdr()
helpers for all 31 msg::* POD types using Fast-CDR (XCDR1 LE with DDS
encapsulation header). The resulting buffers are wire-compatible with all
ROS2 distros and can be handed directly to FastDDS write_serialized_payload()
or CycloneDDS dds_writecdr(), removing the need for per-vendor generated
type files.

Add CdrTopicInfo.h with type_name() and max_serialized_size() template
specializations for all 31 types, providing the metadata the DDS middleware
layer needs to register topics and pre-allocate payload buffers.

Add 14 CDR round-trip tests across two new groups (cdr_topic_info,
cdr_serialization) covering fixed-size, string, array, and
vector-of-struct types. Update cmake/test/CMakeLists.txt to link
libfastcdr into the server test binary and enable exceptions, which
Fast-CDR templates require. Server test count: 97 → 111.

Blocked on: feature/ros2-cyclonedds-enum-factory (carla-simulator#9620)
@update-docs

update-docs Bot commented Apr 5, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would update our CHANGELOG.md based on your changes.

…e to CDR, add 6 tests

Replace 30 fastddsgen-generated PubSubType classes (and FastDDSTypeMap.h) with
a single GenericCdrPubSubType<T> template that implements TopicDataType by
delegating serialize()/deserialize() to CdrSerialization.h, and type_name()/
m_typeSize to CdrTopicInfo<T>.

Rewrite FastDDSPublisherMiddleware and FastDDSSubscriberMiddleware to use
GenericCdrPubSubType instead of FastDDSTypeMap. Remove to_fastdds()/from_fastdds()
conversion calls. Publishers now pass the POD msg pointer directly to
DataWriter::write(); subscribers receive CDR payloads directly into _message_ptr.

Add 6 generic_cdr_pubsubtype tests covering: type name contract, m_typeSize,
serialize/deserialize round-trip via SerializedPayload_t (fixed-size and string
types), createData/deleteData, and getKey(). Update cmake/test/CMakeLists.txt
to also link libfastrtps.a and libfoonathan_memory (required by TopicDataType
static initializers). Server test count: 111 to 117.
@JArmandoAnaya
JArmandoAnaya force-pushed the feature/ros2-cdr-serialization branch from 9e93214 to 0a9ca58 Compare April 5, 2026 02:57
JArmandoAnaya added a commit to JArmandoAnaya/carla that referenced this pull request Apr 5, 2026
Delete 125 auto-generated FastDDS type files from
LibCarla/source/carla/ros2/types/: 31 type-definition pairs
({TypeName}.h + {TypeName}.cpp), 31 PubSubType pairs
({TypeName}PubSubTypes.h + {TypeName}PubSubTypes.cpp), and
FastDDSConversions.h.

These files were generated by fastddsgen from IDL definitions and are no
longer referenced anywhere in the codebase. GenericCdrPubSubType<T>
(introduced in carla-simulator#9643) replaces all 31 hand-generated PubSubType classes by
serializing carla::ros2::msg::* POD structs directly to CDR bytes via
CdrSerialization.h, with no dependency on these files.

Both cmake/fast_dds/CMakeLists.txt and cmake/cyclone_dds/CMakeLists.txt
collect type files via file(GLOB) patterns (types/*.h, types/*.cpp), so no
CMake changes are needed. The globs self-adjust on the next configure pass.

After this change, LibCarla/source/carla/ros2/types/ contains only:
CdrSerialization.h, CdrTopicInfo.h, and msg/ (31 POD struct headers).

Tests: 120/120 server + 56/56 client + 2/2 smoke.
@JArmandoAnaya JArmandoAnaya changed the title feat(LibCarla/ros2): add unified CDR serialization layer (CdrSerialization + CdrTopicInfo) feat(LibCarla/ros2): [5/7] add unified CDR serialization and GenericCdrPubSubType Apr 6, 2026
@JArmandoAnaya
JArmandoAnaya marked this pull request as ready for review April 8, 2026 08:57
@JArmandoAnaya
JArmandoAnaya requested a review from a team as a code owner April 8, 2026 08:57
Comment thread LibCarla/source/carla/ros2/types/CdrSerialization.h Outdated
Comment thread LibCarla/source/carla/ros2/types/CdrSerialization.h Outdated
Comment thread LibCarla/source/carla/ros2/types/CdrSerialization.h
@JArmandoAnaya

Copy link
Copy Markdown
Contributor Author

@LuisPovedaCano Thank you for your review. I'm going to check in depth the changes on this PR to be sure all of them are correctly aligned with the DDS standards. I will fix this ASAP and let you know when it is done.

…nd add 9 robustness tests

Fix four spec-compliance issues in CdrSerialization.h and GenericCdrPubSubType.h
flagged during a deep review against the OMG DDSI-RTPS v2.5 spec and DDS-XTypes
1.3 clause 7.4.1.1, plus a critical runtime bug that prevented large-payload sensors
(Image, PointCloud2) from publishing at all.

--- Spec-compliance fixes ---

A. Sequence length type (DDS-XTypes 7.4.1.1 violation)
PointCloud2::fields and TFMessage::transforms used int32_t for CDR sequence lengths.
DDS-XTypes 1.3 clause 7.4.1.1 requires unsigned long (uint32_t). Changed four call
sites: two serialize_cdr writes and two deserialize_cdr reads.

B. Public API error contract (deserialize_from_cdr always returned true)
Both serialize_to_cdr() and deserialize_from_cdr() now wrap Fast-CDR calls in
try/catch(eprosima::fastcdr::exception::Exception). Returns empty vector / false
on error. Previously, exceptions escaped through the bool-returning function,
crashing the receive thread on the first malformed payload.

C. Sanity cap on CDR sequence lengths
Added kMaxCdrSequenceElements = 1u << 20 (1,048,576). Before each
vector::resize(seq_len) in the manual sequence helpers, throws
BadParamException if seq_len exceeds the cap. Prevents OOM-abort on hostile
or corrupt buffers (relevant because PR carla-simulator#9644's CycloneDDS path hands raw
network bytes to deserialize_from_cdr via dds_takecdr).

D. Explicit LITTLE_ENDIANNESS
Replaced Cdr::DEFAULT_ENDIAN with Cdr::LITTLE_ENDIANNESS in serialize_to_cdr(),
deserialize_from_cdr(), GenericCdrPubSubType::serialize(), and
GenericCdrPubSubType::deserialize(). Hardcode payload->encapsulation = CDR_LE
in GenericCdrPubSubType::serialize(). Matches DDSI-RTPS v2.5 Table 10.3
(CDR_LE = {0x00, 0x01}). In deserialize(), LITTLE_ENDIANNESS is the initial hint
only; read_encapsulation() still parses the actual byte order from the wire header.

--- Large-message publish fix ---

E. Fix FastDDSPublisherMiddleware::Publish returning RETCODE_ERROR (code 1) for
Image and PointCloud2 topics.

Root cause: getSerializedSizeProvider() returned the static
CdrTopicInfo<T>::max_serialized_size() value (648 bytes for Image, 27597 bytes
for PointCloud2). FastDDS pre-allocates the payload buffer at that size.
serialize() then wrapped payload->data in a fixed-size FastBuffer and called
serialize_cdr(), which threw NotEnoughMemoryException once the real payload
(~1.4 MB for 800x600 RGB, 1-20 MB for LiDAR) exceeded the tiny pre-allocated
buffer. RETCODE_ERROR propagated up to FastDDSPublisherMiddleware::Publish.

Fix:
- Add cdr_serialized_size<T>(msg) to CdrSerialization.h: performs a dry-run
  serialize_encapsulation() + serialize_cdr() into a heap FastBuffer and
  returns getSerializedDataLength(). Result is provably equal to
  serialize_to_cdr(msg).size().
- Change getSerializedSizeProvider() in GenericCdrPubSubType to capture the
  message pointer and return cdr_serialized_size(*msg), so FastDDS resizes
  payload->data to the actual size before calling serialize().
- Change serialize() to use an auto-growing FastBuffer (no size ceiling) and
  memcpy into payload->data after serialization. The post-copy
  len > payload->max_size guard is a safety net for non-resizing memory modes.
- Update CdrTopicInfo::max_serialized_size() doc comment: it is now an initial
  preallocation hint, not a hard upper bound.

--- New tests (Group 10: 12 -> 21 tests) ---

Spec-compliance tests (6):
- pointcloud2_multi_field_round_trip: 3 PointFields, exercises manual sequence loop
- tfmessage_multi_transform_round_trip: 2 TransformStamped entries
- deserialize_truncated_returns_false: half-buffer Header, expects false
- deserialize_corrupt_encapsulation_returns_false: 2-byte garbage header, expects false
- deserialize_pointcloud2_hostile_length_returns_false: 0xFFFFFFFF fields_size, expects false
- deserialize_tfmessage_hostile_length_returns_false: 0xFFFFFFFF transforms_size, expects false

Large-message regression tests (3):
- cdr_serialized_size_matches_serialize_to_cdr: asserts cdr_serialized_size(msg) ==
  serialize_to_cdr(msg).size() for Header, Image, PointCloud2, TFMessage
- cdr_serialized_size_image_exceeds_static_max: 800x600 RGB (~1.44 MB) round-trip;
  asserts computed size > CdrTopicInfo<Image>::max_serialized_size() (648 B)
- cdr_serialized_size_pointcloud2_exceeds_static_max: 22000-point cloud (~352 KB)
  round-trip; same assertion for PointCloud2 (27597 B static max)

Server tests: 117 -> 126. Client tests: 56 (unchanged).
@JArmandoAnaya

Copy link
Copy Markdown
Contributor Author

Hello @LuisPovedaCano , I already added a new commit with all the fixes. I also found that on this PR appears a bug that I was to resolve in the next PR #9644 [6/7], but it looks like it was already present here, so that's why I had to add extra code to port the fix to this branch. The PR is ready.

@LuisPovedaCano
LuisPovedaCano dismissed their stale review April 8, 2026 13:58

The changes have been applied

@LuisPovedaCano
LuisPovedaCano merged commit f53144c into carla-simulator:ue4-dev Apr 8, 2026
JArmandoAnaya added a commit to JArmandoAnaya/carla that referenced this pull request Apr 9, 2026
Delete 125 auto-generated FastDDS type files from
LibCarla/source/carla/ros2/types/: 31 type-definition pairs
({TypeName}.h + {TypeName}.cpp), 31 PubSubType pairs
({TypeName}PubSubTypes.h + {TypeName}PubSubTypes.cpp), and
FastDDSConversions.h.

These files were generated by fastddsgen from IDL definitions and are no
longer referenced anywhere in the codebase. GenericCdrPubSubType<T>
(introduced in carla-simulator#9643) replaces all 31 hand-generated PubSubType classes by
serializing carla::ros2::msg::* POD structs directly to CDR bytes via
CdrSerialization.h, with no dependency on these files.

Both cmake/fast_dds/CMakeLists.txt and cmake/cyclone_dds/CMakeLists.txt
collect type files via file(GLOB) patterns (types/*.h, types/*.cpp), so no
CMake changes are needed. The globs self-adjust on the next configure pass.

After this change, LibCarla/source/carla/ros2/types/ contains only:
CdrSerialization.h, CdrTopicInfo.h, and msg/ (31 POD struct headers).

Tests: 120/120 server + 56/56 client + 2/2 smoke.
JArmandoAnaya added a commit to JArmandoAnaya/carla that referenced this pull request Apr 9, 2026
Delete 125 auto-generated FastDDS type files from
LibCarla/source/carla/ros2/types/: 31 type-definition pairs
({TypeName}.h + {TypeName}.cpp), 31 PubSubType pairs
({TypeName}PubSubTypes.h + {TypeName}PubSubTypes.cpp), and
FastDDSConversions.h.

These files were generated by fastddsgen from IDL definitions and are no
longer referenced anywhere in the codebase. GenericCdrPubSubType<T>
(introduced in carla-simulator#9643) replaces all 31 hand-generated PubSubType classes by
serializing carla::ros2::msg::* POD structs directly to CDR bytes via
CdrSerialization.h, with no dependency on these files.

Both cmake/fast_dds/CMakeLists.txt and cmake/cyclone_dds/CMakeLists.txt
collect type files via file(GLOB) patterns (types/*.h, types/*.cpp), so no
CMake changes are needed. The globs self-adjust on the next configure pass.

After this change, LibCarla/source/carla/ros2/types/ contains only:
CdrSerialization.h, CdrTopicInfo.h, and msg/ (31 POD struct headers).

Tests: 120/120 server + 56/56 client + 2/2 smoke.
JArmandoAnaya added a commit to JArmandoAnaya/carla that referenced this pull request Apr 9, 2026
FastDDSTypeMap.h was replaced by GenericCdrPubSubType.h (introduced in
carla-simulator#9643) and is no longer included anywhere in the codebase. It references
31 deleted PubSubTypes.h headers and the deleted FastDDSConversions.h,
making it dead code that would cause a build error if ever included.

This completes the cleanup started in the previous commit (125 files
deleted from types/). Total legacy FastDDS files removed: 126.
LuisPovedaCano pushed a commit that referenced this pull request Apr 10, 2026
…#9645)

* feat(LibCarla/ros2): remove legacy FastDDS-generated type files

Delete 125 auto-generated FastDDS type files from
LibCarla/source/carla/ros2/types/: 31 type-definition pairs
({TypeName}.h + {TypeName}.cpp), 31 PubSubType pairs
({TypeName}PubSubTypes.h + {TypeName}PubSubTypes.cpp), and
FastDDSConversions.h.

These files were generated by fastddsgen from IDL definitions and are no
longer referenced anywhere in the codebase. GenericCdrPubSubType<T>
(introduced in #9643) replaces all 31 hand-generated PubSubType classes by
serializing carla::ros2::msg::* POD structs directly to CDR bytes via
CdrSerialization.h, with no dependency on these files.

Both cmake/fast_dds/CMakeLists.txt and cmake/cyclone_dds/CMakeLists.txt
collect type files via file(GLOB) patterns (types/*.h, types/*.cpp), so no
CMake changes are needed. The globs self-adjust on the next configure pass.

After this change, LibCarla/source/carla/ros2/types/ contains only:
CdrSerialization.h, CdrTopicInfo.h, and msg/ (31 POD struct headers).

Tests: 120/120 server + 56/56 client + 2/2 smoke.

* docs(changelog): add ROS2 DDS middleware decoupling entry

* feat(LibCarla/ros2): delete FastDDSTypeMap.h (missed in legacy cleanup)

FastDDSTypeMap.h was replaced by GenericCdrPubSubType.h (introduced in
#9643) and is no longer included anywhere in the codebase. It references
31 deleted PubSubTypes.h headers and the deleted FastDDSConversions.h,
making it dead code that would cause a build error if ever included.

This completes the cleanup started in the previous commit (125 files
deleted from types/). Total legacy FastDDS files removed: 126.
germanros1987 pushed a commit that referenced this pull request Aug 19, 2026
Introduce the middleware-neutral type layer of the ROS 2 middleware
decoupling series, ported from ue4-dev:

- types/msg/*.h: 31 plain C++ structs, one per ROS 2 message type, no
  DDS dependency, standard library headers only, all members
  value-initialized (upstream ue4-dev #9612).
- types/CdrSerialization.h: serialize_to_cdr(), deserialize_from_cdr()
  and cdr_serialized_size() for all msg::* types using Fast-CDR
  (classic CDR, little-endian, DDS encapsulation header). The buffers
  are wire-compatible with every ROS 2 distribution and can be handed
  directly to FastDDS write() paths or CycloneDDS dds_writecdr(),
  removing the need for per-vendor generated type files. A
  kMaxCdrSequenceElements cap rejects hostile sequence lengths during
  deserialization (upstream ue4-dev #9643).
- types/CdrTopicInfo.h: per-type type_name(), REP-2011 RIHS01 type
  hash and max_serialized_size(); the hashes let ROS 2 Iron and newer
  RMWs parse the type hash CARLA advertises via USER_DATA (upstream
  ue4-dev #9681).
- types/UserDataFormat.h: build_user_data() / build_user_data_for<T>()
  helpers producing the REP-2016 "typehash=RIHS01_<hex>;" key-value
  payload (upstream ue4-dev #9681).

UE5 adaptation: ue5-dev pins FastDDS 2.11.2 with bundled Fast-CDR 1.x,
so CdrSerialization.h keeps the Fast-CDR 1.x spellings
(eprosima::fastcdr::Cdr::DDS_CDR, getSerializedDataLength()) instead
of the Fast-CDR 2.x forms the ue4-dev tip carries since its Fast-DDS
2.14.6 upgrade (ue4-dev #9789). Five lines differ; the wire format is
identical either way and is pinned by the golden-bytes test added in
the follow-up test commit.

The FastDDSConversions.h / FastDDSTypeMap.h files from #9612 are
deliberately not ported; they were superseded by unified CDR upstream.

The new headers are not referenced by any build target yet; they start
compiling when the middleware abstraction lands in the next PR of the
series.

(adapted from ue4-dev 542959a)
(adapted from ue4-dev f53144c)
(adapted from ue4-dev c64e8f4)
(adapted from ue4-dev b865088)

(cherry picked from commit 5d0d578)
germanros1987 pushed a commit that referenced this pull request Aug 19, 2026
Introduce the vendor-neutral middleware strategy layer of the ROS 2
middleware decoupling series and its FastDDS implementation, compiled
into libcarla-ros2-native.so. Ported from ue4-dev:

- middleware/Middleware.h: the Middleware enum plus the string and
  ROS 2 type-name helpers; the CycloneDDS value and its availability
  branches are present but stay compiled out until the CycloneDDS
  middleware lands (upstream ue4-dev #9608).
- middleware/IPublisherMiddleware.h, ISubscriberMiddleware.h: the
  type-erased publisher/subscriber strategy interfaces. Subscribers
  write received samples straight into caller-owned storage to avoid a
  copy (upstream ue4-dev #9608).
- middleware/MiddlewareFactory.h: creates the active middleware for a
  traits type; each vendor arm is double-gated on its
  CARLA_ROS2_MIDDLEWARE_* macro and CARLA_ROS2_MIDDLEWARE_TESTING so
  the suite exercises the availability logic without linking DDS
  (upstream ue4-dev #9608).
- middleware/ActiveMiddleware.{h,cpp}: a DDS-free bridge
  (SetActiveMiddleware) so ROS2.cpp, the only ROS 2 translation unit in
  carla-server, can select the middleware without any DDS header
  crossing the shared-library boundary. Nothing calls it until the
  cutover; the definition ships now so the shared lib has a translation
  unit that compiles MiddlewareFactory.h and the FastDDS headers with
  the real vendor macros.
- middleware/fastdds/GenericCdrPubSubType.h: one FastDDS TopicDataType
  that serializes every carla::ros2::msg::* struct through the unified
  CdrSerialization.h path, replacing the generated per-type PubSubType
  classes; getSerializedSizeProvider reports the actual instance size
  so variable-length payloads (camera frames, point clouds) are not
  bounded by the static max size (upstream ue4-dev #9643).
- middleware/fastdds/FastDDS{Publisher,Subscriber}Middleware.h: the
  FastDDS strategy implementations. Each endpoint advertises the
  REP-2016 "typehash=RIHS01_<hex>;" USER_DATA so Jazzy RMWs match on
  the REP-2011 type hash (upstream ue4-dev #9681).
- middleware/fastdds/FastDDSSharedParticipant.{h,cpp}: a refcounted
  process-wide DomainParticipant shared across all FastDDS endpoints,
  avoiding the discovery storm that destroying N participants back to
  back caused on shutdown (upstream ue4-dev #9681).

UE5 adaptation: ue5-dev pins FastDDS 2.11.2 with bundled Fast-CDR 1.x,
so GenericCdrPubSubType.h keeps the Fast-CDR 1.x spellings
(eprosima::fastcdr::Cdr::DDS_CDR, getSerializedDataLength()) matching
CdrSerialization.h from the previous PR of the series. The wire format
is classic CDR little-endian and is unchanged.

The existing publishers keep using the generated FastDDS types; the
cutover to this abstraction and the PublisherImpl/SubscriberImpl
rewrite land in the next PR of the series. No behavior change.

(adapted from ue4-dev 82c28e2)
(adapted from ue4-dev f53144c)
(adapted from ue4-dev 02a83ef)
(adapted from ue4-dev c64e8f4)

(cherry picked from commit f6d9a5b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants