CARLA
Loading...
Searching...
No Matches
CdrSerialization.h
Go to the documentation of this file.
1// Copyright (c) 2025 Computer Vision Center (CVC) at the Universitat Autonoma de Barcelona (UAB).
2// This work is licensed under the terms of the MIT license.
3// For a copy, see <https://opensource.org/licenses/MIT>.
4
5#pragma once
6
7#include <fastcdr/Cdr.h>
8#include <fastcdr/FastBuffer.h>
9#include <fastcdr/exceptions/BadParamException.h>
10#include <fastcdr/exceptions/Exception.h>
11
12#include <cstdint>
13#include <vector>
14
62
63namespace carla {
64namespace ros2 {
65
66// ==========================================================================
67// Internal CDR helpers — one overload pair per message type.
68// Ordered from least-dependent to most-dependent so each helper's body
69// can call the helpers for its nested types without forward declarations.
70//
71// Wire format: OMG DDSI-RTPS v2.5 Section 10 + DDS-XTypes 1.3 clause 7.4.1.1
72// (Classic CDR, encoding version 1, little-endian). Sequences are encoded
73// as a uint32_t length followed by elements; strings as a uint32_t length
74// (including the terminating NUL) followed by bytes; bool as a single octet.
75// ==========================================================================
76
77/// Sanity cap for the length field of a CDR sequence read from the wire.
78/// Protects against malformed/hostile payloads claiming a multi-GB sequence,
79/// which would otherwise OOM-abort the process inside std::vector::resize().
80/// 1,048,576 elements is far above any realistic ROS2 message (PointCloud2
81/// rarely has more than a dozen fields; TFMessage rarely has more than a few
82/// hundred transforms) while bounding the worst-case allocation to ~80 MiB.
83static constexpr uint32_t kMaxCdrSequenceElements = 1u << 20;
84
85// --------------------------------------------------------------------------
86// Leaf types (no nested msg:: fields)
87// --------------------------------------------------------------------------
88
89inline void serialize_cdr(
90 eprosima::fastcdr::Cdr& cdr, const msg::Time& m) {
91 cdr << m.sec;
92 cdr << m.nanosec;
93}
94
95inline void deserialize_cdr(
96 eprosima::fastcdr::Cdr& cdr, msg::Time& m) {
97 cdr >> m.sec;
98 cdr >> m.nanosec;
99}
100
101// --
102
103inline void serialize_cdr(
104 eprosima::fastcdr::Cdr& cdr, const msg::Vector3& m) {
105 cdr << m.x;
106 cdr << m.y;
107 cdr << m.z;
108}
109
110inline void deserialize_cdr(
111 eprosima::fastcdr::Cdr& cdr, msg::Vector3& m) {
112 cdr >> m.x;
113 cdr >> m.y;
114 cdr >> m.z;
115}
116
117// --
118
119inline void serialize_cdr(
120 eprosima::fastcdr::Cdr& cdr, const msg::Quaternion& m) {
121 cdr << m.x;
122 cdr << m.y;
123 cdr << m.z;
124 cdr << m.w;
125}
126
127inline void deserialize_cdr(
128 eprosima::fastcdr::Cdr& cdr, msg::Quaternion& m) {
129 cdr >> m.x;
130 cdr >> m.y;
131 cdr >> m.z;
132 cdr >> m.w;
133}
134
135// --
136
137inline void serialize_cdr(
138 eprosima::fastcdr::Cdr& cdr, const msg::Point& m) {
139 cdr << m.x;
140 cdr << m.y;
141 cdr << m.z;
142}
143
144inline void deserialize_cdr(
145 eprosima::fastcdr::Cdr& cdr, msg::Point& m) {
146 cdr >> m.x;
147 cdr >> m.y;
148 cdr >> m.z;
149}
150
151// --
152
153inline void serialize_cdr(
154 eprosima::fastcdr::Cdr& cdr, const msg::Point32& m) {
155 cdr << m.x;
156 cdr << m.y;
157 cdr << m.z;
158}
159
160inline void deserialize_cdr(
161 eprosima::fastcdr::Cdr& cdr, msg::Point32& m) {
162 cdr >> m.x;
163 cdr >> m.y;
164 cdr >> m.z;
165}
166
167// --
168
169inline void serialize_cdr(
170 eprosima::fastcdr::Cdr& cdr, const msg::NavSatStatus& m) {
171 cdr << m.status;
172 cdr << m.service;
173}
174
175inline void deserialize_cdr(
176 eprosima::fastcdr::Cdr& cdr, msg::NavSatStatus& m) {
177 cdr >> m.status;
178 cdr >> m.service;
179}
180
181// --
182
183inline void serialize_cdr(
184 eprosima::fastcdr::Cdr& cdr, const msg::RegionOfInterest& m) {
185 cdr << m.x_offset;
186 cdr << m.y_offset;
187 cdr << m.height;
188 cdr << m.width;
189 cdr << m.do_rectify;
190}
191
192inline void deserialize_cdr(
193 eprosima::fastcdr::Cdr& cdr, msg::RegionOfInterest& m) {
194 cdr >> m.x_offset;
195 cdr >> m.y_offset;
196 cdr >> m.height;
197 cdr >> m.width;
198 cdr >> m.do_rectify;
199}
200
201// --
202
203inline void serialize_cdr(
204 eprosima::fastcdr::Cdr& cdr, const msg::Float32& m) {
205 cdr << m.data;
206}
207
208inline void deserialize_cdr(
209 eprosima::fastcdr::Cdr& cdr, msg::Float32& m) {
210 cdr >> m.data;
211}
212
213// --
214
215inline void serialize_cdr(
216 eprosima::fastcdr::Cdr& cdr, const msg::AckermannDrive& m) {
217 cdr << m.steering_angle;
219 cdr << m.speed;
220 cdr << m.acceleration;
221 cdr << m.jerk;
222}
223
224inline void deserialize_cdr(
225 eprosima::fastcdr::Cdr& cdr, msg::AckermannDrive& m) {
226 cdr >> m.steering_angle;
228 cdr >> m.speed;
229 cdr >> m.acceleration;
230 cdr >> m.jerk;
231}
232
233// --
234
235/// PointField: name is a string; offset, datatype, count are primitives.
236inline void serialize_cdr(
237 eprosima::fastcdr::Cdr& cdr, const msg::PointField& m) {
238 cdr << m.name;
239 cdr << m.offset;
240 cdr << m.datatype;
241 cdr << m.count;
242}
243
244inline void deserialize_cdr(
245 eprosima::fastcdr::Cdr& cdr, msg::PointField& m) {
246 cdr >> m.name;
247 cdr >> m.offset;
248 cdr >> m.datatype;
249 cdr >> m.count;
250}
251
252// --
253
254inline void serialize_cdr(
255 eprosima::fastcdr::Cdr& cdr, const msg::TF2Error& m) {
256 cdr << m.error;
257 cdr << m.error_string;
258}
259
260inline void deserialize_cdr(
261 eprosima::fastcdr::Cdr& cdr, msg::TF2Error& m) {
262 cdr >> m.error;
263 cdr >> m.error_string;
264}
265
266// --------------------------------------------------------------------------
267// Types with nested msg:: fields
268// --------------------------------------------------------------------------
269
270inline void serialize_cdr(
271 eprosima::fastcdr::Cdr& cdr, const msg::Header& m) {
272 serialize_cdr(cdr, m.stamp);
273 cdr << m.frame_id;
274}
275
276inline void deserialize_cdr(
277 eprosima::fastcdr::Cdr& cdr, msg::Header& m) {
278 deserialize_cdr(cdr, m.stamp);
279 cdr >> m.frame_id;
280}
281
282// --
283
284inline void serialize_cdr(
285 eprosima::fastcdr::Cdr& cdr, const msg::Lateral& m) {
286 serialize_cdr(cdr, m.stamp);
288 cdr << m.steering_tire_angle;
291}
292
293inline void deserialize_cdr(
294 eprosima::fastcdr::Cdr& cdr, msg::Lateral& m) {
295 deserialize_cdr(cdr, m.stamp);
297 cdr >> m.steering_tire_angle;
300}
301
302// --
303
304inline void serialize_cdr(
305 eprosima::fastcdr::Cdr& cdr, const msg::Longitudinal& m) {
306 serialize_cdr(cdr, m.stamp);
308 cdr << m.velocity;
309 cdr << m.acceleration;
310 cdr << m.jerk;
312 cdr << m.is_defined_jerk;
313}
314
315inline void deserialize_cdr(
316 eprosima::fastcdr::Cdr& cdr, msg::Longitudinal& m) {
317 deserialize_cdr(cdr, m.stamp);
319 cdr >> m.velocity;
320 cdr >> m.acceleration;
321 cdr >> m.jerk;
323 cdr >> m.is_defined_jerk;
324}
325
326// --
327
328inline void serialize_cdr(
329 eprosima::fastcdr::Cdr& cdr, const msg::Control& m) {
330 serialize_cdr(cdr, m.stamp);
332 serialize_cdr(cdr, m.lateral);
334}
335
336inline void deserialize_cdr(
337 eprosima::fastcdr::Cdr& cdr, msg::Control& m) {
338 deserialize_cdr(cdr, m.stamp);
340 deserialize_cdr(cdr, m.lateral);
342}
343
344// --
345
346inline void serialize_cdr(
347 eprosima::fastcdr::Cdr& cdr, const msg::Twist& m) {
348 serialize_cdr(cdr, m.linear);
349 serialize_cdr(cdr, m.angular);
350}
351
352inline void deserialize_cdr(
353 eprosima::fastcdr::Cdr& cdr, msg::Twist& m) {
354 deserialize_cdr(cdr, m.linear);
355 deserialize_cdr(cdr, m.angular);
356}
357
358// --
359
360inline void serialize_cdr(
361 eprosima::fastcdr::Cdr& cdr, const msg::Transform& m) {
363 serialize_cdr(cdr, m.rotation);
364}
365
366inline void deserialize_cdr(
367 eprosima::fastcdr::Cdr& cdr, msg::Transform& m) {
370}
371
372// --
373
374inline void serialize_cdr(
375 eprosima::fastcdr::Cdr& cdr, const msg::Pose& m) {
376 serialize_cdr(cdr, m.position);
378}
379
380inline void deserialize_cdr(
381 eprosima::fastcdr::Cdr& cdr, msg::Pose& m) {
384}
385
386// --
387
388inline void serialize_cdr(
389 eprosima::fastcdr::Cdr& cdr, const msg::Clock& m) {
390 serialize_cdr(cdr, m.clock);
391}
392
393inline void deserialize_cdr(
394 eprosima::fastcdr::Cdr& cdr, msg::Clock& m) {
395 deserialize_cdr(cdr, m.clock);
396}
397
398// --
399
400inline void serialize_cdr(
401 eprosima::fastcdr::Cdr& cdr, const msg::String& m) {
402 cdr << m.data;
403}
404
405inline void deserialize_cdr(
406 eprosima::fastcdr::Cdr& cdr, msg::String& m) {
407 cdr >> m.data;
408}
409
410// --
411
412inline void serialize_cdr(
413 eprosima::fastcdr::Cdr& cdr, const msg::TransformStamped& m) {
414 serialize_cdr(cdr, m.header);
415 cdr << m.child_frame_id;
416 serialize_cdr(cdr, m.transform);
417}
418
419inline void deserialize_cdr(
420 eprosima::fastcdr::Cdr& cdr, msg::TransformStamped& m) {
421 deserialize_cdr(cdr, m.header);
422 cdr >> m.child_frame_id;
424}
425
426// --
427
428inline void serialize_cdr(
429 eprosima::fastcdr::Cdr& cdr, const msg::TwistWithCovariance& m) {
430 serialize_cdr(cdr, m.twist);
431 cdr << m.covariance;
432}
433
434inline void deserialize_cdr(
435 eprosima::fastcdr::Cdr& cdr, msg::TwistWithCovariance& m) {
436 deserialize_cdr(cdr, m.twist);
437 cdr >> m.covariance;
438}
439
440// --
441
442inline void serialize_cdr(
443 eprosima::fastcdr::Cdr& cdr, const msg::PoseWithCovariance& m) {
444 serialize_cdr(cdr, m.pose);
445 cdr << m.covariance;
446}
447
448inline void deserialize_cdr(
449 eprosima::fastcdr::Cdr& cdr, msg::PoseWithCovariance& m) {
450 deserialize_cdr(cdr, m.pose);
451 cdr >> m.covariance;
452}
453
454// --
455
456inline void serialize_cdr(
457 eprosima::fastcdr::Cdr& cdr, const msg::PoseStamped& m) {
458 serialize_cdr(cdr, m.header);
459 serialize_cdr(cdr, m.pose);
460}
461
462inline void deserialize_cdr(
463 eprosima::fastcdr::Cdr& cdr, msg::PoseStamped& m) {
464 deserialize_cdr(cdr, m.header);
465 deserialize_cdr(cdr, m.pose);
466}
467
468// --
469
470inline void serialize_cdr(
471 eprosima::fastcdr::Cdr& cdr, const msg::PoseWithCovarianceStamped& m) {
472 serialize_cdr(cdr, m.header);
473 serialize_cdr(cdr, m.pose);
474}
475
476inline void deserialize_cdr(
477 eprosima::fastcdr::Cdr& cdr, msg::PoseWithCovarianceStamped& m) {
478 deserialize_cdr(cdr, m.header);
479 deserialize_cdr(cdr, m.pose);
480}
481
482// --
483
484inline void serialize_cdr(
485 eprosima::fastcdr::Cdr& cdr, const msg::AckermannDriveStamped& m) {
486 serialize_cdr(cdr, m.header);
487 serialize_cdr(cdr, m.drive);
488}
489
490inline void deserialize_cdr(
491 eprosima::fastcdr::Cdr& cdr, msg::AckermannDriveStamped& m) {
492 deserialize_cdr(cdr, m.header);
493 deserialize_cdr(cdr, m.drive);
494}
495
496// --
497
498inline void serialize_cdr(
499 eprosima::fastcdr::Cdr& cdr, const msg::GearCommand& m) {
500 serialize_cdr(cdr, m.stamp);
501 cdr << m.command;
502}
503
504inline void deserialize_cdr(
505 eprosima::fastcdr::Cdr& cdr, msg::GearCommand& m) {
506 deserialize_cdr(cdr, m.stamp);
507 cdr >> m.command;
508}
509
510// --
511
512inline void serialize_cdr(
513 eprosima::fastcdr::Cdr& cdr, const msg::TurnIndicatorsCommand& m) {
514 serialize_cdr(cdr, m.stamp);
515 cdr << m.command;
516}
517
518inline void deserialize_cdr(
519 eprosima::fastcdr::Cdr& cdr, msg::TurnIndicatorsCommand& m) {
520 deserialize_cdr(cdr, m.stamp);
521 cdr >> m.command;
522}
523
524// --
525
526inline void serialize_cdr(
527 eprosima::fastcdr::Cdr& cdr, const msg::HazardLightsCommand& m) {
528 serialize_cdr(cdr, m.stamp);
529 cdr << m.command;
530}
531
532inline void deserialize_cdr(
533 eprosima::fastcdr::Cdr& cdr, msg::HazardLightsCommand& m) {
534 deserialize_cdr(cdr, m.stamp);
535 cdr >> m.command;
536}
537
538// --
539
540inline void serialize_cdr(
541 eprosima::fastcdr::Cdr& cdr, const msg::Engage& m) {
542 serialize_cdr(cdr, m.stamp);
543 cdr << m.engage;
544}
545
546inline void deserialize_cdr(
547 eprosima::fastcdr::Cdr& cdr, msg::Engage& m) {
548 deserialize_cdr(cdr, m.stamp);
549 cdr >> m.engage;
550}
551
552// --
553
554inline void serialize_cdr(
555 eprosima::fastcdr::Cdr& cdr, const msg::VehicleEmergencyStamped& m) {
556 serialize_cdr(cdr, m.stamp);
557 cdr << m.emergency;
558}
559
560inline void deserialize_cdr(
561 eprosima::fastcdr::Cdr& cdr, msg::VehicleEmergencyStamped& m) {
562 deserialize_cdr(cdr, m.stamp);
563 cdr >> m.emergency;
564}
565
566// --
567
568inline void serialize_cdr(
569 eprosima::fastcdr::Cdr& cdr, const msg::SteeringReport& m) {
570 serialize_cdr(cdr, m.stamp);
571 cdr << m.steering_tire_angle;
572}
573
574inline void deserialize_cdr(
575 eprosima::fastcdr::Cdr& cdr, msg::SteeringReport& m) {
576 deserialize_cdr(cdr, m.stamp);
577 cdr >> m.steering_tire_angle;
578}
579
580// --
581
582inline void serialize_cdr(
583 eprosima::fastcdr::Cdr& cdr, const msg::GearReport& m) {
584 serialize_cdr(cdr, m.stamp);
585 cdr << m.report;
586}
587
588inline void deserialize_cdr(
589 eprosima::fastcdr::Cdr& cdr, msg::GearReport& m) {
590 deserialize_cdr(cdr, m.stamp);
591 cdr >> m.report;
592}
593
594// --
595
596inline void serialize_cdr(
597 eprosima::fastcdr::Cdr& cdr, const msg::ControlModeReport& m) {
598 serialize_cdr(cdr, m.stamp);
599 cdr << m.mode;
600}
601
602inline void deserialize_cdr(
603 eprosima::fastcdr::Cdr& cdr, msg::ControlModeReport& m) {
604 deserialize_cdr(cdr, m.stamp);
605 cdr >> m.mode;
606}
607
608// --
609
610inline void serialize_cdr(
611 eprosima::fastcdr::Cdr& cdr, const msg::TurnIndicatorsReport& m) {
612 serialize_cdr(cdr, m.stamp);
613 cdr << m.report;
614}
615
616inline void deserialize_cdr(
617 eprosima::fastcdr::Cdr& cdr, msg::TurnIndicatorsReport& m) {
618 deserialize_cdr(cdr, m.stamp);
619 cdr >> m.report;
620}
621
622// --
623
624inline void serialize_cdr(
625 eprosima::fastcdr::Cdr& cdr, const msg::HazardLightsReport& m) {
626 serialize_cdr(cdr, m.stamp);
627 cdr << m.report;
628}
629
630inline void deserialize_cdr(
631 eprosima::fastcdr::Cdr& cdr, msg::HazardLightsReport& m) {
632 deserialize_cdr(cdr, m.stamp);
633 cdr >> m.report;
634}
635
636// --
637
638inline void serialize_cdr(
639 eprosima::fastcdr::Cdr& cdr, const msg::VelocityReport& m) {
640 serialize_cdr(cdr, m.header);
641 cdr << m.longitudinal_velocity;
642 cdr << m.lateral_velocity;
643 cdr << m.heading_rate;
644}
645
646inline void deserialize_cdr(
647 eprosima::fastcdr::Cdr& cdr, msg::VelocityReport& m) {
648 deserialize_cdr(cdr, m.header);
649 cdr >> m.longitudinal_velocity;
650 cdr >> m.lateral_velocity;
651 cdr >> m.heading_rate;
652}
653
654// --
655
656inline void serialize_cdr(
657 eprosima::fastcdr::Cdr& cdr, const msg::CarlaCollisionEvent& m) {
658 serialize_cdr(cdr, m.header);
659 cdr << m.other_actor_id;
661}
662
663inline void deserialize_cdr(
664 eprosima::fastcdr::Cdr& cdr, msg::CarlaCollisionEvent& m) {
665 deserialize_cdr(cdr, m.header);
666 cdr >> m.other_actor_id;
668}
669
670// --
671
672inline void serialize_cdr(
673 eprosima::fastcdr::Cdr& cdr, const msg::NavSatFix& m) {
674 serialize_cdr(cdr, m.header);
675 serialize_cdr(cdr, m.status);
676 cdr << m.latitude;
677 cdr << m.longitude;
678 cdr << m.altitude;
679 cdr << m.position_covariance;
681}
682
683inline void deserialize_cdr(
684 eprosima::fastcdr::Cdr& cdr, msg::NavSatFix& m) {
685 deserialize_cdr(cdr, m.header);
686 deserialize_cdr(cdr, m.status);
687 cdr >> m.latitude;
688 cdr >> m.longitude;
689 cdr >> m.altitude;
690 cdr >> m.position_covariance;
692}
693
694// --
695
696inline void serialize_cdr(
697 eprosima::fastcdr::Cdr& cdr, const msg::Imu& m) {
698 serialize_cdr(cdr, m.header);
700 cdr << m.orientation_covariance;
705}
706
707inline void deserialize_cdr(
708 eprosima::fastcdr::Cdr& cdr, msg::Imu& m) {
709 deserialize_cdr(cdr, m.header);
711 cdr >> m.orientation_covariance;
716}
717
718// --
719
720inline void serialize_cdr(
721 eprosima::fastcdr::Cdr& cdr, const msg::CarlaEgoVehicleControl& m) {
722 serialize_cdr(cdr, m.header);
723 cdr << m.throttle;
724 cdr << m.steer;
725 cdr << m.brake;
726 cdr << m.hand_brake;
727 cdr << m.reverse;
728 cdr << m.gear;
729 cdr << m.manual_gear_shift;
730}
731
732inline void deserialize_cdr(
733 eprosima::fastcdr::Cdr& cdr, msg::CarlaEgoVehicleControl& m) {
734 deserialize_cdr(cdr, m.header);
735 cdr >> m.throttle;
736 cdr >> m.steer;
737 cdr >> m.brake;
738 cdr >> m.hand_brake;
739 cdr >> m.reverse;
740 cdr >> m.gear;
741 cdr >> m.manual_gear_shift;
742}
743
744// --
745
746inline void serialize_cdr(
747 eprosima::fastcdr::Cdr& cdr, const msg::CarlaLineInvasion& m) {
748 serialize_cdr(cdr, m.header);
749 cdr << m.crossed_lane_markings;
750}
751
752inline void deserialize_cdr(
753 eprosima::fastcdr::Cdr& cdr, msg::CarlaLineInvasion& m) {
754 deserialize_cdr(cdr, m.header);
755 cdr >> m.crossed_lane_markings;
756}
757
758// --
759
760inline void serialize_cdr(
761 eprosima::fastcdr::Cdr& cdr, const msg::Odometry& m) {
762 serialize_cdr(cdr, m.header);
763 cdr << m.child_frame_id;
764 serialize_cdr(cdr, m.pose);
765 serialize_cdr(cdr, m.twist);
766}
767
768inline void deserialize_cdr(
769 eprosima::fastcdr::Cdr& cdr, msg::Odometry& m) {
770 deserialize_cdr(cdr, m.header);
771 cdr >> m.child_frame_id;
772 deserialize_cdr(cdr, m.pose);
773 deserialize_cdr(cdr, m.twist);
774}
775
776// --
777
778inline void serialize_cdr(
779 eprosima::fastcdr::Cdr& cdr, const msg::Image& m) {
780 serialize_cdr(cdr, m.header);
781 cdr << m.height;
782 cdr << m.width;
783 cdr << m.encoding;
784 cdr << m.is_bigendian;
785 cdr << m.step;
786 cdr << m.data;
787}
788
789inline void deserialize_cdr(
790 eprosima::fastcdr::Cdr& cdr, msg::Image& m) {
791 deserialize_cdr(cdr, m.header);
792 cdr >> m.height;
793 cdr >> m.width;
794 cdr >> m.encoding;
795 cdr >> m.is_bigendian;
796 cdr >> m.step;
797 cdr >> m.data;
798}
799
800// --
801
802inline void serialize_cdr(
803 eprosima::fastcdr::Cdr& cdr, const msg::CameraInfo& m) {
804 serialize_cdr(cdr, m.header);
805 cdr << m.height;
806 cdr << m.width;
807 cdr << m.distortion_model;
808 cdr << m.d;
809 cdr << m.k;
810 cdr << m.r;
811 cdr << m.p;
812 cdr << m.binning_x;
813 cdr << m.binning_y;
814 serialize_cdr(cdr, m.roi);
815}
816
817inline void deserialize_cdr(
818 eprosima::fastcdr::Cdr& cdr, msg::CameraInfo& m) {
819 deserialize_cdr(cdr, m.header);
820 cdr >> m.height;
821 cdr >> m.width;
822 cdr >> m.distortion_model;
823 cdr >> m.d;
824 cdr >> m.k;
825 cdr >> m.r;
826 cdr >> m.p;
827 cdr >> m.binning_x;
828 cdr >> m.binning_y;
829 deserialize_cdr(cdr, m.roi);
830}
831
832// --
833
834/// PointCloud2::fields is a sequence of structs; FastCDR's generic vector
835/// operator calls serialize() on each element, which our POD types don't
836/// provide. Write length + elements manually.
837inline void serialize_cdr(
838 eprosima::fastcdr::Cdr& cdr, const msg::PointCloud2& m) {
839 serialize_cdr(cdr, m.header);
840 cdr << m.height;
841 cdr << m.width;
842 // CDR sequence length is uint32_t per DDS-XTypes 1.3 clause 7.4.1.1.
843 cdr << static_cast<uint32_t>(m.fields.size());
844 for (const auto& f : m.fields) {
845 serialize_cdr(cdr, f);
846 }
847 cdr << m.is_bigendian;
848 cdr << m.point_step;
849 cdr << m.row_step;
850 cdr << m.data;
851 cdr << m.is_dense;
852}
853
854inline void deserialize_cdr(
855 eprosima::fastcdr::Cdr& cdr, msg::PointCloud2& m) {
856 deserialize_cdr(cdr, m.header);
857 cdr >> m.height;
858 cdr >> m.width;
859 uint32_t fields_size{0u};
860 cdr >> fields_size;
861 if (fields_size > kMaxCdrSequenceElements) {
862 throw eprosima::fastcdr::exception::BadParamException(
863 "PointCloud2::fields length exceeds sane CDR sequence cap");
864 }
865 m.fields.resize(static_cast<size_t>(fields_size));
866 for (auto& f : m.fields) {
867 deserialize_cdr(cdr, f);
868 }
869 cdr >> m.is_bigendian;
870 cdr >> m.point_step;
871 cdr >> m.row_step;
872 cdr >> m.data;
873 cdr >> m.is_dense;
874}
875
876// --
877
878/// TFMessage::transforms is a sequence of TransformStamped structs.
879/// Write length + elements manually.
880inline void serialize_cdr(
881 eprosima::fastcdr::Cdr& cdr, const msg::TFMessage& m) {
882 // CDR sequence length is uint32_t per DDS-XTypes 1.3 clause 7.4.1.1.
883 cdr << static_cast<uint32_t>(m.transforms.size());
884 for (const auto& t : m.transforms) {
885 serialize_cdr(cdr, t);
886 }
887}
888
889inline void deserialize_cdr(
890 eprosima::fastcdr::Cdr& cdr, msg::TFMessage& m) {
891 uint32_t transforms_size{0u};
892 cdr >> transforms_size;
893 if (transforms_size > kMaxCdrSequenceElements) {
894 throw eprosima::fastcdr::exception::BadParamException(
895 "TFMessage::transforms length exceeds sane CDR sequence cap");
896 }
897 m.transforms.resize(static_cast<size_t>(transforms_size));
898 for (auto& t : m.transforms) {
899 deserialize_cdr(cdr, t);
900 }
901}
902
903// ==========================================================================
904// Public API
905// ==========================================================================
906
907/// Serialize a msg::X to a CDR byte buffer including the DDS encapsulation
908/// header (Classic CDR, encoding version 1, little-endian). The returned
909/// buffer is wire-compatible with all ROS2 distros and can be passed to
910/// FastDDS write_serialized_payload() or CycloneDDS dds_writecdr().
911/// Returns an empty vector if Fast-CDR raises an exception (e.g. out of
912/// memory while growing the internal FastBuffer).
913template<typename T>
914std::vector<uint8_t> serialize_to_cdr(const T& msg) {
915 eprosima::fastcdr::FastBuffer fb;
916 // Force LITTLE_ENDIANNESS so the encapsulation header is CDR_LE
917 // ({0x00, 0x01}) per DDSI-RTPS v2.5 Table 10.3, regardless of host
918 // endianness. ROS2 ecosystems test against CDR_LE.
919 eprosima::fastcdr::Cdr cdr{
920 fb,
921 eprosima::fastcdr::Cdr::LITTLE_ENDIANNESS,
922 eprosima::fastcdr::CdrVersion::XCDRv1};
923 try {
924 cdr.serialize_encapsulation();
925 serialize_cdr(cdr, msg);
926 } catch (const eprosima::fastcdr::exception::Exception&) {
927 return std::vector<uint8_t>{};
928 }
929 const char* buf{fb.getBuffer()};
930 const size_t len{cdr.get_serialized_data_length()};
931 return std::vector<uint8_t>{
932 reinterpret_cast<const uint8_t*>(buf),
933 reinterpret_cast<const uint8_t*>(buf) + len};
934}
935
936/// Return the exact CDR-serialized size in bytes for a message instance,
937/// including the 4-byte DDS encapsulation header. Used by GenericCdrPubSubType
938/// to tell FastDDS the actual payload size before write(), so the payload
939/// buffer is sized correctly for variable-length fields (e.g. Image::data,
940/// PointCloud2::data). The result is provably equal to serialize_to_cdr(msg).size().
941template<typename T>
942uint32_t cdr_serialized_size(const T& msg) {
943 eprosima::fastcdr::FastBuffer fb;
944 eprosima::fastcdr::Cdr cdr{
945 fb,
946 eprosima::fastcdr::Cdr::LITTLE_ENDIANNESS,
947 eprosima::fastcdr::CdrVersion::XCDRv1};
948 cdr.serialize_encapsulation();
949 serialize_cdr(cdr, msg);
950 return static_cast<uint32_t>(cdr.get_serialized_data_length());
951}
952
953/// Deserialize a msg::X from a CDR byte buffer that was produced by
954/// serialize_to_cdr() or by any ROS2-compatible DDS middleware.
955/// Returns true on success, false on any Fast-CDR error (truncated buffer,
956/// malformed encapsulation header, sequence length exceeding the sanity
957/// cap, etc.). The buffer must include the 4-byte DDS encapsulation header.
958template<typename T>
960 const uint8_t* data, size_t size, T& msg) {
961 eprosima::fastcdr::FastBuffer fb{
962 // FastBuffer requires a non-const pointer; the buffer is only read.
963 reinterpret_cast<char*>(const_cast<uint8_t*>(data)),
964 size};
965 eprosima::fastcdr::Cdr cdr{
966 fb,
967 eprosima::fastcdr::Cdr::LITTLE_ENDIANNESS,
968 eprosima::fastcdr::CdrVersion::XCDRv1};
969 try {
970 cdr.read_encapsulation();
971 deserialize_cdr(cdr, msg);
972 } catch (const eprosima::fastcdr::exception::Exception&) {
973 return false;
974 }
975 return true;
976}
977
978} // namespace ros2
979} // namespace carla
static constexpr uint32_t kMaxCdrSequenceElements
Sanity cap for the length field of a CDR sequence read from the wire.
std::vector< uint8_t > serialize_to_cdr(const T &msg)
Serialize a msg::X to a CDR byte buffer including the DDS encapsulation header (Classic CDR,...
uint32_t cdr_serialized_size(const T &msg)
Return the exact CDR-serialized size in bytes for a message instance, including the 4-byte DDS encaps...
bool deserialize_from_cdr(const uint8_t *data, size_t size, T &msg)
Deserialize a msg::X from a CDR byte buffer that was produced by serialize_to_cdr() or by any ROS2-co...
void deserialize_cdr(eprosima::fastcdr::Cdr &cdr, msg::Time &m)
void serialize_cdr(eprosima::fastcdr::Cdr &cdr, const msg::Time &m)
This file contains definitions of common data structures used in traffic manager.
std::array< double, 12 > p
Definition CameraInfo.h:25
std::vector< double > d
Definition CameraInfo.h:22
std::array< double, 9 > r
Definition CameraInfo.h:24
std::array< double, 9 > k
Definition CameraInfo.h:23
std::vector< int32_t > crossed_lane_markings
autoware_control_msgs/msg/Control
Definition Control.h:15
Longitudinal longitudinal
Definition Control.h:19
std::string frame_id
Definition Header.h:15
std::vector< uint8_t > data
std::array< double, 9 > linear_acceleration_covariance
Definition Imu.h:22
std::array< double, 9 > angular_velocity_covariance
Definition Imu.h:20
Vector3 linear_acceleration
Definition Imu.h:21
std::array< double, 9 > orientation_covariance
Definition Imu.h:18
Quaternion orientation
Definition Imu.h:17
Vector3 angular_velocity
Definition Imu.h:19
autoware_control_msgs/msg/Lateral
Definition Lateral.h:13
bool is_defined_steering_tire_rotation_rate
Definition Lateral.h:18
float steering_tire_rotation_rate
Definition Lateral.h:17
autoware_control_msgs/msg/Longitudinal
std::array< double, 9 > position_covariance
Definition NavSatFix.h:26
PoseWithCovariance pose
Definition Odometry.h:18
TwistWithCovariance twist
Definition Odometry.h:19
std::string child_frame_id
Definition Odometry.h:17
std::vector< PointField > fields
Definition PointCloud2.h:19
std::vector< uint8_t > data
Definition PointCloud2.h:23
Quaternion orientation
Definition Pose.h:15
std::vector< TransformStamped > transforms
Definition TFMessage.h:14