# GUIDED mode requirement

**URL:** https://discuss.bluerobotics.com/t/guided-mode-requirement/20171
**Category:** General Discussion
**Tags:** ardusub, pymavlink
**Created:** [April 23, 2025, 2:53pm UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171 "2025-04-23T14:53:19Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![chang-M](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@chang-M](https://discuss.bluerobotics.com/u/chang-M)
#### Post date: [April 23, 2025, 2:53pm UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/1 "2025-04-23T14:53:19Z")

</div>

Hi! I want to use GUIDED mode to do some development, but I found that I couldn’t switch to this mode. Is there any other requirement to switch this mode? I have sent the location via GPS\_INPUT message to the rov and the rov has also received the message.

---

<div class="post-metadata">

### Author: ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)
#### Post date: [April 23, 2025, 5:16pm UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/2 "2025-04-23T17:16:39Z")

</div>

Hi @chang-M -  
Guided mode indeed requires the autopilot to know its position. What messages are you generating with location, and how? How are they being sent to the autopilot?  
Your motion sensors also need to be calibrated (accelerometer & compass) to be in this mode as well…

---

<div class="post-metadata">

### Author: ![chang-M](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@chang-M](https://discuss.bluerobotics.com/u/chang-M)
#### Post date: [April 24, 2025, 2:47am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/3 "2025-04-24T02:47:07Z")

</div>

@tony-white Thank you for your reply, My message code is as follows:

```auto
def send_gps_input(master, lat, lon, hdop, fix_quality, numsats):
    try:
        time_usec = int(time.time() * 1e6)

        # 1e7 
        lat_int = int(lat * 1e7)
        lon_int = int(lon * 1e7)

        # GPS_INPUT_IGNORE_FLAGS
        ignore_flags = (mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_VEL_HORIZ |
             mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_VEL_VERT |
             mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_SPEED_ACCURACY)

        master.mav.gps_input_send(
            time_usec, # Timestamp (micros since boot or Unix epoch)
            0, # ID of the GPS for multiple GPS inputs
            # Flags indicating which fields to ignore (see GPS_INPUT_IGNORE_FLAGS enum).
            # All other fields must be provided.
            ignore_flags,
            0, # GPS time (milliseconds from start of GPS week)
            0, # GPS week number
            fix_quality, # 0-1: no fix, 2: 2D fix, 3: 3D fix. 4: 3D with DGPS. 5: 3D with RTK
            lat_int, # Latitude (WGS84), in degrees * 1E7
            lon_int, # Longitude (WGS84), in degrees * 1E7
            0, # Altitude (AMSL, not WGS84), in m (positive for up)
            int(hdop * 100), # GPS HDOP horizontal dilution of position in m
            1, # GPS VDOP vertical dilution of position in m
            0, # GPS velocity in m/s in NORTH direction in earth-fixed NED frame
            0, # GPS velocity in m/s in EAST direction in earth-fixed NED frame
            0, # GPS velocity in m/s in DOWN direction in earth-fixed NED frame
            0, # GPS speed accuracy in m/s
            0, # GPS horizontal accuracy in m
            0, # GPS vertical accuracy in m
            numsats # Number of satellites visible.
        )
        print(f"GPS_INPUT sent: lat={lat}, lon={lon}, hdop={hdop}, numsats={numsats}")
    except Exception as e:
        print(f"Failed to send GPS_INPUT: {e}")

```

After executing the code, I can see the correct position in the GLOBAL\_POSITION\_INT message, and also display the position correctly in QGC, but I can’t switch to GUIDED mode. And there is another problem, which is when I use SET\_POSITION\_TARGET\_GLOBAL\_INT to set the rov position in ALT\_HOLD mode, the lat and lon of the message are invalid, and the robot is just moving up and down to the target alt. Is this also the two reasons you mentioned above?  
This is my code for setting the location:

```auto
    def set_global_position(self):
        type_mask = (  
                # mavutil.mavlink.POSITION_TARGET_TYPEMASK_X_IGNORE |
                # mavutil.mavlink.POSITION_TARGET_TYPEMASK_Y_IGNORE |
                # mavutil.mavlink.POSITION_TARGET_TYPEMASK_Z_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_VX_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_VY_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_VZ_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_AX_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_AY_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_AZ_IGNORE |
                # mavutil.mavlink.POSITION_TARGET_TYPEMASK_FORCE_SET |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_YAW_IGNORE |
                mavutil.mavlink.POSITION_TARGET_TYPEMASK_YAW_RATE_IGNORE
        )
        # MAV_FRAME_GLOBAL
        # MAV_FRAME_GLOBAL_RELATIVE_ALT
        # MAV_FRAME_GLOBAL_TERRAIN_ALT

        lat,lon = get_target_location()
        if lat is None or lon is None:
            LOG.error('The target location cannot be obtained, please check the UGPS')
            return
        self.master.mav.set_position_target_global_int_send(
            int(1e3 * (time.time() - self.boot_time)),
            self.master.target_system, self.master.target_component,
            mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT,
            type_mask,
            int(lat * 1e7),
            int(lon * 1e7),
            -0.5, # alt
            0, 0, 0, # speed
            0, 0, 0, # acc
            0, 0 # yaw, yaw_rate
        )

```

---

<div class="post-metadata">

### Author: ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)
#### Post date: [April 24, 2025, 5:29pm UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/4 "2025-04-24T17:29:16Z")

</div>

Hi @chang-M -  
This python script shows how to send position and heading to the vehicle. To use it, copy the text and save it as fake\_gps\_yaw.py:

1. In BlueOS, navigate to terminal, take red-pill, and nano a new file named fake\_gps\_yaw.py, save (cntrl o) and exit (cntrl x).
2. chmod +X fake\_gps\_yaw.py
3. Edit the file (nano fake\_gps\_yaw.py) and on line 96, change the IP address of the vehicle to an interface it has a connection on - typically this would be 192.168.2.2 as this is the static IP on the Pi ethernet adapter by default, the example is what I used for my unit that is only connected via WiFi and received that dhcp address.  
response = requests.post(‘[http://192.168.1.23:6040/mavlink](http://192.168.1.23:6040/mavlink)’, json=payload)
4. Optionally edit the error message on line 101 to use the same IP address.
5. In autopilot parameters, verify that `EK3_SRC1_POSXY`, `EK3_SRC1_YVELXY`, `EK3_SRC1_YAW`, are all set to GPS. Also verify that `GPS_TYPE` is set to MAV.
6. Run the script. The vehicle will jump to the coordinates and heading described in the file, and update as the script runs.

```py
import requests
import json
import time
from datetime import datetime, timezone
import math

def get_gps_week_and_ms():
    # GPS epoch started January 6, 1980
    gps_epoch = datetime(1980, 1, 6, tzinfo=timezone.utc)
    current = datetime.now(timezone.utc)
    
    # Calculate total seconds since GPS epoch
    total_seconds = (current - gps_epoch).total_seconds()
    
    # Calculate GPS week number (7 days = 604800 seconds)
    week = math.floor(total_seconds / 604800)
    
    # Calculate milliseconds into the week
    ms = int((total_seconds % 604800) * 1000)
    
    return week, ms

def calculate_circle_position(center_lat, center_lon, radius, angle_degrees):
    """
    Calculate position and yaw for a point on a circle
    radius in meters, angle in degrees
    Returns lat, lon (in 1e7 format) and yaw in degrees
    """
    # Convert center coordinates from 1e7 format to radians
    lat1 = center_lat / 1e7 * math.pi / 180
    lon1 = center_lon / 1e7 * math.pi / 180
    
    # Earth's radius in meters
    R = 6378137.0
    
    # Convert angle to radians
    angle_rad = math.radians(angle_degrees)
    
    # Calculate offset position
    dx = radius * math.cos(angle_rad)
    dy = radius * math.sin(angle_rad)
    
    # Calculate new position
    new_lat = lat1 + (dy / R)
    new_lon = lon1 + (dx / R) / math.cos(lat1)
    
    # Convert back to degrees * 1e7
    new_lat_e7 = int(new_lat * 180 / math.pi * 1e7)
    new_lon_e7 = int(new_lon * 180 / math.pi * 1e7)
    
    # Calculate yaw (90 degrees offset from angle as yaw is clockwise from north)
    yaw = (angle_degrees + 90) % 360
    
    return new_lat_e7, new_lon_e7, yaw

def send_gps_data(lat, lon, alt, yaw):
    # Get current GPS week and milliseconds
    week, week_ms = get_gps_week_and_ms()
    
    # Current time in microseconds
    time_usec = int(time.time() * 1e6)
    
    payload = {
        "header": {
            "system_id": 255,
            "component_id": 0,
            "sequence": 0
        },
        "message": {
            "type": "GPS_INPUT",
            "time_usec": time_usec,
            "time_week_ms": week_ms,
            "lat": int(lat), # Latitude in degrees * 1e7
            "lon": int(lon), # Longitude in degrees * 1e7
            "alt": int(alt), # Altitude in meters * 1e3 (millimeters)
            "hdop": 100, # Horizontal dilution of precision (100 = 1.0)
            "vdop": 100, # Vertical dilution of precision (100 = 1.0)
            "vn": 0, # North velocity in m/s
            "ve": 0, # East velocity in m/s
            "vd": 0, # Down velocity in m/s
            "speed_accuracy": 100, # Speed accuracy in mm/s
            "horiz_accuracy": 100, # Horizontal accuracy in mm
            "vert_accuracy": 200, # Vertical accuracy in mm
            "ignore_flags": {
                "bits": 0 # 0 means use all fields
            },
            "time_week": week,
            "gps_id": 0,
            "fix_type": 3, # 3D fix
            "satellites_visible": 10,
            "yaw": int(yaw * 100) # Updated yaw value
        }
    }

    try:
        response = requests.post('http://192.168.15.10:6040/mavlink', json=payload)
        if response.status_code != 200:
            print(f"Failed to send GPS data. Status code: {response.status_code}")
            print(f"Response content: {response.text}")
    except requests.exceptions.ConnectionError as e:
        print(f"Connection Error: Could not connect to mavlink2rest server at http://192.168.15.10:6040")
        print(f"Detailed error: {str(e)}")
    except requests.exceptions.RequestException as e:
        print(f"Error sending GPS data: {type(e). __name__ }")
        print(f"Detailed error: {str(e)}")

def main():
    # Center coordinates (San Francisco, CA)
    center_lat = 377777778 # 37.7777778 degrees
    center_lon = -1224167778 # -122.4167778 degrees
    alt = 10000 # 10 meters (in millimeters)
    radius = 10 # 10 meters radius
    
    angle = 0.0
    while True:
        # Calculate new position and yaw
        lat, lon, yaw = calculate_circle_position(center_lat, center_lon, radius, angle)
        print(f"Sending GPS data: Lat={lat/1e7}, Lon={lon/1e7}, Alt={alt/1e3}m, Yaw={yaw}")
        send_gps_data(lat, lon, alt, yaw)
        
        # Increment angle (1 degree per update)
        angle = (angle + 1) % 360
        time.sleep(0.1) # Send GPS data every second

if __name__ == " __main__":
    main() 

```

---

<div class="post-metadata">

### Author: ![chang-M](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@chang-M](https://discuss.bluerobotics.com/u/chang-M)
#### Post date: [April 29, 2025, 5:41am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/5 "2025-04-29T05:41:58Z")

</div>

Thank you for your explanation ! @EliotBR  
I have another question, that is, when I switch to GUIDED mode in QGC, there will be an error in MAV\_COM(176). I have sent location information to my rov through the GPS\_INPUT message, and my robot also displays location in the QGC and GLOBAL\_POSITION\_INT message. EK3\_SRC1\_POSXY, EK3\_SRC1\_YVELXY has been set to GPS. Do I need to set other parameters? Or is it because my location information is missing some key factors？  
Here is the sending location code:

```auto
def send_gps_input(master, lat, lon, hdop, fix_quality, numsats):
    try:
        time_usec = int(time.time() * 1e6)

        lat_int = int(lat * 1e7)
        lon_int = int(lon * 1e7)

        # GPS_INPUT_IGNORE_FLAGS
        ignore_flags = (mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_VEL_HORIZ |
             mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_VEL_VERT |
             mavutil.mavlink.GPS_INPUT_IGNORE_FLAG_SPEED_ACCURACY)

        master.mav.gps_input_send(
            time_usec, # Timestamp (micros since boot or Unix epoch)
            0, # ID of the GPS for multiple GPS inputs
            # Flags indicating which fields to ignore (see GPS_INPUT_IGNORE_FLAGS enum).
            # All other fields must be provided.
            ignore_flags,
            0, # GPS time (milliseconds from start of GPS week)
            0, # GPS week number
            fix_quality, # 0-1: no fix, 2: 2D fix, 3: 3D fix. 4: 3D with DGPS. 5: 3D with RTK
            lat_int, # Latitude (WGS84), in degrees * 1E7
            lon_int, # Longitude (WGS84), in degrees * 1E7
            0, # Altitude (AMSL, not WGS84), in m (positive for up)
            int(hdop * 100), # GPS HDOP horizontal dilution of position in m
            1, # GPS VDOP vertical dilution of position in m
            0, # GPS velocity in m/s in NORTH direction in earth-fixed NED frame
            0, # GPS velocity in m/s in EAST direction in earth-fixed NED frame
            0, # GPS velocity in m/s in DOWN direction in earth-fixed NED frame
            0, # GPS speed accuracy in m/s
            0, # GPS horizontal accuracy in m
            0, # GPS vertical accuracy in m
            numsats # Number of satellites visible.
        )
        print(f"GPS_INPUT sent: lat={lat}, lon={lon}, hdop={hdop}, numsats={numsats}")
    except Exception as e:
        print(f"Failed to send GPS_INPUT: {e}")

```

---

<div class="post-metadata">

### Author: ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)
#### Post date: [April 29, 2025, 6:36am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/6 "2025-04-29T06:36:38Z")

</div>

Hi @chang-M,

I’ve moved your comment here, because it’s on the same topic.

> [@PX4 disarmed automatically](https://discuss.bluerobotics.com/t/px4-disarmed-automatically/20126/6):
>
> when I switch to GUIDED mode in QGC, there will be an error in MAV\_COM(176).

That’s [the mode switch message](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_MODE). The command failure/rejection should be accompanied by some kind of error message, or at least an error type should be findable through the corresponding [`MAV_RESULT`](https://mavlink.io/en/messages/common.html#MAV_RESULT) that the autopilot replies with.

> [@PX4 disarmed automatically](https://discuss.bluerobotics.com/t/px4-disarmed-automatically/20126/6):
>
> EK3\_SRC1\_POSXY, EK3\_SRC1\_YVELXY has been set to GPS. Do I need to set other parameters?

As in @tony-white’s response above, you should

> [@tony-white](#):
>
> Also verify that `GPS_TYPE` is set to MAV.

---

<div class="post-metadata">

### Author: ![chang-M](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@chang-M](https://discuss.bluerobotics.com/u/chang-M)
#### Post date: [April 29, 2025, 7:10am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/7 "2025-04-29T07:10:20Z")

</div>

Yes, my GPS\_TYPE is also set to MAV, and I execute the command to switch to GUIDED mode. The result is MAV\_RESULT\_FAILED. Is it because the ardusub system has any checks? I also tried all the options to turn off GPS\_CHECK and still returned this result.  
The underwater GPS I use is the SBL of waterlink. Can I use [this code from four years ago](https://github.com/bluerobotics/companion/blob/master/tools/underwater-gps.py) (change the addresses of MAV2RESET and other interfaces in it) to perform underwater positioning? Is there a built-in underwater positioning device processing program in blueos? (just like ping360 sonar and p30)

---

<div class="post-metadata">

### Author: ![chang-M](https://avatars.discourse-cdn.com/v4/letter/c/439d5e/32.png) [@chang-M](https://discuss.bluerobotics.com/u/chang-M)
#### Post date: [May 7, 2025, 4:36am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/8 "2025-05-07T04:36:38Z")

</div>

@EliotBR@tony-white Thank you for your help 😃. I am now able to switch to GUIDED mode, but I still can’t switch to AUTO mode. When switching to AUTO mode, I will not return any MAV\_RESULT messages when I keep waiting. Why is this? Are there any conditions required to use AUTO mode? I couldn’t switch to AUTO mode during the system trial in the upper right corner of the [BlueOS document website](https://blueos.cloud/docs/latest/usage/overview/). Is it because the firmware itself does not support AUTO mode?

---

<div class="post-metadata">

### Author: ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)
#### Post date: [May 7, 2025, 5:55am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/9 "2025-05-07T05:55:15Z")

</div>

Hi @chang-M -  
Have you uploaded a valid mission file to the autopilot? This is required for auto mode to have something to follow…

---

<div class="post-metadata">

### Author: ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)
#### Post date: [May 7, 2025, 6:50am UTC](https://discuss.bluerobotics.com/t/guided-mode-requirement/20171/10 "2025-05-07T06:50:56Z")

</div>

> [@chang-M](#):
>
> The underwater GPS I use is the SBL of waterlink. Can I use [this code from four years ago](https://github.com/bluerobotics/companion/blob/master/tools/underwater-gps.py) (change the addresses of MAV2RESET and other interfaces in it) to perform underwater positioning? Is there a built-in underwater positioning device processing program in blueos?

That code is from our old Companion software, which is no longer maintained or supported.

WaterLinked UGPS support is not built in to BlueOS, but is instead available through [a dedicated Extension](https://docs.bluerobotics.com/BlueOS-Extensions-Repository/#:~:text=Water%20Linked%20UGPS,-Maintainer), which you can install through the [Extensions manager](https://blueos.cloud/docs/stable/usage/advanced/#extensions-manager) 🙂
