Adapters
Adapters are responsible for ingesting specific map types, converting them into the standard DroneDeploy map format, then adding this data to the dynamic map. The map adapters are also able to do the inverse: taking a map from the dynamic map and converting it back into the source map format, then loading this map on the source robot.
Adapters are defined in the "adapters"
field of the map
component within the agent-settings.json
configuration file. The "adapters"
field is a key-value object where each key is the unique name given to the adapter and the value is another key-value object describing that adapters type and unique settings. With this approach, multiple adapters can be defined and active at any one time.
Adapters have three base fields common to all, these are:
Setting | Type | Description |
---|---|---|
enabled | bool | Defines whether or not the adapter is enabled or not. |
type | string | Describes the type of adapter that will be instanced. This must match a predefined type string. Current options include spot , ros.occupancy-grid , ros.laser-scan , ros.pointcloud2 , ros.path , ros.polygon , ros.tf , and static-pointcloud . |
settings | object | A key-value object storing unique settings for the adapter in question. More on this in the next sections. |
Example
...
{
"enabled": true,
"id": "map",
"settings": {
"logLevel": 4,
"name": "map",
"dynamicMaps": {
"spot": {
"adapters": {
"spot": {
"enabled": true,
"type": "spot",
"settings": {
"colorTransformer": "auto",
"interval": "5s",
"upAxis": "z",
"transformTargetFrameID": "seed",
"voxelSettings": {
"enabled": false
}
}
}
}
},
"ros": {
"adapters": {
"ros-adapter": {
"enabled": false,
"type": "ros.pointcloud2",
"settings": {
"colorTransformer": "auto",
"pointcloudSource": "/ros/camera/rgb/points",
"interval": "100ms",
"upAxis": "y",
"transformTargetFrameID": "seed",
"voxelSettings": {
"enabled": true,
"octreeDepth": 4,
"octreeResolution": 1,
"voxelChunkSize": 20000,
"refreshOctree": true
}
}
}
}
}
}
}
}
There are currently 8 standard adapters which are able to be used. Each adapter has unique settings to control its behaviour.
Spot
Adapter Type: "spot"
This adapter subscribes to and ingests Spot's GraphNav map.
Setting | Type | Description | Default |
---|---|---|---|
transformTargetFrameID | string | The frame you would like to name Spot's anchor frame. | "seed" |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "spot",
"settings": {
"transformTargetFrameID": "seed"
}
}
ROS TF
Adapter Type: "ros.tf"
This adapter subscribes to a ROS TF topic.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the tf message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form: "/tf" , then the path will be "/ros/tf" . | |
interval | string | The subscription interval used by the adapter. It is defined in human-readable formats, such as “100ms” or “0.1s” . | "1s" |
interval | array of strings | The adapter can be configured to ignore specified frames. |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.tf",
"settings": {
"source": "/ros/tf",
"interval": "100ms"
}
}
ROS LaserScan
Adapter Type: "ros.laser-scan"
This adapter subscribes to a ROS LaserScan topic.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the LaserScan message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form: "/scan" , then the path will be "/ros/scan" . | |
interval | string | The subscription interval used by the adapter. It is defined in human-readable formats, such as “100ms” or “0.1s” . | "1s" |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.laser-scan",
"settings": {
"source": "/ros/scan",
"interval": "100ms"
}
}
ROS OccupancyGrid
Adapter Type: "ros.occupancy-grid"
This adapter subscribes to a ROS OccupancyGrid topic.
The OccupancyGrid adapter is able to decode occupancy grid messages and convert them into 3D points that can be then ingested by the map component. It does this by iterating through each cell within the occupancy grid and deciding whether it belongs to one of three states; occupied, unoccupied, and unexplored. The adapter classifies cell values that are equal to -1 as unexplored, values equal to 0 as unoccupied, and values equal to 100 as occupied. By default only occupied cells are converted to points and ingested. However, the others can be enabled as desired.
Cells are converted to points based on the associated map meta data. X and Y positions for the corresponding point are calculated to the center of each cell. The points position in Z axis is fixed at 0.
Points are colored according to their classification. By default, unexplored points are colored white, unoccupied points are green, and occupied points are black. These colors can be configured.
The resolution of the occupancy grid is an important consideration when setting the resolution of the octree to be used in the map component. Ideally the octree should have the same or a slightly larger resolution. For example, if the occupancy grid resolution is 0.1 m
then the octree resolution should be set to >= 0.1 m
.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the OccupancyGrid message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form: "/map" , then the path will be "/ros/map" . | |
interval | string | The subscription interval used by the adapter. It is defined in human-readable formats, such as “100ms” or “0.1s” . | "1s" |
ingestUnexplored | bool | Should the adapter ingest unexplored space when decoding the OccupancyGrid message? It is strongly not recommended to enable this for large maps. Unexplored space is coded as cells with value == -1 . | false |
ingestUnoccupied | bool | Should the adapter ingest unoccupied space when decoding the OccupancyGrid message. It is not recommended to enable this for large maps. Unoccupied space is coded as cells with value == 0 . | false |
ingestOccupied | bool | Should the adapter ingest occupied space when decoding the OccupancyGrid message? Occupied space is coded as cells with value == 100 . | true |
unexploredColor | [int, int, int] | The color that should be applied to points ingested as unexplored. Defaults to white. | [255, 255, 255] |
unoccupiedColor | [int, int, int] | The color that should be applied to points ingested as unoccupied. Defaults to green. | [50, 255, 50] |
occupiedColor | [int, int, int] | The color that should be applied to points ingested as occupied. Defaults to black. | [20, 20, 20] |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.occupancy-grid",
"settings": {
"source": "/ros/map",
"interval": "100ms",
"ingestOccupied":true,
"occupiedColor":[255, 50, 50]
}
}
ROS Pointcloud2
Adapter Type: "ros.pointcloud2"
This adapter uses a subscription to a ROS Pointcloud2 topic.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the pointcloud2 message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form:"/camera/rgb/points" , then the path will be "/ros/camera/rgb/points" . | |
interval | string | The subscription interval used by the adapter. It is defined in human-readable formats, such as “100ms” or “0.1s” . | "1s" |
colorTransformer | string | Can be one of "auto" , "rgb8" or "intensity" . this field defines which method to use to colour each point. In most situations, "auto" should be used. However, if both colour and intensity information exists in the source then setting this to "rgb8" , or "intensity" will let you explicitly choose which to use.- "rgb8" will look for an "rgb" field and decode it by assuming the standard ROS float32 to RGB method.- "intensity" will look for an "intensity" field and apply that to each RGB channel to get a grayscale mapping- "auto" will use whatever is available. If both exist it will default to rgb8 . | "auto" |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.pointcloud2",
"settings": {
"colorTransformer": "auto",
"source": "/ros/camera/rgb/points",
"interval": "100ms",
"upAxis": "y"
}
}
ROS Path
Adapter Type: "ros.path"
This adapter uses a subscription to a ROS Path topic. It inserts the path into the map as a series of nodes and edges.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the path message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form:"/path" , then the path will be "/ros/path" . |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.path",
"settings": {
"source": "/ros/path"
}
}
ROS Polygon
Adapter Type: "ros.polygon"
This adapter uses a subscription to a ROS Polygon topic. It inserts the path into the map as a series of nodes and edges.
Setting | Type | Description | Default |
---|---|---|---|
source | string | The topic path of the polygon message source. Note that this is the topic path as presented in the live data viewer. This means for a ROS source of the form:"/polygon" , then the path will be "/ros/polygon" . |
Example
"uniqueAdapterName": {
"enabled": true,
"type": "ros.polygon",
"settings": {
"source": "/ros/polygon"
}
}
Static Point clouds
Adapter Type: "static-pointcloud"
The static pointcloud adapter is used to load pointcloud .obj
files pointed at with the "filepath"
field. It is able to load point clouds with and without colour information.
Setting | Type | Description | Default |
---|---|---|---|
filepath | string | The path of the file containing pointcloud information | |
updateMethod | string | The update method defines when points will be inserted from the pointcloud. It can be either "periodic" or "onchange" - "periodic" will trigger an update at a specified interval- "onchange" will monitor the referenced file and trigger an update on any changes. This method is useful for situations where a SLAM map is constantly being built and saved to disk by a SLAM algorithm. | "periodic" |
updateInterval | string | When updateMethod is set to periodic , this defines the interval for updates. The interval must be specified as a human-readable interval, e.g. "100ms" or "0.1s". | "1s" |
renameFileOnRead | bool | This is a boolean which adds additional file handling behaviour to minimise collisions with file events. When enabled, the agent will rename the file by adding a .copy postfix before reading the file into memory. When complete the agent will check to see if a new file has been created with the original name while it has been busy. If so it will discard the .copy version. If no new file has been created it will undo the rename procedure by removing the .copy tag. This parameter is only relevant when updateMethod is set to onchange . | false |
sampleMethod | string | The sampling method describes how points will be inserted from the pointcloud. It can be either "all" or "random" .- "all" will insert all loaded points in every update. Careful consideration should be given to the size of the pointcloud file when using this method.- "random" will sample a predetermined number of random points from the loaded pointcloud file. This method is useful for repeatably visualising a static pointcloud within the Robot Automation Portal operations view. | "random" |
sampleSize | number | When using the random "sampleMethod" , this setting defines the number of points that will be randomly sampled per update. | 1000 |
Example
"uniqueAdapterName": {
"enabled": false,
"type": "static-pointcloud",
"settings": {
"filepath": "pointclouds/carpark.obj",
"renameFileOnRead": true,
"sampleMethod": "all",
"updateMethod": "periodic",
"updateInterval": "2000ms",
"sampleSize": 5000
}
}
Shared Settings
There are also common settings that can be applied to any adapter. The settings defined below relate to general point coordinate systems and transform bindings.
Transform binding can be useful in situations where a point source needs to be bound to a coordinate system that is moving. Transforming points into this coordinate system before they are inserted into the map is generally recommended over binding the voxels object itself in Local Operations. This is due in part to achieving better timing synchronisation between the pose transform and the point source, and it allows for accumulation of points when "refreshOctree"
is disabled.
Setting | Type | Description | Default |
---|---|---|---|
upAxis | string | The up axis parameter can be defined as either "x" , "y" , or "z" and is used as shorthand for some simple axis rotations to transform points between common up axis nomenclature and the z-axis up that the Robot Automation Platform uses. | "z" |
useTransform | bool | Bind the points inserted by this adapter to a transformation frame. This transformation frame must be published by an instance of the conversions component running a "ros_tf_transforms" preset. | false |
traverseTransformTree | bool | Build and use a transform tree by traversing child-parent relationships between "transformSourceFrameID" and "transformTargetFrameID" .Note: All adapter insertion attempts will be blocked until a complete transformation tree can be established. If you are using this functionality and no voxels are being created, manually check a transformation path can be established. | false |
transformSourceComponent | string | The name of the conversions component that is publishing transform messages. When setting up a conversions component this is the value provided in the "name" field. | |
transformInterval | string | This defines the interval that will be used by the adapter to subscribe to transform topics. The interval must be specified as a human-readable interval, e.g. "100ms" or "0.1s" . In general this should be faster than the general adapter subscription interval. | "0ms" |
transformSourceFrameID | string | The frameID of the coordinate transform that the adapter points belong to. | |
transformTargetFrameID | string | The frameID of the coordinate transform that will be targeted in the traversal process. |
To use the transform binding functionality within the adapter you first must enable the conversions component with a "ros_tf_transforms"
preset rule. Please see the here for more information.
Example
"useTransform": true,
"traverseTransformTree": true,
"transformSourceComponent": "transforms",
"transformSourceFrameID": "/base_link",
"transformTargetFrameID": "/map",
"transformInterval": "10ms"