Работа с файлами журнала rosbag

rosbag или сумка являются форматом файла в ROS для того, чтобы хранить данные о сообщении. Эти сумки часто создаются, подписываясь на одну или несколько тем ROS и храня полученные данные о сообщении в эффективной файловой структуре. MATLAB® может считать эти rosbag файлы и справку с фильтрацией и извлечением данных о сообщении. Смотрите Файлы журнала ROS (rosbags) для получения дополнительной информации о поддержке rosbag в MATLAB.

В этом примере вы загрузите rosbag и изучите, как выбрать и получить содержавшие сообщения.

Предпосылки: работа с основными сообщениями ROS

Загрузите rosbag

Загрузите файл в качестве примера с помощью rosbag команды.

bag = rosbag('ex_multiple_topics.bag')
bag = 
  BagSelection with properties:

           FilePath: '/tmp/BR2019ad_1062519_57051/mlx_to_docbook6/tp844ca463/robotics-ex73200760/ex_multiple_topics.bag'
          StartTime: 201.3400
            EndTime: 321.3400
        NumMessages: 36963
    AvailableTopics: [4x3 table]
    AvailableFrames: {0x1 cell}
        MessageList: [36963x4 table]

Объект, возвращенный в вызов rosbag, является объектом BagSelection, который является представлением всех сообщений в rosbag.

Отображение объекта показывает детали о том, сколько сообщений содержится в файле (NumMessages) и время, когда первые (StartTime) и последнее (EndTime) сообщение были зарегистрированы.

Оцените свойство AvailableTopics видеть больше информации о темах и типах сообщений, которые зарегистрированы в сумке:

bag.AvailableTopics
ans=4×3 table
                           NumMessages         MessageType                MessageDefinition       
                           ___________    ______________________    ______________________________

    /clock                    12001       rosgraph_msgs/Clock       ''                            
    /gazebo/link_states       11999       gazebo_msgs/LinkStates    'geometry_msgs/Pose[] Pose...'
    /odom                     11998       nav_msgs/Odometry         '  uint32 Seq...'             
    /scan                       965       sensor_msgs/LaserScan     '  uint32 Seq...'             

Таблица AvailableTopics содержит отсортированный список тем, которые включены в rosbag. Таблица хранит количество сообщений, типа сообщения и определения сообщения для темы. Для получения дополнительной информации о типе данных table MATLAB и какие операции можно выполнить на нем, см. документацию для Таблиц (MATLAB).

Первоначально rosbag только индексируется MATLAB, и никакие фактические данные о сообщении не считаны.

Вы можете хотеть отфильтровать и сузить выбор сообщений как можно больше на основе этого индекса, прежде чем любые сообщения загрузятся в память MATLAB.

Выберите Messages

Прежде чем вы получите любые данные о сообщении, необходимо выбрать набор сообщений на основе критериев, таких как метка времени, название темы и тип сообщения.

Можно исследовать все сообщения в текущем выборе:

bag.MessageList
ans=36963×4 table
     Time            Topic                MessageType          FileOffset
    ______    ___________________    ______________________    __________

    201.34    /gazebo/link_states    gazebo_msgs/LinkStates       9866   
    201.34    /odom                  nav_msgs/Odometry            7666   
    201.34    /clock                 rosgraph_msgs/Clock          4524   
    201.35    /clock                 rosgraph_msgs/Clock         10962   
    201.35    /clock                 rosgraph_msgs/Clock         12876   
    201.35    /odom                  nav_msgs/Odometry           12112   
    201.35    /gazebo/link_states    gazebo_msgs/LinkStates      11016   
    201.36    /gazebo/link_states    gazebo_msgs/LinkStates      12930   
    201.36    /odom                  nav_msgs/Odometry           14026   
    201.37    /odom                  nav_msgs/Odometry           14844   
    201.37    /gazebo/link_states    gazebo_msgs/LinkStates      15608   
    201.37    /clock                 rosgraph_msgs/Clock         14790   
    201.38    /clock                 rosgraph_msgs/Clock         16704   
    201.38    /gazebo/link_states    gazebo_msgs/LinkStates      16758   
    201.38    /odom                  nav_msgs/Odometry           17854   
    201.39    /gazebo/link_states    gazebo_msgs/LinkStates      18672   
      ⋮

Таблица MessageList содержит одну строку для каждого сообщения в сумке (существует более чем 30 000 строк для сумки в этом примере). Строки сортируются по метке времени первый столбец, который представляет время (в секундах), когда это сообщение было зарегистрировано.

Поскольку список является очень большим, можно также отобразить выбор строк со знакомым синтаксисом выбора строки и столбца:

bag.MessageList(500:505,:)
ans=6×4 table
    Time           Topic                MessageType          FileOffset
    ____    ___________________    ______________________    __________

    203     /clock                 rosgraph_msgs/Clock         339384  
    203     /gazebo/link_states    gazebo_msgs/LinkStates      331944  
    203     /gazebo/link_states    gazebo_msgs/LinkStates      333040  
    203     /gazebo/link_states    gazebo_msgs/LinkStates      334136  
    203     /gazebo/link_states    gazebo_msgs/LinkStates      335232  
    203     /odom                  nav_msgs/Odometry           336328  

Используйте функцию select, чтобы сузить выбор сообщений. Функция select работает с объектом bag.

Можно отфильтровать список сообщений ко времени, названию темы, типу сообщения или любой комбинации трех.

Чтобы выбрать все сообщения, которые были опубликованы по теме /odom, используйте следующую select команду:

bagselect1 = select(bag, 'Topic', '/odom')
bagselect1 = 
  BagSelection with properties:

           FilePath: '/tmp/BR2019ad_1062519_57051/mlx_to_docbook6/tp844ca463/robotics-ex73200760/ex_multiple_topics.bag'
          StartTime: 201.3400
            EndTime: 321.3300
        NumMessages: 11998
    AvailableTopics: [1x3 table]
    AvailableFrames: {0x1 cell}
        MessageList: [11998x4 table]

Вызовы select функционального возврата другой объект BagSelection, который может использоваться, чтобы сделать дальнейшие выборы или получить данные о сообщении. Все объекты выбора независимы друг от друга, таким образом, можно очистить их от рабочей области, если вы сделаны.

Можно сделать различный выбор, который комбинирует два критерия. Чтобы получить список сообщений, которые были зарегистрированы в течение первых 30 секунд после rosbag и опубликованы по теме /odom, введите следующую команду:

start = bag.StartTime
start = 201.3400
bagselect2 = select(bag, 'Time', [start start + 30], 'Topic', '/odom')
bagselect2 = 
  BagSelection with properties:

           FilePath: '/tmp/BR2019ad_1062519_57051/mlx_to_docbook6/tp844ca463/robotics-ex73200760/ex_multiple_topics.bag'
          StartTime: 201.3400
            EndTime: 231.3200
        NumMessages: 2997
    AvailableTopics: [1x3 table]
    AvailableFrames: {0x1 cell}
        MessageList: [2997x4 table]

Используйте последний выбор, чтобы сузить окно времени еще больше:

bagselect3 = select(bagselect2, 'Time', [205 206])
bagselect3 = 
  BagSelection with properties:

           FilePath: '/tmp/BR2019ad_1062519_57051/mlx_to_docbook6/tp844ca463/robotics-ex73200760/ex_multiple_topics.bag'
          StartTime: 205.0200
            EndTime: 205.9900
        NumMessages: 101
    AvailableTopics: [1x3 table]
    AvailableFrames: {0x1 cell}
        MessageList: [101x4 table]

Выбор на этом последнем шаге, управляемом на существующем выборе bagselect2 и, возвратил новый объект bagselect3.

Если вы хотите сохранить набор опций выбора, сохраните элементы выбора в массиве ячеек и затем снова используйте его позже как вход к функции select:

selectOptions = {'Time', [start, start+1; start+5, start+6], 'MessageType', {'sensor_msgs/LaserScan', 'nav_msgs/Odometry'}};
bagselect4 = select(bag, selectOptions{:})
bagselect4 = 
  BagSelection with properties:

           FilePath: '/tmp/BR2019ad_1062519_57051/mlx_to_docbook6/tp844ca463/robotics-ex73200760/ex_multiple_topics.bag'
          StartTime: 201.3400
            EndTime: 207.3300
        NumMessages: 209
    AvailableTopics: [2x3 table]
    AvailableFrames: {0x1 cell}
        MessageList: [209x4 table]

Считайте выбранные данные о сообщении

После того, как вы сузите свой выбор сообщения, вы можете хотеть считать фактические данные о сообщении в MATLAB. В зависимости от размера вашего выбора это может занять много времени и использовать большую память вашего компьютера.

Чтобы получить сообщения в вас выбор как массив ячеек, используйте функцию readMessages:

msgs = readMessages(bagselect3);
size(msgs)
ans = 1×2

   101     1

Получившийся массив ячеек содержит столько элементов, сколько обозначенный в свойстве NumMessages выбора возражают.

В чтении данных о сообщении можно также быть более выборочными и только получить сообщения в определенных индексах. Вот пример получения 4 сообщений:

msgs = readMessages(bagselect3, [1 2 3 7])
msgs = 4x1 cell array
    {1x1 Odometry}
    {1x1 Odometry}
    {1x1 Odometry}
    {1x1 Odometry}

msgs{2}
ans = 
  ROS Odometry message with properties:

     MessageType: 'nav_msgs/Odometry'
          Header: [1x1 Header]
    ChildFrameId: 'base_footprint'
            Pose: [1x1 PoseWithCovariance]
           Twist: [1x1 TwistWithCovariance]

  Use showdetails to show the contents of the message

Каждым сообщением в массиве ячеек является стандартный MATLAB объект сообщения ROS. Для получения дополнительной информации о сообщениях смотрите работу с Основным примером сообщений ROS.

Извлеките данные о сообщении как временные ряды

Иногда вы не интересуетесь полными сообщениями, но только определенными свойствами, которые характерны для всех сообщений в выборе. В этом случае полезно получить данные о сообщении как временные ряды вместо этого. Временные ряды являются вектором данных, который выбирается в зависимости от времени и представляет эволюцию времени одного или нескольких динамических свойств. Для получения дополнительной информации о поддержке временных рядов MATLAB см. документацию для Временных рядов (MATLAB).

В случае сообщений ROS в rosbag временные ряды могут помочь выразить изменение в конкретных элементах сообщения в течение времени. Можно извлечь эту информацию через функцию timeseries. Это эффективно памятью, поскольку полные сообщения не должны храниться в памяти.

Используйте тот же выбор, но используйте функцию timeseries, чтобы только извлечь свойства для x-position и оси z угловая скорость:

ts = timeseries(bagselect3, 'Pose.Pose.Position.X', 'Twist.Twist.Angular.Z')
  timeseries

  Timeseries contains duplicate times.

  Common Properties:
            Name: '/odom Properties'
            Time: [101x1 double]
        TimeInfo: tsdata.timemetadata
            Data: [101x2 double]
        DataInfo: tsdata.datametadata

Возврат этого вызова является объектом timeseries, который может использоваться для последующего анализа или обработки.

Обратите внимание на то, что этот метод извлечения данных только поддержан, если текущий выбор содержит одну тему с одним типом сообщения.

Чтобы видеть данные, содержавшие во временных рядах, получите доступ к свойству Data:

ts.Data
ans = 101×2

    0.0003    0.0003
    0.0003    0.0003
    0.0003   -0.0006
    0.0003   -0.0006
    0.0003   -0.0010
    0.0003   -0.0010
    0.0003   -0.0003
    0.0003   -0.0003
    0.0003   -0.0003
    0.0003   -0.0003
      ⋮

Существует много других возможных способов работать с данными временных рядов. Вычислите среднее значение столбцов данных:

mean(ts)
ans = 1×2
10-3 ×

    0.3213   -0.4616

Можно также отобразить данные на графике временных рядов:

figure
plot(ts, 'LineWidth', 3)