Requesting EXTENDED_SYS_STATE

Hello,
I am trying get the EXTENDED_SYS_STATE message so I could have access to landed_state to check if the drone is on ground or not. I tried using a code that worked in the past to get another message and it’s fields, but it strangely does not work when I replace with the EXTENDED_SYS_STATE respective information.

# -*- coding: utf-8 -*-

from __future__ import print_function
import time
from dronekit import connect, VehicleMode, LocationGlobalRelative


# Set up option parsing to get connection string
import argparse
parser = argparse.ArgumentParser(description='Commands vehicle using vehicle.simple_goto.')
parser.add_argument('--connect',
                    help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()

connection_string = args.connect
sitl = None

# Connect to the Vehicle
print('Connecting to vehicle on: %s' % connection_string)
vehicle = connect(connection_string, wait_ready=True)

while True:
    @vehicle.on_message('EXTENDED_SYS_STATE')
    def listener(self, name, message):
        print(message.landed_state)


vehicle.close()

the command I use to run the script and the output I receive is this :
image

I am using a simulated drone create from a fork from the ardupilot master and dronekit. Is there something different about this message that I need to add other functions in dronekit to make it work?

I never used that message but seems like you’re using that decorator wrong.

import time
import argparse
import dronekit
from pymavlink import mavutil

def callback_extended_sys_state(self, name, msg):
    print(msg.landed_state)

parser = argparse.ArgumentParser(description='Commands vehicle using vehicle.simple_goto.')
parser.add_argument('--connect', help="Vehicle connection target string. If not specified, SITL automatically started and used.")
args = parser.parse_args()

connection_string = args.connect

vehicle = dronekit.connect(connection_string, wait_ready=True)
print("Connected to vehicle:", connection_string)
vehicle.add_message_listener(name="EXTENDED_SYS_STATE", fn=callback_extended_sys_state)

while True:
    try:
        vehicle.send_mavlink(vehicle.message_factory.command_long_encode(0, 0, mavutil.mavlink.MAV_CMD_REQUEST_MESSAGE, 0, 245, 0, 0, 0, 0, 0, 0))
        time.sleep(5)
    except KeyboardInterrupt:
        vehicle.close()
        exit(0)

This should work although I didn’t run.
Are you sure you’re connecting to the vehicle?
You should see:

Connected to the vehicle: …

with this code.
Also if your simulated vehicle produces that message, you should the value of it on the screen.

I didn’t place a print for “Connected to vehicle” like you, but it does connected, I added other functions to test that.
May I ask you why the decorator I used is wrong? I have used it for other messages and it worked, like
SYSTEM_TIME to get the time_unix_usec field and the dronekit wiki suggests using this decorator for messages

yeah, I ran your code and didn’t print anything too

You’re decorating a function inside a loop.
One time is enough.
The decorator is not wrong, you’re using it wrong.
I prefer .add_message_listener since it is removable, choose what suits best for your application.

If it is not printing anything, means that you could not be able to connect to the vehicle.
At least you should see:

If you don’t see the above message, means that you did not connect to the vehicle.
If you’re not seeing the output value of msg.landed_state line by line, means that vehicle is not producing that message.
Can you see that message from MAVProxy?
Type:

watch EXTENDED_SYS_STATE

I tried with both Copter and Plane, but can’t catch it either. Could be a VTOL feature, IDK, but does not matter since you should be able to catch the message and field value itself with the above technique.
Make sure your vehicle is sending that message with MAVProxy.

Oh, sorry I expressed myself wrongly, It did print Connected to the vehicle, I meant it didn’t print anything from the message

1 Like

I thought I needed the loop so that the script could constantly catch the message

So, it means that that message doesn’t send from the vehicle.
I need to take a look at the source code how that message could be received.

Nope, when you decorate a function, that function will be called every time the corresponding message is received from vehicle.

OK, now I got the message:
When you run the below command from MAVProxy:

long MAV_CMD_REQUEST_MESSAGE 245 0 0 0 0 0 0 0

You should see something below in the console:

Got COMMAND_ACK: REQUEST_MESSAGE: ACCEPTED
< EXTENDED_SYS_STATE {vtol_state : 3, landed_state : 2}

So the vehicle is emitting that message only if you request it.
So periodically send that COMMAND_LONG message to the vehicle from your script and try to catch the response.
I updated the code, give it a try.

Hello, I used the updated version, but it doesn’t give any value, the terminal where I am running the script, the only output is Connected to vehicle: udp:“numbers” and in the other where the drone is being simulated, just keep outputting Got COMMAND_ACK: REQUEST_MESSAGE: ACCEPTED.

I also tried the long MAV_CMD_REQUEST_MESSAGE 245 0 0 0 0 0 0 0 but the console only showed Got COMMAND_ACK: REQUEST_MESSAGE: ACCEPTED

Ok, Noticed something.
While running the script, if I go to MavProxy Console and send long MAV_CMD_REQUEST_MESSAGE 245 0 0 0 0 0 0 0 0 , the terminal with the script prints the value of EXTENDED_SYS_STATE.landed_state. I also armed the drone and lifted from the ground and sent the command again, and the printed value changed. Now just figure how to make the script to all this by itself

I updated the code, please try.
It works for me.

I don’t know what happened yesterday, but it didn’t work, but now works just fine. Well all well that ends well

1 Like

thank you for the help

1 Like

Hi @Mustafa_Gokce , sorry for bringing this up after some months, but if I may ask, why the time.sleep?

No, I understand the time.sleep suspend the code, I meant, why are you suspending the code?

If there is no delay in the loop that sends the message request, it will be sent many times in rapid succession, which is probably not desired behavior. You could make the loop faster by decreasing the delay if you wanted to retrieve the extended system data more frequently.

If a blocking infinite loop like that is undesirable, you could spin it off into a thread or use a measured timeout within another loop to send it at a reasonable rate.