AWS IoT RoboRunner tutorials - AWS IoT RoboRunner

AWS IoT RoboRunner tutorials

The following tutorials describe how to develop a custom task manager for managing tasks and how to develop a fleet management system (FMS) gateway that serves as a message routing layer between the task manager and a vendor's fleet management system.

Develop a task manager

Task manager sample application code

The task manager sample application is associated with this tutorial. To use the sample application, you must patch the CLI as instructed in the README.md of the Java SDK.

AWS IoT RoboRunner can be used to accomplish tasks using a custom task manager. This section walks through a sample task manager that can be hosted in the AWS Cloud as an AWS Lambda function.

This package is a sample implementation of a task manager that you can write to manage tasks with AWS IoT RoboRunner. With AWS IoT RoboRunner, you can model concepts about your site like workers, fleets, and tasks. It also gives you lower-level primitive data types like ActionTemplate, Activity, and Action to plan and run work. This Lambda function is an example implementation of a task manager that makes use of AWS IoT RoboRunner APIs to plan a move task to move a worker from location A to B.

Most industrial systems have their own way of modeling work orders they want their fleet of robots to perform. You typically start by translating a work order into an AWS IoT RoboRunner task. Once a task is registered in AWS IoT RoboRunner, you can make use of the task manager to plan, allocate, and dispatch it.

The key components of this package are:

  • Planner: This takes in a task, breaks it down into sub-tasks, and creates dependencies between them if needed. It generates action templates, which can be thought of as the action, such as MOVE, that workers perform.

  • Allocator: This component looks at planned tasks and assigns worker fleets to them. This component also creates activities and actions. An action is an immutable version of an action template and an activity is an immutable version of task.

  • Dispatcher: This component looks at allocated activities and converts them into a format that the fleet management system gateway understands. This component sends the FMS gateway specific payload to an endpoint that dispatches the actions to a vendor fleet management system. For this sample Lambda function, you use Amazon SQS as the destination.

Another key component of this package is a listener that looks at responses from the FMS gateway through an endpoint (Amazon SQS in this case) and updates the actions, activity, task, and worker state in AWS IoT RoboRunner.

The following images are sample flow diagrams of data when accessing the AWS IoT RoboRunner APIs from a task manager. In these diagrams, the assumption is that the FMS gateway is listening and responding to Amazon SQS endpoints.


                Diagram representing data accessing AWS IoT RoboRunner from a task
                    manager.

                Diagram representing the request and response cycle from
                    a task manager.

Develop a gateway

Fleet manager system sample application

The fleet manager system gateway sample application is associated with this tutorial. To use the sample application, you must patch the CLI as shown in the README.md of the Java SDK.

You can use AWS IoT RoboRunner to coordinate workers purchased from multiple vendors. Each vendor provides a fleet management system (FMS) that manages their respective workers. Each vendor FMS provides a REST API that allows callers with a network connection to assign tasks and to request state from the vendor workers. The following diagram represents these interactions.


                Diagram representing the development of a
                    fleet management system gateway.

The vendor fleet management systems and their respective robots likely exist on the on-site local network and are not directly accessible via the internet. Therefore, you need an intermediary service that has both internet and local connections to facilitate communication between AWS IoT RoboRunner and the vendor fleet management system.

The AWS IoT RoboRunner fleet management system gateway sample is an example implementation of a highly flexible service that is deployable as a AWS IoT Greengrass V2 component to an on-site compute server at a customer site. The FMS gateway serves as a single aggregated message routing layer between the vendor FMS available on the local network and any external components that need to access the vendor FMS API. For external components that are remote to the customer site (such as the task manager), the FMS gateway supports using Amazon SQS queues as the message passing interface.

This simple implementation of an FMS gateway doesn't contain vendor-specific business logic. The responsibility of creating valid REST requests and parsing the responses from specific vendor FMS APIs still belongs to the external components (such as the task manager). However, because the FMS gateway is generic, it can be used in conjunction with any vendor FMS that offers a REST API. In fact, the FMS gateway can be configured to make calls to any service providing REST APIs, including individual workers.

Read worker and task status

You can read worker and task status from the example implementation of the fleet management system gateway and report it back to AWS IoT RoboRunner. As long as the fleet management system (FMS) gateway is configured correctly, any API calls available on the vendor FMS are also available to external components (such as the task manager). However, the FMS gateway doesn't offer a generic method to read worker or task status from any vendor FMS. Using an example vendor FMS, the following examples are sample payloads to the FMS gateway that perform these requests on workers. The examples define the group of actions intended for a specific worker as a mission.

Reading worker status from an FMS gateway

The following example is a sample task request message sent to the configured Amazon SQS queue that requests the list of available workers.

{ "payload_id": "payload-id-0966-1657-2899", # This is to match request and response messages. "comms_channel_id": "vendor-worker-tracker-sqs", # This should match the FMS gateway configuration. # A list of individual REST API calls to be made to the FMS. # These will be called in order on the FMS. "request_list": [ # Represents the REST request GET /<vendor-FMS-API-ENDPOINT>/robots. # Gets the list of workers managed by the FMS. { "method": "GET", "command": "robots" } ] }

The following example is a task response message (via the response Amazon SQS queue) for the preceding request.

{ "payload_id": "payload-id-0966-1657-2899", # Matches the payload_id in the request. "comms_channel_id": "vendor-worker-tracker-sqs", # request_list kept in response for easier debugging. "request_list": [ { "method": "GET", "command": "robots" } ], # List of responses received in order of their corresponding requests. "response_list": [ # This is the response that lists the robots managed by the FMS. { # The status code of the FMS REST response. "status_code": 200, # Did the FMS return a successful response? "ok": true, # Reason text from the FMS. "reason": "OK", # Message body of the FMS REST response. # This shows that there are two workers managed by the FMS # and their corresponding workers ids. "content": [ { "url": "/v2.0.0/robots/1", "id": 1 }, { "url": "/v2.0.0/robots/2", "id": 2 } ] } ], # This shows that no errors occurred in the execution of the FMSG itself. "FMSG_Error": null }

The following example is a sample task request message sent to the configured request Amazon SQS queue that requests the states for two workers.

{ "payload_id": "payload-id-6999-5269-2240", # This is to match request and response messages. "comms_channel_id": "vendor-worker-tracker-sqs", # This should match the FMS gateway configuration. # A list of individual REST API calls to be made to the FMS. # These will be called in order on the FMS. "request_list": [ # Represents the REST request GET /<vendor-FMS-API-ENDPOINT>/robots/1 # that gets the status of worker with id 1 { "method": "GET", "command": "robots/1" }, # Represents the REST request GET /<vendor-FMS-API-ENDPOINT>/robots/2 # that gets the status of worker with id 2. { "method": "GET", "command": "robots/2" } ] }

The following example is a task response message (via the response Amazon SQS queue) for the preceding request.

{ "payload_id": "payload-id-6999-5269-2240", # Matches the payload_id in the request. "comms_channel_id": "vendor-worker-tracker-sqs", # request_list kept in response for easier debugging "request_list": [ { "method": "GET", "command": "robots/1" }, { "method": "GET", "command": "robots/2" } ], # List of responses received in order of their corresponding requests "response_list": [ .# This is the status response for robot 1 { # The status code of the FMS REST response. "status_code": 200, # Did the FMS return a successful response? "ok": true, # Reason text from the FMS. "reason": "OK", # Message body of the FMS REST response. "content": { "status": { "joystick_low_speed_mode_enabled": false, "mode_id": 7, "moved": 1776.85985639794, "mission_queue_id": 0, "header": { "stamp": { "secs": 0, "nsecs": 0 }, "frame_id": "", "seq": 0 }, "robot_name": "VENDOR_R1737", "uptime": 580, "errors": [], "unloaded_map_changes": false, "distance_to_next_target": 0.0, "battery_voltage": 0.0, "mode_key_state": "idle", "battery_percentage": 67.19999694824219, "map_id": "session-lab-map0-0000-0000-0000-0000", "software_version": "2.13.0.2", "safety_system_muted": false, "mission_text": "Waiting for new missions...", "velocity": { "linear": 0.0, "angular": 0.0 }, "state_text": "Pause", "position": { "y": 4.398640155792236, "x": 10.897378921508789, "orientation": -88.64453887939453 }, "footprint": "[[0.506,-0.32],[0.506,0.32],[-0.454,0.32],[-0.454,-0.32]]", "user_prompt": { "question": "", "has_request": false, "timeout": { "secs": 0, "nsecs": 0 }, "user_group": "", "guid": "", "options": [] }, "mode_text": "Mission", "hook_status": { "trolley": { "width": 0.0, "length": 0.0, "offset_locked_wheels": 0.0, "id": 0, "height": 0.0 }, "available": false, "trolley_attached": false }, "session_id": "session-lab-0000-0000-0000-0000-0000", "joystick_web_session_id": "", "hook_data": { "angle": { "timestamp": { "secs": 0, "nsecs": 0 }, "angle": 0.0 }, "height_state": 0, "brake_state": 0, "height": 0.0, "length": 0.0, "gripper_state": 0 }, "battery_time_remaining": 64556, "state_id": 4 }, "fleet_state_text": "unavailable", "allowed_methods": [ "PUT", "GET", "DELETE" ], "description": "AWS IoT RoboRunner lab worker", "ip": "10.107.1.6", "factory_reset_needed": false, "created_by_id": "vendorconst-guid-0000-0006-users0000000", "operation_mode_info": { "synchronization_enabled": true, "mission_scheduling_enabled": true, "resource_management_enabled": true, "initial_synchronization_enabled": false, "collision_avoidance_enabled": true, "mode_name": "ActiveMode", "charging_staging_enabled": true, "communicator_enabled": true }, "created_by": "/v2.0.0/users/vendorconst-guid-0000-0006-users0000000", "fleet_state": 1, "created_by_name": "User", "active": true, "serial_number": "200100005001737", "robot_group_id": 2, "id": 1, "robot_model": "Vendor100" } }, # This is the status response for robot 2. { "status_code": 200, "ok": true, "reason": "OK", "content": { "status": { "joystick_low_speed_mode_enabled": false, "mode_id": 7, "moved": 268.4711777225223, "mission_queue_id": 0, "header": { "stamp": { "secs": 0, "nsecs": 0 }, "frame_id": "", "seq": 0 }, "robot_name": "vendor_noname", "uptime": 1455747, "errors": [], "unloaded_map_changes": false, "distance_to_next_target": 0.04439999908208847, "battery_voltage": 0.0, "mode_key_state": "idle", "battery_percentage": 100.0, "map_id": "session-lab-map0-0000-0000-0000-0000", "software_version": "2.13.0.2", "safety_system_muted": false, "mission_text": "Waiting for new missions...", "velocity": { "linear": 0.0, "angular": 0.0 }, "state_text": "Ready", "position": { "y": 5.218129634857178, "x": 8.235849380493164, "orientation": -1.5685666799545288 }, "footprint": "[[0.506,-0.32],[0.506,0.32],[-0.454,0.32],[-0.454,-0.32]]", "user_prompt": { "question": "", "has_request": false, "timeout": { "secs": 0, "nsecs": 0 }, "user_group": "", "guid": "", "options": [] }, "mode_text": "Mission", "hook_status": { "trolley": { "width": 0.0, "length": 0.0, "offset_locked_wheels": 0.0, "id": 0, "height": 0.0 }, "available": false, "trolley_attached": false }, "session_id": "session-lab-0000-0000-0000-0000-0000", "joystick_web_session_id": "", "hook_data": { "angle": { "timestamp": { "secs": 0, "nsecs": 0 }, "angle": 0.0 }, "height_state": 0, "brake_state": 0, "height": 0.0, "length": 0.0, "gripper_state": 0 }, "battery_time_remaining": 136800, "state_id": 3 }, "fleet_state_text": "ready", "allowed_methods": [ "PUT", "GET", "DELETE" ], "description": "", "ip": "172.17.0.2", "factory_reset_needed": false, "created_by_id": "vendorconst-guid-0000-0006-users0000000", "operation_mode_info": { "synchronization_enabled": true, "mission_scheduling_enabled": true, "resource_management_enabled": true, "initial_synchronization_enabled": false, "collision_avoidance_enabled": true, "mode_name": "ActiveMode", "charging_staging_enabled": true, "communicator_enabled": true }, "created_by": "/v2.0.0/users/vendorconst-guid-0000-0006-users0000000", "fleet_state": 11, "created_by_name": "User", "active": true, "serial_number": "", "robot_group_id": 2, "id": 2, "robot_model": "Vendor100" } } ], "FMSG_Error": null }

Read task status

When you create a task in AWS IoT RoboRunner, the task manager creates activities and actions that are translated into vendor-specific commands. The task manager sends these commands to the fleet management system gateway. The FMS gateway forwards these commands to a vendor fleet manager or worker. The FMS gateway produces a response that contains the commands that were successfully sent and scheduled. To monitor the status of these commands, you can use the following task request message.

{ "payload_id": "some-request-id-check-tasks-82605716331", "comms_channel_id": "vendor-task-manager", "request_list": [ { "method": "GET", "command": "mission_scheduler/40" }, { "method": "GET", "command": "mission_scheduler/41" }, { "method": "GET", "command": "mission_scheduler/42" } ] }

The following example is a response message for the preceding request.

{ "payload_id": "some-request-id-check-tasks-82605716331", "comms_channel_id": "vendor-task-manager", "request_list": [ { "method": "GET", "command": "mission_scheduler/40" }, { "method": "GET", "command": "mission_scheduler/41" }, { "method": "GET", "command": "mission_scheduler/42" } ], "response_list": [ # Action group 40 is in Done state. # Worker 3 is assigned. # Start time and finish time have valid values. { "status_code": 200, "ok": true, "content": { "priority": 0, "allowed_methods": [ "PUT", "GET", "DELETE" ], "description": "vendor-test-actions-waypoints-0005-0000", "order_time": "2021-10-11T23:53:32", "state": "Done", "finish_time": "2021-10-11T23:55:51", "earliest_start_time": "2021-01-01T00:00:00", "start_time": "2021-10-11T23:53:36", "mission": "/v2.0.0/missions/vendor-test-mission-waypoints-0005-0000", "created_by": "/v2.0.0/users/vendorconst-guid-0000-0006-users0000000", "fleet_schedule_guid": "71139b4c-2aee-11ec-aabf-0a8ec89c7ddb", "mission_id": "vendor-test-actions-waypoints-0005-0000", "high_priority": true, "mission_name": "vendor-test-actions-waypoints-0005-0000", "created_by_name": "User", "robot_id": 3, "created_by_id": "vendorconst-guid-0000-0006-users0000000", "parameters": { "data": [] }, "id": 40 } }, # Action group 41 is in Executing state. # Worker 3 is assigned. # Start time is filled in but finish time is in the past. { "status_code": 200, "ok": true, "content": { "priority": 0, "allowed_methods": [ "PUT", "GET", "DELETE" ], "description": "vendor-test-actions-waypoints-0007-0000", "order_time": "2021-10-11T23:55:18", "state": "Executing", "finish_time": "2021-01-01T00:00:00", "earliest_start_time": "2021-01-01T00:00:00", "start_time": "2021-10-11T23:55:53", "mission": "/v2.0.0/missions/vendor-test-mission-waypoints-0007-0000", "created_by": "/v2.0.0/users/vendorconst-guid-0000-0006-users0000000", "fleet_schedule_guid": "afb96ebc-2aee-11ec-8dc0-0a8ec89c7ddb", "mission_id": "vendor-test-actions-waypoints-0007-0000", "high_priority": true, "mission_name": "vendor-test-actions-waypoints-0007-0000", "created_by_name": "User", "robot_id": 3, "created_by_id": "vendorconst-guid-0000-0006-users0000000", "parameters": { "data": [] }, "id": 41 } }, # Action group 42 is in Pending state. # No worker is assigned. # Start and finish time are in the past. { "status_code": 200, "ok": true, "content": { "priority": 0, "allowed_methods": [ "PUT", "GET", "DELETE" ], "description": "vendor-test-actions-waypoints-0006-0000", "order_time": "2021-10-12T17:42:34", "state": "Pending", "finish_time": "2021-01-01T00:00:00", "earliest_start_time": "2021-01-01T00:00:00", "start_time": "2021-01-01T00:00:00", "mission": "/v2.0.0/missions/vendor-test-mission-waypoints-0006-0000", "created_by": "/v2.0.0/users/vendorconst-guid-0000-0006-users0000000", "fleet_schedule_guid": "c8919abe-2b83-11ec-9079-0a8ec89c7ddb", "mission_id": "vendor-test-actions-waypoints-0006-0000", "high_priority": true, "mission_name": "vendor-test-actions-waypoints-0006-0000", "created_by_name": "User", "robot_id": 0, "created_by_id": "vendorconst-guid-0000-0006-users0000000", "parameters": { "data": [] }, "id": 42 } } ], "FMSG_Error": null }

AWS CLI and SDK for Java

The following are download links for the AWS Command Line Interface and AWS SDK for Java used with the task manager and fleet management system gateway sample applications. For information about the sample applications and how to use them, see Develop a task manager and Develop a gateway.