Metadata-Version: 2.4
Name: artefacts_route_recorder
Version: 0.2.0
Summary: Record navigation routes (a start pose and waypoints) by clicking in RViz, and save them as YAML for tests to drive.
Author-email: TN <tomo@artefacts.com>
Project-URL: Homepage, https://github.com/art-e-fact/artefacts-route-recorder
Project-URL: Bug Tracker, https://github.com/art-e-fact/artefacts-route-recorder/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: PyYAML>=5.1
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: setuptools-scm; extra == "dev"
Requires-Dist: twine; extra == "dev"

# artefacts-route-recorder

A CLI tool that allows users to set their navigation routes by clicking in RViz, storing to YAML, which can then be later loaded into simulation tests through
[artefacts-toolkit-navigation](https://github.com/art-e-fact/artefacts-toolkit-navigation). (`artefacts-route-recorder` is included in `artefacts-toolkit-navigation`)

A route is an optional start pose plus an ordered list of waypoints, each
`{x, y, yaw}` in metres/radians in a named frame (`map` by default).

Works on ROS 2 Humble (Python 3.10) and Jazzy (Python 3.12), and needs only
`rclpy`, the standard message packages and PyYAML.

## Quick start

```bash
# source python environment if using a venv
source venv/bin/activate
# source ros
source /opt/ros/<ros-distro>/setup.bash  # setup.zsh under zsh
# Record a route on Turtlebot3 demo
artefacts-route record routes/lab.yaml --map /opt/ros/jazzy/share/nav2_bringup/maps/tb3_sandbox.yaml
# /opt/ros/humble/share/nav2_bringup/maps/turtlebot3_world.yaml
```

Click **2D Pose Estimate** once where the robot should start, then **Publish
Point** for each waypoint. Close RViz or press enter in the terminal to save
`routes/lab.yaml`. `artefacts-route replay` draws it back.

## Installation

### Pre-requisites
If using `record --map` (i.e with a preexisting map) you will need to install `nav2_map_server`

```bash
sudo apt install ros-<distro>-nav2-map-server
```

### Install

```bash
source /opt/ros/<ros-distro>/setup.bash
python3 -m venv --system-site-packages venv  # if using a virtual environment
source venv/bin/activate # if using
pip install artefacts-route-recorder
```

## Recording

There are two ways to record, depending on whether you already have RViz up.

**1. RViz (and a map) already running** 

```bash
artefacts-route record [routes/<name>.yaml]
```

The recorder just subscribes to the topics the RViz tools publish on. Add
`--map-ref maps/<map-name>.yaml` if you want the route file to remember which map it
was recorded against (path plus a sha256 of the yaml and image); this does not
launch anything.

**2. Nothing is running and you only have a saved map**

```bash
artefacts-route record [routes/<name>.yaml] --map maps/<map-name>.yaml
```

This starts `nav2_map_server` on that map, drives it through configure/activate,
and opens RViz with the bundled config (`rviz/record.rviz`) already pointed at
`/map` and `/route_markers`. Closing RViz saves the route and quits.

Use **Publish Point** for waypoints when Nav2 is running: a **2D Goal Pose**
click is recorded too, but Nav2 also drives the robot there.

### Terminal commands while recording

```
[enter] or s   save and quit          u   undo the last waypoint
q              quit without saving    c   clear all waypoints (keeps start pose)
l              list what is recorded   h   help
```

Ctrl-C also saves and quits.

The route is saved to the file you give, or to `routes/<date>_<time>.yaml` if not provided.
The filename is also the route's name. `--force` overwrites an existing file.

## Inspecting and replaying

```bash
artefacts-route list                   # all routes in routes/, * marks the most recent
artefacts-route show                   # print the latest route's YAML + any problems
artefacts-route show routes/lab_loop.yaml
artefacts-route replay                 # publish the latest route as RViz markers
artefacts-route replay routes/lab_loop.yaml
```

`replay` publishes a `visualization_msgs/MarkerArray` on `/route_markers` with
**transient local** durability, so RViz picks it up whenever it connects: a
blue line through the waypoints, a green arrow and an index label at each one,
and an orange arrow for the start pose. The bundled RViz config already has a
matching MarkerArray display.

`routes/.latest` remembers the last route saved into `routes/`, which is what
the commands above default to. Give `show`, `replay` or `list` a directory
instead of a file for the latest route in it.

## YAML format

```yaml
format_version: 1
name: lab_loop
recorded_at: "2026-09-17T14:55:00+00:00"
ros_distro: jazzy
frame_id: map
map:                              # null unless --map/--map-ref was used
  file: maps/lab.yaml
  sha256: "abc123..."
initial_pose: {x: 1.2, y: 0.45, yaw: 0.0}    # null if never set
waypoints:
  - {x: 3.1, y: 0.5, yaw: 0.0}
  - {x: 3.1, y: 2.8, yaw: 1.5708}
```

### Loading routes from Python

```python
from artefacts_route_recorder.schema import Route, RoutesDir

route, path = RoutesDir("routes").find("lab_loop")   # None = the latest route
route = Route.load("routes/lab_loop.yaml")
print(route.initial_pose, route.waypoints)
```

## Release

Releases go to PyPI (sdist and wheel), built and uploaded by `bin/release`:

1. Move the `[Unreleased]` notes in `CHANGELOG.md` under the new version and commit.
2. Tag that commit with the bare version: `git tag 0.1.0`. The package version
   comes from this tag (setuptools-scm).
3. `pip install -e ".[dev]"` once, for `build`, `setuptools-scm` and `twine`.
4. `bin/release` uploads to TestPyPI; `bin/release production` to PyPI.
