2026-04-12 14:44:05 +08:00
|
|
|
|
from flask import Flask, send_file, request, jsonify, send_from_directory
|
|
|
|
|
|
import motor
|
|
|
|
|
|
import time
|
|
|
|
|
|
import os
|
2026-04-19 14:46:01 +08:00
|
|
|
|
import json
|
2026-04-20 14:19:56 +08:00
|
|
|
|
import sys
|
|
|
|
|
|
sys.path.insert(0, os.path.dirname(__file__))
|
|
|
|
|
|
import agent
|
2026-04-12 14:44:05 +08:00
|
|
|
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
2026-04-25 15:49:23 +08:00
|
|
|
|
HTTPS_HOST = os.getenv('HOST', '0.0.0.0')
|
|
|
|
|
|
HTTPS_PORT = int(os.getenv('HTTPS_PORT', '5443'))
|
|
|
|
|
|
DEBUG_MODE = os.getenv('FLASK_DEBUG', '1') == '1'
|
|
|
|
|
|
|
2026-04-12 14:44:05 +08:00
|
|
|
|
# 静态文件路由
|
|
|
|
|
|
@app.route('/CSS/<path:filename>')
|
|
|
|
|
|
def serve_css(filename):
|
|
|
|
|
|
return send_from_directory('CSS', filename)
|
|
|
|
|
|
|
|
|
|
|
|
@app.route('/Javascript/<path:filename>')
|
|
|
|
|
|
def serve_js(filename):
|
|
|
|
|
|
return send_from_directory('Javascript', filename)
|
|
|
|
|
|
|
|
|
|
|
|
# 主页路由
|
|
|
|
|
|
@app.route('/')
|
|
|
|
|
|
def index():
|
|
|
|
|
|
return send_file('index.html')
|
|
|
|
|
|
|
|
|
|
|
|
# 控制电机路由
|
|
|
|
|
|
@app.route('/control', methods=['POST'])
|
|
|
|
|
|
def control():
|
|
|
|
|
|
data = request.get_json()
|
|
|
|
|
|
direction = data.get('direction')
|
|
|
|
|
|
|
|
|
|
|
|
# forward 与 backward 反向调整
|
|
|
|
|
|
try:
|
|
|
|
|
|
if direction == 'forward':
|
|
|
|
|
|
print("控制垃圾桶前进")
|
|
|
|
|
|
motor.backward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '前进中'})
|
|
|
|
|
|
elif direction == 'backward':
|
|
|
|
|
|
print("控制垃圾桶后退")
|
|
|
|
|
|
motor.forward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '后退中'})
|
2026-04-13 16:51:31 +08:00
|
|
|
|
elif direction == 'left':
|
|
|
|
|
|
print("控制垃圾桶左移")
|
|
|
|
|
|
motor.move_left(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '左移中'})
|
|
|
|
|
|
elif direction == 'right':
|
|
|
|
|
|
print("控制垃圾桶右移")
|
|
|
|
|
|
motor.move_right(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '右移中'})
|
|
|
|
|
|
elif direction == 'rotate_left':
|
|
|
|
|
|
print("控制垃圾桶左旋转")
|
|
|
|
|
|
motor.rotate_left(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '左旋转中'})
|
|
|
|
|
|
elif direction == 'rotate_right':
|
|
|
|
|
|
print("控制垃圾桶右旋转")
|
|
|
|
|
|
motor.rotate_right(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '右旋转中'})
|
|
|
|
|
|
elif direction == 'forward_left':
|
|
|
|
|
|
print("控制垃圾桶左前移动")
|
|
|
|
|
|
motor.move_left_forward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '左前移动中'})
|
|
|
|
|
|
elif direction == 'forward_right':
|
|
|
|
|
|
print("控制垃圾桶右前移动")
|
|
|
|
|
|
motor.move_right_forward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '右前移动中'})
|
|
|
|
|
|
elif direction == 'backward_left':
|
|
|
|
|
|
print("控制垃圾桶左后移动")
|
|
|
|
|
|
motor.move_left_backward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '左后移动中'})
|
|
|
|
|
|
elif direction == 'backward_right':
|
|
|
|
|
|
print("控制垃圾桶右后移动")
|
|
|
|
|
|
motor.move_right_backward(speed=0.6)
|
|
|
|
|
|
# 不使用time.sleep,让电机持续运行
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '右后移动中'})
|
2026-04-12 14:44:05 +08:00
|
|
|
|
elif direction == 'stop':
|
|
|
|
|
|
print("停止垃圾桶")
|
|
|
|
|
|
motor.stop()
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '已停止'})
|
|
|
|
|
|
else:
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '无效的方向'})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"控制出错: {e}")
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': f'控制出错: {e}'})
|
|
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
# 保存轨迹路由
|
|
|
|
|
|
@app.route('/save_path', methods=['POST'])
|
|
|
|
|
|
def save_path():
|
|
|
|
|
|
data = request.get_json()
|
|
|
|
|
|
path_name = data.get('name')
|
|
|
|
|
|
recorded_actions = data.get('actions')
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
if not path_name or not recorded_actions:
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '路径名称和轨迹数据不能为空'})
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
try:
|
|
|
|
|
|
# 确保Path目录存在
|
|
|
|
|
|
os.makedirs('Path', exist_ok=True)
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
# 保存为JSON文件
|
|
|
|
|
|
file_path = os.path.join('Path', f'{path_name}.json')
|
|
|
|
|
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
|
|
|
|
json.dump({'name': path_name, 'actions': recorded_actions}, f, ensure_ascii=False, indent=2)
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
return jsonify({'status': 'success', 'message': '轨迹保存成功'})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"保存轨迹出错: {e}")
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': f'保存轨迹出错: {e}'})
|
|
|
|
|
|
|
|
|
|
|
|
# 列出轨迹路由
|
|
|
|
|
|
@app.route('/list_paths', methods=['GET'])
|
|
|
|
|
|
def list_paths():
|
|
|
|
|
|
try:
|
|
|
|
|
|
# 确保Path目录存在
|
|
|
|
|
|
os.makedirs('Path', exist_ok=True)
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
# 列出所有轨迹文件
|
|
|
|
|
|
path_files = [f.replace('.json', '') for f in os.listdir('Path') if f.endswith('.json')]
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
return jsonify({'status': 'success', 'paths': path_files})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"列出轨迹出错: {e}")
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': f'列出轨迹出错: {e}'})
|
|
|
|
|
|
|
|
|
|
|
|
# 加载轨迹路由
|
|
|
|
|
|
@app.route('/load_path', methods=['GET'])
|
|
|
|
|
|
def load_path():
|
|
|
|
|
|
path_name = request.args.get('name')
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
if not path_name:
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '路径名称不能为空'})
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
try:
|
|
|
|
|
|
file_path = os.path.join('Path', f'{path_name}.json')
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '轨迹文件不存在'})
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
|
|
|
|
data = json.load(f)
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
return jsonify({'status': 'success', 'data': data})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"加载轨迹出错: {e}")
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': f'加载轨迹出错: {e}'})
|
|
|
|
|
|
|
|
|
|
|
|
# 删除轨迹路由
|
|
|
|
|
|
@app.route('/delete_path', methods=['DELETE'])
|
|
|
|
|
|
def delete_path():
|
|
|
|
|
|
data = request.get_json()
|
|
|
|
|
|
path_name = data.get('name')
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
if not path_name:
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '路径名称不能为空'})
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
try:
|
|
|
|
|
|
file_path = os.path.join('Path', f'{path_name}.json')
|
|
|
|
|
|
if not os.path.exists(file_path):
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': '轨迹文件不存在'})
|
2026-04-20 14:19:56 +08:00
|
|
|
|
|
2026-04-19 14:46:01 +08:00
|
|
|
|
os.remove(file_path)
|
|
|
|
|
|
return jsonify({'status': 'success', 'message': '轨迹删除成功'})
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
print(f"删除轨迹出错: {e}")
|
|
|
|
|
|
return jsonify({'status': 'error', 'message': f'删除轨迹出错: {e}'})
|
|
|
|
|
|
|
2026-04-20 14:19:56 +08:00
|
|
|
|
agent.create_agent_routes(app, motor)
|
|
|
|
|
|
|
2026-04-12 14:44:05 +08:00
|
|
|
|
if __name__ == '__main__':
|
2026-04-25 15:49:23 +08:00
|
|
|
|
print(f"HTTPS server available at https://localhost:{HTTPS_PORT}")
|
|
|
|
|
|
app.run(host=HTTPS_HOST, port=HTTPS_PORT, debug=DEBUG_MODE, ssl_context='adhoc')
|