Ir al contenido

Rutas y patrullas de Recon

Define los recorridos que hace un robot Recon: rutas como paradas ordenadas con tiempos de espera y acciones de llegada, y patrullas que asignan una ruta a un robot y la ejecutan según un horario. Cubre cómo crear, cambiar y eliminar ambas.

En esta página

Una ruta es el trayecto: una lista ordenada de paradas en un mapa. Una patrulla es una ruta asignada a un robot, con un horario opcional. Puedes ejecutar una misma ruta en varios robots, cada uno con su propia patrulla. Los ejemplos usan la función auxiliar robot_api de la descripción general.

Necesitas una clave de API con acceso de administrador a la ubicación del mapa para las rutas, y acceso de administrador al robot para las patrullas.

Crea una ruta

createRobotRoute recibe un nombre, el mapa y las paradas en el orden en que el robot las visita. Cada parada hace referencia a un punto de ruta o lleva una pose propia:

Python
route = robot_api("createRobotRoute", {
    "name": "Night perimeter",
    "mapUuid": MAP_UUID,
    "waypoints": [
        {"name": "Dock door", "waypointRefUuid": DOCK_DOOR_WAYPOINT_UUID, "dwellStrategy": "DURATION", "dwellTimeSecs": 30},
        {"name": "North fence", "pose": {"position": [40.0, 8.5, 0.0], "orientation": [0.0, 0.0, 0.0, 1.0]}, "dwellStrategy": "NONE"},
        {"name": "Server room", "waypointRefUuid": SERVER_ROOM_WAYPOINT_UUID, "dwellStrategy": "DURATION", "dwellTimeSecs": 60},
    ],
})["routeView"]["route"]
  • El orden es el de la lista.
  • Espera: DURATION mantiene al robot en la parada durante dwellTimeSecs segundos; NONE sigue en cuanto llega. Una parada que no indica ni dwellStrategy ni dwellTimeSecs espera 15 segundos. Usa estas dos estrategias; las demás se comportan como NONE.
  • Una ejecución por envío. El robot visita cada parada una vez y la ejecución termina. Si no puede llegar a una parada, toda la ejecución termina como FAILED. Para repetir una ruta, usa un horario de patrulla.
  • Los horarios pertenecen a las patrullas: una solicitud de ruta con deployConditions o deviceUuid se rechaza.

El campo route.waypointMap de la respuesta contiene las paradas, con el ID de parada como clave, cada una con su ordinal (0 para la primera parada), su pose o waypointRefUuid, y dwellTimeMs. Las acciones de llegada y el progreso del robot (waypointUuid en su estado y en sus eventos) se refieren a los ID de parada, que no son los ID de los puntos de ruta a los que hace referencia cada parada.

Lee una ruta con getRobotRoute (uuid), o todas las rutas de un mapa con findRobotRoutesByMap (mapUuid).

Cambia una ruta

updateRobotRoute cambia una ruta, identificada por su uuid. Una lista de waypoints reemplaza todas las paradas de la ruta, así que envía todas las paradas que quieras conservar, cada una con:

  • su uuid, para conservar el ID de esa parada. Una parada sin él se crea como una parada nueva con un ID nuevo, y las acciones de llegada que una patrulla tenga para el ID anterior dejan de aplicarse;
  • su ordinal, porque al actualizar, el orden lo dan los ordinales, no la lista;
  • sus rules, porque una parada enviada sin ellas pierde sus acciones de llegada.

La forma segura de editar es leer la ruta, cambiarla y enviarla completa de vuelta:

Python
route = robot_api("getRobotRoute", {"uuid": ROUTE_UUID})["routeView"]
stops = sorted(route["route"]["waypointMap"].values(), key=lambda s: s["ordinal"])
rules = route.get("waypointRules") or {}

def as_request(stop, ordinal):
    request = {
        "uuid": stop["uuid"],
        "name": stop["name"],
        "ordinal": ordinal,
        "dwellStrategy": stop.get("dwellStrategy", "DURATION"),
        "dwellTimeSecs": stop.get("dwellTimeMs", 15000) // 1000,
        "rules": [{"ruleName": r["name"], "action": r["action"], "ruleFilters": r.get("ruleFilters")} for r in rules.get(stop["uuid"], [])],
    }
    if stop.get("waypointRefUuid"):
        request["waypointRefUuid"] = stop["waypointRefUuid"]
    else:
        request["pose"] = stop["pose"]
    return request

stops[0]["dwellTimeMs"] = 45000  # dwell 45 seconds at the first stop
robot_api("updateRobotRoute", {
    "uuid": ROUTE_UUID,
    "waypoints": [as_request(stop, i) for i, stop in enumerate(stops)],
})

Para cambiar el nombre de una ruta, envía solo uuid y name; si omites waypoints, las paradas quedan como están. Una ruta no se puede pasar a otro mapa.

deleteRobotRoute (uuid) se rechaza mientras haya patrullas que usen la ruta: elimina primero esas patrullas (findPatrolsByRoute las enumera).

Acciones de llegada

Una parada puede ejecutar acciones cuando el robot llega a ella. Son reglas, con la misma forma que las acciones de otras reglas de Rhombus: cada una tiene un ruleName y una action y, de forma opcional, ruleFilters con scheduleUuids para ejecutarse solo durante un horario. Por ejemplo, "action": {"alertAction": true} genera una alerta en Rhombus en esa parada.

Pueden estar en dos lugares:

Se definen conSe ejecutan para
En la parada de la rutarules en cada parada de createRobotRoute o updateRobotRouteTodos los robots que ejecutan la ruta
En una patrullawaypointActions en createPatrol o updatePatrol, una entrada por ID de paradaSolo el robot de esa patrulla

Cuando varios robots comparten una ruta, es preferible usar las acciones de llegada de la patrulla.

  • Las acciones de la ruta y de la patrulla se devuelven en waypointRules, con el ID de parada como clave.
  • Las acciones de llegada también se ejecutan cuando el robot abandona una parada (porque ese tramo falló o se canceló). Si importa saber si el robot llegó realmente, revisa sus eventos.
  • Cambia estas acciones solo con las operaciones de robots, no con las operaciones de reglas de /api/rules/.

Crea una patrulla

createPatrol asigna una ruta a un robot. La ruta debe estar en el mapa asignado del robot:

Python
patrol = robot_api("createPatrol", {
    "deviceUuid": ROBOT_UUID,
    "routeUuid": ROUTE_UUID,
    "name": "Night perimeter (east robot)",
    "deployConditions": [{"type": "SCHEDULED_EVENT", "minOfDay": 1320}],
    "waypointActions": [
        {"routeWaypointUuid": SERVER_ROOM_STOP_ID, "rules": [{"ruleName": "Server room check", "action": {"alertAction": True}}]},
    ],
})["patrolView"]["patrol"]
print(patrol["uuid"], patrol["enabled"])

Omite deployConditions para una patrulla que solo se ejecute cuando la envíes. Una patrulla nueva queda habilitada.

Horarios

El horario de una patrulla es su primera condición de despliegue. Envía una de estas:

Se ejecutadeployConditionsscheduleUuid
Una vez al día a una hora fija[{"type": "SCHEDULED_EVENT", "minOfDay": 1320}] (22:00)Opcional: hace que se ejecute solo dentro del horario, por ejemplo, en días laborables
Cada N minutos u horas durante ciertos horarios[{"type": "RECURRING_EVENT", "repeatInterval": 30, "timeUnit": "MINUTES"}]Obligatorio: las horas en las que se repite. Sin él, la patrulla nunca se ejecuta
  • minOfDay son los minutos después de la medianoche, en la zona horaria de la ubicación del robot.
  • scheduleUuid es uno de los horarios de tu organización (getSchedules).
  • El robot lleva el horario por sí mismo. Si toca una ejecución mientras el robot está ocupado (ya está patrullando, se está recargando o alguien lo está conduciendo), esa ejecución se omite, no se pone en cola.

Cambia, pausa o elimina una patrulla

updatePatrol identifica la patrulla por su patrolUuid y cambia solo los campos que envías:

CampoEfecto
nameCambia el nombre de la patrulla
enabledfalse pausa el horario y rechaza los envíos de esta patrulla; true la reanuda. Envía siempre un booleano: null cuenta como false
deployConditions, con scheduleUuid cuando el horario usa unoUna lista no vacía reemplaza el horario; una lista vacía lo quita
waypointActionsReemplaza todas las acciones de llegada de la patrulla
Python
robot_api("updatePatrol", {"patrolUuid": PATROL_UUID, "enabled": False})

findPatrolsByRobot (deviceUuid) enumera las patrullas de un robot en su mapa asignado, getPatrol (patrolUuid) devuelve una, y deletePatrol (patrolUuid) la elimina junto con su horario y sus acciones de llegada. El robot y la ruta de una patrulla no se pueden cambiar: en su lugar, crea una patrulla nueva.