redf stands for "ROS Endpoint Definition Format", it defines a yaml format which describes the endpoints of a ROS system.
redf currently supports humble and iron.
A common problem of ROS is that it only contains message definitions, there is no definition of the topics available and their QoS settings expected. redf aims to solve this by defining the endpoints in a yaml file and generating code so that other packages will not have wrong topics and mismatched QoS.
Currently redf can:
- Generate a rclcpp based ROS package with the topics, services, actions and their QoS
Other planned features includes:
- Generate documentations
- Generate a rclpy based package
- Integrate with the rosidl codegen
- Integrate with rcl
An example redf file
title: Test Api
description: test api
version: 0.0.1
maintainers:
- name: example
email: example@example.com
license: Apache License 2.0
endpoints:
- title: My Sensor
type: topic
topic: my_sensor
message_type: std_msgs/msg/String
description: Example sensor topic
qos: sensor_dataGenerate a ROS package from the yaml
redf --out=out --gen=cpp example.yamlThis will generate a full, ready-to-use ROS package, it can be included into a colcon workspace and be used by other packages.
An example of using the endpoint definitions:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(test_node)
find_package(rclcpp REQUIRED)
find_package(test_api REQUIRED)
add_executable(test_node main.cpp)
target_link_libraries(test_node rclcpp::rclcpp test_api::test_api)test_apiautomatically brings in the required messages.
main.cpp:
#include <test_api.hpp>
#include <rclcpp/rclcpp.hpp>
int main(int argc, char* argv[]) {
rclcpp::init(argc, argv);
auto test_node = rclcpp::Node::make_shared("test_node");
using test_api::MySensor;
auto pub = test_node->create_publisher<MySensor::MessageType>(MySensor::topic_name(), MySensor::qos());
MySensor::MessageType msg;
msg.data = "hello";
pub->publish(msg);
return 0;
}MessageTypeis a alias to the message type used for the topic (in this case, it isstd_msgs/msg/String).topic_name()returns astd::stringwith the topic name of the endpoint.qos()returns therclcpp::QoSof the endpoint.
Example for service clients:
#include <test_api.hpp>
#include <rclcpp/rclcpp.hpp>
int main(int argc, char* argv[]) {
rclcpp::init(argc, argv);
auto test_node = rclcpp::Node::make_shared("test_node");
using test_namespace::test_api::TestService;
auto client = test_node->create_client<TestService::ServiceType>(TestService::service_name());
auto req = std::make_shared<TestService::ServiceType::Request>();
client->async_send_request(req);
return 0;
}ServiceTypeis a alias to the message type used for the topic (in this case, it isexample_interfaces/srv/AddTwoInts).service_name()returns astd::stringwith the service name of the endpoint.- The default service qos will be used.
For more examples, see https://github.com/ros2/examples, usages with redf is the same, just replace the message types, strings and qos with those from the generated library.
The full format of redf is available as a json schema here.
You can also generate the schema from source with
cargo run -F json_schema --bin generate-schemaSometimes a system may use namespaced topics to separate the channels between similar nodes. For example, a camera array may publish their images to /camera_0/image_raw, /camera_1/image_raw... etc. This can be represented with redf via variable subsitution.
- title: Camera Images
type: topic
description: Raw camera images
topic: '/{camera_id}/image_raw'
message_type: sensor_msgs/msg/ImageWhen redf generates code for this endpoint, it will have an argument in the topic_name function, e.g.
static inline std::string topic_name(const std::string& camera_id) {
const std::string topic = "/" + camera_id + "/image_raw";
return topic;
}This also works for service and action names.
-
Install the yaml extension https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml
-
Edit your vscode settings to include this
"yaml.schemas": {
"https://raw.githubusercontent.com/osrf/redf/main/redf.schema.json": "*.redf.yaml"
}- Make sure your filename ends with
.redf.yaml.
You should now have code completion for redf
Requirements:
- supported ros distro
- rosdeps
- ament_cmake
- std_msgs
- example_interfaces
- rclcpp
- rclcpp_action
Use rosdep to resolve and install the dependencies
rosdep resolve -q ament_cmake std_msgs example_interfaces rclcpp rclcpp_action | sed '/^#/d' | xargs sudo apt installSource ROS and run the tests
. /opt/ros/{DISTRO}/setup.bash && cargo test