ROS2-Kernkommunikation
06 Knoten
06 Knoten (Nodes)
6.1 Zusammenfassung der Knoten
6.1.1 Was ist ein Knoten
Ein Knoten ist die grundlegendste Berechnungseinheit in ROS 2. Ein Knoten ist ein Prozess, der die ROS 2 API verwendet, um mit anderen Knoten zu kommunizieren. Jeder Knoten ist normalerweise für bestimmte Funktionen verantwortlich, wie z. B. das Lesen von Sensordaten, die Datenverarbeitung, die Steuerung von Implementierern usw.
6.1.2 Eigenschaften der Knoten
| Eigenschaften | Anmerkungen |
|---|---|
| Leichtgewichtig | Eine ausführbare Datei kann mehrere Knoten enthalten |
| Verteilung | Der Knoten kann auf verschiedenen Maschinen ausgeführt werden. |
| Entkoppelt | Kommunikation zwischen Knoten über Schnittstelle, nicht direkt abhängig |
| Gruppierbar | Mehrere Knoten zur Ausführung komplexer Funktionen |
| Unabhängiger Lebenszyklus | Jeder Knoten unabhängig starten und schließen |
6.1.3 Regeln für die Knotenbenennung
Der Knotenname muss eindeutig sein (im selben Namensraum)
Es können nur Buchstaben, Zahlen und Unterstriche enthalten sein
Groß-/Kleinschreibung beachten
Empfohlene Verwendung eines beschreibenden Namens
Namensbeispiel:
| Knotenname | Bewertung |
|---|---|
| Camera_driver | Hervorragend. |
| path_planner | Hervorragend. |
| Node1 | Nicht empfohlen (nicht beschreibend) |
| Oh, my-node. | Ungültig (mit Bindestrich) |
6.2 Hello World-Knoten-Fall
6.2.1 Python-Kit erstellen
workspace ersetzt den tatsächlichen Workspace-Pfad
cd workspace/src
ros2 pkg create pkg_helloworld_py --build-type ament_python --dependencies rclpy --node-name helloworld6.2.2 Vorbereitung der Codes
import rclpy
from rclpy.node import Node
import time
class HelloWorldNode(Node):
def __init__(self, name):
super().__init__(name)
while rclpy.ok():
self.get_logger().info("Hello World")
time.sleep(0.5)
def main(args=None):
rclpy.init(args=args)
node = HelloWorldNode("helloworld")
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()colcon build --packages-select pkg_helloworld_py
source install/setup.bash
ros2 run pkg_helloworld_py helloworld6.3 Nächste Schritte
1.07 Topic-Kommunikation
2.08 Service-Kommunikation
07 Topic-Kommunikation
07 Aktuelle Mitteilungen (Topics)
7.1 Zusammenfassung der aktuellen Kommunikation
7.1.1 Was ist eine Topic-Kommunikation?
Topic ist der Mechanismus für asynchrone Kommunikation zwischen ROS 2-Knoten unter Verwendung des Veröffentlichungs-/Abonnement-Modus (Pub/Sub). Der Herausgeberknoten gibt Nachrichten an das Topic aus, und der Abonnentenknoten erhält Informationen vom Topic, und keiner muss den anderen kennen.
7.1.2 Eigenschaften der Topic-Kommunikation
| Eigenschaften | Beschreibung | Anwendungsszene |
|---|---|---|
| Asynchrone Kommunikation | Sender wartet nicht auf die Antwort des Abonnenten | Sensordatenstrom |
| Mehrere zu mehreren | Mehrere Herausgeber und Abonnenten | Datenübertragung |
| Lose gekoppelt | Entkopplung | Modulare Konstruktion |
| Stream-Übertragung | Laufende Datenströme | Kontinuierliche Überwachung |
7.1.3 Regeln für die Topic-Benennung
| Regel | Anmerkungen |
|---|---|
| Muss mit (globaler Namensraum) oder relativem Namen beginnen | |
| Verwenden Sie Kleinbuchstaben, Zahlen und Unterstriche | |
| Verwenden Sie /, um Namensraum-Ebenen zu trennen | |
| Vermeiden Sie reservierte Namen |
Namensbeispiel:
| Topic-Name | Bewertung |
|---|---|
| /cmd_vel | Standards, empfohlen |
| /camera/image_raw | Ebene klar. Empfohlen. |
| /sensor/front_camera/image | Namensraum, empfohlen. |
| /MyTopic | Nicht empfohlen (großgeschrieben) |
| add_vel | Relativer Name (Knoten-Namensraum hinzugefügt) |
7.2 Kommunikationsfälle
7.2.1 Neues Funktionspaket
cd ~/workspaces/src
ros2 pkg create pkg_topic --build-type ament_python --dependencies rclpy --node-name publisher_demo7.2.2 Der Autor erreicht
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class Topic_Pub(Node):
def __init__(self,name):
super().__init__(name)
self.pub = self.create_publisher(String,"/topic_demo",1)
self.timer = self.create_timer(1,self.pub_msg)
def pub_msg(self):
msg = String()
msg.data = "Hi,I send a message."
self.pub.publish(msg)
def main():
rclpy.init()
pub_demo = Topic_Pub("publisher_node")
rclpy.spin(pub_demo)
pub_demo.destroy_node()
rclpy.shutdown()7.2.3 Konfigurationsdateien bearbeiten
7.2.4 Funktionspaket kompilieren
cd ~/workspace
colcon build --packages-select pkg_topic
source install/setup.bash7.2.5 Veröffentlichungsknoten ausführen
ros2 run pkg_topic publisher_demo
ros2 topic list
ros2 topic echo /topic_demo7.2.6 Abonnenten erstellen
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class Topic_Sub(Node):
def __init__(self,name):
super().__init__(name)
self.sub = self.create_subscription(String,"/topic_demo",self.sub_callback,1)
def sub_callback(self,msg):
self.get_logger().info(msg.data)
def main():
rclpy.init()
sub_demo = Topic_Sub("subscriber_node")
rclpy.spin(sub_demo)
sub_demo.destroy_node()
rclpy.shutdown()7.2.7 Konfigurationsdateien bearbeiten
7.2.8 Funktionspaket kompilieren
cd ~/workspace
colcon build --packages-select pkg_topic
source install/setup.bash7.2.9 Knoten betreiben
ros2 run pkg_topic publisher_demo
ros2 run pkg_topic subscriber_demo7.3 Nächste Schritte
1.08 Service-Kommunikation
2.09 Action-Kommunikation
08 Service-Kommunikation
08 Service-Kommunikation (Services)
8.1 Übersicht über die Service-Kommunikation
8.1.1 Was ist Service-Kommunikation
Service ist der Mechanismus für synchronisierte Kommunikation zwischen Knoten in ROS 2, unter Verwendung des Client/Server-Modells. Der Client sendet die Anfrage, der Service bearbeitet sie und gibt die Antwort zurück.
8.1.2 Services vs. Topics
| Merkmal | Services | Topics |
|---|---|---|
| Kommunikationsmodus | Synchron (Anfrage-Antwort) | Asynchron (Veröffentlichungs-Abonnement) |
| Verbindung | Eins zu eins. | Mehrere zu mehreren. |
| Anwendungsszene | Kurze Operationsabfrage | Laufende Datenströme |
| Block | Client blockiert wartend. | Keine Blockierung. |
| Rückgabewert | Wir müssen die Antwort zurückgeben. | Keine Antwort |
8.1.3 Definition des Servicetyps
# File: example interfaces/srv/AddTwoInts.srv
int64 a
int64 b
---
int64 sum8.2 Beispiele für Service-Kommunikation
8.2.1 Neues Funktionspaket
ros2 pkg create pkg_service --build-type ament_python --dependencies rclpy --node-name server_demo8.2.2 Service-Endpunkt erstellen
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
class Service_Server(Node):
def __init__(self,name):
super().__init__(name)
self.srv = self.create_service(AddTwoInts, '/add_two_ints', self.Add2Ints_callback)
def Add2Ints_callback(self,request,response):
response.sum = request.a + request.b
print("response.sum = ",response.sum)
return response
def main():
rclpy.init()
server_demo = Service_Server("publisher_node")
rclpy.spin(server_demo)
server_demo.destroy_node()
rclpy.shutdown()ros2 interface show example_interfaces/srv/AddTwoInts8.2.3 Konfigurationsdateien bearbeiten
'server_demo = pkg_service.server_demo:main',8.2.4 Funktionspaket kompilieren
colcon build --packages-select pkg_service
source install/setup.bash
ros2 run pkg_service server_demoros2 service list
ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 1,b: 4}"8.2.5 Client erstellen
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts
class Service_Client(Node):
def __init__(self,name):
super().__init__(name)
self.client = self.create_client(AddTwoInts,'/add_two_ints')
while not self.client.wait_for_service(timeout_sec=1.0):
print("service not available, waiting again...")
self.request = AddTwoInts.Request()
def send_request(self):
self.request.a = 10
self.request.b = 90
self.future = self.client.call_async(self.request)
def main():
rclpy.init()
service_client = Service_Client("client_node")
service_client.send_request()
while rclpy.ok():
rclpy.spin_once(service_client)
if service_client.future.done():
try:
response = service_client.future.result()
print("Result = ",response.sum)
except Exception as e:
service_client.get_logger().info('Service call failed %r' % (e,))
break
service_client.destroy_node()
rclpy.shutdown()8.2.6 Konfigurationsdateien bearbeiten
'client_demo = pkg_service.client_demo:main'8.2.7 Funktionspaket kompilieren
cd ~/workspace
colcon build --packages-select pkg_service
source install/setup.bash
ros2 run pkg_service server_demosource install/setup.bash
ros2 run pkg_service client_demo8.3 Nächste Schritte
1.09 Action-Kommunikation - Action-Kommunikation lernen (lange Mission)
- 10 TF2-Koordinatentransformation - benutzerdefinierten Servicetyp erstellen
09 Action-Kommunikation
09 Action-Kommunikation (Actions)
9.1 Zusammenfassung der Action-Kommunikation
9.1.1 Was ist Bewegungskommunikation?
Action ist der Kommunikationsmechanismus, der in ROS 2 verwendet wird, um lange Aufgaben zu bearbeiten. Ähnlich wie Services sind Actions ein Client-Server-Modus, aber unterstützen:
-
Echtzeit-Feedback während der Mandatsumsetzung
-
Client kann eine aktive Aufgabe abbrechen.
-
Geeignet für die Bearbeitung von Operationen, die Sekunden bis Minuten dauern können.
9.1.2 Action vs. Services
| Merkmal | Service | Action |
|---|---|---|
| Anwendungsdauer | Kurze Operation (ms-s) | Lange Aufgaben (Sekunden-Minuten) |
| Feedback | Kein Echtzeit-Feedback | Sendet kontinuierlich Feedback |
| Abbrechen | Nicht unterstützt | Aber abbrechen. |
| Block | Client-Block | Deaktivieren |
| Anwendungsszene | Abfrage, einfache Operationen | Navigation, Erfassung |
9.2 Action-Kommunikationsfälle
9.2.1 Neues Funktionskit
ros2 pkg create --build-type ament_cmake pkg_interfacesint64 num
---
int64 sum
---
float64 progress<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>rosidl_default_runtime</exec_depend>
<depend>action_msgs</depend>
<member_of_group>rosidl_interface_packages</member_of_group>find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"action/Progress.action")cd ~/workspace
colcon build --packages-select pkg_interfacesros2 interface show pkg_interfaces/action/Progressros2 pkg create pkg_action --build-type ament_python --dependencies rclpy pkg_interfaces --node-name action_server_demo4. Service-End-Realisierung
4.1 Service-Anbieter erstellen
import time
import rclpy
from rclpy.action import ActionServer
from rclpy.node import Node
from pkg_interfaces.action import Progress
class Action_Server(Node):
def __init__(self):
super().__init__('progress_action_server')
self._action_server = ActionServer(
self,
Progress,
'get_sum',
self.execute_callback)
self.get_logger().info('The action server has started!')
def execute_callback(self, goal_handle):
self.get_logger().info('Starting task execution...')
feedback_msg = Progress.Feedback()
total = 0
for i in range(1, goal_handle.request.num + 1):
total += i
feedback_msg.progress = i / goal_handle.request.num
self.get_logger().info('Continuous feedback: %.2f' % feedback_msg.progress)
goal_handle.publish_feedback(feedback_msg)
time.sleep(1)
goal_handle.succeed()
result = Progress.Result()
result.sum = total
self.get_logger().info('Task completed!')
return result
def main(args=None):
rclpy.init(args=args)
Progress_action_server = Action_Server()
rclpy.spin(Progress_action_server)
Progress_action_server.destroy_node()
rclpy.shutdown()4.2 Konfigurationsdateien bearbeiten
'action_server_demo = pkg_action.action_server_demo:main',4.3 Funktionspaket kompilieren
cd ~/workspace
colcon build --packages-select pkg_action
source install/setup.bash
ros2 run pkg_action action_server_demoros2 action list
ros2 action send_goal /get_sum pkg_interfaces/action/Progress "{num: 10}"