> 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 (maybe visual information, or a GPS fix) you may want to reset the cyclops and ekf position to that new ground truth. You can do that when connected the the drone over mavlink with vozilla.

<figure><img src="/files/ilsPtZLVVo8Gq49KGvjQ" alt=""><figcaption></figcaption></figure>

Just right click on the map while connected over mavlink and click "Relocalize here" to move the EKF and cyclops 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. For external test clients using MAVProxy, add a temporary upstream endpoint and restart MAVProxy:

```bash
vns-config add mavproxy.device udpin:0.0.0.0:14610
sudo systemctl restart mavproxy
```

The standard external GCS output is not forwarded to other MAVProxy outputs, so it is not a reliable path for commands targeted at Cyclops.

### 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.
