AFOP 2024-05-03 11:45 采纳率: 0%
浏览 11

python无人机tello编程网页控制

from flask import Flask, render_template, request, jsonify
from djitellopy import Tello
import os
import cv2
import time
import threading

app = Flask(__name__)


tello_lock = threading.Lock()
tello = None


def get_tello():
    global tello
    if tello is None:
        tello = Tello()
        tello.connect()
    return tello


# 创建截图函数
def take_screenshot(frame):
    # 指定保存目录
    save_path = "images/"
    # 如果目录不存在,则创建它
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    # 生成文件名
    timestamp = int(time.time())
    file_name = f"screenshot_{timestamp}.jpg"
    # 保存截图
    cv2.imwrite(os.path.join(save_path, file_name), frame)
    print(f"Screenshot saved: {file_name}")


# 处理控制命令
def handle_command(tello, command):
    if command == "takeoff":
        tello.takeoff()
    elif command == "land":
        tello.land()
    elif command == "forward":
        tello.send_rc_control(0, 50, 0, 0)
    elif command == "back":
        tello.send_rc_control(0, -50, 0, 0)
    elif command == "left":
        tello.send_rc_control(50, 0, 0, 0)
    elif command == "right":
        tello.send_rc_control(-50, 0, 0, 0)
    elif command == "up":
        tello.send_rc_control(0, 0, 50, 0)
    elif command == "down":
        tello.send_rc_control(0, 0, -50, 0)
    elif command == "ccw":
        tello.send_rc_control(0, 0, 0, -50)
    elif command == "cw":
        tello.send_rc_control(0, 0, 0, 50)
    elif command == "ss":
        take_screenshot(tello.get_frame_read().frame)
    else:
        print("Unknown command")


# 启动视频流和控制线程
def start_video_and_control():
    show_video()
    while True:
        command = input("Enter command (takeoff, land, forward, back, left, right, up, down, ccw, cw, screenshot): ")
        handle_command(command)


# 创建 Flask 路由
@app.route("/command")
def tello_control():
    return render_template("flask_control.html")


@app.route("/command", methods=["POST"])
def handle_web_command():
    command = request.form.get("command")
    if command:
        tello = get_tello()
        handle_command(tello, command)
        return jsonify({"status": "Command executed", "command": command})
    return jsonify({"status": "Invalid command"})


@app.teardown_appcontext
def teardown_tello(exception):
    global tello
    if tello is not None:
        tello.streamoff()
        tello.end()
        tello = None


def start_video_and_control():
    # 启动视频流
    tello = get_tello()
    tello.streamon()

    # 创建一个线程来显示视频流
    video_thread = threading.Thread(target=show_video)
    video_thread.start()

    # 等待视频线程启动
    video_thread.join()

    # 创建一个线程来处理控制命令
    control_thread = threading.Thread(target=start_control_input)
    control_thread.start()

    # 等待控制线程启动
    control_thread.join()


# 显示视频流的函数
def show_video():
    while True:
        frame = tello.get_frame_read().frame
        cv2.imshow("Tello Video Stream", frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break


# 处理控制命令输入的函数
def start_control_input():
    while True:
        command = input("Enter command (takeoff, land, forward, back, left, right, up, down, ccw, cw, screenshot): ")
        handle_command(tello, command)


if __name__ == "__main__":
    app.run(debug=False)

    # 启动视频流和控制线程
    start_video_and_control()


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Tello Drone Control</title>
    <style>
        body {
            text-align: center;
            font-family: Arial, sans-serif;
        }
        button {
            margin: 5px;
            padding: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>Tello无人机按键控制</h1>
    <form action="/command" method="POST">
        <button type="submit" name="command" value="takeoff">起飞</button>
        <button type="submit" name="command" value="land">降落</button>
        <button type="submit" name="command" value="forward">前进</button>
        <button type="submit" name="command" value="back">后退</button>
        <button type="submit" name="command" value="left">左转</button>
        <button type="submit" name="command" value="right">右转</button>
        <button type="submit" name="command" value="up">上升</button>
        <button type="submit" name="command" value="down">下降</button>
        <button type="submit" name="command" value="ccw">逆时针旋转</button>
        <button type="submit" name="command" value="cw">顺时针旋转</button>
        <button type="submit" name="command" value="ss">截图</button>
    </form>
</body>
</html>

报错问题

img

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-03 11:45
    关注

    引自免费微信小程序:皆我百晓生

    看起来你在尝试通过Flask搭建一个简单的Web界面来控制DJI Tello无人机,并且在执行过程中遇到了一些错误。这些错误提示与H.264解码有关,这通常发生在视频流接收不完整或者编码格式不正确的情况下。

    为了解决这个问题,你可以尝试以下几个步骤:

    1. 更新djitellopy库:确保你使用的djitellopy版本是最新的。旧版本可能会导致视频流的问题。
    2. 检查网络连接:确保无人机与电脑之间的Wi-Fi连接稳定,因为不稳定或延迟的网络可能导致视频流中断。
    3. 使用不同的视频编解码器:尝试更改Tello的视频编码器设置,看看是否可以改善视频流质量。

    针对上述建议,首先更新djitellopy库,你可以使用下面的命令:

    pip install --upgrade djitellopy
    

    然后,我们可以在初始化Tello时设置视频编解码器为MJPEG,这通常是更稳定的选项:

    def get_tello():
        global tello
        if tello is None:
            tello = Tello()
            tello.connect()
            # 设置视频编解码器为MJPEG
            tello.set_video_codec("mjpeg")
        return tello
    

    修改后的代码如下:

    from flask import Flask, render_template, request, jsonify
    from djitellopy import Tello
    import os
    import cv2
    import time
    import threading
    
    app = Flask(__name__)
    
    tello_lock = threading.Lock()
    tello = None
    
    
    def get_tello():
        global tello
        if tello is None:
            tello = Tello()
            tello.connect()
            # 设置视频编解码器为MJPEG
            tello.set_video_codec("mjpeg")
        return tello
    
    
    # 其他部分保持不变...
    

    将这段代码替换到你提供的代码中,然后重新运行应用。这应该能解决视频流中的大部分解码错误。如果仍然存在问题,可能需要检查其他硬件或软件配置,例如确认你的计算机支持处理H.264视频流,或者检查是否有防火墙阻止了视频数据的传输。

    如果你继续遇到问题,可能需要查看Tello的官方文档或社区论坛,寻找更多关于视频流问题的帮助。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月3日

悬赏问题

  • ¥50 求恶意流量检测系统搭建教程( C++ python C)
  • ¥15 mmseqs内存报错
  • ¥15 vika文档如何与obsidian同步
  • ¥15 华为手机相册里面的照片能够替换成自己想要的照片吗?
  • ¥15 陆空双模式无人机飞控设置
  • ¥15 sentaurus lithography
  • ¥100 求抖音ck号 或者提ck教程
  • ¥15 关于#linux#的问题:子进程1等待子进程A、B退出后退出(语言-c语言)
  • ¥20 web页面如何打开Outlook 365的全球离线通讯簿功能
  • ¥15 io.jsonwebtoken.security.Keys