feat: implement stop functionality for robot operations and remove obsolete stop endpoint
This commit is contained in:
@@ -24,16 +24,6 @@ endpoints:
|
||||
timeout: 5.0
|
||||
enabled: true
|
||||
|
||||
- path: /robot/stop
|
||||
method: POST
|
||||
type: service
|
||||
ros_name: cobot/stop
|
||||
msg_type: std_srvs/srv/Trigger
|
||||
summary: "Немедленно остановить движение"
|
||||
description: "Вызывает сервис экстренной остановки — движение прерывается немедленно."
|
||||
tags: [motion]
|
||||
response_fields: [success, message]
|
||||
timeout: 5.0
|
||||
enabled: true
|
||||
|
||||
- path: /robot/move/named
|
||||
|
||||
@@ -6,6 +6,7 @@ import uvicorn
|
||||
from fastapi import FastAPI
|
||||
from fastmcp import FastMCP
|
||||
from sensor_msgs.msg import JointState
|
||||
from std_srvs.srv import Trigger
|
||||
|
||||
from .dynamic_router import build_dynamic_router
|
||||
from .ros_node import CobotWebNode, get_bridge, set_bridge
|
||||
@@ -47,6 +48,16 @@ def main():
|
||||
app.include_router(positions.router)
|
||||
app.mount("/mcp", mcp_http)
|
||||
|
||||
@app.post("/stop", tags=["stop"], summary="Остановить всё: runner, траекторию и планировщик")
|
||||
def stop_all():
|
||||
runner.stop_if_running()
|
||||
trajectory.send_stop_trajectory()
|
||||
try:
|
||||
result = get_bridge().call_service(Trigger, "cobot/stop", Trigger.Request())
|
||||
return {"status": "stopped", "success": result.success, "message": result.message}
|
||||
except RuntimeError:
|
||||
return {"status": "stopped", "success": True, "message": "Планировщик не запущен"}
|
||||
|
||||
uvicorn.run(app, host=host, port=port)
|
||||
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ from typing import Optional
|
||||
|
||||
import yaml
|
||||
from fastapi import APIRouter, Form, HTTPException, Query, UploadFile, File
|
||||
from std_srvs.srv import Trigger
|
||||
|
||||
from .ros_node import get_bridge
|
||||
|
||||
router = APIRouter(prefix="/sequences", tags=["sequences"])
|
||||
@@ -95,12 +93,12 @@ async def start_runner(
|
||||
return {"status": "started", "pid": _process.pid, "config": filename}
|
||||
|
||||
|
||||
@router.post("/stop", summary="Остановить motion_sequence_runner и послать cobot/stop")
|
||||
def stop_runner():
|
||||
def stop_if_running() -> Optional[int]:
|
||||
"""Kill the runner process if it is running. Returns exit code or None if not running."""
|
||||
global _process
|
||||
with _lock:
|
||||
if not _process or _process.poll() is not None:
|
||||
raise HTTPException(404, "Runner не запущен")
|
||||
return None
|
||||
pgid = os.getpgid(_process.pid)
|
||||
os.killpg(pgid, signal.SIGTERM)
|
||||
try:
|
||||
@@ -108,10 +106,8 @@ def stop_runner():
|
||||
except subprocess.TimeoutExpired:
|
||||
os.killpg(pgid, signal.SIGKILL)
|
||||
_process.wait()
|
||||
code = _process.returncode
|
||||
return _process.returncode
|
||||
|
||||
result = get_bridge().call_service(Trigger, "cobot/stop", Trigger.Request())
|
||||
return {"status": "stopped", "returncode": code, "success": result.success, "message": result.message}
|
||||
|
||||
|
||||
@router.get("/status", summary="Статус motion_sequence_runner")
|
||||
|
||||
@@ -5,7 +5,6 @@ from datetime import datetime
|
||||
from builtin_interfaces.msg import Duration
|
||||
from fastapi import APIRouter, File, HTTPException, Query, UploadFile
|
||||
from pydantic import BaseModel, Field
|
||||
from std_srvs.srv import Trigger
|
||||
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint
|
||||
|
||||
from .config_loader import load_joint_limits, load_joint_names
|
||||
@@ -172,11 +171,9 @@ async def send_csv_trajectory(
|
||||
return {"status": "sent", "points": len(rows), "filename": file.filename}
|
||||
|
||||
|
||||
@router.post("/stop", summary="Остановить выполнение траектории")
|
||||
def stop_trajectory():
|
||||
def send_stop_trajectory() -> None:
|
||||
"""Publish a hold-position (or empty) trajectory to freeze joint motion."""
|
||||
bridge = get_bridge()
|
||||
|
||||
# Replace ongoing trajectory with single point at current position
|
||||
joint_states = bridge.get_latest("/joint_states")
|
||||
if joint_states is not None and len(joint_states.position) >= N_JOINTS:
|
||||
current_positions = list(joint_states.position[:N_JOINTS])
|
||||
@@ -189,10 +186,6 @@ def stop_trajectory():
|
||||
_publish(msg)
|
||||
_log("[stop] joint_states недоступны, отправлена пустая траектория")
|
||||
|
||||
# cobot/stop cancels MoveIt action-based motion
|
||||
result = bridge.call_service(Trigger, "cobot/stop", Trigger.Request())
|
||||
_log(f"[stop] cobot/stop -> success={result.success}, message={result.message}")
|
||||
return {"status": "stopped", "success": result.success, "message": result.message}
|
||||
|
||||
|
||||
@router.get("/logs", summary="Последние лог-записи траекторного модуля")
|
||||
|
||||
Reference in New Issue
Block a user