Skip to content

bug: Deserialization error from Zero to Cyclone #41

Description

@adriano-tumino

When sending Robot struct via ZeroDDS, the topic matches, but Cyclone prints a deserialization error.

#pragma once

module common {
    module util {
        struct Location {
            double x;
            double y;
            double z;
        };

        struct Orientation {
            double x;
            double y;
            double z;
        };
    };

    struct Robot {
        ::common::util::Location location;
        ::common::util::Orientation orientation;
    };
};
//build.rs
fn main() {
    zerodds_build::Config::new()
        .out_dir("./src/generated")
        .flatten_shared_includes(false)
        .compile(&["./idl/Robot.idl"])
        .unwrap();
}
#[allow(clippy::all, clippy::pedantic, dead_code)]
mod generated {
    include!("generated/Robot.rs");
}

fn test_robot(participant: &DomainParticipant) {
    let qos = TopicQos {
        reliability: ReliabilityQosPolicy {
            kind: ReliabilityKind::Reliable,
            max_blocking_time: Duration::from_secs(1),
        },
        ..Default::default()
    };

    let entity_topic = participant
        .create_topic::<Robot>("entity.robot", qos)
        .expect("create_topic");

    let writer_qos = DataWriterQos {
        reliability: ReliabilityQosPolicy {
            kind: ReliabilityKind::Reliable,
            max_blocking_time: Duration::from_secs(1),
        },
        ..Default::default()
    };

    let publisher = participant.create_publisher(PublisherQos::default());
    let writer = publisher
        .create_datawriter::<Robot>(&entity_topic, writer_qos)
        .expect("writer construction");

    let mut counter: u64 = 0;
    while counter < 100 {
        let robot = Robot {
            location: Location {
                x: 10.0,
                y: 20.0,
                z: 30.0,
            },
            orientation: Orientation {
                x: 1.0,
                y: 2.0,
                z: 3.0,
            },
        };

        let result = writer.write(&robot);
        match result {
            Ok(()) => {
                counter += 1;
                println!("writed {}: {:?}", counter, robot);
            }
            Err(e) => println!("Error to write: {}", e),
        }

        std::thread::sleep(std::time::Duration::from_millis(500));
    }
}

fn main() {
    println!("Starting Test");
    let factory = DomainParticipantFactory::instance();

    let participant = factory
        .create_participant(100, DomainParticipantQos::default())
        .unwrap();
    test_robot(&participant);
    println!("End Test");
}
void robot_topic(std::uint8_t domain = DEFAULT_DOMAIN, ParticipantType type = WRITER) {
    auto participant = ::dds::domain::DomainParticipant(domain);

    auto topic = ::dds::topic::Topic<::common::Robot>(
        participant, "entity.robot",
        ::dds::topic::qos::TopicQos()
            << ::dds::core::policy::Reliability::Reliable(::dds::core::Duration(1, 0)));
    const std::uint8_t max_number_of_package = 100;
    switch (type) {
        case WRITER: {
            auto publisher =
                ::dds::pub::Publisher(participant, participant.default_publisher_qos());
            auto writer = ::dds::pub::DataWriter<::common::Robot>(publisher, topic,
                                                                  ::dds::pub::qos::DataWriterQos());
            std::jthread worker_thread([&]() {
                std::uint32_t num_packets = 0;

                while (num_packets < max_number_of_package) {
                    ::common::Robot data; /*
                     data.id(num_packets);
                     data.label("Robot"); */
                    data.location(::common::util::Location(10, 20, 30));
                    data.orientation(::common::util::Orientation(1, 2, 3));

                    writer.write(data);  // Write to DDS

                    num_packets++;
                    std::println("Written: X: {} | Y: '{}'", num_packets, data.location().x(),
                                 data.location().y());

                    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers,
                    // readability-magic-numbers)
                    std::this_thread::sleep_for(std::chrono::milliseconds(500));
                }
            });
        } break;
        case READER: {
            auto subscriber =
                ::dds::sub::Subscriber(participant, participant->default_subscriber_qos());
            auto reader = ::dds::sub::DataReader<::common::Robot>(subscriber, topic,
                                                                  ::dds::sub::qos::DataReaderQos());
            std::jthread worker_thread([&]() {
                std::uint32_t num_packets = 0;

                while (num_packets < max_number_of_package) {
                    auto samples = reader.take();
                    for (const auto& sample : samples) {
                        if (sample.info().valid()) {
                            num_packets++;
                            const auto& robot = sample.data();
                            std::println("Read: X: {} | Y: '{}'", robot.location().x(),
                                         robot.location().y());
                        }
                    }

                    std::this_thread::sleep_for(std::chrono::milliseconds(1));
                }
            });
        } break;
    }
}

int main() {
    std::println("Start Robot writer");
    robot_topic(DEFAULT_DOMAIN, READER);
    std::println("Close Test");
}
Cyclone Error: recv: data(application, vendor 1.240): 39902a68:9c5e0000:68e61a1b:103 #5: deserialization entity.robot/common::Robot failed (for reasons unknown)

I am using the version of Zero from the main branch. I am on Windows 11 and both programs are running on the same machine.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions