> For the complete documentation index, see [llms.txt](https://docs.theseus.us/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.theseus.us/cyclops/developers/manual-relocalization.md).

# Manual Relocalization

If you are flying with Cyclops in the loop but have some additional information (i.e. visual information, or a GPS fix) you are able to manually reset the Cyclops position over MAVLink with Vozilla.

<figure><img src="https://content.gitbook.com/content/hzvlBbeiwnrjdGDAaBcQ/blobs/y1RUrSLx8o8r1F9JTxt4/Peek%202026-05-27%2021-18.gif" alt=""><figcaption></figcaption></figure>

To manually relocalize, right click on the map while connected over MAVLink and click "*Relocalize here*". The Cyclops position will update to the point you clicked. It also resets Cyclops and can be useful if scale or heading estimation is offset.

### Overview

Cyclops can accept a manual relocalize command over MAVLink. Send a targeted `COMMAND_INT` using command id `43003` (`MAV_CMD_EXTERNAL_POSITION_ESTIMATE`) with the new WGS84 latitude and longitude. When accepted, Cyclops synchronously resets its map-match position state to that coordinate.

Use `COMMAND_INT`, not `COMMAND_LONG`, so latitude and longitude are carried as `degE7` integers instead of lossy `float32` values.

### Target

Target the Cyclops MAVLink identity:

| Field              | Default | Source                   |
| ------------------ | ------- | ------------------------ |
| `target_system`    | `218`   | `mavproxy.source_system` |
| `target_component` | `191`   | `mavproxy.mvps_compid`   |

Read the deployed values with:

```bash
vns-config get mavproxy.source_system
vns-config get mavproxy.mvps_compid
```

The command must arrive on a MAVLink path that Cyclops receives. For autopilot Lua scripts, send it from the flight controller.

{% hint style="info" %}
Cyclops now uses MAVLink Router instead of MAVProxy. The `vns-config` commands remain the same, but other MAVProxy-specific commands will not work.
{% endhint %}

To restart MAVLink Router service, use the command:

```bash
sudo systemctl restart mavlink-router.service
```

### COMMAND\_INT Fields

| Field          | Value                                                      |
| -------------- | ---------------------------------------------------------- |
| `command`      | `43003` (`MAV_CMD_EXTERNAL_POSITION_ESTIMATE`)             |
| `frame`        | `MAV_FRAME_GLOBAL` (`0`)                                   |
| `current`      | `0`                                                        |
| `autocontinue` | `0`                                                        |
| `param1`       | `0` for a reset request                                    |
| `param2`       | `0`                                                        |
| `param3`       | Optional accuracy in meters; `0` is accepted               |
| `param4`       | `0`                                                        |
| `x`            | Latitude in `degE7`, e.g. `37.4221234` -> `374221234`      |
| `y`            | Longitude in `degE7`, e.g. `-122.0839876` -> `-1220839876` |
| `z`            | `NaN`; altitude is not used for the reset                  |

Cyclops validates that latitude and longitude are finite and inside normal WGS84 bounds. The target must also be inside the loaded map area.

### Response

Cyclops replies with `COMMAND_ACK` for command `43003`:

| Result                            | Meaning                                                                      |
| --------------------------------- | ---------------------------------------------------------------------------- |
| `MAV_RESULT_ACCEPTED`             | Reset succeeded.                                                             |
| `MAV_RESULT_TEMPORARILY_REJECTED` | Cyclops is already relocalizing. Retry later.                                |
| `MAV_RESULT_FAILED`               | Coordinates are invalid, outside the map, or the map matcher is unavailable. |

After an accepted reset, Cyclops also publishes a `GLOBAL_POSITION_INT` confirmation at the reset coordinate. Normal map matching resumes after the first post-reset odometry sample refreshes the displacement baseline.

### pymavlink Example

```python
import math
from pymavlink import mavutil

MAV_CMD_EXTERNAL_POSITION_ESTIMATE = 43003

lat = 37.4221234
lon = -122.0839876

master = mavutil.mavlink_connection("udpout:192.168.218.100:14610")
master.mav.command_int_send(
    218,  # target_system: mavproxy.source_system
    191,  # target_component: mavproxy.mvps_compid
    mavutil.mavlink.MAV_FRAME_GLOBAL,
    MAV_CMD_EXTERNAL_POSITION_ESTIMATE,
    0,  # current
    0,  # autocontinue
    0,  # param1: reset request
    0,  # param2
    0,  # param3: optional accuracy_m
    0,  # param4
    round(lat * 1e7),
    round(lon * 1e7),
    math.nan,
)

ack = master.recv_match(type="COMMAND_ACK", blocking=True, timeout=3)
print(ack)
```

Use the endpoint that reaches Cyclops in your deployment. With MAVProxy, that is the flight-controller path or a configured upstream endpoint like the example above.
