Fast-DDS: Binding a Fast RTPS publisher with a ROS 2 Dashing subscriber node fails

I am pushing https://github.com/ros2/rmw_fastrtps/issues/251 here, as I am not sure at this point if this is a problem on the ROS 2 node or a problem on the agent code.

System specifications:

  • OS: Ubuntu 18.04
  • Fast-RTPS version: 1.8.2
  • Fast-RTPS-Gen version: 1.0.2
  • ROS 2 version: Dashing
  • rmw_fastrtps version 0.7.6
  • Setup: px4_ros_com built from source. Launching micrortps_bridge -t UDP in a console and sensor_combined_listener in another.

Code snippets:

  • The agent publisher code:
/*!
 * @file SensorCombined_Publisher.cpp
 * This file contains the implementation of the publisher functions.
 *
 * This file was adapted from the fastcdrgen tool.
 */


#include <fastrtps/participant/Participant.h>
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/attributes/PublisherAttributes.h>

#include <fastrtps/Domain.h>


#include "SensorCombined_Publisher.h"


SensorCombined_Publisher::SensorCombined_Publisher() : mp_participant(nullptr), mp_publisher(nullptr) {}

SensorCombined_Publisher::~SensorCombined_Publisher() { Domain::removeParticipant(mp_participant);}

bool SensorCombined_Publisher::init()
{
    // Create RTPSParticipant
    ParticipantAttributes PParam;
    PParam.rtps.builtin.domainId = 0;
    PParam.rtps.builtin.leaseDuration = c_TimeInfinite;
    PParam.rtps.setName("SensorCombined_publisher");  //You can put here the name you want
    mp_participant = Domain::createParticipant(PParam);
    if(mp_participant == nullptr)
        return false;

    // Register the type
    Domain::registerType(mp_participant, static_cast<TopicDataType*>(&myType));

    // Create Publisher
    PublisherAttributes Wparam;
    Wparam.topic.topicKind = NO_KEY;
    Wparam.topic.topicDataType = myType.getName();  //This type MUST be registered
    Wparam.topic.topicName = "rt/SensorCombined_PubSubTopic";
    mp_publisher = Domain::createPublisher(mp_participant, Wparam, static_cast<PublisherListener*>(&m_listener));
    if(mp_publisher == nullptr)
        return false;
    //std::cout << "Publisher created, waiting for Subscribers." << std::endl;
    return true;
}

void SensorCombined_Publisher::PubListener::onPublicationMatched(Publisher* pub, MatchingInfo& info)
{
    if (info.status == MATCHED_MATCHING)
    {
        n_matched++;
        std::cout << "Publisher matched" << std::endl;
    }
    else
    {
        n_matched--;
        std::cout << "Publisher unmatched" << std::endl;
    }
}

void SensorCombined_Publisher::run()
{
    while(m_listener.n_matched == 0)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(250)); // Sleep 250 ms
    }

    // Publication code
    px4_msgs::msg::SensorCombined st;

    /* Initialize your structure here */

    int msgsent = 0;
    char ch = 'y';
    do
    {
        if(ch == 'y')
        {
            mp_publisher->write(&st);  ++msgsent;
            std::cout << "Sending sample, count=" << msgsent << ", send another sample?(y-yes,n-stop): ";
        }
        else if(ch == 'n')
        {
            std::cout << "Stopping execution " << std::endl;
            break;
        }
        else
        {
            std::cout << "Command " << ch << " not recognized, please enter \"y/n\":";
        }
    }while(std::cin >> ch);
}

    void SensorCombined_Publisher::publish(px4_msgs::msg::SensorCombined* st)
{
    mp_publisher->write(st);
}
  • The subscriber ROS 2 node:
/**
 * @brief Sensor Combined uORB topic listener example
 * @file sensor_combined_listener.cpp
 * @addtogroup examples
 * @author Nuno Marques <nuno.marques@dronesolutions.io>
 * @author Vicente Monge
 */

 #include <rclcpp/rclcpp.hpp>
 #include <px4_msgs/msg/sensor_combined.hpp>

/**
 * @brief Sensor Combined uORB topic data callback
 */
class SensorCombinedListener : public rclcpp::Node
{
public:
	explicit SensorCombinedListener() : Node("sensor_combined_listener") {
		subscription_ = this->create_subscription<px4_msgs::msg::SensorCombined>(
			"SensorCombined_PubSubTopic",
			[this](const px4_msgs::msg::SensorCombined::UniquePtr msg) {
			std::cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
			std::cout << "RECEIVED SENSOR COMBINED DATA"   << std::endl;
			std::cout << "============================="   << std::endl;
			std::cout << "ts: "          << msg->timestamp    << std::endl;
			std::cout << "gyro_rad[0]: " << msg->gyro_rad[0]  << std::endl;
			std::cout << "gyro_rad[1]: " << msg->gyro_rad[1]  << std::endl;
			std::cout << "gyro_rad[2]: " << msg->gyro_rad[2]  << std::endl;
			std::cout << "gyro_integral_dt: " << msg->gyro_integral_dt << std::endl;
			std::cout << "accelerometer_timestamp_relative: " << msg->accelerometer_timestamp_relative << std::endl;
			std::cout << "accelerometer_m_s2[0]: " << msg->accelerometer_m_s2[0] << std::endl;
			std::cout << "accelerometer_m_s2[1]: " << msg->accelerometer_m_s2[1] << std::endl;
			std::cout << "accelerometer_m_s2[2]: " << msg->accelerometer_m_s2[2] << std::endl;
			std::cout << "accelerometer_integral_dt: " << msg->accelerometer_integral_dt << std::endl;
		});
	}

private:
	rclcpp::Subscription<px4_msgs::msg::SensorCombined>::SharedPtr subscription_;
};

int main(int argc, char *argv[])
{
	std::cout << "Starting sensor_combined listener node..." << std::endl;
	setvbuf(stdout, NULL, _IONBF, BUFSIZ);
	rclcpp::init(argc, argv);
	rclcpp::spin(std::make_shared<SensorCombinedListener>());

	rclcpp::shutdown();
	return 0;
}

A WireShark record from localhost with both agent and ROS 2 node subscriber running: https://drive.google.com/open?id=1QTx6xjRQZ1Rh1F-sibek40AvvSsF3hw6.

@richiware @LuisGP @MiguelCompany any tips will help, as this is currently a development blocker. Thank you!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 32 (12 by maintainers)

Most upvoted comments

For everyone still having this issue, I added a fix to the FastRTPSGen tool that through an argument passed to the fastrrpsgen script (-typeros2), the type naming will be generated with the structure compatible with ROS2 topics. So now there is no need to change the naming manually after generating the code.

Hope this helps!

@ldg810 thank you! I should have found that source earlier.

The solution (even though not ideal) was added in https://github.com/PX4/Firmware/pull/13907. Thanks for the support. Closing.

@TSC21

@dirk-thomas I was able to change the Type name of the agent side. Though, weirdly enough, I get the following when trying to echo the topic:

$ ros2 topic echo /SensorCombined_PubSubTopic 
Cannot echo topic '/SensorCombined_PubSubTopic', as it contains more than one type: [px4_msgs/msg/SensorCombined, px4_msgs/msg/SensorCombined]

?? What’s happening here? As far as I can tell the types look exactly the same…

Did you found any solution of this problem?

I found a trick to solve the problem from here. My environment is Fast-RTPS master, ROS2 dashing, Ubuntu 18.04

I used px4_ros_com repository. After generate micrortps_agent source, you should modify Name of the topic. as follows. In case of SensorCombined Data, (in SensorCombinedPubSubTypes.cpp) setName("px4_msgs::msg::SensorCombined"); to setName("px4_msgs::msg::dds_::SensorCombined_");

Then, you can echo the topic!

root@ldg810-X299-WU8:/home/user/git/PX4_rtps/px4_ros_com_ros2# ros2 topic echo /SensorCombined_PubSubTopic
timestamp: 2681980000
gyro_rad: [-0.0014800801873207092, -0.0010418224846944213, -0.0023238887079060078]
gyro_integral_dt: 4000
accelerometer_timestamp_relative: 0
accelerometer_m_s2: [-0.3590507507324219, 0.21467521786689758, -9.883310317993164]
accelerometer_integral_dt: 4000
---
timestamp: 2681988000
gyro_rad: [0.0009716902859508991, -0.006787224672734737, -0.00034484994830563664]
gyro_integral_dt: 4000
accelerometer_timestamp_relative: 0
accelerometer_m_s2: [-0.18192364275455475, 0.13727518916130066, -9.877113342285156]
accelerometer_integral_dt: 4000