Ir al contenido

Enviar y seguir robots Recon

Envía un robot Recon a una patrulla, a un punto de su mapa o de vuelta a su base de carga con las operaciones deploy y sendHome, y luego sigue la ejecución hasta su resultado con el estado y los eventos del robot.

En esta página

Dos operaciones mueven un robot: deploy lo envía a una patrulla o a un punto, y sendHome lo devuelve a su base de carga. Ambas entregan el comando al robot y responden; después, el robot lo acepta o lo rechaza, e informa cómo le fue. Los ejemplos usan la función auxiliar robot_api de la descripción general.

Necesitas una clave de API con acceso de administrador al robot.

Advertencia

Estas llamadas mueven una máquina física. Asegúrate de que el área sea segura para que el robot circule por ella, pide que una persona confirme antes de que un proceso automatizado o controlado por IA envíe un robot, y ten a mano una forma de detenerlo: la parada de emergencia del socket en vivo.

Revisa el robot primero

Envía un robot que esté conectado y libre: esperando (IDLE), acoplándose o cargando por su cuenta (IDLE_DOCKING), o con su última actividad terminada. Lee su estado (Monitorear robots):

Python
FREE = {"IDLE", "IDLE_DOCKING"}
DONE = {"COMPLETED", "FAILED", "CANCELED"}

state = robot_api("getFullState", {"deviceUuid": ROBOT_UUID, "force": False})["fullState"]
if state["connectionStatus"] != "GREEN":
    raise SystemExit("The robot isn't connected")
if state.get("activity") not in FREE and state.get("event") not in DONE:
    raise SystemExit(f"The robot is busy: {state.get('activity')}")

El robot tiene la última palabra: puede rechazar un comando que esta comprobación deja pasar (Cuando el robot lo rechaza).

Ejecuta una patrulla ahora

Envía el robot con navType PATROL y el UUID de la patrulla. La patrulla debe estar habilitada y su ruta debe estar en el mapa del robot:

Python
run = robot_api("deploy", {"deviceUuid": ROBOT_UUID, "navType": "PATROL", "patrolUuid": PATROL_UUID})
RUN_UUID = run["routeRunUuid"]

La patrulla se ejecuta con sus propias acciones de llegada. Para enviarla de esta forma, la patrulla no necesita un horario (Rutas y patrullas).

Envía el robot a un punto

Envía el robot con navType POSE y una pose completa (los tres valores de position y los cuatro de orientation). Para enviarlo a un punto de ruta guardado, usa la pose de ese punto de ruta:

Python
waypoint = robot_api("getRobotWaypoint", {"mapUuid": MAP_UUID, "waypointUuid": WAYPOINT_UUID})["waypoint"]
run = robot_api("deploy", {"deviceUuid": ROBOT_UUID, "navType": "POSE", "pose": waypoint["pose"]})
RUN_UUID = run["routeRunUuid"]

Cuando el robot llega, la actividad se completa, y el robot espera allí hasta su siguiente comando o hasta que vuelve a su base por su cuenta (IDLE_DOCKING).

Envía el robot a la base

Python
robot_api("sendHome", {"deviceUuid": ROBOT_UUID})

El robot va hasta su base de carga y se acopla. sendHome interrumpe una patrulla en lugar de terminarla: la patrulla queda en SUSPENDED y puede reanudarse por sí sola (un evento RESUMED) después de que el robot se acople. Para terminar una ejecución, envía CMD_NAVIGATE_CANCEL por el socket en vivo; no hay ninguna operación REST que la cancele.

Qué significa la respuesta

"error": false con un routeRunUuid significa que el comando llegó al robot, no que el robot lo aceptó:

  • El robot lo acepta o lo rechaza. Sigue la ejecución (abajo) para saber qué ocurrió.
  • Si el robot no es accesible, la llamada falla con un estado 5xx. Revisa connectionStatus antes de enviarlo, y vuelve a intentarlo más tarde en lugar de hacerlo en un bucle.
  • Una solicitud incompleta también falla con 500, no con 400: un envío PATROL sin patrolUuid o de una patrulla deshabilitada, o un envío POSE sin una pose completa. Valida la solicitud antes de enviarla.

Cuando el robot lo rechaza

El robot compara cada comando nuevo con lo que está haciendo. Lo rechaza (con un evento REJECTED, en el que preemptedBy indica la actividad que lo impide) cuando:

  • su parada de emergencia está activada;
  • está retenido por mantenimiento del mapa;
  • vuelve a su base para recargarse, o se está recargando después de quedarse con poca batería;
  • un operador lo está conduciendo;
  • en el caso de una patrulla, va hacia un punto o de vuelta a su base.

Una patrulla nueva reemplaza a una patrulla en curso (la ejecución anterior termina como CANCELED), y sendHome suspende una. Un robot que está en su base de carga primero se separa de ella (fase UNDOCKING).

Sigue la ejecución

El routeRunUuid que devuelve deploy es el ID de actividad de la ejecución: aparece como activityUuid en el estado del robot y en sus eventos.

  • Mientras se ejecuta, consulta getFullState: activity, phase, waypointIndex de waypointTotal, estimatedTimeRemainingSec y distanceRemaining, siempre que activityUuid sea tu ejecución.
  • Para conocer el resultado, lee los eventos del robot para ese activityUuid hasta que uno sea final: COMPLETED, FAILED (con failureReason), CANCELED o REJECTED.
Python
import time

FINAL = {"COMPLETED", "FAILED", "CANCELED", "REJECTED"}

def wait_for_run(robot_uuid, run_uuid, started_ms, timeout_s=3600):
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        now = int(time.time() * 1000)
        for event in robot_events(robot_uuid, started_ms - 60_000, now + 60_000):
            if event.get("activityUuid") == run_uuid and event.get("event") in FINAL:
                return event
        time.sleep(15)
    raise TimeoutError(f"run {run_uuid} hasn't finished")

started = int(time.time() * 1000)
run = robot_api("deploy", {"deviceUuid": ROBOT_UUID, "navType": "PATROL", "patrolUuid": PATROL_UUID})
result = wait_for_run(ROBOT_UUID, run["routeRunUuid"], started)
print(result["event"], result.get("failureReason") or "", (result.get("preemptedBy") or {}).get("activity", ""))

robot_events es el lector de Monitorear robots. La ventana empieza un minuto antes y termina un minuto después para compensar las diferencias del reloj del robot. Para recibir actualizaciones a medida que ocurren, el socket en vivo entrega los mismos eventos como mensajes BEHAVIOR_EVENT, con el ID de la ejecución en activity_uuid.

Lleva tu propio registro de las ejecuciones a partir de estos eventos. Las operaciones de ejecuciones de ruta y de ejecuciones de punto de ruta de la referencia de la API no devuelven las ejecuciones iniciadas por deploy ni por los horarios de las patrullas.