07. ROS service, ROS action fogalma, felhasználása
Elmélet
ROS Service
- Request/reply communication
- Use a client-server model
- Similar to Remote Procedure Calls (RPC)
- Blocking behavior by default (can be async)
ROS .srv files
int a
int b
---
int sum
#request constants
int8 FOO=1
int8 BAR=2
#request fields
int8 foobar
another_pkg/AnotherMessage msg
---
#response constants
uint32 SECRET=123456
#response fields
another_pkg/YetAnotherMessage val
CustomMessageDefinedInThisPackage value
uint32 an_integer
ROS Action

Forrás: ROS 2 Documentation. Licenc: CC BY 4.0.
- Ideal for communication with slower processes, e.g. environmental inetarcion
- Asynchronous communication (non-blocking)
- Actions consist of a goal, feedback, and a result
- Built on topics and services and function similarly to services
- Actions are preemptable, (can be canceled while executing)
- Provide steady feedback, unlike services which return a single response
- Actions use a client-server model, similar to the publisher-subscriber model
- An action client node sends a goal to an action server node that acknowledges the goal and returns a stream of feedback and a result.
ROS .action files
# Define the goal
uint32 dishwasher_id # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete
Building custom interfaces (.msg , .srv and .action files)
CMakeList.txtandpackage.xmlneed to be modified- For messages and services, see https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Custom-ROS2-Interfaces.html
- For actions, see https://docs.ros.org/en/foxy/Tutorials/Intermediate/Creating-an-Action.html
Gyakorlat
1. ROS Service-ek használata Turtlesimben
-
Indítsunk el egy Turtlesim szimulátort, majd külön terminálban a billentyűzetes vezérlést:
ros2 run turtlesim turtlesim_noderos2 run turtlesim turtle_teleop_key -
Vizsgáljuk meg az elérhető Service-eket és a hozzájuk tartozó interfészeket:
ros2 service list -t ros2 service type /spawn ros2 interface show turtlesim/srv/Spawn ros2 node info /turtlesim -
Hozzunk létre egy második teknőst a
(2.0, 2.0)pozícióban:ros2 service call /spawn turtlesim/srv/Spawn "{x: 2.0, y: 2.0, theta: 0.0, name: 'turtle2'}" -
Figyeljük meg a választ, majd töröljük a második teknőst:
ros2 service call /kill turtlesim/srv/Kill "{name: 'turtle2'}"
2. Saját Python Service Server: a teknős pozíciójának ellenőrzése
Készítsünk olyan ROS node-ot, amely a /turtle1/pose topicról olvassa a teknős pozícióját, és a /check_position Service-en keresztül megállapítja, hogy a teknős a (5.5, 5.5) középponttól legfeljebb 2.0 egységre van-e.
A szerver a std_srvs/srv/Trigger típust használja: a kérés üres, a válasz success mezője jelzi a feltétel teljesülését, a message pedig a mért távolságot tartalmazza.
-
Hozzuk létre a
position_checker.pyfájlt a meglévőros2_coursePython-csomagban. Adjuk hozzá az új entry point-ot asetup.py-hoz.import math import rclpy from rclpy.node import Node from turtlesim.msg import Pose from std_srvs.srv import Trigger class PositionChecker(Node): def __init__(self): super().__init__('position_checker') self.pose = None # Subscriber: aktuális teknőspozíció self.pose_sub = self.create_subscription( Pose, '/turtle1/pose', self.pose_callback, 10 ) # Service Server self.service = self.create_service( Trigger, '/check_position', self.check_position_callback ) def pose_callback(self, msg): self.pose = msg def check_position_callback(self, request, response): if self.pose is None: response.success = False response.message = 'No pose received.' return response # TODO 1: számítsuk ki a távolságot az (5.5, 5.5) ponttól! distance = ... # TODO 2: igaz-e, hogy a távolság legfeljebb 2.0? response.success = ... response.message = f'Distance: {distance:.2f}' return response def main(args=None): rclpy.init(args=args) node = PositionChecker() try: rclpy.spin(node) except KeyboardInterrupt: pass finally: node.destroy_node() if rclpy.ok(): rclpy.shutdown() if __name__ == '__main__': main() -
Egészítsük ki a két
TODOsort! -
Győződjünk meg róla, hogy a
package.xmltartalmazza a futásidejű függőségeket:<exec_depend>rclpy</exec_depend> <exec_depend>turtlesim</exec_depend> <exec_depend>std_srvs</exec_depend> -
Fordítsuk a csomagot, majd futtassuk az új node-ot (a Turtlesim maradjon elindítva):
cd ~/ros2_ws colcon build --symlink-install ros2 run ros2_course position_checkerEgy másik terminálban vizsgáljuk meg a Service-t, majd hívjuk meg:
ros2 service list -t ros2 service type /check_position ros2 interface show std_srvs/srv/Trigger ros2 service call /check_position std_srvs/srv/Trigger "{}"Mozgassuk el a teknőst a billentyűzetes vezérléssel, és ismételjük meg a hívást. Figyeljük meg, hogyan változik a
successérték és a távolság!
3. ROS Action kipróbálása Turtlesimben
Az Action működését most parancssorból vizsgáljuk meg. Saját Action Server és Action Client implementálása nem szükséges.
-
Indítsuk el a Turtlesim és a billentyűzetes vezérlés node-jait, ha még nem futnak:
ros2 run turtlesim turtlesim_noderos2 run turtlesim turtle_teleop_key -
Vizsgáljuk meg az Action-öket:
ros2 action list -t ros2 action info /turtle1/rotate_absolute ros2 interface show turtlesim/action/RotateAbsolute -
Küldjünk célszöget az Action Servernek, és kérjük a feedback megjelenítését:
ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 3.14}" --feedbackPróbáljunk ki más célszöget is, például
1.57radiánt. Aturtle_teleop_keytermináljában használható abszolút forgatási billentyűk hatását is megfigyelhetjük.