Skip to content

bug: Topic mismatch error when writing from Cyclone to Zero #42

Description

@adriano-tumino

When I try to publish the Robot struct from Cyclone to ZeroDDS, I get a topic mismatch error (displayed by Cyclone Insight) and Zero receives nothing. Additionally, I can see the data correctly via Insight.

#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_entity(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 reader_qos = DataReaderQos {
        reliability: ReliabilityQosPolicy {
            kind: ReliabilityKind::Reliable,
            max_blocking_time: Duration::from_secs(1),
        },
        ..Default::default()
    };

    let subscriber = participant.create_subscriber(SubscriberQos::default());
    let reader = subscriber
        .create_datareader::<Robot>(&entity_topic, reader_qos)
        .expect("create reader");

    println!("Waiting Match");
    reader
        .wait_for_matched_publication(1, std::time::Duration::from_secs(15))
        .unwrap();

    let mut count: u64 = 0;
    println!("Starting Receiver!");
    loop {
        match reader.take() {
            Ok(samples) => {
                for item in samples {
                    println!("Read #{count}: {:?}", item);
                    count += 1;
                }
            }

            Err(err) => {
                println!("error: {}", err)
            }
        }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let factory = DomainParticipantFactory::instance();

    let participant = factory
        .create_participant(100, DomainParticipantQos::default())
        .unwrap();

    test_entity(&participant);

    Ok(())
}
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");
}
Image Image

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