运行时获取ROS消息类型实现通用订阅回调的技术问题
问题原因
你通过rosparam获取到的topic_type是字符串类型,而rospy.Subscriber的第二个参数要求传入实际的消息类对象,不能直接传入字符串,这是订阅器无法正常运行的核心原因。
解决方法
你需要对字符串格式的话题类型做动态导入,转换为ROS可识别的消息类,修改后的可运行代码如下:
import rospy import importlib def generic_cb(data): # 若需适配更多无data字段的消息类型,可在此处添加类型判断逻辑 print(data.data) if __name__ == '__main__': rospy.init_node('generic_node') # 读取参数,设置默认值避免参数缺失报错 topic_name = rospy.get_param('topic_name', '/chatter') topic_type_str = rospy.get_param('topic_type', 'std_msgs/String') # 动态导入对应消息类 try: pkg_name, msg_name = topic_type_str.split('/') msg_module = importlib.import_module(f"{pkg_name}.msg") topic_type = getattr(msg_module, msg_name) except ValueError: rospy.logerr(f"话题类型格式错误,要求格式为「包名/消息名」,当前输入为{topic_type_str}") exit(1) except ImportError: rospy.logerr(f"无法导入消息包{pkg_name},请检查对应包是否已正确编译安装") exit(1) except AttributeError: rospy.logerr(f"消息包{pkg_name}中不存在名为{msg_name}的消息类型") exit(1) rospy.Subscriber(topic_name, topic_type, generic_cb) rospy.loginfo(f"已成功订阅话题:{topic_name},消息类型:{topic_type_str}") rospy.spin()
参数配置示例
你可以通过launch文件或者命令行设置对应参数:
- launch文件配置示例:
<node name="generic_node" pkg="你的功能包名" type="上述脚本的文件名.py"> <param name="topic_name" value="/chatter" /> <param name="topic_type" value="std_msgs/String" /> </node>
- 命令行参数设置示例:
rosparam set /generic_node/topic_name /chatter rosparam set /generic_node/topic_type std_msgs/String
内容的提问来源于stack exchange,提问作者BTables
相关产品推荐
相关产品推荐

