lcm-cli 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. lcm_cli-0.2.0/.github/workflows/ci.yml +104 -0
  2. lcm_cli-0.2.0/.gitignore +59 -0
  3. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/LICENSE +1 -1
  4. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/PKG-INFO +154 -27
  5. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/README.md +142 -20
  6. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/README_zh.md +145 -19
  7. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/pyproject.toml +14 -9
  8. lcm_cli-0.2.0/src/lcm_cli/__init__.py +3 -0
  9. lcm_cli-0.2.0/src/lcm_cli/__main__.py +8 -0
  10. lcm_cli-0.2.0/src/lcm_cli/cli.py +92 -0
  11. lcm_cli-0.2.0/src/lcm_cli/commands/node_list.py +133 -0
  12. lcm_cli-0.2.0/src/lcm_cli/commands/play.py +94 -0
  13. lcm_cli-0.2.0/src/lcm_cli/commands/record.py +131 -0
  14. lcm_cli-0.2.0/src/lcm_cli/commands/topic_bw.py +57 -0
  15. lcm_cli-0.2.0/src/lcm_cli/commands/topic_echo.py +334 -0
  16. lcm_cli-0.2.0/src/lcm_cli/commands/topic_info.py +142 -0
  17. lcm_cli-0.2.0/src/lcm_cli/commands/topic_list.py +119 -0
  18. lcm_cli-0.2.0/src/lcm_cli/commands/topic_stats.py +151 -0
  19. lcm_cli-0.2.0/src/lcm_cli/commands/type_list.py +40 -0
  20. lcm_cli-0.2.0/src/lcm_cli/commands/type_show.py +51 -0
  21. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/core/discovery.py +5 -4
  22. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/core/lcm_type_builder.py +11 -9
  23. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/core/lcm_type_parser.py +2 -0
  24. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/core/stats.py +62 -22
  25. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/display/echo_display.py +5 -4
  26. lcm_cli-0.2.0/src/lcm_cli/display/stats_display.py +211 -0
  27. lcm_cli-0.2.0/src/lcm_cli/display/type_display.py +100 -0
  28. lcm_cli-0.2.0/src/lcm_cli/export.py +295 -0
  29. lcm_cli-0.2.0/src/lcm_cli/lcm_log.py +106 -0
  30. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/listener.py +3 -1
  31. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/protocol.py +2 -0
  32. lcm_cli-0.2.0/src/lcm_cli/source.py +150 -0
  33. lcm_cli-0.2.0/tests/__init__.py +1 -0
  34. lcm_cli-0.2.0/tests/conftest.py +1 -0
  35. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/helpers.py +2 -2
  36. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/test_echo_display.py +2 -2
  37. lcm_cli-0.2.0/tests/test_export.py +173 -0
  38. lcm_cli-0.2.0/tests/test_lcm_log.py +79 -0
  39. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/test_lcm_type_builder.py +16 -2
  40. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/test_lcm_type_parser.py +11 -6
  41. lcm_cli-0.2.0/tests/test_new_commands.py +314 -0
  42. lcm_cli-0.2.0/tests/test_play.py +84 -0
  43. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/test_protocol.py +2 -4
  44. lcm_cli-0.2.0/tests/test_record.py +93 -0
  45. lcm_cli-0.2.0/tests/test_source.py +99 -0
  46. {lcm_cli-0.1.0 → lcm_cli-0.2.0}/tests/test_stats.py +58 -5
  47. lcm_cli-0.1.0/.gitignore +0 -33
  48. lcm_cli-0.1.0/src/lcm_tools/__init__.py +0 -3
  49. lcm_cli-0.1.0/src/lcm_tools/__main__.py +0 -6
  50. lcm_cli-0.1.0/src/lcm_tools/cli.py +0 -52
  51. lcm_cli-0.1.0/src/lcm_tools/commands/node_list.py +0 -82
  52. lcm_cli-0.1.0/src/lcm_tools/commands/topic_echo.py +0 -188
  53. lcm_cli-0.1.0/src/lcm_tools/commands/topic_list.py +0 -69
  54. lcm_cli-0.1.0/src/lcm_tools/commands/topic_stats.py +0 -87
  55. lcm_cli-0.1.0/src/lcm_tools/display/stats_display.py +0 -103
  56. lcm_cli-0.1.0/tests/__init__.py +0 -1
  57. lcm_cli-0.1.0/tests/conftest.py +0 -1
  58. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/commands/__init__.py +0 -0
  59. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/core/__init__.py +0 -0
  60. {lcm_cli-0.1.0/src/lcm_tools → lcm_cli-0.2.0/src/lcm_cli}/display/__init__.py +0 -0
@@ -0,0 +1,104 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ tags:
7
+ - 'v*'
8
+ pull_request:
9
+ branches: [main]
10
+
11
+ jobs:
12
+ test:
13
+ name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }})
14
+ runs-on: ${{ matrix.os }}
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
19
+ os: [ubuntu-latest, macOS-latest]
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ uses: actions/setup-python@v5
26
+ with:
27
+ python-version: ${{ matrix.python-version }}
28
+ cache: 'pip'
29
+
30
+ - name: Install dependencies
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ pip install -e ".[dev]"
34
+
35
+ - name: Lint with Ruff
36
+ run: |
37
+ ruff check src/lcm_cli tests
38
+
39
+ - name: Type check with mypy
40
+ run: |
41
+ mypy src/lcm_cli --ignore-missing-imports
42
+
43
+ - name: Run tests
44
+ run: |
45
+ pytest tests/ -v --cov=lcm_cli --cov-report=xml
46
+
47
+ - name: Upload coverage to Codecov
48
+ if: matrix.python-version == '3.12' && matrix.os == 'ubuntu-latest'
49
+ uses: codecov/codecov-action@v4
50
+ with:
51
+ file: ./coverage.xml
52
+ fail_ci_if_error: false
53
+
54
+ build:
55
+ name: Build distribution
56
+ needs: test
57
+ runs-on: ubuntu-latest
58
+ if: startsWith(github.ref, 'refs/tags/v')
59
+
60
+ steps:
61
+ - uses: actions/checkout@v4
62
+
63
+ - name: Set up Python
64
+ uses: actions/setup-python@v5
65
+ with:
66
+ python-version: '3.12'
67
+
68
+ - name: Install build tools
69
+ run: |
70
+ pip install build twine
71
+
72
+ - name: Build package
73
+ run: |
74
+ python -m build
75
+
76
+ - name: Check package
77
+ run: |
78
+ twine check dist/*
79
+
80
+ - name: Upload dist
81
+ uses: actions/upload-artifact@v4
82
+ with:
83
+ name: dist
84
+ path: dist/
85
+
86
+ publish:
87
+ name: Publish to PyPI
88
+ needs: build
89
+ runs-on: ubuntu-latest
90
+ if: startsWith(github.ref, 'refs/tags/v')
91
+ environment:
92
+ name: pypi
93
+ url: https://pypi.org/p/lcm-cli
94
+ permissions:
95
+ id-token: write
96
+
97
+ steps:
98
+ - uses: actions/download-artifact@v4
99
+ with:
100
+ name: dist
101
+ path: dist/
102
+
103
+ - name: Publish to PyPI
104
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,59 @@
1
+ # Byte-compiled / cache
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ *.egg
6
+
7
+ # Distribution / packaging
8
+ dist/
9
+ build/
10
+ *.tar.gz
11
+ *.whl
12
+
13
+ # Tests & coverage
14
+ .pytest_cache/
15
+ htmlcov/
16
+ .coverage
17
+ coverage.xml
18
+
19
+ # Type checking
20
+ .mypy_cache/
21
+
22
+ # Linting
23
+ .ruff_cache/
24
+
25
+ # IDE
26
+ .vscode/
27
+ .idea/
28
+ *.swp
29
+ *.swo
30
+ *~
31
+
32
+ # LCM reference repo (not part of this project)
33
+ lcm_ref/
34
+
35
+ # lcm-gen generated Python types
36
+ gen_types/
37
+
38
+ # Test LCM types (sample files)
39
+ test_lcm_types/
40
+
41
+ # Virtual environments
42
+ venv/
43
+ .venv-build/
44
+ .env/
45
+
46
+ # OS files
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Logs
51
+ *.log
52
+
53
+ # Development scripts and internal docs
54
+ scripts/
55
+ docs/superpowers/
56
+
57
+ # Temporary files
58
+ tmp/
59
+ temp/
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 lcm-tools contributors
3
+ Copyright (c) 2024 lcm-cli contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lcm-cli
3
- Version: 0.1.0
4
- Summary: ROS2-like command line tools for LCM (Lightweight Communications and Marshalling)
5
- Project-URL: Homepage, https://github.com/lcm-tools/lcm-tools
6
- Project-URL: Repository, https://github.com/lcm-tools/lcm-tools
7
- Project-URL: Issues, https://github.com/lcm-tools/lcm-tools/issues
8
- Author: lcm-tools contributors
3
+ Version: 0.2.0
4
+ Summary: Command line tools for monitoring and debugging LCM (Lightweight Communications and Marshalling)
5
+ Project-URL: Homepage, https://github.com/Joyserr/lcm-cli
6
+ Project-URL: Repository, https://github.com/Joyserr/lcm-cli
7
+ Project-URL: Issues, https://github.com/Joyserr/lcm-cli/issues
8
+ Author: lcm-cli contributors
9
9
  License-Expression: MIT
10
10
  License-File: LICENSE
11
- Keywords: cli,debugging,lcm,middleware,multicast,robotics,ros2
11
+ Keywords: cli,debugging,lcm,middleware,multicast,robotics
12
12
  Classifier: Development Status :: 4 - Beta
13
13
  Classifier: Environment :: Console
14
14
  Classifier: Intended Audience :: Developers
@@ -33,40 +33,56 @@ Requires-Dist: typer>=0.12.0
33
33
  Provides-Extra: decode
34
34
  Requires-Dist: lcm>=1.5.0; extra == 'decode'
35
35
  Provides-Extra: dev
36
+ Requires-Dist: build>=0.10; extra == 'dev'
37
+ Requires-Dist: mypy>=1.0; extra == 'dev'
38
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
36
39
  Requires-Dist: pytest-timeout>=2.1; extra == 'dev'
37
40
  Requires-Dist: pytest>=7.0; extra == 'dev'
41
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
42
+ Requires-Dist: twine>=4.0; extra == 'dev'
38
43
  Description-Content-Type: text/markdown
39
44
 
40
45
  # LCM CLI Tools
41
46
 
42
47
  **[English](README.md)** | [中文](README_zh.md)
43
48
 
44
- > ROS2-style command line tools for monitoring and debugging LCM (Lightweight Communications and Marshalling) networks.
49
+ > Command line tools for monitoring and debugging LCM (Lightweight Communications and Marshalling) networks.
45
50
 
46
51
  ## Features
47
52
 
48
53
  ```
49
- lcm topic echo <channel> — View real-time topic data (like ros2 topic echo)
50
- lcm topic list — List active topics/channels (like ros2 topic list)
51
- lcm topic stats — Real-time topic stats: rate, bandwidth, msg count (like ros2 topic hz)
52
- lcm node list List discovered publisher nodes (like ros2 node list)
54
+ lcm topic echo <channel> — View real-time topic data
55
+ lcm topic list — List active topics/channels
56
+ lcm topic stats — Real-time topic stats: rate, bandwidth, msg count
57
+ lcm topic bw <channel> Monitor bandwidth for a single channel with sparkline graph
58
+ lcm topic info <channel> — Detailed channel information with type structure
59
+ lcm node list — List discovered publisher nodes
60
+ lcm type list — List all registered LCM types
61
+ lcm type show <type> — Show type field structure
62
+ lcm record — Record live LCM traffic to .log file
63
+ lcm play <file.log> — Replay .log file to multicast
53
64
  ```
54
65
 
55
- **Highlight**: Built-in pure-Python `.lcm` file parser — no `lcm-gen` or `PYTHONPATH` needed. Just point to your `.lcm` files and messages are decoded automatically.
66
+ **Highlights**:
67
+ - Built-in pure-Python `.lcm` file parser — no `lcm-gen` or `PYTHONPATH` needed
68
+ - **Message Export**: CSV/JSONL export with field extraction (`--csv`, `--jsonl`, `--field`)
69
+ - **Advanced Monitoring**: Sort/filter stats (`--sort`, `--top`, `--freeze`, `--spark`)
70
+ - **Live Watch Mode**: Continuous refresh for topic/node list (`--watch`)
71
+ - **Recording & Playback**: Full log file support compatible with `lcm-logger`
56
72
 
57
73
  ## Installation
58
74
 
59
75
  ```bash
60
76
  # From PyPI
61
- pip install lcm-tools
77
+ pip install lcm-cli
62
78
 
63
79
  # From source (development)
64
- git clone https://github.com/your-username/lcm-tools.git
65
- cd lcm-tools
80
+ git clone https://github.com/Joyserr/lcm-cli.git
81
+ cd lcm-cli
66
82
  pip install -e .
67
83
 
68
84
  # Optional: traditional lcm-gen Python package decode support
69
- pip install lcm-tools[decode]
85
+ pip install lcm-cli[decode]
70
86
  ```
71
87
 
72
88
  **Requirements**: Python >= 3.9, `typer`, `rich` (`lcm` package is optional, only for legacy `--type module.Class` decoding).
@@ -77,9 +93,15 @@ pip install lcm-tools[decode]
77
93
  # Show all subcommands
78
94
  lcm --help
79
95
 
96
+ # Show version
97
+ lcm --version
98
+
80
99
  # List active channels (listens for 5 seconds)
81
100
  lcm topic list
82
101
 
102
+ # Continuous watch mode (live refresh)
103
+ lcm topic list --watch
104
+
83
105
  # View messages on a channel (raw hex format)
84
106
  lcm topic echo EXAMPLE
85
107
 
@@ -92,15 +114,106 @@ lcm topic echo "CAM.*"
92
114
  # Monitor real-time statistics for all channels
93
115
  lcm topic stats
94
116
 
95
- # Monitor a specific channel only
96
- lcm topic stats CAMERA
117
+ # Sort by bandwidth, show top 5
118
+ lcm topic stats --sort bw --top 5
119
+
120
+ # Freeze mode (single snapshot)
121
+ lcm topic stats --freeze
122
+
123
+ # Monitor bandwidth with sparkline graph
124
+ lcm topic bw CAMERA --spark
125
+
126
+ # Detailed channel information
127
+ lcm topic info CAMERA --lcm-file types/
97
128
 
98
129
  # List discovered publisher nodes
99
130
  lcm node list
100
131
  ```
101
132
 
133
+ ## Recording & Playback
134
+
135
+ ```bash
136
+ # Record all channels to a .log file
137
+ lcm record
138
+
139
+ # Record specific channels with regex
140
+ lcm record --channel "CAM.*" -o camera.log
141
+
142
+ # Record for a fixed duration
143
+ lcm record -d 60 # 60 seconds
144
+
145
+ # Replay a .log file
146
+ lcm play camera.log
147
+
148
+ # Replay at 2x speed
149
+ lcm play camera.log --speed 2.0
150
+
151
+ # Loop playback
152
+ lcm play camera.log --loop
153
+ ```
154
+
155
+ ## Message Export
156
+
157
+ ```bash
158
+ # Export to CSV (headers auto-determined from first message)
159
+ lcm topic echo EXAMPLE --csv output.csv
160
+
161
+ # Export to JSON Lines
162
+ lcm topic echo EXAMPLE --jsonl output.jsonl
163
+
164
+ # Extract specific fields
165
+ lcm topic echo EXAMPLE --field position --field velocity --csv data.csv
166
+
167
+ # Extract nested fields
168
+ lcm topic echo EXAMPLE --field imu.accel.x --field imu.gyro.y
169
+
170
+ # Extract array slices
171
+ lcm topic echo EXAMPLE --field "position[0:2]"
172
+
173
+ # Custom timestamp format
174
+ lcm topic echo EXAMPLE --csv data.csv --ts-format iso
175
+ ```
176
+
177
+ ## Advanced Statistics
178
+
179
+ ```bash
180
+ # Sort channels by message rate
181
+ lcm topic stats --sort rate
182
+
183
+ # Show top 10 channels by bandwidth
184
+ lcm topic stats --sort bw --top 10
185
+
186
+ # Single snapshot (non-interactive)
187
+ lcm topic stats --freeze
188
+
189
+ # Add sparkline trend visualization
190
+ lcm topic stats --spark
191
+
192
+ # Monitor bandwidth for a single channel
193
+ lcm topic bw CAMERA --window 10 --spark
194
+
195
+ # Read stats from log file
196
+ lcm topic stats --from recording.log
197
+ ```
198
+
102
199
  ## Message Decoding
103
200
 
201
+ ### Type Diagnostics
202
+
203
+ ```bash
204
+ # List all registered types
205
+ lcm type list
206
+
207
+ # Filter by package
208
+ lcm type list --package exlcm
209
+
210
+ # Show type structure
211
+ lcm type show example_t --lcm-file types/
212
+
213
+ # Grep search types
214
+ lcm type list --grep "sensor"
215
+ ```
216
+
104
217
  ### Method 1: Specify `.lcm` files directly (recommended)
105
218
 
106
219
  No `lcm-gen` installation, no `PYTHONPATH` configuration. The tool includes a built-in pure-Python parser:
@@ -133,7 +246,7 @@ Supports the complete LCM type system:
133
246
 
134
247
  ```bash
135
248
  # Install the lcm Python package
136
- pip install lcm-tools[decode]
249
+ pip install lcm-cli[decode]
137
250
 
138
251
  # Generate Python files with lcm-gen, then configure PYTHONPATH
139
252
  lcm-gen --python -d types/ types/example_t.lcm
@@ -195,6 +308,8 @@ Reference: [LCM UDP Multicast Protocol](https://lcm-proj.github.io/lcm/content/u
195
308
 
196
309
  ## LCM vs ROS2 Concepts
197
310
 
311
+ LCM and ROS2 share similar pub/sub communication patterns. Here's a concept mapping:
312
+
198
313
  | LCM Concept | ROS2 Equivalent | Description |
199
314
  |-------------|----------------|-------------|
200
315
  | Channel | Topic | Message publish/subscribe conduit |
@@ -204,13 +319,21 @@ Reference: [LCM UDP Multicast Protocol](https://lcm-proj.github.io/lcm/content/u
204
319
  ## Project Structure
205
320
 
206
321
  ```
207
- src/lcm_tools/
322
+ src/lcm_cli/
323
+ ├── __init__.py # Package definition + version
324
+ ├── __main__.py # python -m lcm_cli entry point
208
325
  ├── cli.py # Typer entry point, registers subcommands
209
326
  ├── commands/
210
- │ ├── topic_echo.py # lcm topic echo
211
- │ ├── topic_list.py # lcm topic list
212
- │ ├── topic_stats.py # lcm topic stats
213
- └── node_list.py # lcm node list
327
+ │ ├── topic_echo.py # lcm topic echo (with --csv/--jsonl export)
328
+ │ ├── topic_list.py # lcm topic list (with --watch mode)
329
+ │ ├── topic_stats.py # lcm topic stats (with --sort/--top/--freeze)
330
+ ├── topic_bw.py # lcm topic bw (bandwidth monitor)
331
+ │ ├── topic_info.py # lcm topic info (channel details)
332
+ │ ├── node_list.py # lcm node list (with --watch mode)
333
+ │ ├── type_list.py # lcm type list
334
+ │ ├── type_show.py # lcm type show
335
+ │ ├── record.py # lcm record
336
+ │ └── play.py # lcm play
214
337
  ├── core/
215
338
  │ ├── discovery.py # Passive channel/node discovery
216
339
  │ ├── stats.py # Real-time statistics (rate, bandwidth)
@@ -218,9 +341,13 @@ src/lcm_tools/
218
341
  │ └── lcm_type_builder.py # Runtime decode class generation + TypeRegistry
219
342
  ├── display/
220
343
  │ ├── echo_display.py # Rich panel display (with recursive nesting)
221
- └── stats_display.py # Statistics table display
344
+ ├── stats_display.py # Statistics table display (with sparkline)
345
+ │ └── type_display.py # Type structure table display
346
+ ├── export.py # Field extraction + CSV/JSONL writers
347
+ ├── lcm_log.py # LCM log file reader/writer (lcm-logger compatible)
222
348
  ├── listener.py # UDP multicast listener thread
223
- └── protocol.py # LCM Wire Protocol parser
349
+ ├── protocol.py # LCM Wire Protocol parser
350
+ └── source.py # PacketSource abstraction (live/offline)
224
351
  ```
225
352
 
226
353
  ## Testing
@@ -2,32 +2,43 @@
2
2
 
3
3
  **[English](README.md)** | [中文](README_zh.md)
4
4
 
5
- > ROS2-style command line tools for monitoring and debugging LCM (Lightweight Communications and Marshalling) networks.
5
+ > Command line tools for monitoring and debugging LCM (Lightweight Communications and Marshalling) networks.
6
6
 
7
7
  ## Features
8
8
 
9
9
  ```
10
- lcm topic echo <channel> — View real-time topic data (like ros2 topic echo)
11
- lcm topic list — List active topics/channels (like ros2 topic list)
12
- lcm topic stats — Real-time topic stats: rate, bandwidth, msg count (like ros2 topic hz)
13
- lcm node list List discovered publisher nodes (like ros2 node list)
10
+ lcm topic echo <channel> — View real-time topic data
11
+ lcm topic list — List active topics/channels
12
+ lcm topic stats — Real-time topic stats: rate, bandwidth, msg count
13
+ lcm topic bw <channel> Monitor bandwidth for a single channel with sparkline graph
14
+ lcm topic info <channel> — Detailed channel information with type structure
15
+ lcm node list — List discovered publisher nodes
16
+ lcm type list — List all registered LCM types
17
+ lcm type show <type> — Show type field structure
18
+ lcm record — Record live LCM traffic to .log file
19
+ lcm play <file.log> — Replay .log file to multicast
14
20
  ```
15
21
 
16
- **Highlight**: Built-in pure-Python `.lcm` file parser — no `lcm-gen` or `PYTHONPATH` needed. Just point to your `.lcm` files and messages are decoded automatically.
22
+ **Highlights**:
23
+ - Built-in pure-Python `.lcm` file parser — no `lcm-gen` or `PYTHONPATH` needed
24
+ - **Message Export**: CSV/JSONL export with field extraction (`--csv`, `--jsonl`, `--field`)
25
+ - **Advanced Monitoring**: Sort/filter stats (`--sort`, `--top`, `--freeze`, `--spark`)
26
+ - **Live Watch Mode**: Continuous refresh for topic/node list (`--watch`)
27
+ - **Recording & Playback**: Full log file support compatible with `lcm-logger`
17
28
 
18
29
  ## Installation
19
30
 
20
31
  ```bash
21
32
  # From PyPI
22
- pip install lcm-tools
33
+ pip install lcm-cli
23
34
 
24
35
  # From source (development)
25
- git clone https://github.com/your-username/lcm-tools.git
26
- cd lcm-tools
36
+ git clone https://github.com/Joyserr/lcm-cli.git
37
+ cd lcm-cli
27
38
  pip install -e .
28
39
 
29
40
  # Optional: traditional lcm-gen Python package decode support
30
- pip install lcm-tools[decode]
41
+ pip install lcm-cli[decode]
31
42
  ```
32
43
 
33
44
  **Requirements**: Python >= 3.9, `typer`, `rich` (`lcm` package is optional, only for legacy `--type module.Class` decoding).
@@ -38,9 +49,15 @@ pip install lcm-tools[decode]
38
49
  # Show all subcommands
39
50
  lcm --help
40
51
 
52
+ # Show version
53
+ lcm --version
54
+
41
55
  # List active channels (listens for 5 seconds)
42
56
  lcm topic list
43
57
 
58
+ # Continuous watch mode (live refresh)
59
+ lcm topic list --watch
60
+
44
61
  # View messages on a channel (raw hex format)
45
62
  lcm topic echo EXAMPLE
46
63
 
@@ -53,15 +70,106 @@ lcm topic echo "CAM.*"
53
70
  # Monitor real-time statistics for all channels
54
71
  lcm topic stats
55
72
 
56
- # Monitor a specific channel only
57
- lcm topic stats CAMERA
73
+ # Sort by bandwidth, show top 5
74
+ lcm topic stats --sort bw --top 5
75
+
76
+ # Freeze mode (single snapshot)
77
+ lcm topic stats --freeze
78
+
79
+ # Monitor bandwidth with sparkline graph
80
+ lcm topic bw CAMERA --spark
81
+
82
+ # Detailed channel information
83
+ lcm topic info CAMERA --lcm-file types/
58
84
 
59
85
  # List discovered publisher nodes
60
86
  lcm node list
61
87
  ```
62
88
 
89
+ ## Recording & Playback
90
+
91
+ ```bash
92
+ # Record all channels to a .log file
93
+ lcm record
94
+
95
+ # Record specific channels with regex
96
+ lcm record --channel "CAM.*" -o camera.log
97
+
98
+ # Record for a fixed duration
99
+ lcm record -d 60 # 60 seconds
100
+
101
+ # Replay a .log file
102
+ lcm play camera.log
103
+
104
+ # Replay at 2x speed
105
+ lcm play camera.log --speed 2.0
106
+
107
+ # Loop playback
108
+ lcm play camera.log --loop
109
+ ```
110
+
111
+ ## Message Export
112
+
113
+ ```bash
114
+ # Export to CSV (headers auto-determined from first message)
115
+ lcm topic echo EXAMPLE --csv output.csv
116
+
117
+ # Export to JSON Lines
118
+ lcm topic echo EXAMPLE --jsonl output.jsonl
119
+
120
+ # Extract specific fields
121
+ lcm topic echo EXAMPLE --field position --field velocity --csv data.csv
122
+
123
+ # Extract nested fields
124
+ lcm topic echo EXAMPLE --field imu.accel.x --field imu.gyro.y
125
+
126
+ # Extract array slices
127
+ lcm topic echo EXAMPLE --field "position[0:2]"
128
+
129
+ # Custom timestamp format
130
+ lcm topic echo EXAMPLE --csv data.csv --ts-format iso
131
+ ```
132
+
133
+ ## Advanced Statistics
134
+
135
+ ```bash
136
+ # Sort channels by message rate
137
+ lcm topic stats --sort rate
138
+
139
+ # Show top 10 channels by bandwidth
140
+ lcm topic stats --sort bw --top 10
141
+
142
+ # Single snapshot (non-interactive)
143
+ lcm topic stats --freeze
144
+
145
+ # Add sparkline trend visualization
146
+ lcm topic stats --spark
147
+
148
+ # Monitor bandwidth for a single channel
149
+ lcm topic bw CAMERA --window 10 --spark
150
+
151
+ # Read stats from log file
152
+ lcm topic stats --from recording.log
153
+ ```
154
+
63
155
  ## Message Decoding
64
156
 
157
+ ### Type Diagnostics
158
+
159
+ ```bash
160
+ # List all registered types
161
+ lcm type list
162
+
163
+ # Filter by package
164
+ lcm type list --package exlcm
165
+
166
+ # Show type structure
167
+ lcm type show example_t --lcm-file types/
168
+
169
+ # Grep search types
170
+ lcm type list --grep "sensor"
171
+ ```
172
+
65
173
  ### Method 1: Specify `.lcm` files directly (recommended)
66
174
 
67
175
  No `lcm-gen` installation, no `PYTHONPATH` configuration. The tool includes a built-in pure-Python parser:
@@ -94,7 +202,7 @@ Supports the complete LCM type system:
94
202
 
95
203
  ```bash
96
204
  # Install the lcm Python package
97
- pip install lcm-tools[decode]
205
+ pip install lcm-cli[decode]
98
206
 
99
207
  # Generate Python files with lcm-gen, then configure PYTHONPATH
100
208
  lcm-gen --python -d types/ types/example_t.lcm
@@ -156,6 +264,8 @@ Reference: [LCM UDP Multicast Protocol](https://lcm-proj.github.io/lcm/content/u
156
264
 
157
265
  ## LCM vs ROS2 Concepts
158
266
 
267
+ LCM and ROS2 share similar pub/sub communication patterns. Here's a concept mapping:
268
+
159
269
  | LCM Concept | ROS2 Equivalent | Description |
160
270
  |-------------|----------------|-------------|
161
271
  | Channel | Topic | Message publish/subscribe conduit |
@@ -165,13 +275,21 @@ Reference: [LCM UDP Multicast Protocol](https://lcm-proj.github.io/lcm/content/u
165
275
  ## Project Structure
166
276
 
167
277
  ```
168
- src/lcm_tools/
278
+ src/lcm_cli/
279
+ ├── __init__.py # Package definition + version
280
+ ├── __main__.py # python -m lcm_cli entry point
169
281
  ├── cli.py # Typer entry point, registers subcommands
170
282
  ├── commands/
171
- │ ├── topic_echo.py # lcm topic echo
172
- │ ├── topic_list.py # lcm topic list
173
- │ ├── topic_stats.py # lcm topic stats
174
- └── node_list.py # lcm node list
283
+ │ ├── topic_echo.py # lcm topic echo (with --csv/--jsonl export)
284
+ │ ├── topic_list.py # lcm topic list (with --watch mode)
285
+ │ ├── topic_stats.py # lcm topic stats (with --sort/--top/--freeze)
286
+ ├── topic_bw.py # lcm topic bw (bandwidth monitor)
287
+ │ ├── topic_info.py # lcm topic info (channel details)
288
+ │ ├── node_list.py # lcm node list (with --watch mode)
289
+ │ ├── type_list.py # lcm type list
290
+ │ ├── type_show.py # lcm type show
291
+ │ ├── record.py # lcm record
292
+ │ └── play.py # lcm play
175
293
  ├── core/
176
294
  │ ├── discovery.py # Passive channel/node discovery
177
295
  │ ├── stats.py # Real-time statistics (rate, bandwidth)
@@ -179,9 +297,13 @@ src/lcm_tools/
179
297
  │ └── lcm_type_builder.py # Runtime decode class generation + TypeRegistry
180
298
  ├── display/
181
299
  │ ├── echo_display.py # Rich panel display (with recursive nesting)
182
- └── stats_display.py # Statistics table display
300
+ ├── stats_display.py # Statistics table display (with sparkline)
301
+ │ └── type_display.py # Type structure table display
302
+ ├── export.py # Field extraction + CSV/JSONL writers
303
+ ├── lcm_log.py # LCM log file reader/writer (lcm-logger compatible)
183
304
  ├── listener.py # UDP multicast listener thread
184
- └── protocol.py # LCM Wire Protocol parser
305
+ ├── protocol.py # LCM Wire Protocol parser
306
+ └── source.py # PacketSource abstraction (live/offline)
185
307
  ```
186
308
 
187
309
  ## Testing