ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Dynamically get topic type for rosbag

asked 2022-07-05 06:04:47 -0600

cookieClicker gravatar image

updated 2022-07-15 11:28:50 -0600

Hello,

I want to create a service, which records multiple different topics into a rosbag-file. The problem is, that I need the data type of the topic that is going to be recorded to subscribe to the topic. I start the service with the command line

rosservice call /start_data_recorder "topics: ['scan','map','imu/data']

to collect the three topics.

    def on_start_recording(self, msg):

        # Initialize new Rosbag
        PATH = "../catkin_ws/src/robolab_base/data_recorder/recordings"
        self.bag = rosbag.Bag(f'{PATH}/Rec.bag', 'w') 

        for topic in msg.topics:

            # Initialize new datawriter class
            subscriber = DataWriter(topic, self.bag, self.shutdown_recording)

            # Collect topic data
            data_type = rostopic.get_topic_type("/" + topic, blocking = False)[0]

            Sub = self._ros_api.Subscriber(topic, ros_msg_type, subscriber.callback)
            self.subscribers.append(Sub)

        return StartDataRecordingResponse()

with my DataWriter class writing the data to the bag file and a service (StartDataRecording.srv)

However, I get an error message, when initialising the Subscriber Sub:

Error processing request: data_class [sensor_msgs/LaserScan] is not a class

I suppose that data_type is not a valid output, but I am not sure how to proceed from here to get each topic recorded with the rosbag.

Edit:

I fixed it, by using rostopic.get_topic_class() instead of rostopic.get_topic_type() which provided the type of data needed for the Subscriber.

edit retag flag offensive close merge delete

Comments

We don't know your (other) requirements, but perhaps osrf/nodelet_rosbag can already do this.

gvdhoorn gravatar image gvdhoorn  ( 2022-07-06 00:54:56 -0600 )edit

Since I have to integrate a given API, I hoped there would be a direct way to read the topic type.

cookieClicker gravatar image cookieClicker  ( 2022-07-07 02:12:59 -0600 )edit

2 Answers

Sort by ยป oldest newest most voted
1

answered 2022-07-06 21:59:51 -0600

lindzey gravatar image

updated 2022-07-07 05:41:37 -0600

I've done something similar via:

import importlib

def get_type(msg_type_str):
    pkg, tt = msg_type_str.split('/')
    msg_module = importlib.import_module(pkg + ".msg")
    msg_type = getattr(msg_module, tt)
    return msg_type

msg_type = get_type('sensor_msgs/LaserScan')
msg = msg_type()

Edit:

Since you don't include the definition of self._ros_api, I'm not sure what's going wrong for you, but the following works for me:

import rospy
rospy.init_node('ipython')

def callback(msg):
    print("got msg!", msg)

msg_type = get_type('std_msgs/Float32')               

sub = rospy.Subscriber("sub_test", msg_type, callback)

I tested it by publishing from the command line: rostopic pub /sub_test std_msgs/Float32 "data: 2.0"

edit flag offensive delete link more

Comments

Thanks so far, I've tried your approach and got the header (seq, stamp, angle_min, ...) from the class returned back. Which is unfortunately not the data type I was looking for. My problem rather is how to make the Subscriber recognize data_type as the data type of the topic. At the moment Argument of type "Unknown | None" cannot be assigned to the type "Type[T@Subscriber]".

cookieClicker gravatar image cookieClicker  ( 2022-07-07 01:07:21 -0600 )edit

It would be easier to help you if you included a minimum failing example + the full output ... otherwise we're just guessing as to what you've tried.

lindzey gravatar image lindzey  ( 2022-07-07 05:42:49 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2022-07-05 06:04:47 -0600

Seen: 265 times

Last updated: Jul 15 '22