Работа с rosbag Logfiles

Rosbag или bag - это формат файла в ROS для хранения данных сообщений. Эти сумки часто создаются путем подписки на одну или несколько тем ROS и хранения полученных данных сообщения в эффективной файловой структуре. MATLAB ® может считать эти файлы rosbag и помочь с фильтрацией и извлечением данных сообщений. Для получения дополнительной информации о поддержке rosbag в MATLAB см. ROS Log Files (rosbags).

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

Необходимые условия: Работа с базовыми сообщениями ROS

Загрузка rosbag

Загрузите файл примера, используя rosbag команда.

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

           FilePath: '/tmp/BR2021ad_1684407_61364/mlx_to_docbook6/tp6773ed82/ros-ex71482057/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       {0x0 char                      }
    /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...'             }

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

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

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

Выбор сообщений

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

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

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   
      ⋮

The 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 функция для сужения выбора сообщений. The select функция действует на bag объект.

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

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

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

           FilePath: '/tmp/BR2021ad_1684407_61364/mlx_to_docbook6/tp6773ed82/ros-ex71482057/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 topic, введите следующую команду:

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

           FilePath: '/tmp/BR2021ad_1684407_61364/mlx_to_docbook6/tp6773ed82/ros-ex71482057/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/BR2021ad_1684407_61364/mlx_to_docbook6/tp6773ed82/ros-ex71482057/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/BR2021ad_1684407_61364/mlx_to_docbook6/tp6773ed82/ros-ex71482057/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=4×1 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]
            Pose: [1x1 PoseWithCovariance]
           Twist: [1x1 TwistWithCovariance]
    ChildFrameId: 'base_footprint'

  Use showdetails to show the contents of the message

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

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

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

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

Используйте тот же выбор, но используйте timeseries функция, чтобы извлечь только свойства для x-положения и 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)

Figure contains an axes. The axes with title Time Series Plot:/odom Properties contains 2 objects of type line.