Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions modules/tools/cyber_recorder_gui/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
load("//tools:apollo_package.bzl", "apollo_package", "apollo_cc_binary", "apollo_qt_library")

package(default_visibility = ["//visibility:public"])

apollo_cc_binary(
name = "cyber_recorder_gui_lite",
srcs = ["main.cpp"],
copts = [
"-Iexternal/qt",
"-std=c++17",
"-fPIC",
],
linkopts = [
"-pthread",
],
deps = [
":cyber_recorder_gui_lite_lib",
"//cyber",
"//cyber/proto:record_cc_proto",
"@qt//:qt_core",
"@qt//:qt_gui",
"@qt//:qt_widgets",
],
)

apollo_qt_library(
name = "cyber_recorder_gui_lite_lib",
srcs=["mainwindow.cpp",
"record_playbar.cpp",
"info.cc",
"doubleslider.cc",
"player/play_task_buffer.cc",
"player/play_task_consumer.cc",
"player/play_task_producer.cc",
"player/play_task.cc",
"player/player.cc"],
hdrs=["mainwindow.h",
"record_playbar.h",
"info.h",
"doubleslider.h",
"player/play_param.h",
"player/play_task_buffer.h",
"player/play_task_consumer.h",
"player/play_task_producer.h",
"player/play_task.h",
"player/player.h"],
#srcs = glob(["*.cpp","*.cc"]),
#hdrs = glob(["*.h"]),
uis = glob(["*.ui"]),
copts = [
"-Iexternal/qt",
"-std=c++17",
"-fPIC",
],
includes = [
".",
],
linkstatic = False,
deps = [
"//cyber",
"//cyber/common:cyber_common",
"//cyber/proto:record_cc_proto",
"@qt//:qt_core",
"@qt//:qt_gui",
"@qt//:qt_widgets",
],
)


# TODO(all): Disable linter temporarily as the generated ui files should be
# excluded from check. But we should also check the .h and .cc files, if they
# are extracted to their own cc_libraries. See the TODO above.
# cpplint()
apollo_package(enable_source=False)
apollo_package()
Comment on lines +74 to +75
62 changes: 62 additions & 0 deletions modules/tools/cyber_recorder_gui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
cmake_minimum_required(VERSION 3.5)

project(cyber_recorder_gui_lite VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Comment on lines +11 to +12

find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)

set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
mainwindow.ui
record_playbar.cpp
record_playbar.h

)
Comment on lines +17 to +25

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(cyber_recorder_gui_lite
MANUAL_FINALIZATION
${PROJECT_SOURCES}
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET cyber_recorder_gui_lite APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
# ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
if(ANDROID)
add_library(cyber_recorder_gui_lite SHARED
${PROJECT_SOURCES}
)
# Define properties for Android with Qt 5 after find_package() calls as:
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
else()
add_executable(cyber_recorder_gui_lite
${PROJECT_SOURCES}
)
endif()
endif()

target_link_libraries(cyber_recorder_gui_lite PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

set_target_properties(cyber_recorder_gui_lite PROPERTIES
MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
)

if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(cyber_recorder_gui_lite)
endif()
119 changes: 119 additions & 0 deletions modules/tools/cyber_recorder_gui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Cyber Recorder GUI Lite

`cyber_recorder_gui_lite` is a lightweight Qt graphical interface for replaying Apollo Cyber record files. It can open one record file or all record shards in a directory, display basic record information, and publish the recorded messages back to Cyber for debugging.

This module is the reduced version of `modules/cyber_recorder_gui`. It is intentionally kept as a separate package and executable so that both versions can coexist without an install-name conflict.

## Features

- Open a single `.record` file.
- Open a directory containing `.record` and `.record.*` shards.
- Preview record metadata and channel information.
- Play, pause, resume, and stop playback.
- Seek during playback with the progress bar.
- Display the selected time range and current playback status.

The lite version does not include the full version's map selector or `log2worldsim` export workflow.

## Build

From the Apollo workspace root (`/apollo_workspace` inside the development container):

```bash
# Apollo buildtool workflow
buildtool build -p modules/tools/cyber_recorder_gui --cpu
```

For a direct Bazel build (after the Apollo dependencies are installed):

```bash
bazel build //modules/tools/cyber_recorder_gui:cyber_recorder_gui_lite
```

The generated executable is:

```text
bazel-bin/modules/tools/cyber_recorder_gui/cyber_recorder_gui_lite
```

## Run

Run the executable directly:

```bash
./bazel-bin/modules/tools/cyber_recorder_gui/cyber_recorder_gui_lite
```

Or start it with `cyber_launch`:

```bash
cyber_launch start modules/tools/cyber_recorder_gui/launch/cyber_recorder_gui_lite.launch
```

The application initializes the Cyber node `cyber_recorder_gui_lite` and shows a window titled **Cyber Recorder GUI Lite**.

## Basic usage

1. Click **File** and select one record file, or click **Dir** and select a directory.
2. Check the metadata shown in the information panel.
3. Click **Play** to start replay.
4. Use **Pause** / **Resume** to control playback.
5. Drag or click the upper progress bar to seek while playing.
6. Click **Stop** to reset playback to the beginning.

The directory picker starts at `/apollo_workspace/data/`. Directory playback loads files matching `*.record` and `*.record.*`, sorted by file name. Keep record shards in a naturally sortable sequence, for example:

```text
demo.record
demo.record.00000
demo.record.00001
```

## Playback defaults

| Setting | Default |
| --- | --- |
| Playback rate | `1.0` |
| Start time | Record beginning |
| End time | Record end (`uint64_t` maximum is used as the default bound) |
| Preload time | `3` seconds |
| Loop playback | Disabled |
| Channel selection | All channels when no filter is configured |

The lower dual-handle slider currently updates the displayed `Range` label only; it does not restrict the actual playback interval.

## Troubleshooting

### No window appears

Make sure the container has access to the host display (X11 or Wayland) and that Qt can connect to it.

### A record cannot be opened

Verify that the path points to an Apollo Cyber record, that the file is not corrupted, and that the current user can read it. You can inspect a file with Apollo's record tools before starting the GUI.

### Other modules receive no messages

Confirm that the record contains the expected channel and that the subscriber is running in the same Cyber environment. The following commands can help:

```bash
cyber_channel list
cyber_channel echo /your/channel/name
```

### The progress bar does not seek

Seeking is enabled while playback is active. Start playback before dragging or clicking the upper progress bar.

## Source layout

| Path | Purpose |
| --- | --- |
| `main.cpp` | Qt application entry point and Cyber initialization |
| `mainwindow.ui` | Main window layout |
| `mainwindow.cpp` / `mainwindow.h` | File selection, playback controls, and status updates |
| `info.cc` / `info.h` | Record metadata reader |
| `player/` | Playback tasks, buffering, and message publishing |
| `launch/cyber_recorder_gui_lite.launch` | `cyber_launch` configuration |
| `BUILD` | Bazel targets and package installation rule |
| `cyberfile.xml` | Apollo package metadata (`cyber-recorder-gui-lite`) |
119 changes: 119 additions & 0 deletions modules/tools/cyber_recorder_gui/README_cn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Cyber Recorder GUI Lite 使用说明

`cyber_recorder_gui_lite` 是一个基于 Qt 的 Apollo Cyber record 轻量级图形回放工具。它可以打开单个 record 文件,也可以加载目录中的分片 record 文件,显示 record 基础信息,并将消息重新发布到 Cyber 通道,方便调试依赖历史数据的模块。

本模块是 `modules/cyber_recorder_gui` 的缩减版。它使用独立的包名、节点名和可执行文件名,可以与完整版同时保留,避免安装目标冲突。

## 功能

- 打开单个 `.record` 文件。
- 打开包含 `.record` 和 `.record.*` 分片文件的目录。
- 预览 record 元信息和通道信息。
- 播放、暂停、继续和停止回放。
- 使用进度条在播放过程中跳转。
- 显示选定时间范围和当前播放状态。

缩减版不包含完整版中的地图选择器和 `log2worldsim` 导出流程。

## 编译

在 Apollo 工作空间根目录执行(容器内通常为 `/apollo_workspace`):

```bash
# 使用 Apollo buildtool
buildtool build -p modules/tools/cyber_recorder_gui --cpu
```

如果 Apollo 依赖已经安装,也可以直接使用 Bazel:

```bash
bazel build //modules/tools/cyber_recorder_gui:cyber_recorder_gui_lite
```

生成的可执行文件路径为:

```text
bazel-bin/modules/tools/cyber_recorder_gui/cyber_recorder_gui_lite
```

## 启动

直接运行:

```bash
./bazel-bin/modules/tools/cyber_recorder_gui/cyber_recorder_gui_lite
```

或者使用 `cyber_launch`:

```bash
cyber_launch start modules/tools/cyber_recorder_gui/launch/cyber_recorder_gui_lite.launch
```

程序启动时会初始化 Cyber 节点 `cyber_recorder_gui_lite`,窗口标题为 **Cyber Recorder GUI Lite**。

## 基本使用流程

1. 点击 **File** 选择单个 record 文件,或点击 **Dir** 选择一个目录。
2. 在信息框中检查 record 元信息。
3. 点击 **Play** 开始回放。
4. 使用 **Pause** / **Resume** 暂停或继续。
5. 播放时拖动或点击上方进度条进行跳转。
6. 点击 **Stop** 停止播放并将进度重置到起点。

目录选择框默认打开 `/apollo_workspace/data/`。目录模式只加载文件名匹配 `*.record` 或 `*.record.*` 的文件,并按文件名排序。建议分片文件保持自然排序,例如:

```text
demo.record
demo.record.00000
demo.record.00001
```

## 默认播放参数

| 参数 | 默认值 |
| --- | --- |
| 播放速率 | `1.0` |
| 起始时间 | record 起点 |
| 结束时间 | record 末尾(默认边界使用 `uint64_t` 最大值) |
| 预加载时间 | `3` 秒 |
| 循环播放 | 关闭 |
| 通道选择 | 未配置过滤条件时播放全部通道 |

下方双端滑条目前只更新 `Range` 文本,不会真正限制播放器的播放起止时间。

## 常见问题

### 启动后没有窗口

请确认容器已经正确透传宿主机的 X11 或 Wayland 显示环境,并且 Qt 能够连接显示服务。

### 无法打开 record 文件

请确认路径指向 Apollo Cyber record 文件,文件没有损坏,且当前用户具有读取权限。可以先使用 Apollo 自带的 record 工具检查文件。

### 其他模块收不到回放消息

确认 record 中包含目标通道,并确认订阅模块和 GUI 运行在同一个 Cyber 环境中。可以执行:

```bash
cyber_channel list
cyber_channel echo /your/channel/name
```

### 进度条无法跳转

只有在播放状态下才会处理跳转。请先点击 **Play**,再拖动或点击上方进度条。

## 源码结构

| 路径 | 用途 |
| --- | --- |
| `main.cpp` | Qt 程序入口及 Cyber 初始化 |
| `mainwindow.ui` | 主窗口布局 |
| `mainwindow.cpp` / `mainwindow.h` | 文件选择、播放控制和状态更新 |
| `info.cc` / `info.h` | record 元信息读取 |
| `player/` | 播放任务、缓冲和消息发布 |
| `launch/cyber_recorder_gui_lite.launch` | `cyber_launch` 启动配置 |
| `BUILD` | Bazel 构建目标和安装规则 |
| `cyberfile.xml` | Apollo 包元数据(`cyber-recorder-gui-lite`) |
Loading