YAML Configuration

SOSS is configured by means of a YAML file that specifies a set of compulsory fields, plus some optional ones. The most common fields required to configure a System-Handle are:

  • types: specifies the IDL types used by SOSS to transmit messages.

    • idl: IDL content.

  • systems: specifies the middlewares involved in the communication, allowing to configure them.

  • routes: specifies which bridges SOSS needs to create.

    • from-to: publisher/subscriber communication.

    • server-clients: server/client communication.

  • topics/services: specify the topics exchanged over the routes above in either publisher/subscriber or client/server type communications, allowing to configure them.

    • type: type involved in the communication.

    • route: communication bridge to apply.

    • remap: allows to establish equivalences between topic names, types, and custom configurations.

A generic YAML communicating two systems has the following structure:

types:
    idl: <idl_content>
    paths: [idl_include_path_1, id_include_path_2 ]
systems:
    <system_1_name>: {
        type: <system_1_type>,
        types-from: <other_system_name>,
        <system_1_config>
    }
    <system_2_name>: {
        type: <system_2_type>,
        types-from: <other_system_name>,
        <system_2_config>
    }
routes:
    <route_name>: { from: <system_1_name>, to: <system_2_name> }
    <service_route_name>: {
        server: <system_1_name>,
        client: [<system_2_name>, <other_system_name>]
    }
topics:
    <topic_name>:
        type: <type_name>
        route: <route_name>
        remap:
            <system_1_name>: {
                type: <type_remap_name>,
                topic: <topic_remap_name>
            }
        <custom_topic_key>: <custom_topic_config>
services:
    <service_name>:
        type: <type_service_name>
        route: <service_route_name>
        remap:
            system_2_name>: {
                type: <type_remap_name>,
                topic: <topic_name>
            }
        <custom_service_key>: <custom_service_config>

Here is a nontrivial example, which translates a number of topics and some service clients between WebSocket+Rosbridge_v2, ROS2, and a (fictitious) automated door-opening firmware:

systems:
    web: { type: websocket_server_json, types-from: ros2, port: 12345 }
    robot: { type: ros2 }
    door:
        type: veridian_dynamics_proprietary_door_firmware
        types-from: ros2
        serial: 1765TED

routes:
    web2robot: {from: web, to: robot}
    robot2web: {from: web, to: robot}
    door_broadcast: {from: door, to: [web, robot]}
    web_service: {server: web, clients: robot}
    door_service: {server: door, clients: [web, robot]}

topics:
    videocall_signalling_tx:
        type: "rmf_msgs/SignallingMessage"
        route: web2robot
    videocall_presence: { type: "std_msgs/String", route: web2robot }
    call_button_state_array:
        type: "rmf_msgs/CallButtonStateArray"
        route: robot2web
    videocall_signalling_rx:
        type: "rmf_msgs/SignallingMessage"
        remap: {
            robot:
                type: {"videocall_signalling_rx/{message.message_to}" }
        }
        route: robot2web
    door_status:
        type: "rmf_msgs/DoorStatus"
        route: door_broadcast

services:
    get_video_callers:
        type: "rmf_msgs/GetVideoCallers"
        route: web_service
    reserve_robot: { type: "rmf_msgs/ReserveRobot", route: web_service }
    release_robot: { type: "rmf_msgs/ReleaseRobot", route: web_service }
    open_door: { type: "rmf_msgs/OpenDoor", route: door_service }
    close_door: { type: "rmf_msgs/CloseDoor", route: door_service }

The idea is that each system plays some role in the overall system of systems, and the user needs to specify the channels that these systems are expected to communicate over, as well as the direction that information should flow over those channels. Topics can be many-to-many, one-to-many, or many-to-one. Additionally, service-client routes can be provided. Services must always designate one service provider, but may have one or more clients. Some systems may have a different name for a topic or a service, so the remap dictionary allows the configuration file to specify a different name that SOSS should use for each system.

Here is a diagram that illustrates the concept:

_images/bubbles_of_bubbles.png

In the diagram, Robot A has a bunch of internal topics and services. It wishes to export some (but not all) of them to a much larger collection of other topics and services. In the process, some topic/service names will need to change, and perhaps some other filtering will occur (for example, the rate of publishing of its location will only be 1 Hz instead of 100 Hz, or its camera image will be dramatically down-sampled, etc.). The SOSS configuration file will specify the topics within Robot A that the robot needs to export, as well as what system middlewares each exported topic needs to be forwarded to.

Types definition

Some System-Handles have the ability to inform SOSS of the types definition (using XTypes) that they can use. The System-Handles of ROS1 and ROS2 are examples of this. Nevertheless, there are cases where the System-Handle is not able to retrieve the type specification (websocket, mock, dds, fiware, …) that it needs for the communication.

In those cases, there are two ways to pass this information to the System-Handle:

  • Using the types-from property, that imports the types specification from another system.

  • Specifying the type yourself by embedding an IDL into the YAML.

Regarding the second option, the IDL content can be provided in the YAML either directly, as follows:

types:
    idls:
        - >
            struct name
            {
                idl_type1 member_1_name;
                idl_type2 member_2_name;
            };

or by inclusion of a paths field, that can be used to provide the preprocessor with a list of paths where to search for IDL files to include into the IDL content. The syntax in this case would be:

types:
    idls:
        - >
            #include <idl_file_to_parse.idl>

        paths: [ idl_file_to_parse_path ]

Notice that these two approaches can be mixed.

The name for each type can be whatever the user wants, with the two following rules:

  1. The name cannot have spaces in it.

  2. The name must be formed only by letters, numbers and underscores.

Note: a minimum of a structure type is required for the communication.

For more details about IDL definition, please refer to IDL documentation.

The following is an example of a full configuration defining a dds-fiware communication using the types definition contained in the idls block.

types:
    idls:
        - >
            struct Stamp
            {
                int32 sec;
                uint32 nanosec;
            };

            struct Header
            {
                string frame_id;
                stamp stamp;
            };

systems:
    dds: { type: dds }
    fiware: { type: fiware, host: 192.168.1.59, port: 1026 }

routes:
    fiware_to_dds: { from: fiware, to: dds }
    dds_to_fiware: { from: dds, to: fiware }

topics:
    hello_dds:
        type: "Header"
        route: fiware_to_dds
    hello_fiware:
        type: "Header"
        route: dds_to_fiware

Systems definition

A System-Handle may need additional configuration that should be defined in its systems entry as a YAML map. Each entry of this section represents a middleware involved in the communication, and corresponds to an instance of a System-Handle. All System-Handles accept the type and types-from options in their systems entry. If type is omitted, the key of the YAML entry will be used as type.

systems:
    dds:
    ros2_domain5: { type: ros2, domain: 5, node_name: "soss_5" }
    fiware: { host: 192.168.1.59, port: 1026 }

The snippet above will create three System-Handles:

  • A DDS System-Handle or SOSS-DDS with default configuration.

  • A ROS2 System-Handle or SOSS-ROS2 named ros2_domain with domain = 5 and node_name = "soss_5".

  • A Fiware System-Handle or SOSS-FIWARE with host = 192.168.1.59 and port = 1026.

The System-Handles currently available for SOSS are listed in a table that you can find in the Related Links section of this documentation.

A new System-Handle can be created by implementing the desired SystemHandle subclasses to add support to any other protocol or system. For more information consult the System-Handle Creation section.

Routes definition

This section allows enumerating the bridges between the systems that SOSS must manage. To achieve bidirectional communication, both ways must be specified.

routes definition keywords are specific depending on whether the route is defining a publisher/subscriber path (from-to) or a service/client communication path (server-client). For example:

routes:
    ros2_to_dds: { from: ros2_domain5, to: dds }
    dds_to_ros2: { from: dds, to: ros2_domain5 }
    dds_server: { server: dds, clients: ros2_domain5 }
    fiware_server: { server: fiware, clients: [ dds, ros2_domain5 ] }

This YAML defines the following routes:

_images/routes.png
  • The route ros2_to_dds defines a ros2_domain5 publisher with a dds subscriber.

  • The route dds_to_ros2 defines a dds publisher with a ros2_domain5 subscriber.

  • Having the routes ros2_to_dds and dds_to_ros2 results in a bidirectional communication between the ros2_domain5 and dds systems.

  • The route dds_server defines a dds server with only one client: ros2_domain5.

  • The route fiware_server defines a fiware server with two clients: ros2_domain5 and dds.

Topics definition

Each system is able to publish/subscribe to each other’s topics. These publish/subscription policies are set directly in the YAML configuration file by specifying the topic type and its route (which system is the publisher and which is the subscriber) as the main parameters:

topics:
    point_to_ros2:
        type: "geometry_msgs/Point"
        route: dds_to_ros2
    point_to_dds:
        type: "geometry_msgs/Point"
        route: ros2_to_dds
  • The topic point_to_ros2 will create a dds publisher and a ros2_domain5 subscriber.

_images/point_to_ros2.png
  • The topic point_to_dds will create a ros2_domain5 publisher and a dds subscriber.

_images/point_to_dds.png

If a custom System-Handle needs additional configuration regarding the topics, it can be added to the topic definition as new map entries.

Services definition

service definition is very similar to topics definition, with the difference that in this case routes can only be chosen among the ones specified with the server/client syntax; also, the type entry for these fields usually follows the request/response model, pairing each of them with the corresponding route, depending on which system acts as the server and which as the client(s).

services:
    get_map:
        type: "nav_msgs/GetMap"
        route: dds_server
    update_position:
        type: "Position"
        route: fiware_server
  • The service get_map will create a dds server and a ros2_domain5 client.

_images/get_map.png
  • The service update_position will create a fiware server, and dds and ros2_domain5 clients.

_images/update_position.png

If a custom System-Handle needs additional configuration regarding the services, it can be added in the service definition as new map entries.

Remapping

Sometimes, topics or types from one system are different from those managed by the systems with which it is being bridged. To solve this, SOSS allows to remap types and topics in the Topics definition and in the Services definition.

services:
    set_destination:
        type: "nav_msgs/Position"
        route: dds_server
        remap:
            dds:
                type: "dds/Destination"
                topic: "command_destination"

In this services entry, the remap section defines the type and the topic that must be used in the dds system, instead of the ones defined by the service definition, which will be used by the ros2_domain5 system.

_images/remap.png