eProsima / Micro-XRCE-DDS-Agent

Micro XRCE-DDS Agent respository. Looking for commercial support? Contact info@eprosima.com
Apache License 2.0
113 stars 81 forks source link

Fast-DDS-Gen SensorCombined.idl subscriber does not find MicroXRCEAgent topics #353

Closed cafrank closed 1 year ago

cafrank commented 1 year ago

How do I view MicroXRCEAgent DDS messages from a Fast-DDS-Gan app? I did:

MicroXRCEAgent serial -D /dev/ttyS0 -b 1500000
Works with ros2 topic list, and ros2 topic echo /fmu/out/sensor_combined. Created SensorCombined.idl from px4_msgs.git, and used Fast-DDS-Gan to create a subscriber.

$ git clone –recursive https://github.com/eProsima/Fast-DDS-Gen.git $ cd Fast-DDS-Gen $ gradlew build $ git clone https://github.com/PX4/px4_msgs.git $ mkdir px4_msgs/build && cd px4_msgs/build $ cmake .. $ make -j 20 Using: rosidl_adapter/px4_msgs/msg/SensorCombined.idl $ ~/git/Fast-DDS-Gen/scripts/fastddsgen -example CMake SensorCombined.idl I even changed the topic in SensorCombinedSubscriber.cxx

//CREATE THE TOPIC
topic_ = participant_->create_topic(
    // "SensorCombinedTopic",
    "/fmu/out/sensor_combined",
    type_.get_type_name(),
    TOPIC_QOS_DEFAULT);

Result: pi@pi02w1:~/foo/build $ ./SensorCombined subscriber Starting Waiting for Data, press Enter to stop the DataReader.

pablogs9 commented 1 year ago

In ROS 2 (are you publishing to ROS 2?) topic names are prefixed with rt/ and types are mangled. So you will need to subscribe to rt/SensorCombinedTopic with type px4_msgs::msg::dds_::SensorCombined_.

cafrank commented 1 year ago

I have two systems, each of which chats with a PX4 via: MicroXRCEAgent serial -D /dev/ttyS0 -b 1500000 System1: ros2 works with: ros2 topic echo /fmu/out/sensor_combined System 2: No ros. fastddsgen -example CMake SensorCombined.idl

pablogs9 commented 1 year ago

Does it work if you create the system 2 subscriber with the names that I mentioned?

cafrank commented 1 year ago

Now subscribed to: rt/SensorCombinedTopic Where is the type set? String in the IDL? px4msgs::msg::dds::SensorCombined_. Checking...

pablogs9 commented 1 year ago
topic_ = participant_->create_topic(
    // "SensorCombinedTopic",
    "/fmu/out/sensor_combined",
    type_.get_type_name(), <------ HERE
    TOPIC_QOS_DEFAULT);
cafrank commented 1 year ago
topic_ = participant_->create_topic(
    "rt/SensorCombinedTopic",
    "px4_msgs::msg::dds_::SensorCombined_",
    TOPIC_QOS_DEFAULT);

Starting 2023-11-08 07:05:57.559 [PARTICIPANT Error] Type : px4msgs::msg::dds::SensorCombined_ Not Registered -> Function create_topic

pablogs9 commented 1 year ago

@EduPonz will give some tips

cafrank commented 1 year ago

I switched to the Fast DDS Subscriber docs: https://fast-dds.docs.eprosima.com/en/latest/fastdds/getting_started/getting_started.html, but the mangled topic names and ::dds:: failed with [PARTICIPANT Error] Type : ...SensorCombined_ Not Registered I did get create_topic to succeed with px4_msgs::msg::SensorCombined, but it still receives no messages. Looking for the right topic name now. ros2 has a list topic command. Is there a comparable c++ function?

cafrank commented 1 year ago
  1. I confirmed (via sniffer) that the RTPS packets from " ros2 topic echo /fmu/out/sensor_combined" have the topic: "rt/fmu/out/sensor_combined"

  2. While running with create_topic("rt/fmu/out/sensor_combined", "px4_msgs::msg::SensorCombined", ... it caused the ros2 echo command to fail with: $ ros2 topic echo /fmu/out/sensor_combined Cannot echo topic '/fmu/out/sensor_combined', as it contains more than one type: [px4_msgs/msg/SensorCombined, px4_msgs::msg::SensorCombined]

  3. So how about: create_topic("rt/fmu/out/sensor_combined", "px4_msgs/msg/SensorCombined" Nope. That failed with: [PARTICIPANT Error] Type : px4_msgs/msg/SensorCombined, Not Registered -> Function create_topic

cafrank commented 1 year ago

Solved: It turns out that @pablogs9 had the right idea all along. In the end, we needed the following combination: create_topic( "rt/fmu/out/sensor_combined", "px4msgs::msg::dds::SensorCombined_", TOPIC_QOS_DEFAULT);

The piece I missed was that the type "px4msgs::msg::dds::SensorCombined" had to be registered before creating the topic. The type was originally registered by the participant with the generated name "px4_msgs::msg::SensorCombined".

Solution:

  1. In the HelloWorldPubSubType() constructor, set the correct type name setName("px4msgs::msg::dds::SensorCombined_");
  2. Pass type_.get_type_name() to create_topic create_topic("rt/fmu/out/sensorcombined", type.get_type_name(), TOPIC_QOS_DEFAULT);

This also works alongside ros2 topic echo /fmu/out/sensor_combined

EduPonz commented 1 year ago

Hi @cafrank, I'm glad you could overcome your problem. One other way of getting the right typename is to pass the flag -typeros2 to Fast DDS Gen, and then get the typename from the type support with the get_type_name() API. In Vulcanexus, we have a tutorial to intercommunicate ROS 2 and Fast DDS applications (exactly what you're trying to accomplish) that might come in handy: Fast DDS - Vulcanexus Topic Intercommunication. This tutorial not only covers the topic name mangling, but also some other considerations necessary when writing and IDL for intercommunication with ROS 2 .msg types.