调用ROS服务时出现rospy.ServiceException提示rail_displacement属性只读是什么原因?
问题原因
核心触发原因
字段类型不匹配
waypoint.msg中rail_direction明确定义为bool类型,但你在add_move.py里给该字段赋值的是整数类型的direction_rail(测试用例里值为44)。该值存入数据库后,get_moves服务端读取返回时,ROS反序列化需要把整数值写入bool类型的字段,而ROS Python接口的消息实例属性默认是只读状态,直接抛出attribute is read-only的错误。
你单独运行get_data正常,是因为此时读取的是之前符合类型要求的旧数据,调用add_move存入不符合类型要求的新数据后,加载新数据才会触发报错。必填字段缺失
waypoint.msg中定义了int32 order字段,但你构造waypoint实例时完全没有给该字段赋值。如果你的get_moves服务端没有对该字段做默认值兼容,从数据库读取到空值后反序列化到int32类型字段时,也会触发类型错误。消息定义未同步编译
如果你曾经修改过waypoint.msg的字段顺序、类型,但是没有重新编译database_helper包,也没有重启所有相关服务节点,会导致服务端和客户端的消息定义不一致。反序列化时字节流会对应到错误的字段,进一步触发类型不匹配的只读属性错误。
修复方案
- 修正
add_move.py中的类型赋值逻辑,给rail_direction赋值前做类型转换,同时补充order字段赋值:
_waypoint.order = i # 按航点顺序赋值排序字段 _waypoint.rail_direction = bool(wp[i]['direction_rail']) # 转成bool类型再赋值
- 重新编译你的ROS工作空间,执行
catkin_make或catkin build,之后重启所有相关的服务节点、UI进程,确保所有节点使用的消息定义一致。 - 检查
get_moves服务端的实现,确认所有从数据库读取的字段值类型和waypoint.msg的定义完全匹配,避免出现float赋值给int、int赋值给bool的情况。
内容的提问来源于stack exchange,提问作者Emad Deve
相关产品推荐
相关产品推荐

