refactor(tools): Restructure bagtrans tool and integrate into aimrt_cli (#68)

* CI: change build worlflow image tag from v20240927 to latest

* refactor(tools): Restructure bagtrans tool and integrate into aimrt_cli

- Integrate bagtrans functionality into aimrt_cli
- Update CMakeLists.txt and documentation to reflect these changes

* choro: format the code

* choro: change the document

* choro: remove the bagtrans options

---------

Co-authored-by: yuguanlin <yuguanlin@agibot.com>
This commit is contained in:
ATT_POWER 2024-10-31 21:46:25 +08:00 committed by GitHub
parent acf57080c2
commit b2fd9cb78b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 38 additions and 260 deletions

View File

@ -14,7 +14,6 @@ option(AIMRT_BUILD_EXAMPLES "AimRT build examples." OFF)
option(AIMRT_BUILD_DOCUMENT "AimRT build document." OFF) option(AIMRT_BUILD_DOCUMENT "AimRT build document." OFF)
option(AIMRT_BUILD_RUNTIME "AimRT build runtime." ON) option(AIMRT_BUILD_RUNTIME "AimRT build runtime." ON)
option(AIMRT_BUILD_CLI_TOOLS "AimRT build aimrt command line tools." OFF) option(AIMRT_BUILD_CLI_TOOLS "AimRT build aimrt command line tools." OFF)
option(AIMRT_BUILD_BAGTRANS "AimRT build bagtrans tool." OFF)
option(AIMRT_BUILD_PYTHON_RUNTIME "AimRT build python runtime." OFF) option(AIMRT_BUILD_PYTHON_RUNTIME "AimRT build python runtime." OFF)
@ -144,21 +143,6 @@ if(AIMRT_BUILD_CLI_TOOLS)
endif() endif()
endif() endif()
if(AIMRT_BUILD_BAGTRANS)
include(CheckPythonPackage)
check_python_package(build BUILD_FOUND)
check_python_package(wheel WHEEL_FOUND)
check_python_package(setuptools SETUPTOOLS_FOUND)
if(NOT BUILD_FOUND
OR NOT WHEEL_FOUND
OR NOT SETUPTOOLS_FOUND)
set(AIMRT_BUILD_BAGTRANS OFF)
message(WARNING "Can not find build, wheel or setuptools in your python environment, will not compile bagtrans tool!")
message(WARNING "Try to install build, wheel and setuptools by `pip3 install build wheel setuptools --upgrade`")
endif()
endif()
if(AIMRT_BUILD_WITH_PROTOBUF) if(AIMRT_BUILD_WITH_PROTOBUF)
include(GetProtobuf) include(GetProtobuf)
include(ProtobufGenCode) include(ProtobufGenCode)
@ -300,12 +284,6 @@ if(AIMRT_INSTALL
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_BINARY_DIR}\" --config ${CMAKE_BUILD_TYPE} --target create_python_pkg)") install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_BINARY_DIR}\" --config ${CMAKE_BUILD_TYPE} --target create_python_pkg)")
endif() endif()
if(AIMRT_INSTALL
AND AIMRT_BUILD_WITH_ROS2
AND AIMRT_BUILD_BAGTRANS)
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_BINARY_DIR}\" --config ${CMAKE_BUILD_TYPE} --target bagtrans)")
endif()
# Print all aimrt options # Print all aimrt options
message("\n AIMRT CMake Options/Info:") message("\n AIMRT CMake Options/Info:")
get_cmake_property(all_variables VARIABLES) get_cmake_property(all_variables VARIABLES)

View File

@ -10,7 +10,6 @@ cmake -B build ^
-DAIMRT_BUILD_DOCUMENT=ON ^ -DAIMRT_BUILD_DOCUMENT=ON ^
-DAIMRT_BUILD_RUNTIME=ON ^ -DAIMRT_BUILD_RUNTIME=ON ^
-DAIMRT_BUILD_CLI_TOOLS=ON ^ -DAIMRT_BUILD_CLI_TOOLS=ON ^
-DAIMRT_BUILD_BAGTRANS=OFF ^
-DAIMRT_BUILD_PYTHON_RUNTIME=ON ^ -DAIMRT_BUILD_PYTHON_RUNTIME=ON ^
-DAIMRT_USE_FMT_LIB=ON ^ -DAIMRT_USE_FMT_LIB=ON ^
-DAIMRT_BUILD_WITH_PROTOBUF=ON ^ -DAIMRT_BUILD_WITH_PROTOBUF=ON ^

View File

@ -12,7 +12,6 @@ cmake -B build \
-DAIMRT_BUILD_DOCUMENT=ON \ -DAIMRT_BUILD_DOCUMENT=ON \
-DAIMRT_BUILD_RUNTIME=ON \ -DAIMRT_BUILD_RUNTIME=ON \
-DAIMRT_BUILD_CLI_TOOLS=ON \ -DAIMRT_BUILD_CLI_TOOLS=ON \
-DAIMRT_BUILD_BAGTRANS=ON \
-DAIMRT_BUILD_PYTHON_RUNTIME=ON \ -DAIMRT_BUILD_PYTHON_RUNTIME=ON \
-DAIMRT_USE_FMT_LIB=ON \ -DAIMRT_USE_FMT_LIB=ON \
-DAIMRT_BUILD_WITH_PROTOBUF=ON \ -DAIMRT_BUILD_WITH_PROTOBUF=ON \

View File

@ -8,7 +8,7 @@
- 现在可以传入 zenoh 原生配置; - 现在可以传入 zenoh 原生配置;
- mqtt 新增配置项以支持加密传输; - mqtt 新增配置项以支持加密传输;
- 新增了第三方库 asioruntime::core 不再引用 boost改为引用独立的 asio 库,以减轻依赖; - 新增了第三方库 asioruntime::core 不再引用 boost改为引用独立的 asio 库,以减轻依赖;
- 新增 bagtrans 命令行工具,用于将 使用 aimrt record_playback 插件录制的 bag 文件转换为 ros2 的 bag 文件; - 新增 aimrt_cli trans 命令,用于将 使用 aimrt record_playback 插件录制的 bag 文件转换为 ros2 的 bag 文件;
- 新增 Echo 插件,用于回显消息; - 新增 Echo 插件,用于回显消息;
**次要修改** **次要修改**

View File

@ -1,39 +1,25 @@
# bagtrans 工具 # 转换 AimRT 的 bag 文件为 ROS2 的 bag 文件
## 简介 ## 简介
**bagtrans** 是一个 AimRT 官方提供的命令行工具,目前可以将 AimRT **recordplayback** 插件记录的 bag 文件转换为 ROS2 的 bag 文件其中ros2 原生消息会直接转换pb 消息会转换为 aimrt 提供的 ros2_plugin_proto 中的 RosMsgWrapper 消息类型 **aimrt_cli** 工具可以将 AimRT **recordplayback** 插件记录的 bag 文件转换为 ROS2 的 bag 文件其中ros2 消息会直接转换pb 消息则不会转换。
## 安装 基本使用样例如下:
```
**bagtrans** 工具是一个基于 Python 开发的小工具,并且依赖于 aimrt 提供的 ros2_plugin_protobuf 消息类型,需要按照以下步骤安装: aimrt_cli trans -s [your_aimrtbag_source_dir] -o [your_output_dir]
1. 需要您的 python 环境中安装了 build、wheel 和 setuptools 包,如果未安装,可以使用以下命令安装:
```bash
pip3 install build wheel setuptools --upgrade
``` ```
2. 需要编译生成 aimrt 源码库中的 ros2_plugin_proto 消息类型,并且在 build.sh 文件中确保`AIMRT_BUILD_ROS2_PLUGIN``AIMRT_BUILD_RECORD_PLAYBACK_PLUGIN``AIMRT_BUILD_BAGTRANS` 选项为`ON`,执行您 aimrt 源码库中的`build.sh`文件进行编译,编译完成后,在 `<path_to_your_aimrt_src_code>/src/tools/bagtrans/build/dist` 文件夹下可找到编译生成的`whl`文件。 您也可以使用 `aimrt_cli -h/--help`查看支持的命令行选项。
3. 在终端中执行以下命令:
```
cd <path_to_your_aimrt_src_code>/src/tools/bagtrans/build/dist
pip3 install bagtrans-<version>-py3-none-any.whl
```
**bagtrans**工具将会自动安装到您的 python 环境中。使用 `pip list | grep bagtrans`可查看是否安装成功。可使用 `pip uninstall bagtrans`进行卸载。
## 使用说明 ## 使用说明
**bagtrans** 工具的使用方法如下: **aimrt_cli** 工具的使用方法如下:
每次使用前,需要使用命令 `source <path_to_your_aimrt_src_code>/src/tools/bagtrans/build/share/ros2_plugin_proto/local_setup.bash` 以修改环境变量。 `trans` 命令的使用方法如下:
transbag 命令的使用方法如下:
```bash ```bash
bagtrans trans -h, --help 会显示参数说明: aimrt_cli trans -h, --help 会显示参数说明:
options: options:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -44,5 +30,3 @@ options:
``` ```
其中 `-s` 参数为必填参数,表示 aimrtbag 的源目录,`-o` 参数为必填参数表示转换后的bag的输出目录如果输出目录不存在则会自动创建如果输出目录存在则会覆盖。 其中 `-s` 参数为必填参数,表示 aimrtbag 的源目录,`-o` 参数为必填参数表示转换后的bag的输出目录如果输出目录不存在则会自动创建如果输出目录存在则会覆盖。

View File

@ -7,6 +7,7 @@
**aimrt_cli**是一个 AimRT 官方提供的命令行工具,目前支持以下功能: **aimrt_cli**是一个 AimRT 官方提供的命令行工具,目前支持以下功能:
- [为新项目生成脚手架代码](./gen_prj.md) - [为新项目生成脚手架代码](./gen_prj.md)
- [转换 AimRT 的 bag 文件为 ROS2 的 bag 文件](./bagtrans_tool.md)
您也可以直接执行`aimrt_cli --help`获取内置帮助说明。更多功能敬请期待。 您也可以直接执行`aimrt_cli --help`获取内置帮助说明。更多功能敬请期待。

View File

@ -34,7 +34,7 @@ if(AIMRT_BUILD_WITH_ROS2)
add_subdirectory(example_ros2) add_subdirectory(example_ros2)
endif() endif()
if(AIMRT_BUILD_ROS2_PLUGIN OR AIMRT_BUILD_BAGTRANS) if(AIMRT_BUILD_ROS2_PLUGIN)
add_subdirectory(plugins/ros2_plugin_proto) add_subdirectory(plugins/ros2_plugin_proto)
endif() endif()
endif() endif()

View File

@ -16,10 +16,6 @@ if(AIMRT_BUILD_CLI_TOOLS)
add_subdirectory(aimrt_cli) add_subdirectory(aimrt_cli)
endif() endif()
if(AIMRT_BUILD_WITH_ROS2 AND AIMRT_BUILD_BAGTRANS)
add_subdirectory(bagtrans)
endif()
if(AIMRT_BUILD_PYTHON_RUNTIME AND AIMRT_BUILD_PYTHON_PACKAGE) if(AIMRT_BUILD_PYTHON_RUNTIME AND AIMRT_BUILD_PYTHON_PACKAGE)
add_subdirectory(package_aimrt_py) add_subdirectory(package_aimrt_py)
endif() endif()

View File

@ -3,6 +3,7 @@
from aimrt_cli.command import CommandBase from aimrt_cli.command import CommandBase
from aimrt_cli.generator.project_generator import ProjectGenerator from aimrt_cli.generator.project_generator import ProjectGenerator
from aimrt_cli.trans.rosbag_trans import RosbagTrans
class GenCommand(CommandBase): class GenCommand(CommandBase):
@ -23,3 +24,6 @@ class GenCommand(CommandBase):
generator = ProjectGenerator(cfg_path=args.project_cfg, output_dir=args.output_dir) generator = ProjectGenerator(cfg_path=args.project_cfg, output_dir=args.output_dir)
generator.generate() generator.generate()
trans = RosbagTrans(args.src_dir, args.output_dir)
trans.trans()

View File

@ -1,8 +1,8 @@
# Copyright (c) 2023, AgiBot Inc. # Copyright (c) 2023, AgiBot Inc.
# All rights reserved. # All rights reserved.
from bagtrans.command import CommandBase from aimrt_cli.command import CommandBase
from bagtrans.trans.rosbag_trans import RosbagTrans from aimrt_cli.trans.rosbag_trans import RosbagTrans
class TransCommand(CommandBase): class TransCommand(CommandBase):

View File

@ -3,8 +3,8 @@
import argparse import argparse
from aimrt_cli.command.gen_command import GenCommand from aimrt_cli.command.gen_command import GenCommand
from aimrt_cli.command.trans_command import TransCommand
def main(description=None): def main(description=None):
@ -12,18 +12,26 @@ def main(description=None):
description = 'This is the application generation tool for AimRT.' description = 'This is the application generation tool for AimRT.'
parser = argparse.ArgumentParser(description=description) parser = argparse.ArgumentParser(description=description)
parser.add_argument( subparsers = parser.add_subparsers(dest='command')
"generate",
help="generate the configured project, the configuration yaml files is required.", # gen sub command
type=str gen_parser = subparsers.add_parser('gen', help='Generate the configured project')
) gen_parser.add_argument("-p", "--project_cfg", help="path of the configuration yaml file")
# will support more console parameters later. gen_parser.add_argument("-o", "--output_dir", help="directory you want to output your files")
gen_command = GenCommand()
gen_command.add_arguments(parser, "gen") # bag trans sub command
trans_parser = subparsers.add_parser('trans', help='Transform bag files')
trans_parser.add_argument("-s", "--src_dir", help="aimrtbag source directory")
trans_parser.add_argument("-o", "--output_dir", help="directory you want to output your files")
args = parser.parse_args() args = parser.parse_args()
if args.generate == "gen":
gen_command.main(args=args) if args.command == 'gen':
generator = GenCommand()
generator.main(args=args)
elif args.command == 'trans':
trans = TransCommand()
trans.main(args=args)
else: else:
parser.print_help() parser.print_help()
return 0 return 0

View File

@ -1,15 +1,13 @@
# Copyright (c) 2024 The AimRT Authors. # Copyright (c) 2024 The AimRT Authors.
# AimRT is licensed under Mulan PSL v2. # AimRT is licensed under Mulan PSL v2.
from bagtrans.trans import TransBase from aimrt_cli.trans import TransBase
import os import os
import sqlite3 import sqlite3
import shutil import shutil
from pathlib import Path from pathlib import Path
import yaml import yaml
from dataclasses import dataclass from dataclasses import dataclass
from ros2_plugin_proto.msg import RosMsgWrapper
import rclpy.serialization
class IndentDumper(yaml.Dumper): class IndentDumper(yaml.Dumper):
@ -315,50 +313,6 @@ class RosbagTrans(TransBase):
print(f"Error create metadata table, error: {e}") print(f"Error create metadata table, error: {e}")
conn.rollback() conn.rollback()
def update_pb_msg(self, conn, cursor):
try:
cursor.execute("SELECT id, topic_id, timestamp, data FROM messages")
rows = cursor.fetchall()
update_data = []
for row in rows:
id, topic_id, timestamp, data = row
if topic_id not in self.topic_info_dict or not self.topic_info_dict[topic_id].msg_type.startswith("pb"):
continue
msg = RosMsgWrapper()
data = [bytes([d]) for d in data]
msg.data = data
msg.serialization_type = "pb"
serialized_data = rclpy.serialization.serialize_message(msg)
update_data.append((sqlite3.Binary(serialized_data), id))
cursor.executemany("UPDATE messages SET data = ? WHERE id = ?", update_data)
conn.commit()
except Exception as e:
print(f"Error updating msg data from pb to RosMsgWrapper, error: {e}")
conn.rollback()
try:
cursor.execute("SELECT id, name, type FROM topics")
rows = cursor.fetchall()
for row in rows:
id = row[0]
topic_name = row[1]
msg_type = row[2]
if msg_type.startswith("pb"):
topic_name = encode_topic_name(topic_name, msg_type)
msg_type = "ros2_plugin_proto/msg/RosMsgWrapper"
cursor.execute("UPDATE topics SET name = ? , type = ? WHERE id = ?", (topic_name, msg_type, id))
conn.commit()
except Exception as e:
print(f"Error updating topics table data , error: {e}")
conn.rollback()
def trans_single_db(self, db_path: Path): def trans_single_db(self, db_path: Path):
single_bag_info = SingleBagProcess(self.topic_info_dict, db_path) single_bag_info = SingleBagProcess(self.topic_info_dict, db_path)
self.all_duration += single_bag_info.duration_nanoseconds self.all_duration += single_bag_info.duration_nanoseconds
@ -376,7 +330,6 @@ class RosbagTrans(TransBase):
self.insert_schema_version(conn, cursor) self.insert_schema_version(conn, cursor)
self.insert_metadata_table(conn, cursor) self.insert_metadata_table(conn, cursor)
self.insert_topics_table(conn, cursor) self.insert_topics_table(conn, cursor)
self.update_pb_msg(conn, cursor)
self.update_messages_table(conn, cursor) self.update_messages_table(conn, cursor)
except Exception as e: except Exception as e:
print(f"Error updating messages table: {e}") print(f"Error updating messages table: {e}")

View File

@ -1,34 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.
# Get all the files in folder
file(GLOB_RECURSE BAGTRANS_SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/bagtrans/*")
set(BAGTRANS_BUILD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/build)
add_custom_target(
bagtrans
COMMAND ${Python3_EXECUTABLE} -m build --wheel --no-isolation -v
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "${PYTHON_EXECUTABLE} -m build --wheel --no-isolation -v"
DEPENDS ${BAGTRANS_SRC_FILES})
add_custom_target(
copy_ros2_plugin_proto_files_bagtrans
COMMAND ${CMAKE_COMMAND} -E make_directory ${BAGTRANS_BUILD_DIR}/lib/
COMMAND ${CMAKE_COMMAND} -E make_directory ${BAGTRANS_BUILD_DIR}/local/
COMMAND ${CMAKE_COMMAND} -E make_directory ${BAGTRANS_BUILD_DIR}/share/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_INSTALL_PREFIX}/lib/ ${BAGTRANS_BUILD_DIR}/lib/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_INSTALL_PREFIX}/local/ ${BAGTRANS_BUILD_DIR}/local/
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_INSTALL_PREFIX}/share/ ${BAGTRANS_BUILD_DIR}/share/
COMMENT "Copying ROS2 files"
DEPENDS aimrt::plugins::ros2_plugin)
add_dependencies(bagtrans copy_ros2_plugin_proto_files_bagtrans)
if(AIMRT_INSTALL)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DESTINATION bin
USE_SOURCE_PERMISSIONS)
endif()

View File

@ -1,2 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.

View File

@ -1,36 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
hiddenimports=['__future__'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='bagtrans',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)

View File

@ -1,13 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.
class CommandBase:
def __init__(self):
super(CommandBase, self).__init__()
def add_arguments(self, parser, cmd_name):
pass
def main(self, *, args=None):
raise NotImplementedError()

View File

@ -1,30 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.
import argparse
from bagtrans.command.trans_command import TransCommand
def main(description=None):
if description is None:
description = 'This is the bagtrans tool.'
parser = argparse.ArgumentParser(description=description)
subparsers = parser.add_subparsers(dest='command', required=True)
# Create a subparser for the "trans" command
trans_parser = subparsers.add_parser('trans', help='translate the aimrtbag to ros2bag')
trans_command = TransCommand()
trans_command.add_arguments(trans_parser, "trans")
args = parser.parse_args()
if args.command == "trans":
trans_command.main(args=args)
else:
parser.print_help()
return 0
if __name__ == '__main__':
main()

View File

@ -1,4 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.
setuptools>=59.6.0

View File

@ -1,23 +0,0 @@
# Copyright (c) 2023, AgiBot Inc.
# All rights reserved.
from setuptools import find_packages, setup
package_name = 'bagtrans'
setup(
name=package_name,
app='bagtrans',
version='0.0.1',
packages=find_packages(exclude=['test']),
author='Yu Guanlin',
author_email='yuguanlin@agibot.com',
description='transfer aimrt bag file to ros2 bag file',
license='',
entry_points={
'console_scripts': [
'bagtrans = bagtrans.main:main',
],
},
include_package_data=True,
)

View File

@ -10,7 +10,6 @@ cmake -B build ^
-DAIMRT_BUILD_DOCUMENT=ON ^ -DAIMRT_BUILD_DOCUMENT=ON ^
-DAIMRT_BUILD_RUNTIME=ON ^ -DAIMRT_BUILD_RUNTIME=ON ^
-DAIMRT_BUILD_CLI_TOOLS=ON ^ -DAIMRT_BUILD_CLI_TOOLS=ON ^
-DAIMRT_BUILD_BAGTRANS=OFF ^
-DAIMRT_BUILD_PYTHON_RUNTIME=ON ^ -DAIMRT_BUILD_PYTHON_RUNTIME=ON ^
-DAIMRT_USE_FMT_LIB=ON ^ -DAIMRT_USE_FMT_LIB=ON ^
-DAIMRT_BUILD_WITH_PROTOBUF=ON ^ -DAIMRT_BUILD_WITH_PROTOBUF=ON ^

View File

@ -12,7 +12,6 @@ cmake -B build \
-DAIMRT_BUILD_DOCUMENT=ON \ -DAIMRT_BUILD_DOCUMENT=ON \
-DAIMRT_BUILD_RUNTIME=ON \ -DAIMRT_BUILD_RUNTIME=ON \
-DAIMRT_BUILD_CLI_TOOLS=ON \ -DAIMRT_BUILD_CLI_TOOLS=ON \
-DAIMRT_BUILD_BAGTRANS=ON \
-DAIMRT_BUILD_PYTHON_RUNTIME=ON \ -DAIMRT_BUILD_PYTHON_RUNTIME=ON \
-DAIMRT_USE_FMT_LIB=ON \ -DAIMRT_USE_FMT_LIB=ON \
-DAIMRT_BUILD_WITH_PROTOBUF=ON \ -DAIMRT_BUILD_WITH_PROTOBUF=ON \