【DDS中间件】

【DDS中间件】

DDS-Data Distribution Service 数据分发服务

切换DDS

Fast DDS

$ sudo apt install ros-$ROS_DISTRO-rmw-fastrtps-cpp
$ export RMW_IMPLEMENTATION=rmw_fastrtps_cpp

Cyclone DDS

$ sudo apt install ros-$ROS_DISTRO-rmw-cyclonedds-cpp
$ export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

配置局域网通信

域ID

※所有ROS2节点默认使用域ID0
※域ID具有隔离性

//设置域ID
export ROS_DOMAIN_ID=1
//限制ROS2只进行本机通信
export ROS_LOCALHOST_ONLY=1

image
image

调整DDS配置

ROS2通过中间件抽象层来兼容不同厂家的DDS
->直接配置DDS

示例

【限制该话题订阅者数量为1】
【topic_sub_limit.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http:://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">

    <!-- 默认发布者配置 -->
    <publisher profile_name="default_publisher" is_default_profile="true">
        <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
    </publisher>

    <!-- 默认订阅者配置 -->
    <subscriber profile_name="default_subscriber" is_default_profile="true">
        <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
    </subscriber>

    <!-- 话题chatter的发布者配置 -->
    <publisher profile_name="/chatter">
        <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
        <matchedSubscribersAllocation>
            <initial>0</initial>
            <maximum>1</maximum>
            <increment>1</increment>
        </matchedSubscribersAllocation>
    </publisher>
</profiles>
//使用环境变量指定配置文件
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
export RMW_FASTRTPS_USE_QOS_FROM_XML=1
export FASTRTPS_DEFAULT_PROFILES_FILE=./topic_sub_limit.xml
ros2 run demo_nodes_cpp talker

使用DDS共享内存

对于不在同一进程,但在同一主机的节点->通过共享内存的方式实现零复制通信
->需要额外通信接口
※注意:ROS2共享内存通信仅支持普通旧数据类型->常用不定长字符串类型std_msgs/msg/String无法使用
image

#include"rclcpp/loaned_message.hpp"
#include"rclcpp/rclcpp.hpp"
#include"std_msgs/msg/int32.hpp"

class LoanedMessagePublisher : public rclcpp::Node{
    public:
        LoanedMessagePublisher() : Node("loaned_messagw_publisher"){
            publisher_=this->create_publisher<std_msgs::msg::Int32>("loaned_int_topic",10);
            timer_=this->create_wall_timer(std::chrono::seconds(1),[&](){
                auto message=publisher_->borrow_loaned_message();//1.租借消息
                message.get().data=count_++;//2.放入数据
                RCLCPP_INFO(this->get_logger(),"发布数据:%d",message.get().data);
                publisher_->publish(std::move(message));//发布数据
            });
        }
    
    private:
        rclcpp::Publisher<std_msgs::msg::Int32>::SharedPtr publisher_;
        rclcpp::TimerBase::SharedPtr timer_;
        int32_t count_{0};
};
int main(int argc,char** argv){
    rclcpp::init(argc,argv);
    auto node=std::make_shared<LoanedMessagePublisher>();
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

image
【额外配置】

shm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http:://www.eprosima.com/XMLSchemas/fastRTPS_Profiles">

    <data_writer profile_name="default publisher profile" is_default_profile="true">
        <qos>
            <publishMode>
                <kind>SYNCHRONOUS</kind>
            </publishMode>
            <data_sharing>
                <kind>AUTOMATIC</kind>
            </data_sharing>
			 ->数据读取器的服务质量都设置为数据共享
        </qos>
        <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
    </data_writer>

    <data_reader profile_name="default subscription profile" is_default_profile="true">
        <qos>
            <data_sharing>
                <kind>AUTOMATIC</kind>
            </data_sharing>
        </qos>
        <historyMemoryPolicy>DYNAMIC</historyMemoryPolicy>
    </data_reader>
</profiles>
source install/setup.bash
RMW_IMPLEMENTATION=rmw_fastrtps_cpp
FASTRTPS_DEFAULT_PROFILES_FILE=./shm.xml
RMW_FASTRTPS_USE_QOS_FROM_XML=1
ros2 run learn_dds_cpp shm_pub

//禁用借用消息
ROS_DISABLE_LOANED_MESSAGES=1

image

posted @ 2025-01-09 20:10  White_ink  阅读(574)  评论(0)    收藏  举报