로봇/ROS

[ROS2] bag 파일 복구

jjjjjjyun 2025. 3. 19. 22:25

센서 데이터 수집을 위해 ros2 bag을 이용했다.

이때 ros2 bag record가 정상 종료되면 db3 파일과 metadata 파일이 생긴다.

  • metadata.yaml은 다음과 같은 내용을 가지고 있으며 ROS 노드와 토픽 메시지 정보가 있다.
rosbag2_bagfile_information:
  version: 4
  storage_identifier: sqlite3
  relative_file_paths:
    - new_0.db3
  duration:
    nanoseconds: 8231007494
  starting_time:
    nanoseconds_since_epoch: 1717553797242000455
  message_count: 102
  topics_with_message_count:
    - topic_metadata:
        name: /turtle1/cmd_vel
        type: geometry_msgs/msg/Twist
        serialization_format: cdr
        offered_qos_profiles: "- history: 3\n  depth: 0\n  reliability: 1\n  durability: 2\n  deadline:\n    sec: 2147483647\n    nsec: 4294967295\n  lifespan:\n    sec: 2147483647\n    nsec: 4294967295\n  liveliness: 1\n  liveliness_lease_duration:\n    sec: 2147483647\n    nsec: 4294967295\n  avoid_ros_namespace_conventions: false"
      message_count: 102
  compression_format: ""
  compression_mode: ""

 

  • 이게 있어야 ros2 bag info로 정보 확인이 가능하다.
  • 하지만 없어도 bag파일을 play하는데 문제되지는 않는다.
  • sigint가 발생해야 metadata.yaml이 생성된다.

 


문제 및 해결

문제

비정상적인 종료에 따라 bag 파일이 제대로 저장되지 않는 문제 발생

 

분석

  • metadata.yaml 까지 생성되어야 ros2 bag info 명령으로 bag 파일 정보 확인이 가능하다.
  • 비정상적인 종료 발생 시 metadata.yaml이 제대로 생성되지 않는 문제가 발생한다. ctrl+c 로 종료 시에도 생성되지 않는다.
  • 하지만 metadata.yaml 이 없어도 db3파일을 이용해 bag 파일 play는 가능하다.

해결

  • sigint 발생 시 metadata.yaml 이 정상적으로 생성되는 것을 발견했다.
  • 실행 스크립트 종료 시 ros2 bag이 들어간 프로세스를 검색하고 모두 sigint 처리로 종료시키도록 적용했다.

KILLALL_FUNC() {
  
  while pgrep -f "ros2 bag record" >/dev/null; do
        pgrep -f "ros2 bag record" | xargs kill -2
        echo "=================== KILL ROS2 BAG RECORD ======================"
        sleep 1
  done
}
KILLALL='KILLALL_FUNC'
trap "$KILLALL; sleep 1; $KILLALL" EXIT INT QUIT KILL SEGV TERM

 

 

metadata 복구하기

https://github.com/arplaboratory/ros2bag_fixer

 

GitHub - arplaboratory/ros2bag_fixer

Contribute to arplaboratory/ros2bag_fixer development by creating an account on GitHub.

github.com

 

ros2 bag record 진행 중 PC 전원이 갑자기 종료되거나 비정상적인 종료가 발생하면 db3파일을 직접 play하는 것 외에는 ros2 bag play 명령이 되지 않는다. 비정상적인 종료 시 사진과 같이 저장이 된다.

 

 

sqlite3 툴을 이용해 db3 파일을 sql 파일로 변환한다.

chmod +x sqlite3
./sqlite3 path_to_corrupt.db3 .recover >data.sql

 

sql 파일을 csv 파일로 변환한다.

python3 sql_to_csv.py --input path/to/file.sql --output path/to/output_base.csv

 

*이때 sql_to_csv.py 에서 create_table_pattern = re.compile(r'CREATE TABLE\s+"?(\w+)"?', re.IGNORECASE) 부분을 create_table_pattern = re.compile(r'CREATE TABLE (?:IF NOT EXISTS )?"?(\w+)"?', re.IGNORECASE)로 변경해야 한다.

 

 

결과

변경 후 진행을 하면 다음과 같은 내용을 얻을 수 있다. 이때 두 번째 사진의 data는 BLOB(Binary Large Object) 형식의 내용이다.

https://docs.ros.org/en/noetic/api/grepros/html/ros2_8py_source.html