Skip to main content

Commands

Commands are the main method by which you can instruct your robot to perform a particular action: A single Command might instruct your robot to perform some physical action, like taking-off, landing, or moving in a particular direction; or it might instruct your robot to perform some internal behaviour such as resetting a counter.

Commands are designed to allow the creation of a stable and reliable API to your robot, so that you can develop user facing software which invokes Commands, while being insulated from any implementation changes on the underlying robot.

For working demonstrations for Commands, and of calling Commands using Buttons, please review the MAVLink: Deploy an ArduPilot Simulator and ROS: Deploy a TurtleBot Simulator tutorials; the virtual robots created in these tutorials each include a number of Commands pre-configured.

Agent Setup

In order to be able to send Commands to a robot, the agent on the robot must have two necessary plugins enabled: make sure the command-executor and command-receiver components are enabled in your Agent Configuration, as shown in the snippet below.

{
"enabled": true,
"id": "command-executor",
"settings": {
"logLevel": 4
}
},
{
"enabled": true,
"id": "command-receiver",
"settings": {
"name": "receiver",
"logLevel": 4
}
},

Command Definitions

In order to use a Command to instruct your robot to perform an action, you must first create a corresponding Command Definition (this is true both in the case that you want to invoke the Command via a Button, and also when calling a Command via API).

Commands may be defined both for a particular Robot, and for a Robot Profile. In each case, the list of existent Command Definitions is show on the Commands tab:

A Command may perform one of several possible actions:

  • Send a Control Message, which is transmitted from the appropriate Agent plugin: in the case of the ROS plugin, this publishes a ROS topic, in the case of the MAVLink plugin, this transmits a MAVLink message.
  • Call a Service, which invokes some plugin specific request/response behaviour: in the case of the ROS plugin, this performs a ROS service call, or invokes an actionlib action.

Parameters

A Command can also optionally accept some number of input parameters that are passed into it when it is invoked, and which are substituted into the Payload Template of the Command so as to create a completed message Payload. Parameter input values may be taken from input fields when triggering a Command via a Button, or filled in from data in the source message when triggering a Command via an Event.

Commands are able to provide comprehensive feedback as to their status/progress, and eventual end results: when calling a Command via API, a command may return one or more data payloads along with associated metadata.

A Command Definition may specify the maximum permitted duration which the execution of the Command is allowed to take. Commands which exceed this duration are terminated immediately. Optionally, the Agent my be configured to only accept a Command in the case that it is confident it has a shared understanding of the current clock time with the originator of the Command, ensuring the Command is only executed during the exact time window the user intends.

Examples

ROS Example (TurtleBot Online Tutorial)

In this example, you configure a command called move, and you want this Command to pass a Twist message into the /turtle1/cmd_vel topic for your robot to act on.

The twist message needs two parameters, the x value for forwards and backwards and z values for the amount of left/right rotation.

Command Id:drive

Type: Send Message

Target: The data URI to which the Control Message should be sent. In this case, use /ros/turtle1/cmd_vel which will publish a ROS message on the /turtle1/cmd_vel topic (which causes a Virtual ROS Turtlebot robot to move around in simulation).

Metadata: Used to set any metadata key:value pairs which the target component requires. For this example, the ROS component requires the ros.type key to indicate the ROS message type which the Payload should be converted into:

{
"ros.type": "geometry_msgs/Twist"
}

Payload Template: This is a JSON representation of the message to be sent: in this case, the ROS Twist message. Parameter values may be substituted in by enclosing in ${} markers, as detailed in the following section:

{ "linear": { "x": ${$params.forwardBack}, "y": 0, "z": 0 }, "angular": { "x": 0, "y": 0, "z": ${$params.twist} }}

Parameters:

In this example, the Command will be configured to take two input parameters:

  • forwardBack
  • twist

The Payload Template field supports token replacement and simple expressions using ES2015 Template Literals (the entire Payload Template is one single Template Literal). The value of the input parameters to the Command can be injected into Payload with the pattern ${$params.ParameterName}. In the pattern $params is an object that holds all the parameter values used when the Command was invoked. Simple expressions are also supported within the Payload Template, such as using ${$params.forwardBack * 0.2} to convert the input speed to a smaller value.

In this example, you want a Command called MAV_CMD_NAV_TAKEOFF, which when sent to your MAVLink based aircraft, tells the flight controller to take-off.

Command Id: NAV_TAKEOFF

Type: Send Message

Target:/mavlink/COMMAND_LONG

Payload Template: This example assumes that your robot is already armed and ready for flight:

{ "target_system": 1, "target_component": 1,  "command": 22, "param7": ${$params.altitude}}

Parameters:

In this example, the Command will be configured to take a single input parameter:

  • altitude