Skip to content

Add PX4 ROS 2 service servers docs#3596

Merged
hamishwillee merged 11 commits intomainfrom
feat/ros2-services
Mar 13, 2025
Merged

Add PX4 ROS 2 service servers docs#3596
hamishwillee merged 11 commits intomainfrom
feat/ros2-services

Conversation

@beniaminopozzan
Copy link
Member

@beniaminopozzan beniaminopozzan commented Feb 22, 2025

With this PR, PX4 service servers documentation is added. The documentation consists on a very general overview on the service servers capabilities and a in-dept description of the VehicleCommand service (which is also the only service currently implemented on PX4).

The service description is completed with a references to the available offboard_control_srv node, which uses the service to perform offboard control.

Fixes #2876

@beniaminopozzan beniaminopozzan linked an issue Feb 22, 2025 that may be closed by this pull request
Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>

The service servers that are built into the PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module include:

- `/fmu/vehicle_command` (definition: [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv).)
Copy link
Collaborator

@hamishwillee hamishwillee Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the terminology a bit confusing.

  1. Am I correct that /fmu/vehicle_command is a service (and /fmu/out/ is a publication, and fmu/in is a subscription). How does this relate to "topic" and "message"/

2.You call px4_msgs::srv::VehicleCommand a service type - where does "Type" come from? I have called it a definition here, because that's what is linked. But might have to change back.

[Ultimately I'm asking if this line is OK!)

  1. VehicleCommand.srv is a service server message definition. Should we be auto-generating docs for this, as we do for normal uorb messages?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct that /fmu/vehicle_command is a service (and /fmu/out/ is a publication, and fmu/in is a subscription).

The way it is implemented by the uxrcedds_client in PX4 has the following conventions:

  • A topic whose name is in the form /fmu/out/* is published by PX4 and therefore is subscribed by the user ROS 2 node.
  • A topic whose name is in the form /fmu/in/* is subscribed by PX4 and therefore is published by the user ROS 2 node.
  • A service server is using instead the form /fmu/*.

Note however that this is pure naming convention.

How does this relate to "topic" and "message"/

So in ROS you have messages, for example the sensor_msgs::Imu or the PX4 version of it.
You exchange messages though topics where a node publishes a message on a topic and all subscriber of such topic will receive the message. The topic is nothing else but a identifier (the string /fmu/out/sensor_combined for example) used to match subscribers and publishers.

You have services, where a single server offers a service with a given name (/fmu/vehicle_command for example) and other nodes can create client to sumbit requests to it. The service will reply to such requests with responses. Requests and responses are just messages themself at the very end.

ROS abstracts a bit of that through the service files: a service file such as VehicleCommand.srv when compiled, is splitted in the request message and the reply message:

VehicleCommand.srv is

VehicleCommand request
---
VehicleCommandAck reply

everything above the --- constitutes the request and everything below the reply which will constitute completely independent messages.

You call px4_msgs::srv::VehicleCommand a service type - where does "Type" come from? I have called it a definition here, because that's what is linked. But might have to change back.

Type is probably the wrong word: interface is a better one: https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Custom-ROS2-Interfaces.html#, the files that define interfaces are called interface definitions.

VehicleCommand.srv is a service server message definition. Should we be auto-generating docs for this, as we do for normal uorb messages?

the service definition is not used in the PX4 side, it is only used in the ROS 2 side.
PX4 internally do not uses services so there is no reason to create autodoc for it.
For completeness, the uxrcedds_client vehicle_command service server, when it receives a request from the ROS 2 node, converts it to a full uORB vehicle_command message and publishes inside PX4, the it waits for the vechicle_command_ack response uORB message, checks if it the right one and if it is then it packages in the reply and sends it to ROS 2.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much for this. I'm going to email myself with a link and think about it a bit more.


This can be used to send commands to the vehicle, such as "take off", "land", change mode, and "orbit", and receive a response.

The service is available under `/fmu/vehicle_command`, which can be changed through custom namespaces just like the other PX4 topics.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"which can be changed through custom namespaces just like the other PX4 topics." - I don't know what that means. Can you link it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More info added in 890a999

vehicle_command_client_{this->create_client<px4_msgs::srv::VehicleCommand>("/fmu/vehicle_command")}
```

After that, the client can be used to send any vehicle command request.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code seems to also require that you first wait for the service:

while (!vehicle_command_client_->wait_for_service(1s)) {
			if (!rclcpp::ok()) {

Where does wait_for_service() come from?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not a strict requirement but rather a good pracitice to wait until the service server is ready to accept requests before starting sending them.

You can perfectly not put it in the code: in such case when you send a request you might have to wait for the service to become available to serve it.

In the example it is used to check if PX4 is truly connected to the ROS 2 network. There the code waits untill connection before continuing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we say that? Note that I have no idea where this method is defined (?) I assume wait_for_service() is some kind of standard interface/API? Or is it our own interface that hides some other magic?

Assuming it is standard, you might do something like this:

Suggested change
After that, the client can be used to send any vehicle command request.
::: info
It is good practice to make sure the that the server server is ready to accept requests before sending them. You can use `wait_for_service()` to check if the server is ready.
:::
After that, the client can be used to send any vehicle command request.

Copy link
Collaborator

@hamishwillee hamishwillee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I've added some slight restructure and some questions.

Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
Copy link
Member Author

@beniaminopozzan beniaminopozzan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @hamishwillee for the review!

I hope I answered all your questions :)

vehicle_command_client_{this->create_client<px4_msgs::srv::VehicleCommand>("/fmu/vehicle_command")}
```

After that, the client can be used to send any vehicle command request.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not a strict requirement but rather a good pracitice to wait until the service server is ready to accept requests before starting sending them.

You can perfectly not put it in the code: in such case when you send a request you might have to wait for the service to become available to serve it.

In the example it is used to check if PX4 is truly connected to the ROS 2 network. There the code waits untill connection before continuing.


The service servers that are built into the PX4 [uxrce_dds_client](../modules/modules_system.md#uxrce-dds-client) module include:

- `/fmu/vehicle_command` (definition: [`px4_msgs::srv::VehicleCommand`](https://github.com/PX4/px4_msgs/blob/main/srv/VehicleCommand.srv).)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct that /fmu/vehicle_command is a service (and /fmu/out/ is a publication, and fmu/in is a subscription).

The way it is implemented by the uxrcedds_client in PX4 has the following conventions:

  • A topic whose name is in the form /fmu/out/* is published by PX4 and therefore is subscribed by the user ROS 2 node.
  • A topic whose name is in the form /fmu/in/* is subscribed by PX4 and therefore is published by the user ROS 2 node.
  • A service server is using instead the form /fmu/*.

Note however that this is pure naming convention.

How does this relate to "topic" and "message"/

So in ROS you have messages, for example the sensor_msgs::Imu or the PX4 version of it.
You exchange messages though topics where a node publishes a message on a topic and all subscriber of such topic will receive the message. The topic is nothing else but a identifier (the string /fmu/out/sensor_combined for example) used to match subscribers and publishers.

You have services, where a single server offers a service with a given name (/fmu/vehicle_command for example) and other nodes can create client to sumbit requests to it. The service will reply to such requests with responses. Requests and responses are just messages themself at the very end.

ROS abstracts a bit of that through the service files: a service file such as VehicleCommand.srv when compiled, is splitted in the request message and the reply message:

VehicleCommand.srv is

VehicleCommand request
---
VehicleCommandAck reply

everything above the --- constitutes the request and everything below the reply which will constitute completely independent messages.

You call px4_msgs::srv::VehicleCommand a service type - where does "Type" come from? I have called it a definition here, because that's what is linked. But might have to change back.

Type is probably the wrong word: interface is a better one: https://docs.ros.org/en/jazzy/Tutorials/Beginner-Client-Libraries/Custom-ROS2-Interfaces.html#, the files that define interfaces are called interface definitions.

VehicleCommand.srv is a service server message definition. Should we be auto-generating docs for this, as we do for normal uorb messages?

the service definition is not used in the PX4 side, it is only used in the ROS 2 side.
PX4 internally do not uses services so there is no reason to create autodoc for it.
For completeness, the uxrcedds_client vehicle_command service server, when it receives a request from the ROS 2 node, converts it to a full uORB vehicle_command message and publishes inside PX4, the it waits for the vechicle_command_ack response uORB message, checks if it the right one and if it is then it packages in the reply and sends it to ROS 2.


This can be used to send commands to the vehicle, such as "take off", "land", change mode, and "orbit", and receive a response.

The service is available under `/fmu/vehicle_command`, which can be changed through custom namespaces just like the other PX4 topics.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More info added in 890a999

beniaminopozzan and others added 2 commits March 10, 2025 00:41
Co-authored-by: Hamish Willee <hamishwillee@gmail.com>
Signed-off-by: Beniamino Pozzan <beniamino.pozzan@gmail.com>
@github-actions
Copy link

No flaws found

@hamishwillee
Copy link
Collaborator

@beniaminopozzan Thanks for all of this. I want to merge, because most of this is definitely clear.

As a post process, would appreciate it if you could look at

@hamishwillee hamishwillee merged commit eb09414 into main Mar 13, 2025
2 checks passed
@hamishwillee hamishwillee deleted the feat/ros2-services branch March 13, 2025 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Warning: uXRCE-DDS now supports services

2 participants