I am trying to get values from .yaml file for subscription and writing bag file in ROS. But i encounter with this error and i couldn't solve it. I guess I can't define my values as a class name in code.
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
import rospy
import rosbag
from geometry_msgs.msg import Twist
filename='test.bag'
bag = rosbag.Bag(filename, 'w')
sensor_info=rospy.get_param("/bag/sensor_info")
move_datatype=sensor_info[1]['datatype'] # Twist
move_topic=sensor_info[1]['topic_name'] # /cmd_vel
def move_callback(msg):
x=msg
def main():
global x
rospy.init_node('rosbag_save', anonymous=True)
rospy.Subscriber(move_topic,move_datatype(),move_callback)
while not rospy.is_shutdown():
bag.write(f'{move_topic}',x)
if __name__ == '__main__':
try:
main()
except rospy.ROSInterruptException:
pass
here is my code
bag:
sensor_info:
- {"topic_name": "/multi_scan", "datatype": "LaserScan"}
- {"topic_name": "/cmd_vel", "datatype": "Twist"}
and here is my .yaml file
You're getting this error because when you read the rosparam in from the server it will be stored as a string; which you can't pass to a subscriber. Instead you should convert it to the object type after reading it in. There are a couple of ways to do this, but using globals()
will probably be the easiest. Essentially this returns a dictionary of everything in the global symbol table and from there you can use a key(a string) to get a value(class type). This can be done such as:
sensor_info = rospy.get_param("/bag/sensor_info")
move_datatype_string = sensor_info[1]['datatype'] # Twist
move_topic = sensor_info[1]['topic_name'] # /cmd_vel
move_datatype = globals()[move_datatype_string]