Files
DronePlanning/backend_service/src/main.py
2026-02-26 19:37:55 +08:00

118 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import asyncio
import os
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.staticfiles import StaticFiles
import logging
# import threading # ROS2相关已注释
# import rclpy # ROS2相关已注释
from .models import GeneratePlanRequest, ExecuteMissionRequest, DebugStageRequest
from .websocket_manager import websocket_manager
from .py_tree_generator import py_tree_generator
# from .ros2_client import MissionActionClient # ROS2相关已注释
# --- Application Setup ---
app = FastAPI(
title="Drone Backend Service",
description="Handles mission planning, generation, and execution for the drone.",
version="1.0.0",
)
# --- Mount Static Files for Visualizations ---
static_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'generated_visualizations'))
app.mount("/static", StaticFiles(directory=static_dir), name="static")
# --- ROS2 Node and Client Initialization ---
# ROS2相关代码已注释项目已与ROS2解耦
# rclpy.init()
# ros2_client = MissionActionClient()
# def run_ros2_node():
# """Spins the ROS2 node in a dedicated thread."""
# logging.info("Starting to spin ROS2 node...")
# rclpy.spin(ros2_client)
# logging.info("ROS2 node has stopped spinning.")
# --- API Endpoints ---
@app.post("/generate_plan", response_model=dict)
async def generate_plan_endpoint(request: GeneratePlanRequest):
"""
Receives a user prompt and returns a generated `py_tree.json` with a visualization URL.
"""
try:
pytree_dict = await py_tree_generator.generate(request.user_prompt, drone_state=request.drone_state)
return pytree_dict
except RuntimeError as e:
return {"error": str(e)}
@app.post("/debug_stage", response_model=dict)
async def debug_stage_endpoint(request: DebugStageRequest):
"""
Stage 分阶段调试:运行到指定 stage 并返回该 stage 的输出。
target_stage: 1=TaskUnderstanding, 2=ContextBinding, 3=BTDraft, 4=MiddlewareResolution, 5=MicroFilling, 6=ValidateAndPostprocess
"""
try:
result = py_tree_generator.run_debug_stage(
user_prompt=request.user_prompt,
drone_state=request.drone_state,
target_stage=request.target_stage,
)
return result
except Exception as e:
logging.exception("debug_stage 执行异常")
return {"error": str(e)}
@app.post("/execute_mission", response_model=dict)
async def execute_mission_endpoint(request: ExecuteMissionRequest):
"""
Receives a `py_tree.json` and sends it to the drone for execution.
ROS2相关功能已注释项目已与ROS2解耦。
"""
# ROS2相关代码已注释
# ros2_client.send_goal(request.py_tree)
logging.warning("execute_mission endpoint called but ROS2 is disabled. Mission execution is not available.")
return {"status": "execution_disabled", "message": "ROS2 integration is disabled. Mission execution is not available."}
@app.websocket("/ws/status")
async def websocket_endpoint(websocket: WebSocket):
"""
Handles the WebSocket connection for real-time status updates.
"""
await websocket_manager.connect(websocket)
try:
while True:
await websocket.receive_text()
except WebSocketDisconnect:
websocket_manager.disconnect(websocket)
logging.info("Client disconnected from WebSocket.")
# --- Server Lifecycle ---
@app.on_event("startup")
async def startup_event():
"""
On startup, get the current asyncio event loop and pass it to the websocket manager.
ROS2相关功能已注释项目已与ROS2解耦。
"""
# Configure WebSocket Manager
loop = asyncio.get_running_loop()
websocket_manager.set_loop(loop)
logging.info("WebSocket event loop configured.")
# ROS2相关代码已注释
# Start ROS2 node in a background thread
# ros2_thread = threading.Thread(target=run_ros2_node, daemon=True)
# ros2_thread.start()
# logging.info("ROS2 node thread started.")
@app.on_event("shutdown")
async def shutdown_event():
logging.info("Backend service shutting down.")
# ROS2相关代码已注释
# ros2_client.destroy_node()
# rclpy.shutdown()
# logging.info("ROS2 node shut down successfully.")