问题描述
要与基于 ROS2 的发布者和基于 RTI Connext 的订阅者进行通信,它们都需要具有兼容的 QoS 设置.
我正在使用 RTI Connector for python 并使用 XML Application Creation 来运行订阅者.
我在 ROS2 中运行一个 talker_py,它有一个 默认 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>
现在,当我使用 RTI Connector for python 时,这里的第一步是尝试加载 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关键字.会不会是这样?
推荐答案
当我尝试您的设置时,Connector 提供的输出比您所指示的要多.其中:
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"/>
纠正这些错误后,Connector 会正确实例化.
要根据其架构验证您的 XML 文件,您可以/应该使用 the关联的 XSD 架构定义.