use heapless::String as HString;
use crate::protocol::dds::api::dds_type::DdsType;
use crate::protocol::dds::api::error::DdsApiError;
use crate::protocol::dds::byte_cursor::{ByteCursor, ByteWriter};
use super::std_msgs::Header;
use super::{make_cursor, make_writer};
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Vector3 {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl Vector3 {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
w.align_to(8)?;
w.write_f64(self.x)?;
w.write_f64(self.y)?;
w.write_f64(self.z)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
r.align_to(8)?;
let x = r.read_f64()?;
let y = r.read_f64()?;
let z = r.read_f64()?;
Ok(Self { x, y, z })
}
}
impl DdsType for Vector3 {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Vector3_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl Point {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
w.align_to(8)?;
w.write_f64(self.x)?;
w.write_f64(self.y)?;
w.write_f64(self.z)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
r.align_to(8)?;
let x = r.read_f64()?;
let y = r.read_f64()?;
let z = r.read_f64()?;
Ok(Self { x, y, z })
}
}
impl DdsType for Point {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Point_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Quaternion {
pub x: f64,
pub y: f64,
pub z: f64,
pub w: f64,
}
impl Default for Quaternion {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
z: 0.0,
w: 1.0,
}
}
}
impl Quaternion {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
w.align_to(8)?;
w.write_f64(self.x)?;
w.write_f64(self.y)?;
w.write_f64(self.z)?;
w.write_f64(self.w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
r.align_to(8)?;
let x = r.read_f64()?;
let y = r.read_f64()?;
let z = r.read_f64()?;
let w = r.read_f64()?;
Ok(Self { x, y, z, w })
}
}
impl DdsType for Quaternion {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Quaternion_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Pose {
pub position: Point,
pub orientation: Quaternion,
}
impl Pose {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
self.position.serialize_inner(w)?;
self.orientation.serialize_inner(w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let position = Point::deserialize_inner(r)?;
let orientation = Quaternion::deserialize_inner(r)?;
Ok(Self {
position,
orientation,
})
}
}
impl DdsType for Pose {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Pose_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct PoseStamped {
pub header: Header,
pub pose: Pose,
}
impl DdsType for PoseStamped {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::PoseStamped_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.header.serialize_inner(&mut w)?;
self.pose.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
let header = Header::deserialize_inner(&mut r)?;
let pose = Pose::deserialize_inner(&mut r)?;
Ok(Self { header, pose })
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Twist {
pub linear: Vector3,
pub angular: Vector3,
}
impl Twist {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
self.linear.serialize_inner(w)?;
self.angular.serialize_inner(w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let linear = Vector3::deserialize_inner(r)?;
let angular = Vector3::deserialize_inner(r)?;
Ok(Self { linear, angular })
}
}
impl DdsType for Twist {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Twist_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct TwistStamped {
pub header: Header,
pub twist: Twist,
}
impl DdsType for TwistStamped {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::TwistStamped_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.header.serialize_inner(&mut w)?;
self.twist.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
let header = Header::deserialize_inner(&mut r)?;
let twist = Twist::deserialize_inner(&mut r)?;
Ok(Self { header, twist })
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Transform {
pub translation: Vector3,
pub rotation: Quaternion,
}
impl Transform {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
self.translation.serialize_inner(w)?;
self.rotation.serialize_inner(w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let translation = Vector3::deserialize_inner(r)?;
let rotation = Quaternion::deserialize_inner(r)?;
Ok(Self {
translation,
rotation,
})
}
}
impl DdsType for Transform {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Transform_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct TransformStamped {
pub header: Header,
pub child_frame_id: HString<256>,
pub transform: Transform,
}
impl DdsType for TransformStamped {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::TransformStamped_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.header.serialize_inner(&mut w)?;
w.write_cdr_string(self.child_frame_id.as_str())?;
self.transform.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
let header = Header::deserialize_inner(&mut r)?;
let s = r.read_cdr_string()?;
let mut child_frame_id = HString::<256>::new();
child_frame_id
.push_str(s)
.map_err(|_| DdsApiError::Serialization("child_frame_id exceeds 256-byte capacity"))?;
let transform = Transform::deserialize_inner(&mut r)?;
Ok(Self {
header,
child_frame_id,
transform,
})
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Wrench {
pub force: Vector3,
pub torque: Vector3,
}
impl Wrench {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
self.force.serialize_inner(w)?;
self.torque.serialize_inner(w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let force = Vector3::deserialize_inner(r)?;
let torque = Vector3::deserialize_inner(r)?;
Ok(Self { force, torque })
}
}
impl DdsType for Wrench {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Wrench_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct WrenchStamped {
pub header: Header,
pub wrench: Wrench,
}
impl DdsType for WrenchStamped {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::WrenchStamped_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.header.serialize_inner(&mut w)?;
self.wrench.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
let header = Header::deserialize_inner(&mut r)?;
let wrench = Wrench::deserialize_inner(&mut r)?;
Ok(Self { header, wrench })
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Accel {
pub linear: Vector3,
pub angular: Vector3,
}
impl Accel {
pub(crate) fn serialize_inner(&self, w: &mut ByteWriter<'_>) -> Result<(), DdsApiError> {
self.linear.serialize_inner(w)?;
self.angular.serialize_inner(w)?;
Ok(())
}
pub(crate) fn deserialize_inner(r: &mut ByteCursor<'_>) -> Result<Self, DdsApiError> {
let linear = Vector3::deserialize_inner(r)?;
let angular = Vector3::deserialize_inner(r)?;
Ok(Self { linear, angular })
}
}
impl DdsType for Accel {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Accel_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
Self::deserialize_inner(&mut r)
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct AccelStamped {
pub header: Header,
pub accel: Accel,
}
impl DdsType for AccelStamped {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::AccelStamped_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
self.header.serialize_inner(&mut w)?;
self.accel.serialize_inner(&mut w)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
let header = Header::deserialize_inner(&mut r)?;
let accel = Accel::deserialize_inner(&mut r)?;
Ok(Self { header, accel })
}
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Inertia {
pub m: f64,
pub com: Vector3,
pub ixx: f64,
pub ixy: f64,
pub ixz: f64,
pub iyy: f64,
pub iyz: f64,
pub izz: f64,
}
impl DdsType for Inertia {
const TYPE_NAME: &'static str = "geometry_msgs::msg::dds_::Inertia_";
fn serialize(&self, buf: &mut [u8]) -> Result<usize, DdsApiError> {
let mut w = make_writer(buf)?;
w.align_to(8)?;
w.write_f64(self.m)?;
self.com.serialize_inner(&mut w)?;
w.write_f64(self.ixx)?;
w.write_f64(self.ixy)?;
w.write_f64(self.ixz)?;
w.write_f64(self.iyy)?;
w.write_f64(self.iyz)?;
w.write_f64(self.izz)?;
Ok(4 + w.position())
}
fn deserialize(payload: &[u8]) -> Result<Self, DdsApiError> {
let mut r = make_cursor(payload)?;
r.align_to(8)?;
let m = r.read_f64()?;
let com = Vector3::deserialize_inner(&mut r)?;
let ixx = r.read_f64()?;
let ixy = r.read_f64()?;
let ixz = r.read_f64()?;
let iyy = r.read_f64()?;
let iyz = r.read_f64()?;
let izz = r.read_f64()?;
Ok(Self {
m,
com,
ixx,
ixy,
ixz,
iyy,
iyz,
izz,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::protocol::dds::ros2::msgs::builtin_interfaces::Time;
#[test]
fn vector3_round_trip() {
let original = Vector3 {
x: 1.0,
y: 2.0,
z: 3.0,
};
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
let decoded = Vector3::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn vector3_type_name() {
assert_eq!(Vector3::TYPE_NAME, "geometry_msgs::msg::dds_::Vector3_");
}
#[test]
fn point_round_trip() {
let original = Point {
x: -1.5,
y: 2.5,
z: 0.0,
};
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
let decoded = Point::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn point_type_name() {
assert_eq!(Point::TYPE_NAME, "geometry_msgs::msg::dds_::Point_");
}
#[test]
fn quaternion_round_trip() {
let original = Quaternion {
x: 0.0,
y: 0.0,
z: 0.707,
w: 0.707,
};
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
let decoded = Quaternion::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn quaternion_type_name() {
assert_eq!(
Quaternion::TYPE_NAME,
"geometry_msgs::msg::dds_::Quaternion_"
);
}
#[test]
fn pose_round_trip() {
let original = Pose {
position: Point {
x: 1.0,
y: 2.0,
z: 3.0,
},
orientation: Quaternion {
x: 0.0,
y: 0.0,
z: 0.0,
w: 1.0,
},
};
let mut buf = [0u8; 128];
let written = original.serialize(&mut buf).unwrap();
let decoded = Pose::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn pose_type_name() {
assert_eq!(Pose::TYPE_NAME, "geometry_msgs::msg::dds_::Pose_");
}
#[test]
fn pose_stamped_round_trip() {
let mut frame_id = heapless::String::<256>::new();
frame_id.push_str("base_link").unwrap();
let original = PoseStamped {
header: Header {
stamp: Time { sec: 1, nanosec: 0 },
frame_id,
},
pose: Pose::default(),
};
let mut buf = [0u8; 256];
let written = original.serialize(&mut buf).unwrap();
let decoded = PoseStamped::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn pose_stamped_type_name() {
assert_eq!(
PoseStamped::TYPE_NAME,
"geometry_msgs::msg::dds_::PoseStamped_"
);
}
#[test]
fn twist_round_trip() {
let original = Twist {
linear: Vector3 {
x: 1.0,
y: 0.0,
z: 0.0,
},
angular: Vector3 {
x: 0.0,
y: 0.0,
z: 1.0,
},
};
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
let decoded = Twist::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn twist_type_name() {
assert_eq!(Twist::TYPE_NAME, "geometry_msgs::msg::dds_::Twist_");
}
#[test]
fn twist_byte_layout() {
let original = Twist {
linear: Vector3 {
x: 1.0,
y: 0.0,
z: 0.0,
},
angular: Vector3 {
x: 0.0,
y: 0.0,
z: 1.0,
},
};
let mut buf = [0u8; 64];
let written = original.serialize(&mut buf).unwrap();
assert_eq!(written, 52); assert_eq!(&buf[0..4], &[0x00, 0x01, 0x00, 0x00]);
let one_f64 = 1.0_f64.to_bits().to_le_bytes();
assert_eq!(&buf[4..12], &one_f64);
}
#[test]
fn twist_stamped_round_trip() {
let mut frame_id = heapless::String::<256>::new();
frame_id.push_str("odom").unwrap();
let original = TwistStamped {
header: Header {
stamp: Time {
sec: 10,
nanosec: 0,
},
frame_id,
},
twist: Twist::default(),
};
let mut buf = [0u8; 256];
let written = original.serialize(&mut buf).unwrap();
let decoded = TwistStamped::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn twist_stamped_type_name() {
assert_eq!(
TwistStamped::TYPE_NAME,
"geometry_msgs::msg::dds_::TwistStamped_"
);
}
#[test]
fn transform_round_trip() {
let original = Transform {
translation: Vector3 {
x: 1.0,
y: 2.0,
z: 3.0,
},
rotation: Quaternion {
x: 0.0,
y: 0.0,
z: 0.0,
w: 1.0,
},
};
let mut buf = [0u8; 128];
let written = original.serialize(&mut buf).unwrap();
let decoded = Transform::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn transform_type_name() {
assert_eq!(Transform::TYPE_NAME, "geometry_msgs::msg::dds_::Transform_");
}
#[test]
fn transform_stamped_round_trip() {
let mut frame_id = heapless::String::<256>::new();
frame_id.push_str("world").unwrap();
let mut child = heapless::String::<256>::new();
child.push_str("robot_base").unwrap();
let original = TransformStamped {
header: Header {
stamp: Time { sec: 5, nanosec: 0 },
frame_id,
},
child_frame_id: child,
transform: Transform::default(),
};
let mut buf = [0u8; 512];
let written = original.serialize(&mut buf).unwrap();
let decoded = TransformStamped::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn transform_stamped_type_name() {
assert_eq!(
TransformStamped::TYPE_NAME,
"geometry_msgs::msg::dds_::TransformStamped_"
);
}
#[test]
fn wrench_round_trip() {
let original = Wrench {
force: Vector3 {
x: 10.0,
y: 0.0,
z: -5.0,
},
torque: Vector3 {
x: 0.0,
y: 2.0,
z: 0.0,
},
};
let mut buf = [0u8; 128];
let written = original.serialize(&mut buf).unwrap();
let decoded = Wrench::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn wrench_type_name() {
assert_eq!(Wrench::TYPE_NAME, "geometry_msgs::msg::dds_::Wrench_");
}
#[test]
fn wrench_stamped_round_trip() {
let mut frame_id = heapless::String::<256>::new();
frame_id.push_str("tool0").unwrap();
let original = WrenchStamped {
header: Header {
stamp: Time { sec: 0, nanosec: 0 },
frame_id,
},
wrench: Wrench::default(),
};
let mut buf = [0u8; 256];
let written = original.serialize(&mut buf).unwrap();
let decoded = WrenchStamped::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn wrench_stamped_type_name() {
assert_eq!(
WrenchStamped::TYPE_NAME,
"geometry_msgs::msg::dds_::WrenchStamped_"
);
}
#[test]
fn accel_round_trip() {
let original = Accel {
linear: Vector3 {
x: 9.81,
y: 0.0,
z: 0.0,
},
angular: Vector3 {
x: 0.0,
y: 0.0,
z: 0.1,
},
};
let mut buf = [0u8; 128];
let written = original.serialize(&mut buf).unwrap();
let decoded = Accel::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn accel_type_name() {
assert_eq!(Accel::TYPE_NAME, "geometry_msgs::msg::dds_::Accel_");
}
#[test]
fn accel_stamped_round_trip() {
let mut frame_id = heapless::String::<256>::new();
frame_id.push_str("imu_link").unwrap();
let original = AccelStamped {
header: Header {
stamp: Time {
sec: 0,
nanosec: 500_000_000,
},
frame_id,
},
accel: Accel::default(),
};
let mut buf = [0u8; 256];
let written = original.serialize(&mut buf).unwrap();
let decoded = AccelStamped::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn accel_stamped_type_name() {
assert_eq!(
AccelStamped::TYPE_NAME,
"geometry_msgs::msg::dds_::AccelStamped_"
);
}
#[test]
fn inertia_round_trip() {
let original = Inertia {
m: 1.5,
com: Vector3 {
x: 0.0,
y: 0.0,
z: 0.1,
},
ixx: 0.01,
ixy: 0.0,
ixz: 0.0,
iyy: 0.01,
iyz: 0.0,
izz: 0.02,
};
let mut buf = [0u8; 256];
let written = original.serialize(&mut buf).unwrap();
let decoded = Inertia::deserialize(&buf[..written]).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn inertia_type_name() {
assert_eq!(Inertia::TYPE_NAME, "geometry_msgs::msg::dds_::Inertia_");
}
}