The rapyuta.io platform relies on a sub-component called the cloud bridge for implicitly establishing a communication channel between two or more ROS environments. It is an application-level bridge that offers many compelling features to ROS developers including ROS over the public internet and dedicated features for multi-robot ros communication
The list of topics explained are:
ROS takes a fully connected graph approach for connecting all relevant ROS nodes. While this works on a local network, it is suboptimal over a WAN link where it could lead to a waste of precious bandwidth and run the risk of compromising latency and reliability. We use an application level whitelist-based approach to select exactly what information (topic/service/actions) flows over the Internet. The bridge taps into ROS’s internal mechanics to automate ROS message schema detection and metadata, it also manages dead peers, remote announcements and configuration thereby alleviating the need for complex configuration, build steps, and ROS message definition management.
In a typical ROS application, not all ROS topics are equal. Some are more relevant than others. For instance, some applications would prefer losing a few telemetry messages while ensuring they arrive within a reasonable time-bound. On the other hand, there might be less frequent, but application-critical messages that are required to be delivered. The cloud bridge provides parameters for configuring bounds on delays, QoS, TTL per topic. Additionally, it is possible to configure protocol optimizations, load-balancing, selectable compression, connection pooling, and reassembly. These parameters help reduce routing overheads, maintain ordering (per-topic), reduce payload size (up to 80% under certain conditions for sparse messages like a PointCloud), and allow for horizontal scale out (on services/actions).
Further, each deployment gets a dedicated endpoint to cater to the needs of that particular deployment. Additionally, the endpoint is randomized and has a unique set of encryption keys and credentials to ensure security.
If in the ROS Service logs you experience the error: incoming connection failed: unable to receive data from sender, check sender’s logs for details, please ignore it. The error message is generated by ROS internally as a side effect of the sniffing done by the cloud bridge to determine metadata related to ROSmsg type for the service. It has no other effects on your code and/or the code’s functionality, and you can safely ignore it.
rapyuta.io does not enforce pre-defining which package can depend on the other, this is left to the developer. This can potentially lead to a case where a user may deploy a package that depends on a previously deployed one without sufficient knowledge of the internal workings of the parent package. Cross talk between topics/services/actions in such cases can cause unintended hard to debug errors and failure of application code. To prevent against such unintentional cross-communication between deployments of two packages, rapyuta.io requires a package to declare a whitelist of ROS topics/services/interfaces it can receive from a child dependant on it. If you intend to add a deployment of any package as a dependent deployment of the current package, it must be declared as an inbound ROS interface. An inbound ROS interface could be a: ROS topic that a dependent deployment publishes to the current package, ROS service or ROS action of the dependent deployment, and the current package is allowed to call that ROS action or ROS service.
Topics, services, and actions are the primary way ROS nodes communicate with each other in a ROS (in this document when we refer to ROS we imply ROS1) environment.
Topics, services, and actions are implicitly typed by the message definition used to declare the topic/service/action. For instance, a robot’s sensors may publish information about itself on a topic called /odom and use the message nav_msgs/Odometry, at the same time the onboard controller may receive control commands for its motion on /cmd_vel of the type geometry_msgs/Twist. This pattern may sound familiar to ROS users and is used in the popular move_base package.
When this paradigm needs to be applied to multiple robots, the often used approach is to namespace each of these topics by the <robot_name> so you get topics like /<robot_name>/odom and /<robot_name>/cmd_vel To use this in practice with existing ROS tooling requires a careful juggling of configuration management, setting intricate parameters and some clever tricks with topic remap and/or roslaunch. ROS works well within a single robot system and you can still enjoy all the benefits of the tools, packages, and community. While working with multiple robots due to the design limitations of ROS and requires all nodes to share a common ROS master, which in a dynamic environment with multiple agents quickly falls apart.
The rapyuta.io platform offers an elegant solution for multiple robot communication as a primary feature. In the rapyuta paradigm, the component of each package is treated as an isolated ROS environment. While declaring the package the user is only required to provide the topics/services/actions required to be exposed by that particular component. The platform is then responsible for connecting, managing and securing the ROS environments together. We introduce a set of new features aimed at making it a lot easier to use multiple robots.
When deploying a component to a robot in a multi-robot scenario, the platform expects the user to input a unique alias per component (more on this in the next section). This alias uniquely identifies the robot in an ensemble of connected peers, i.e., components in the same package (each potentially deployed in a physically different device/location) or dependent deployments. The platform detects duplicates explicitly for the case of components and deployment and its immediate parent. In the case of siblings (two deployments depending on the same parent), the component with a duplicate alias is considered a conflict and may enter an error state. The user must be careful and ensure the uniqueness of identities present in this case.
Each components environment offers a latched ROS topic /rapyuta_io_peers of type std_msgs/String, which contains the list of all connected peers in a comma-separated string, the first entity is always the alias of the local bridge.
For example, My_alias,peer_1,peer_2
There may be more than one bridge locally depending on how you deployed the packages and components so you may receive multiple messages. In each case the first element is always the alias of the bridge that published this message.
The end user can potentially use this information in their application logic for multi-robot discovery.
Imagine a game of robot soccer where players are robots, and their head coach is a controller unit. The controller broadcasts the message /move to each player, while players broadcast their respective pose and location through /odom for the controller to subscribe to it. For instance, if the controller wants robot A to move in a specific direction, it explicitly publishes /robotA/move, and similarly publishes /robotB/move and /robotC/move to robot B and robot C respectively. As more players are added to the field, this approach gets complex and lacks the dynamic binding between robot peers and the controller.
On the other hand, each robot peer (say A, B and C) explicitly publishes /robotA/odom, /robotB/odom and /robotC/odom messages for the controller to subscribe. However, a complex launch file creates a bottleneck in this case. Hence, the concept of targets and scopes are introduced for supporting the discovery and addressing of multiple robots.
In the following sections, we discuss the possible communication configurations that may be used to communicate in a multi-robot use case. The presence of these options during package creation is used by the platform to determine if it has to enforce alias constraints at deployment time.
In this configuration, a user may declare a topic/service/action as scoped by selecting the Scoped option. This indicates that when the component is deployed the topic/service or action gets namespaced as seen by the other robots by the alias of the deployed component.
For example, suppose robotA publishes /odom topic in its local ROS environment. While routing /odom to either of the robot peers (for instance a controller) the topic is prefixed with that specific robot’s name, in this case /robotA/odom.
Mathematically, you can express scoped as: A scoped topic is a mapping from a /topic to /robot-peer-name/topic.
/odom ——-> /robotP/odom
If in the ROS Service logs you experience the error: incoming connection failed: unable to receive data from sender, check sender’s logs for details, please ignore it. The error message is generated by ROS internally as a side effect of the sniffing done by the cloud bridge so as to determine metadata related to ROSmsg type for the service. It has no other effects on your code and/or the code’s functionality, and you can safely ignore it.
In the case of services and actions, where there is a clear semantic of a provider and a caller, it is enough to apply a scope as each agent that enters the system knows its own identity and provides enough information to others to be able to reach it.
Topics do not innately have a sense of direction, thus scoping alone does not suffice. We need a mechanism to address/targets peers by their identities (aliases) dynamically.
For example, suppose robots in a particular scenario subscribe to the topic /cmd_vel to move about and a central controller needs to ask a specific robot say robotA to move, then it needs to be able to target only robotA and send messages to its /cmd_vel subscription.
The controller in the above scenario publishes /robotA/cmd_vel topic. While routing /robotA/cmd_vel the bridge strips the prefix robotA and publish the messages on the topic /cmd_vel in robotA’s local ros environment.
Mathematically, you can express targeted as: A targeted topic is a mapping from /robot-alias/topic to /topic.
/robotP/cmd_vel ———–> /cmd_vel
rapyuta.io and the cloud bridge are responsible for maintaining a list of agents,and ensuring that appropriate routing, subscriptions and bridges are formed dynamically for each agent entering a particular system.
This serves a purpose identical to the targeted topics albeit in a dependant deployment scenario.
While creating the package, in the additional information section, when one adds inbound ROS topics one can select the can be targeted . This metadata is used by the platform to bridge communications and enforce alias constraints.
When a package declares a ROS interface like a ROS topic/service/action, it is automatically made available to ROS nodes of other deployments linked via the available design patterns like a dependent deployment.
Conside a sample composition such that two deployments:
that depend on a deployment S (corresponding to package P). The user would quickly recognize that C1 and C2 are effectively sibling deployments with respect to a parent deployment S.
In this scenario, the following ROS specific interfaces are defined by the packages Q1 and Q2 corresponding to C1 and C2 respectively.
This set up is illustrated as shown below.
In such circumstances, availability of a topic/service/action is dictated by the inbound interfaces defined by the package P. In the above example, only /test_topic and /test_service (seen as /C2/test_service) are available to ROS nodes in the deployment S, while /test_topic2 will not.
A key side effect is all of the deployments that depend on S (C1 and C2) will also have available an identical configuration of ROS topics/services/actions to their ROS nodes. In this case, /test_topic and /test_service (seen as /C2/test_service).
Special case: when package P is the publicly provided Rapyuta IO Local Communication Broker package, the package is then equivalent to a package with an Allow All inbound ROS interface configuration. This implies all of the ROS topics/services/actions provided by any child deployments are available to all dependent siblings. In the above example, /test_topic, /test_topic2 and /test_service (seen as /C2/test_service) are available to both C1 and C2 (and any other siblings).
rapyuta.io makes ROS topics/actions/services available to the rosgraph in the target deployment based on the composition. However, data does not flow unless a ROS node within a particular deployment tries to consume it by subscribing to a topic or performing a service request.