将本机 DDS 系统与 ROS2 连接
Interfacing a native DDS system with ROS2
要与基于 ROS2 的发布者和基于 RTI Connext 的订阅者通信,它们都需要具有兼容的 QoS 设置。
我正在为 python 使用 RTI 连接器,并为 运行 订阅者使用 XML 应用程序创建。
我在 ROS2 中 运行 一个 talker_py
具有 default QoS 并在 RTI Connext Pro 中订阅这些消息。
ROS2 IDL 如下所示:
{
module msg
{
module dds_ {
struct String_ {
String data_;
};
};
};
};
我使用 rtiddsgen
实用工具将其转换为 XML 文件。这是转换后的 XML :
<?xml version="1.0" encoding="UTF-8"?>
<types xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/path/to/RTIInstall/rti_connext_dds-5.3.1/bin/../resource/app/app_support/rtiddsgen/schema/rti_dds_topic_types.xsd">
<module name="std_msgs">
<module name="msg">
<module name="dds_">
<struct name="String_">
<member name="data_" type="string"/>
</struct>
</module>
</module>
</module>
</types>
我将 <types>
添加到我的 USER_QoS.xml
中,看起来像 :
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/5.1.0/rti_dds_profiles.xsd" version="5.1.0">
<!-- Qos Library -->
<qos_library name="QosLibrary">
<qos_profile name="DefaultProfile" is_default_qos="true">
<datawriter_qos>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>1000</depth>
</history>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
</reliability>
<durablitiy>
<kind>VOLATILE_DURABILITY_QOS</kind>
</durablitiy>
</datawriter_qos>
<participant_qos>
<transport_builtin>
<mask>UDPV4 | SHMEM</mask>
</transport_builtin>
<!-- Turn on monitoring -->
<!-- Begin Monitoring
<property>
<value>
<element>
<name>rti.monitor.library</name>
<value>rtimonitoring</value>
</element>
<element>
<name>rti.monitor.create_function_ptr</name>
<value>$(NDDS_MONITOR)</value>
</element>
</value>
</property>
End Monitoring -->
</participant_qos>
</qos_profile>
</qos_library>
<!-- types -->
<types>
<module name="std_msgs">
<module name="msg">
<module name="dds_">
<struct name="String_" extensibility="extensible">
<member name="data_" type="std_msgs::msg::dds_::string" "/>
</struct>
</module>
</module>
</module>
</types>
<!-- Domain Library -->
<domain_library name="MyDomainLibrary">
<domain name="MyDomain" domain_id="0">
<register_type name="std_msgs::msg::dds_::String_" type_ref="std_msgs::msg::dds_::String_" />
<topic name="chatter" register_type_ref="std_msgs::msg::dds_::String_"/>
</domain>
</domain_library>
<!-- Participant library -->
<domain_participant_library name="MyParticipantLibrary">
<domain_participant name="Zero" domain_ref="MyDomainLibrary::MyDomain">
<subscriber name="MySubscriber">
<data_reader name="MyChatterReader" topic_ref="chatter" />
</subscriber>
</domain_participant>
</domain_participant_library>
</dds>
现在,当我为 python 使用 RTI 连接器时,这里的第一步是尝试加载 USER_QoS.xml
文件,但它总是给出错误 Unable to parse the .xml file
。我强烈认为这是因为 <types>
定义中存在关键字 module
。
这是 RTI 连接器的 python 脚本:
from __future__ import print_function
from sys import path as sysPath
from os import path as osPath
from time import sleep
filepath = osPath.dirname(osPath.realpath(__file__))
sysPath.append(filepath + "/../../../")
import rticonnextdds_connector as rti
connector = rti.Connector("MyParticipantLibrary::Zero",
filepath + "/../User_QoS.xml")
inputDDS = connector.getInput("MySubscriber::MyChatterReader")
for i in range(1, 500):
inputDDS.take()
numOfSamples = inputDDS.samples.getLength()
for j in range(1, numOfSamples+1):
if inputDDS.infos.isValid(j):
# This gives you a dictionary
sample = inputDDS.samples.getDictionary(j)
x = sample['x']
# Or you can just access the field directly
toPrint = "Received x: " + repr(x)
print(toPrint)
sleep(2)
我觉得连接器无法解析这个 module
关键字。难道是这样吗?
当我尝试您的设置时,连接器提供的输出比您指定的要多。其中:
RTIXMLParser_validateOnStartTag:Parse error at line 15: Unexpected tag 'durablitiy'
这是您 XML 中的一个错误,根据其架构,标签名称应为 durability
。
那么您似乎在将生成的 <types>
标签及其内容复制到您的 XML 时出现了复制粘贴错误。为此,连接器给出以下错误:
RTIXMLParser_parseFromFile_ex:Parse error at line 50: not well-formed (invalid token)
确实,您的第 50 行末尾有多余的引号:
<member name="data_" type="std_msgs::msg::dds_::string" "/>
此外,type
属性的值与您尝试在此处插入的生成的 XML 不同,后者具有:
<member name="data_" type="string"/>
更正这些错误后,连接器会正确实例化。
要根据架构验证您的 XML 文件,您 can/should 使用 the associated XSD schema definition.
要与基于 ROS2 的发布者和基于 RTI Connext 的订阅者通信,它们都需要具有兼容的 QoS 设置。
我正在为 python 使用 RTI 连接器,并为 运行 订阅者使用 XML 应用程序创建。
我在 ROS2 中 运行 一个 talker_py
具有 default QoS 并在 RTI Connext Pro 中订阅这些消息。
ROS2 IDL 如下所示:
{
module msg
{
module dds_ {
struct String_ {
String data_;
};
};
};
};
我使用 rtiddsgen
实用工具将其转换为 XML 文件。这是转换后的 XML :
<?xml version="1.0" encoding="UTF-8"?>
<types xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/path/to/RTIInstall/rti_connext_dds-5.3.1/bin/../resource/app/app_support/rtiddsgen/schema/rti_dds_topic_types.xsd">
<module name="std_msgs">
<module name="msg">
<module name="dds_">
<struct name="String_">
<member name="data_" type="string"/>
</struct>
</module>
</module>
</module>
</types>
我将 <types>
添加到我的 USER_QoS.xml
中,看起来像 :
<dds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://community.rti.com/schema/5.1.0/rti_dds_profiles.xsd" version="5.1.0">
<!-- Qos Library -->
<qos_library name="QosLibrary">
<qos_profile name="DefaultProfile" is_default_qos="true">
<datawriter_qos>
<history>
<kind>KEEP_LAST_HISTORY_QOS</kind>
<depth>1000</depth>
</history>
<reliability>
<kind>RELIABLE_RELIABILITY_QOS</kind>
</reliability>
<durablitiy>
<kind>VOLATILE_DURABILITY_QOS</kind>
</durablitiy>
</datawriter_qos>
<participant_qos>
<transport_builtin>
<mask>UDPV4 | SHMEM</mask>
</transport_builtin>
<!-- Turn on monitoring -->
<!-- Begin Monitoring
<property>
<value>
<element>
<name>rti.monitor.library</name>
<value>rtimonitoring</value>
</element>
<element>
<name>rti.monitor.create_function_ptr</name>
<value>$(NDDS_MONITOR)</value>
</element>
</value>
</property>
End Monitoring -->
</participant_qos>
</qos_profile>
</qos_library>
<!-- types -->
<types>
<module name="std_msgs">
<module name="msg">
<module name="dds_">
<struct name="String_" extensibility="extensible">
<member name="data_" type="std_msgs::msg::dds_::string" "/>
</struct>
</module>
</module>
</module>
</types>
<!-- Domain Library -->
<domain_library name="MyDomainLibrary">
<domain name="MyDomain" domain_id="0">
<register_type name="std_msgs::msg::dds_::String_" type_ref="std_msgs::msg::dds_::String_" />
<topic name="chatter" register_type_ref="std_msgs::msg::dds_::String_"/>
</domain>
</domain_library>
<!-- Participant library -->
<domain_participant_library name="MyParticipantLibrary">
<domain_participant name="Zero" domain_ref="MyDomainLibrary::MyDomain">
<subscriber name="MySubscriber">
<data_reader name="MyChatterReader" topic_ref="chatter" />
</subscriber>
</domain_participant>
</domain_participant_library>
</dds>
现在,当我为 python 使用 RTI 连接器时,这里的第一步是尝试加载 USER_QoS.xml
文件,但它总是给出错误 Unable to parse the .xml file
。我强烈认为这是因为 <types>
定义中存在关键字 module
。
这是 RTI 连接器的 python 脚本:
from __future__ import print_function
from sys import path as sysPath
from os import path as osPath
from time import sleep
filepath = osPath.dirname(osPath.realpath(__file__))
sysPath.append(filepath + "/../../../")
import rticonnextdds_connector as rti
connector = rti.Connector("MyParticipantLibrary::Zero",
filepath + "/../User_QoS.xml")
inputDDS = connector.getInput("MySubscriber::MyChatterReader")
for i in range(1, 500):
inputDDS.take()
numOfSamples = inputDDS.samples.getLength()
for j in range(1, numOfSamples+1):
if inputDDS.infos.isValid(j):
# This gives you a dictionary
sample = inputDDS.samples.getDictionary(j)
x = sample['x']
# Or you can just access the field directly
toPrint = "Received x: " + repr(x)
print(toPrint)
sleep(2)
我觉得连接器无法解析这个 module
关键字。难道是这样吗?
当我尝试您的设置时,连接器提供的输出比您指定的要多。其中:
RTIXMLParser_validateOnStartTag:Parse error at line 15: Unexpected tag 'durablitiy'
这是您 XML 中的一个错误,根据其架构,标签名称应为 durability
。
那么您似乎在将生成的 <types>
标签及其内容复制到您的 XML 时出现了复制粘贴错误。为此,连接器给出以下错误:
RTIXMLParser_parseFromFile_ex:Parse error at line 50: not well-formed (invalid token)
确实,您的第 50 行末尾有多余的引号:
<member name="data_" type="std_msgs::msg::dds_::string" "/>
此外,type
属性的值与您尝试在此处插入的生成的 XML 不同,后者具有:
<member name="data_" type="string"/>
更正这些错误后,连接器会正确实例化。
要根据架构验证您的 XML 文件,您 can/should 使用 the associated XSD schema definition.