This commit is contained in:
2025-03-02 14:09:11 +08:00
parent 93f90389cf
commit 24882543a9
13 changed files with 174 additions and 60 deletions

View File

@@ -58,6 +58,9 @@ model_client = OpenAIChatCompletionClient(
"json_output": True,
"family": "unknown",
},
timeout=30,
max_retries=5,
max_tokens=4096
)
@@ -67,10 +70,10 @@ async def get_team(
) -> RoundRobinGroupChat | SelectorGroupChat:
# Create the team.
scientist_team = create_scientist_team(model_client=model_client)
engineer_team = create_engineer_team()
robot_platform = create_robot_team()
analyst_team = create_analyst_team()
scientist_team = create_scientist_team(user_input_func=user_input_func)
engineer_team = create_engineer_team(user_input_func=user_input_func)
robot_platform = create_robot_team(user_input_func=user_input_func)
analyst_team = create_analyst_team(user_input_func=user_input_func)
user = UserProxyAgent(
name="user",
input_func=user_input_func, # Use the user input function.
@@ -103,7 +106,7 @@ async def get_team(
4.1 MobileRobot_Agent: This agent controls the mobile robot by calling the funciton sendScheme2MobileRobot to place the experimental container into the robot workstation. This agent called before RobotWorkstation_Agent.
4.2 RobotWorkstation_Agent: This agent is called by the mobile robot agent, do not plan it alone.
4.3 DataCollector_Agent: This agent collects experimental data and experimental logs from the characterization device in the robot platform and stores them.
5. Analyst: A team of data analysts who are responsible for analyzing and visualizing experimental data and logs.
5. Analyst: A team of data analysts who are responsible for analyzing and visualizing experimental data and logs. After the user's confirmation can be enter.
- The Data Analysis team has the following members:
5.1 Expriment_Analyst: The agent of data analysts who are responsible for analyzing experimental data and logs.
5.2 Expriment_Optimizer: The agent optimizes the experimental scheme by means of component regulation and so on to make the experimental result close to the desired goal of the user.
@@ -134,6 +137,7 @@ async def get_team(
**Next sub-task:**
n. <team> : <subtask>
Before enter the team of Analyst, you need to request user's instruction by end with "HUMAN".
You can end with "HUMAN" if you need to, which means you need human approval or other advice or instructions;
After plan and delegate tasks are complete, end with "START";
Determine if all sub-teams have completed their tasks, and if so, summarize the findings and end with "TERMINATE".
@@ -338,16 +342,16 @@ RTSP_STREAMS = {
@app.websocket("/video_stream/{camera_id}")
async def websocket_endpoint(websocket: WebSocket, camera_id: str):
await websocket.accept()
rtsp_url = RTSP_STREAMS.get(camera_id)
if not rtsp_url:
await websocket.close(code=4001)
return
fps = 15
fps = 10
frame_interval = 1 / fps
frame_buffer = deque() # 每个连接独立的队列
max_buffer_size = 3 # 限制缓冲区大小,只保留最新的几帧
frame_buffer = deque(maxlen=max_buffer_size) # 设置最大长度
# 启动FFmpeg进程
process = (
ffmpeg
@@ -355,7 +359,7 @@ async def websocket_endpoint(websocket: WebSocket, camera_id: str):
.output('pipe:', format='image2pipe', vcodec='mjpeg', r=fps)
.run_async(pipe_stdout=True, pipe_stderr=True, quiet=True)
)
async def capture_frames():
"""读取并分割完整的JPEG帧"""
buffer = b''
@@ -377,23 +381,39 @@ async def websocket_endpoint(websocket: WebSocket, camera_id: str):
# 提取帧数据并编码
frame_data = buffer[start:end+2]
frame = base64.b64encode(frame_data).decode('utf-8')
# 如果缓冲区已满,清空旧帧再添加新帧
if len(frame_buffer) >= max_buffer_size:
frame_buffer.clear()
frame_buffer.append(frame)
buffer = buffer[end+2:] # 移除已处理数据
# 清理FFmpeg进程
process.kill()
async def send_frames():
"""发送帧到客户端"""
last_send_time = time.time()
while True:
if frame_buffer:
current_time = time.time()
elapsed = current_time - last_send_time
# 确保按照帧率发送
if elapsed >= frame_interval and frame_buffer:
frame = frame_buffer.popleft()
await websocket.send_text(frame)
await asyncio.sleep(frame_interval)
try:
await websocket.send_text(frame)
last_send_time = current_time
except Exception:
break
else:
# 短暂休眠避免CPU过度使用
await asyncio.sleep(max(0.001, frame_interval - elapsed))
# 启动任务并处理退出
capture_task = asyncio.create_task(capture_frames())
send_task = asyncio.create_task(send_frames())
try:
await asyncio.gather(capture_task, send_task)
except asyncio.CancelledError:
@@ -401,7 +421,7 @@ async def websocket_endpoint(websocket: WebSocket, camera_id: str):
send_task.cancel()
await asyncio.gather(capture_task, send_task, return_exceptions=True)
finally:
if process and process.poll() is None: # Check if the process is still running
if process and process.poll() is None:
process.kill()
await websocket.close()