Skip to content

Installing btview, and your first five minutes with it

btview is a normal Python package. It needs Python 3.9 or newer and nothing else — no ROS client library, no Qt, no compiler. The three dependencies (pyzmq, rich, textual) ship as wheels for every platform CI covers.


1. Install

pipx keeps the tool in its own virtual environment and puts a single btview on your PATH, so it can never fight with your ROS or system packages.

python3 -m pip install --user pipx     # if you do not have it yet
python3 -m pipx ensurepath             # then restart your shell

pipx install btview

With pip, into an environment you already have

pip install btview

Inside a ROS 2 workspace this is fine — btview imports nothing from ROS and adds nothing to your ament build. If you would rather not touch the ROS environment at all:

python3 -m venv ~/.venvs/btview
~/.venvs/btview/bin/pip install btview
~/.venvs/btview/bin/btview --version

The unreleased version

main is not always the same as the latest release:

pipx install git+https://github.com/guilyx/btview          # tip of main
pipx install btview==0.2.1                                 # pin a version

From a clone (for development or an offline robot)

git clone https://github.com/guilyx/btview
cd btview
pip install -e .            # add ".[dev]" for the test and lint tooling

On a robot with no internet

Download the wheels on a machine that does have internet, copy them over, install there:

# on your laptop — pass the robot's Python if it differs from yours
pip download btview --dest wheels --only-binary :all: --python-version 39
scp -r wheels robot:/tmp/

# on the robot
pip install --no-index --find-links /tmp/wheels btview

Everything in the dependency tree publishes wheels, so nothing is compiled on the robot. btview itself is pure Python; only pyzmq is platform-specific, so match the robot's architecture when you download.

With Docker

If you would rather not install anything, see docker.md:

docker compose -f .docker/docker-compose.yml run --rm btview demo

2. Check it works — without a robot

btview demo

This starts a synthetic Nav2-style publisher in the same process and connects to it over a real ZMQ socket, so a working demo proves your install, your terminal, and the protocol stack all work. You should see a tree ticking, statuses changing, and a recovery firing every so often.

Press ? for the key list, q to quit.

If the demo looks like garbage — boxes, question marks, mojibake — your terminal or font is not up to unicode. Use:

btview demo --ascii

and add export BTVIEW_ASCII=1 to the robot's shell profile.


3. Point it at a real tree

Your behaviour tree has to be publishing. For Nav2 that is one parameter, set inside the navigator block:

bt_navigator:
  ros__parameters:
    navigate_to_pose:
      plugin: "nav2_bt_navigator::NavigateToPoseNavigator"
      enable_groot_monitoring: true
      groot_server_port: 1667

Then:

btview                          # same machine
btview --host 192.168.1.42      # over the network

Details for other stacks, for BehaviorTree.CPP 3.x, and for what to do when the port is firewalled: nav2.md.

If it cannot connect

btview tells you what it tried and suggests the usual causes. In order of likelihood:

  1. Monitoring is off. It is off by default in Nav2, so nothing is listening. Check with ros2 param get /bt_navigator navigate_to_pose.enable_groot_monitoring.
  2. Wrong port. BehaviorTree.CPP defaults to 1667 and also binds port + 1; check yours with ros2 param get /bt_navigator navigate_to_pose.groot_server_port.
  3. Wrong protocol. BehaviorTree.CPP 3.x speaks a different format — add --protocol v3 (REP 1667, PUB 1666).
  4. The port is not reachable. Test with nc -z <host> 1667, or tunnel it: ssh -L 1667:localhost:1667 robot and then run btview locally.

btview info is the quickest triage — it prints the endpoint, tree size and round-trip latency, or fails with the reason.


4. The three habits worth learning

Watch what is running, nothing else. On a 60-node tree, most nodes are noise:

btview snapshot --active

Log the transitions instead of watching them. This is the one to reach for when a failure happens once an hour:

btview echo --json | tee ~/bt-$(date +%F-%H%M).jsonl

Record on the robot, debug on your laptop. No network, no timing pressure, same UI:

# robot
btview record -o run.btv.jsonl --duration 300
# laptop
btview play run.btv.jsonl --speed 4

Upgrading and removing

pipx upgrade btview
pipx uninstall btview

Shell completion

btview uses argparse, so argcomplete works:

pipx inject btview argcomplete
eval "$(register-python-argcomplete btview)"