mavlink / MAVSDK-Python

MAVSDK client for Python.
https://mavsdk.mavlink.io
BSD 3-Clause "New" or "Revised" License
326 stars 221 forks source link

health.is_global_position_ok with Ardupilot #668

Open Jai-GAY opened 8 months ago

Jai-GAY commented 8 months ago

this line of code does not work with Ardupilot. It never comes out from the for loop. MissionPlanner reports GPS is healthy, and Ardupilot acquired a home position.

if health.is_global_position_ok and health.is_home_position_ok:

telemetry.Health

Pi4B Ubuntu 22.04 64-bit Arducopter v4.2.3 Name: mavsdk Version: 2.1.0 Summary: Python wrapper for MAVSDK Home-page: https://github.com/mavlink/MAVSDK-Python Author: Author-email: License: UNKNOWN Location: /home/pi/.local/lib/python3.10/site-packages Requires: aiogrpc, grpcio, protobuf Required-by: $

arpitpara commented 8 months ago

Try printing what is the response of health from telemetry: async for health in drone.telemetry.health(): print(health,'Drone Health') if health.is_global_position_ok and health.is_home_position_ok: print("-- Global position state is good enough for flying.")

It checks for your Home position is set or not with GPS health.

Jai-GAY commented 8 months ago

Try printing what is the response of health from telemetry:

If I don't break from the for loop, I don't see anything printing. I can only do once or I try to do a counter.

arpitpara commented 8 months ago

Actually you should be getting some response printing cuz everytime you ask for response telemetry it gives you something.. if condition only is for checking if it's ok or not. you can put a break statement after and can only run it for once. Just for testing that only this statement is a problem or not.

JonasVautherin commented 8 months ago

If it hangs there, it may mean that it never receives the message it expects. Is there a different MAVLink message between PX4 and Ardupilot here?

Jai-GAY commented 8 months ago

From this doc, it expects a boolean, my guess is all are false always.

Is there a different MAVLink message between PX4 and Ardupilot here?

Not sure, Copter Mission Command List.

Jai-GAY commented 8 months ago

Try printing what is the response of health from telemetry:

is the is_global_position_ok that failed it. But is_home_position_ok is okay, and is_armable: False, interesting. MP got the GPS: 3D Fix.

***** test code start ****
    print("Waiting for drone to have a global position estimate...")
    i = 0
    async for health in drone.telemetry.health():
        print("-- Health : ", health, " i = ", i)
        if health.is_global_position_ok:  # and health.is_home_position_ok:
            print("-- Global position state is good enough for flying.")
            break
        else:
            print("-- Global position state NOT good for flying. i = ", i)
            if i > 2:
                break
            i = i + 1
            await asyncio.sleep(0.5)
***** test code end ****
Main in
System server b4
System server done
Pi4B Waiting for drone to connect...
-- Connected to drone!
Version: [flight_sw_major: 4, flight_sw_minor: 2, flight_sw_patch: 3, flight_sw_vendor_major: 56, flight_sw_vendor_minor: 52, flight_sw_vendor_patch: 97, os_sw_major: 0, os_sw_minor: 0, os_sw_patch: 0, flight_sw_git_hash: 376130633 , os_sw_git_hash: 663466323230383 , flight_sw_version_type: RELEASE]
Waiting for drone to have a global position estimate...
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, **is_global_position_ok: False**, **is_home_position_ok: True**, is_armable: False]  i =  0
-- Global position state NOT good for flying. i =  0
Battery: 9800.0
Battery_v: 15.52500057220459
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  1
-- Global position state NOT good for flying. i =  1
Battery: 9800.0
Battery_v: 15.528000831604004
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, **is_global_position_ok: False**, **is_home_position_ok: True**, is_armable: False]  i =  2
-- Global position state NOT good for flying. i =  2
Battery: 9800.0
Battery_v: 15.481000900268555
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  3
-- Global position state NOT good for flying. i =  3
Battery: 9800.0
Battery_v: 15.533000946044922
Battery: 9800.0
Battery_v: 15.533000946044922
Battery: 9800.0
Battery_v: 15.533000946044922
print_status_text CancelledError
Battery: 9800.0
Battery_v: 15.527000427246094
Battery: 9800.0
Battery_v: 15.533000946044922
Battery: 9800.0
Battery_v: 15.53700065612793
print_battery CancelledError
-- run ended
Main out
arpitpara commented 8 months ago

Yeah !! Your GPS needs to be fixed. check if you can arm it through MP or try doing GPS calibration. ' is_global_position_ok: False,' This is the indicator that it doesn't get any GPS location. You can try getting your GPS info printed through telemetry through another example, 'examples/telemetry.py'.

Jai-GAY commented 8 months ago

Your GPS needs to be fixed. check if you can arm it through MP or try doing GPS calibration.

GPS already re-calibrated. MP already reported 3D Fix. I can arm with loiter flight mode and fly. Mavsdk-python reports is_home_position_ok: True, isn't it gps is healthy?

'examples/telemetry.py'

Okay, will take a look at the code.

Jai-GAY commented 8 months ago

You can try getting your GPS info printed through telemetry through another example, 'examples/telemetry.py'.

likely found the problem, not working, no printing.

I think similar something to this is missing. await drone.telemetry.set_rate_battery(1)

print_position CancelledError print_gps_info CancelledError

**** test code function ***
async def print_gps_info(drone):
    try:
        async for gps_info in drone.telemetry.gps_info():
            print(f"GPS info: {gps_info}")
    except asyncio.CancelledError:
        print("print_gps_info CancelledError")
        return  # pass

async def print_position(drone):
    try:
        async for position in drone.telemetry.position():
            print(f"Position info: {position}")
    except asyncio.CancelledError:
        print("print_position CancelledError")
        return  # pass
**** test code function ***
Jai-GAY commented 8 months ago

subscribe to these, now we have the info. the problem is clear. Also is_armable: False is a concern where the hardware safety switch is off.

telem_gps = asyncio.ensure_future(print_gps_info(drone))
await drone.telemetry.set_rate_gps_info(1)
telem_pos = asyncio.ensure_future(print_position(drone))
await drone.telemetry.set_rate_position(1)

also do we need to call the drone.telemetry.position() and drone.telemetry.gps_info()? I subscribed to this drone.telemetry.status_text(), but no printing. so I wonder if telemetry.position() and telemetry.gps_info() is of any use. status_text_task = asyncio.ensure_future(print_status_text(drone))

Main in
System server b4
System server done
Pi4B Waiting for drone to connect...
-- Connected to drone!
Version: [flight_sw_major: 4, flight_sw_minor: 2, flight_sw_patch: 3, flight_sw_vendor_major: 56, flight_sw_vendor_minor: 52, flight_sw_vendor_patch: 97, os_sw_major: 0, os_sw_minor: 0, os_sw_patch: 0, flight_sw_git_hash: 376130633 , os_sw_git_hash: 663466323230383 , flight_sw_version_type: RELEASE]
Battery: 9700.0
Battery_v: 15.351000785827637
Waiting for drone to have a global position estimate...
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  0
-- Global position state NOT good for flying. i =  0
Battery: 9700.0
Battery_v: 15.357000350952148
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  1
-- Global position state NOT good for flying. i =  1
**Position info: Position: [latitude_deg: 1.XXXXXX, longitude_deg: 103.YYYYYY, absolute_altitude_m: 21.830001831054688, relative_altitude_m: -0.010000000707805157]**
**GPS info: GpsInfo: [num_satellites: 15, fix_type: FIX_3D]**
Battery: 9700.0
Battery_v: 15.358000755310059
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  2
-- Global position state NOT good for flying. i =  2
Position info: Position: [latitude_deg: 1.XXXX, longitude_deg: 103.YYYYY, absolute_altitude_m: 21.830001831054688, relative_altitude_m: -0.013000000268220901]
GPS info: GpsInfo: [num_satellites: 15, fix_type: FIX_3D]
Battery: 9700.0
Battery_v: 15.35400104522705
-- Health :  Health: [is_gyrometer_calibration_ok: True, is_accelerometer_calibration_ok: True, is_magnetometer_calibration_ok: True, is_local_position_ok: False, is_global_position_ok: False, is_home_position_ok: True, is_armable: False]  i =  3
-- Global position state NOT good for flying. i =  3
Position info: Position: [latitude_deg: 1.XXXXX, longitude_deg: 103.YYYYYY, absolute_altitude_m: 21.84000015258789, relative_altitude_m: -0.00800000037997961]
GPS info: GpsInfo: [num_satellites: 15, fix_type: FIX_3D]
Battery: 9700.0
Battery_v: 15.36500072479248
Position info: Position: [latitude_deg: 1.XXXXX, longitude_deg: 103.YYYYY, absolute_altitude_m: 21.850000381469727, relative_altitude_m: 0.004000000189989805]
GPS info: GpsInfo: [num_satellites: 15, fix_type: FIX_3D]
Battery: 9700.0
Battery_v: 15.368000984191895
Position info: Position: [latitude_deg: 1.XXXXX, longitude_deg: 103.YYYYYY, absolute_altitude_m: 21.84000015258789, relative_altitude_m: -0.0020000000949949026]
GPS info: GpsInfo: [num_satellites: 15, fix_type: FIX_3D]
Battery: 9700.0
Battery_v: 15.367000579833984
print_position CancelledError
print_gps_info CancelledError
print_status_text CancelledError
Battery: 9700.0
Battery_v: 15.358000755310059
Battery: 9700.0
Battery_v: 15.374000549316406
Battery: 9700.0
Battery_v: 15.342000961303711
print_battery CancelledError
-- run ended
Main out

[edit] this one works, but there is no set rate function. telem_rawgps = asyncio.ensure_future(print_gps_rawgps(drone)) drone.telemetry.raw_gps()

RawGps info: RawGps: [timestamp_us: 219937000, latitude_deg: 1.XXXXXX, longitude_deg: 103.YYYYYY, absolute_altitude_m: 26.32000160217285, hdop: 0.8700000047683716, vdop: 1.5499999523162842, velocity_m_s: 0.009999999776482582, cog_deg: 0.0, altitude_ellipsoid_m: 32.749000549316406, horizontal_uncertainty_m: 1.3920000791549683, vertical_uncertainty_m: 2.513000011444092, velocity_uncertainty_m_s: 0.33000001311302185, heading_uncertainty_deg: 0.0, yaw_deg: 0.0]

When the drone is indoors, wonder where RawGps gets the latitude and longitude.

Position info: Position: [latitude_deg: 0.0, longitude_deg: 0.0, absolute_altitude_m: 0.0, relative_altitude_m: 2.5890002250671387] GPS info: GpsInfo: [num_satellites: 0, fix_type: NO_FIX] RawGps info: RawGps: [timestamp_us: 0, latitude_deg: 1.XXXXXXX, longitude_deg: 103.YYYYYYY, absolute_altitude_m: 22.380001068115234, hdop: 99.98999786376953, vdop: 99.98999786376953, velocity_m_s: 0.0, cog_deg: 0.0, altitude_ellipsoid_m: 28.809001922607422, horizontal_uncertainty_m: 1936663.0, vertical_uncertainty_m: 1369427.25, velocity_uncertainty_m_s: 1000.0000610351562, heading_uncertainty_deg: 0.0, yaw_deg: 0.0]

arpitpara commented 8 months ago

You might wanna try downgrading your Ardupilot Firmware Stable Version. 4.1 or less.

Jai-GAY commented 8 months ago

downgrading your Ardupilot Firmware Stable Version. 4.1 or less.

the latest stable version is 4.4.4, and 4.5.0 is in the last stage of beta testing before release. There are many bug fixes and performance improvements. Moving back to 4.1 meaning the users have to forgo the fixes and improvements.

arpitpara commented 8 months ago

No it doesn't mean that you're permanently shifting to 4.1. It helps us find out the bug and we might be able to fix it in further releases. Some version upgrades changes the parameters inside the firmware, If the code is running on older version and not new, we can update the code with newer parameters according to Firmware Version.

ilamanov commented 7 months ago

I am seeing the same issue on the following: MAVSDK-python version: 2.3.0 Arducopter: 4.5.1

I always get

Health: [
is_gyrometer_calibration_ok: True,
is_accelerometer_calibration_ok: True,
is_magnetometer_calibration_ok: True,
is_local_position_ok: False,
is_global_position_ok: False,
is_home_position_ok: True,
is_armable: False
]
julianoes commented 7 months ago

@ilamanov what's the setup where you test this? SITL, or real copter (outside) with GPS signal? Just so I know how to reproduce this.

ilamanov commented 7 months ago

@julianoes It's a real copter outside with ~17 sats

ShafSpecs commented 6 months ago

Not sure if this is related but I do get a few telemetry methods hanging with ardupilot:

Anytime I attempt to print them, it just hangs. Till I manually break out of the loop or shut the program down. Health works well for me though

Jai-GAY commented 6 months ago

Anytime I attempt to print them, it just hangs.

Try again with print("XXXX", flush=True)

Health works well for me though

are you saying you can get both two conditions true in your test? if health.is_global_position_ok and health.is_home_position_ok: Which mavsdk-python version are you using? Which flight stack are you using?