I added some more debug features, for example now, when running tf-tree -p mobile on a fake mobile Robot I get :
░▀█▀░█▀▀░░░░░▀█▀░█▀▄░█▀▀░█▀▀
░░█░░█▀▀░▄▄▄░░█░░█▀▄░█▀▀░█▀▀
░░▀░░▀░░░░░░░░▀░░▀░▀░▀▀▀░▀▀▀
TF-TREE CLI DEBUGGER
[INFO] [1767483009.498731809] [tf_tree_cli_helper]: Mode: REP 105 (Mobile)
[INFO] [1767483009.499220178] [tf_tree_cli_helper]: Single-shot mode: Buffering (3s)…
— TF SNAPSHOT: 2026-01-03 23:30:12 —
🔗 Link: base_link [STATIC]
├── 🔗 Link: base_footprint [STATIC] [STATIC]
│ ⚙️ Joint: to_base_footprint [TF: robot_state_publisher | JointState: joint_state_publisher]
├── 🔗 Link: camera_link [STATIC] [STATIC]
│ ⚙️ Joint: to_camera_link [TF: robot_state_publisher | JointState: joint_state_publisher]
│ └── 🔗 Link: camera_link_optical [STATIC] [STATIC]
│ ⚙️ Joint: to_camera_link_optical [TF: robot_state_publisher | JointState: joint_state_publisher]
├── 🔗 Link: left_wheel [12.3 Hz] [LIVE: 81.5ms]
│ ⚙️ Joint: to_left_wheel [TF: robot_state_publisher | JointState: joint_state_publisher]
└── 🔗 Link: right_wheel [12.3 Hz] [LIVE: 81.6ms]
⚙️ Joint: to_right_wheel [TF: robot_state_publisher | JointState: joint_state_publisher]
└── 🔗 Link: test_orphan [STATIC] [STATIC]
⚙️ Joint: to_test_orphan [TF: robot_state_publisher | JointState: joint_state_publisher]
✅ /joint_states topic
— COMPLIANCE DIAGNOSTIC —
❌ Recommendation: map
❌ Recommendation: odom
✅ Recommendation: base_link
I wished to link a “diagnostic” to the tf-tree discovery, according to REP 105 for mobile and REP 199 for arm robots.
I still doubt about the utility to specify the publisher for TF as it will always be emit by robot_state_publisher. The main idea is to be able to get the same insights as Rviz2 about joint_states not being published :
This state :
Equals this output for tf-tree –profile mobile :
░▀█▀░█▀▀░░░░░▀█▀░█▀▄░█▀▀░█▀▀
░░█░░█▀▀░▄▄▄░░█░░█▀▄░█▀▀░█▀▀
░░▀░░▀░░░░░░░░▀░░▀░▀░▀▀▀░▀▀▀
TF-TREE CLI DEBUGGER
[INFO] [1767558554.199176504] [tf_tree_cli_helper]: Mode: REP 105 (Mobile)
[INFO] [1767558554.200081643] [tf_tree_cli_helper]: Single-shot mode: Buffering (3s)…
— TF SNAPSHOT: 2026-01-04 20:29:17 —
🔥 ALERT: 2 DISJOINTED TREES!
└─ Roots: base_link, right_wheel
🔗 Link: base_link [STATIC]
├── 🔗 Link: base_footprint [STATIC] [STATIC]
│ ⚙️ Joint: to_base_footprint [TF: robot_state_publisher | JointState: ❌ none]
└── 🔗 Link: camera_link [STATIC] [STATIC]
⚙️ Joint: to_camera_link [TF: robot_state_publisher | JointState: ❌ none]
└── 🔗 Link: camera_link_optical [STATIC] [STATIC]
⚙️ Joint: to_camera_link_optical [TF: robot_state_publisher | JointState: ❌ none]
🔗 Link: right_wheel [STATIC]
└── 🔗 Link: test_orphan [STATIC] [STATIC]
⚙️ Joint: to_test_orphan [TF: robot_state_publisher | JointState: ❌ none]
❌ /joint_states topic
— COMPLIANCE DIAGNOSTIC —
❌ Recommendation: map
❌ Recommendation: odom
✅ Recommendation: base_link
This should lead the user to publish joint_states :
and get this output, running tf-tree -p mobile
░▀█▀░█▀▀░░░░░▀█▀░█▀▄░█▀▀░█▀▀
░░█░░█▀▀░▄▄▄░░█░░█▀▄░█▀▀░█▀▀
░░▀░░▀░░░░░░░░▀░░▀░▀░▀▀▀░▀▀▀
TF-TREE CLI DEBUGGER
[INFO] [1767558488.085976588] [tf_tree_cli_helper]: Mode: REP 105 (Mobile)
[INFO] [1767558488.086777159] [tf_tree_cli_helper]: Single-shot mode: Buffering (3s)…
— TF SNAPSHOT: 2026-01-04 20:28:11 —
🔗 Link: base_link [STATIC]
├── 🔗 Link: base_footprint [STATIC] [STATIC]
│ ⚙️ Joint: to_base_footprint [TF: robot_state_publisher | JointState: joint_state_publisher]
├── 🔗 Link: camera_link [STATIC] [STATIC]
│ ⚙️ Joint: to_camera_link [TF: robot_state_publisher | JointState: joint_state_publisher]
│ └── 🔗 Link: camera_link_optical [STATIC] [STATIC]
│ ⚙️ Joint: to_camera_link_optical [TF: robot_state_publisher | JointState: joint_state_publisher]
├── 🔗 Link: left_wheel [13.8 Hz] [LIVE: 72.6ms]
│ ⚙️ Joint: to_left_wheel [TF: robot_state_publisher | JointState: joint_state_publisher]
└── 🔗 Link: right_wheel [13.7 Hz] [LIVE: 72.9ms]
⚙️ Joint: to_right_wheel [TF: robot_state_publisher | JointState: joint_state_publisher]
└── 🔗 Link: test_orphan [STATIC] [STATIC]
⚙️ Joint: to_test_orphan [TF: robot_state_publisher | JointState: joint_state_publisher]
✅ /joint_states topic
— COMPLIANCE DIAGNOSTIC —
❌ Recommendation: map
❌ Recommendation: odom
✅ Recommendation: base_link
or use the light version of tree, running tf-tree -l -p mobile
░▀█▀░█▀▀░░░░░▀█▀░█▀▄░█▀▀░█▀▀
░░█░░█▀▀░▄▄▄░░█░░█▀▄░█▀▀░█▀▀
░░▀░░▀░░░░░░░░▀░░▀░▀░▀▀▀░▀▀▀
TF-TREE CLI DEBUGGER
[INFO] [1767558700.138535938] [tf_tree_cli_helper]: Mode: REP 105 (Mobile)
[INFO] [1767558700.139257144] [tf_tree_cli_helper]: Single-shot mode: Buffering (3s)…
— TF SNAPSHOT: 2026-01-04 20:31:43 —
base_link
├── base_footprint
├── camera_link
│ └── camera_link_optical
├── left_wheel
└── right_wheel
└── test_orphan
Also, I added command flags :
| Flag | Short | Description |
| --- | --- | --- |
| `--profile` | `-p` | Diagnostic mode: `mobile`, `arm`, or `auto` (default). |
| `--save` | `-s` | Export the analysis to a file (e.g., `-s robot_report.txt`). |
| `--alive` | `-a` | Keep node alive; refreshes terminal every 5 seconds. |
| `--light` | `-l` | Get a light TF-Tree as output |
| `--help` | `-h` | Show help message and exit. |
Hope this goes the right way! 