Skip to content

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

Draft
JesusAnaya wants to merge 6 commits intocarla-simulator:ue4-devfrom
JesusAnaya:feature/ros2-cdr-serialization
Draft

feat(LibCarla/ros2): [5/7] add unified CDR serialization and GenericCdrPubSubType#9643
JesusAnaya wants to merge 6 commits intocarla-simulator:ue4-devfrom
JesusAnaya:feature/ros2-cdr-serialization

Conversation

@JesusAnaya
Copy link
Copy Markdown
Contributor

@JesusAnaya JesusAnaya commented Apr 5, 2026

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
Copy link
Copy Markdown

update-docs bot commented Apr 5, 2026

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.
@JesusAnaya JesusAnaya force-pushed the feature/ros2-cdr-serialization branch from 9e93214 to 0a9ca58 Compare April 5, 2026 02:57
JesusAnaya added a commit to JesusAnaya/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.
@JesusAnaya JesusAnaya 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
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.

1 participant