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>
报错问题