dronekit / dronekit-python

DroneKit-Python library for communicating with Drones via MAVLink.
https://readthedocs.org/projects/dronekit-python/
Apache License 2.0
1.59k stars 1.44k forks source link

Exception in message handler for HEARTBEAT when connect to mavlink gimbal #1103

Open QuangKhoi-RTR opened 3 years ago

QuangKhoi-RTR commented 3 years ago

Hi, I tried to connect to my quadcopter which is connected to a mavlink controlled gimbal and receive this error: ERROR:dronekit:Exception in message handler for HEARTBEAT

Traceback (most recent call last):
File "C:\Users\Admin\AppData\Local\Programs\Python\Python39\lib\site-packages\dronekit-2.9.2-py3.9.egg\dronekit__init.py", line 1559, in notify_message_listeners
fn(self, name, msg)
File "C:\Users\Admin\AppData\Local\Programs\Python\Python39\lib\site-packages\dronekit-2.9.2-py3.9.egg\dronekit\
init__.py", line 1251, in listener
raise APIException("mode (%s, %s) not available on mavlink definition" % (m.custom_mode, m.base_mode)) dronekit.APIException: mode (0, 64) not available on mavlink definition

My program:

Import DroneKit-Python

from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative from pymavlink import mavutil import sys import math import time reverse = 1 total_distance = 0 total_capture = 0

connection_string = "tcp:localhost:5763"

connection_string = "tcp:192.168.0.210:20002" print("---------------------------------------------------------") print("Connecting to vehicle on: %s" % (connection_string,)) vehicle = connect(connection_string, wait_ready=True)

Get some vehicle attributes (state)

print ("Get some vehicle attribute values:") print (" GPS: %s" % vehicle.gps_0) print (" Battery: %s" % vehicle.battery) print (" Last Heartbeat: %s" % vehicle.last_heartbeat) print (" Is Armable?: %s" % vehicle.is_armable) print (" System status: %s" % vehicle.system_status.state) print (" Mode: %s" % vehicle.mode.name) # settable print ("Global Location: %s" % vehicle.location.global_frame) print ("Global Location (relative altitude): %s" % vehicle.location.global_relative_frame) vehicle.mode = VehicleMode("GUIDED") time.sleep(2) print (" Mode: %s" % vehicle.mode.name) # settable print("---------------------------------------------------------")

def capturePhoto(): """ Send capture signal to camera """ vehicle._master.mav.command_long_send( vehicle._master.target_system, vehicle._master.target_component, mavutil.mavlink.MAV_CMD_DO_DIGICAM_CONTROL, 0, 1, 0 , 0 , 0 , 1 , 0,0) # param5 : trigger camera print("CAPTURE SIGNAL SENT")

time.sleep(5) capturePhoto() vehicle.close()

When disconnect the gimbal camera, everything works fine.

nandard commented 3 years ago

Hi, i'm currently working on a project who has a similar error with Dronekit (besides, i'm using Intel Realsense T265). How do you fix those problem? I'm very glad to hear it

QuangKhoi-RTR commented 3 years ago

Hi @nandard , it turns out that the Dronekit can't handle the heartbeat message from the gimbal and confused. I solved the issue by using pymavlink directly and pick the heartbeat from the drone.

nandard commented 3 years ago

Hi @nandard , it turns out that the Dronekit can't handle the heartbeat message from the gimbal and confused. I solved the issue by using pymavlink directly and pick the heartbeat from the drone.

Could you specify about "using pymavlink directly and pick the hearbeat from the drone" ? I'm really need your help, please. Thanks

QuangKhoi-RTR commented 3 years ago

That means I'm not using Dronekit anymore, but instead using pymavlink lib to connect to the drone and get the messages I need.:

from pymavlink import mavutil
 # Init connection
connection_string = 'tcp:192.168.0.210:20002'
master = None
while master is None:
    try:
        print("mavlink connecting")
        master = mavutil.mavlink_connection(connection_string)
        time.sleep(0.1)
    except KeyboardInterrupt:
        print("exit")
        sys.exit(0)
    except:
        pass
print("Heartbeat from system (system %u component %u)" % (master.target_system, master.target_system)) # <<<< I used system and component IDs to seperate messages from the drone and gimbal.
# Get the messages
msg = None
    while not msg:
        master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, # request data stream replace position = all for all msg
                                                      10), 1) # rate = 10, turn on = 1
        msg = master.recv_match()
        time.sleep(0.01)
    print(msg)
nandard commented 3 years ago

That means I'm not using Dronekit anymore, but instead using pymavlink lib to connect to the drone and get the messages I need.:

from pymavlink import mavutil
 # Init connection
connection_string = 'tcp:192.168.0.210:20002'
master = None
while master is None:
    try:
        print("mavlink connecting")
        master = mavutil.mavlink_connection(connection_string)
        time.sleep(0.1)
    except KeyboardInterrupt:
        print("exit")
        sys.exit(0)
    except:
        pass
print("Heartbeat from system (system %u component %u)" % (master.target_system, master.target_system)) # <<<< I used system and component IDs to seperate messages from the drone and gimbal.
# Get the messages
msg = None
    while not msg:
        master.mav.request_data_stream_send(0, 0, mavutil.mavlink.MAV_DATA_STREAM_ALL, # request data stream replace position = all for all msg
                                                      10), 1) # rate = 10, turn on = 1
        msg = master.recv_match()
        time.sleep(0.01)
    print(msg)

Thanks a lot man. So basically there's no error message and everything works well by using pymavlink connection, is it? What's the different between using pymavlink and dronekit in drone's programming?