Передача изменений атрибута автомобиля dronekit.io с помощью flask-socket.io

Я пытаюсь отправить данные с моего автомобиля dronekit.io с помощью flask-socket.io. К сожалению, я получил этот журнал:

Starting copter simulator (SITL)
SITL already Downloaded and Extracted.
Ready to boot.
Connecting to vehicle on: tcp:127.0.0.1:5760
>>> APM:Copter V3.3 (d6053245)
>>> Frame: QUAD
>>> Calibrating barometer
>>> Initialising APM...
>>> barometer calibration complete
>>> GROUND START
* Restarting with stat
latitude  -35.363261

>>> Exception in attribute handler for location.global_relative_frame
>>> Working outside of request context.    

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.
longitude  149.1652299

>>> Exception in attribute handler for location.global_relative_frame
>>> Working outside of request context.

This typically means that you attempted to use functionality that needed
an active HTTP request.  Consult the documentation on testing for
information about how to avoid this problem.

Вот мой код:

sample.py

from dronekit import connect, VehicleMode
from flask import Flask
from flask_socketio import SocketIO, emit
import dronekit_sitl
import time

sitl = dronekit_sitl.start_default()
connection_string = sitl.connection_string()
print("Connecting to vehicle on: %s" % (connection_string,))
vehicle = connect(connection_string, wait_ready=True)

def arm_and_takeoff(aTargetAltitude):

    print "Basic pre-arm checks"
    while not vehicle.is_armable:
        print " Waiting for vehicle to initialise..."
        time.sleep(1)

    print "Arming motors"
    vehicle.mode    = VehicleMode("GUIDED")
    vehicle.armed   = True

    while not vehicle.armed:
        print " Waiting for arming..."
        time.sleep(1)

    print "Taking off!"
    vehicle.simple_takeoff(aTargetAltitude)

    while True:
        if vehicle.location.global_relative_frame.alt>=aTargetAltitude*0.95:
            print "Reached target altitude"
            break
        time.sleep(1)

last_latitude = 0.0
last_longitude = 0.0
last_altitude = 0.0

@vehicle.on_attribute('location.global_relative_frame')
def location_callback(self, attr_name, value):
    global last_latitude
    global last_longitude
    global last_altitude
    if round(value.lat, 6) != round(last_latitude, 6):
        last_latitude = value.lat
        print "latitude ", value.lat, "\n"
        emit("latitude", value.lat)
    if round(value.lon, 6) != round(last_longitude, 6):
        last_longitude = value.lon
        print "longitude ", value.lon, "\n"
        emit("longitude", value.lon)
    if round(value.alt) != round(last_altitude):
        last_altitude = value.alt
        print "altitude ", value.alt, "\n"
        emit("altitude", value.alt)

app = Flask(__name__)
socketio = SocketIO(app)

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, debug=True)
    arm_and_takeoff(20)

Из журналов я знаю, что я не должен делать никаких HTTP-запросов внутри метода декоратора "vehicle.on_attribute", и мне нужно искать информацию о том, как решить эту проблему, но я не нашел никакой информации об ошибке.

Надеюсь, вы могли бы помочь мне.

Большое спасибо,

Raniel

1 ответ

emit() Функция по умолчанию возвращает событие обратно активному клиенту. Если вы вызываете эту функцию вне контекста запроса, концепция активного клиента отсутствует, поэтому вы получаете эту ошибку.

У вас есть несколько вариантов:

  1. укажите получателя события и пространство имен, которое вы используете, чтобы не было необходимости искать их в контексте. Вы можете сделать это, добавив room а также namespace аргументы. использование '/' для пространства имен, если вы используете пространство имен по умолчанию.

  2. излучать всем клиентам, добавляя broadcast=True в качестве аргумента, плюс пространство имен, как указано в #1.

Другие вопросы по тегам