7.1.6-ROS-Betriebsverwaltung
Verwaltung von ROS-Knoten mit Launch-Dateien
Launch-Dateien in ROS sind XML-formatierte Dateien, die zum effizienten Starten und Verwalten mehrerer ROS-Knoten verwendet werden. Dieser Abschnitt behandelt die verschiedenen Tags, die in Launch-Dateien verfügbar sind, einschließlich ihrer Attribute und Anwendungsfälle.
Das <launch>-Tag
Das <launch>-Tag ist die Wurzel jeder Launch-Datei und dient als Container für alle anderen Tags.
1. Attribute
- deprecated="Veraltungserklärung"
Zeigt dem Anwender an, dass die aktuelle Launch-Datei veraltet ist.
2. Untergeordnete Tags
- Alle anderen Tags in einer Launch-Datei sind Kindelemente des
<launch>-Tags.
Beispiel:
<launch>
<!-- Other tags go here -->
</launch>Das <node>-Tag
Das <node>-Tag wird verwendet, um einen zu startenden ROS-Knoten anzugeben. Es ist eines der am häufigsten verwendeten Tags in einer Launch-Datei. Beachten Sie, dass der Befehl roslaunch nicht garantiert, dass die Knoten in der deklarierten Reihenfolge starten, da der Knotenstart mehrthreaded erfolgt.
1. Attribute
-
pkg="package_name"
Gibt das Paket an, zu dem der Knoten gehört. -
type="nodeType"
Der Typ des Knotens, der dem Namen der ausführbaren Datei entspricht. -
name="nodeName"
Der Name des Knotens innerhalb der ROS-Netzwerktopologie. -
args="xxx xxx xxx" (optional)
Übergibt Argumente an den Knoten. -
machine="machine_name"
Gibt die Maschine an, auf der der Knoten gestartet werden soll. -
respawn="true | false" (optional)
Legt fest, ob der Knoten automatisch neu starten soll, wenn er beendet wird. -
respawn_delay="N" (optional)
Wennrespawnauf true gesetzt ist, definiert dies eine Verzögerung von N Sekunden, bevor der Knoten neu gestartet wird. -
required="true | false" (optional)
Gibt an, ob dieser Knoten kritisch ist. Bei true wird der gesamteroslaunch-Prozess beendet, wenn der Knoten beendet wird. -
ns="namespace" (optional)
Startet den Knoten innerhalb des angegebenen Namespaces. -
clear_params="true | false" (optional)
Löscht vor dem Knotenstart alle Parameter im privaten Namespace des Knotens. -
output="log | screen" (optional)
Legt fest, wohin die Log-Ausgabe gesendet wird: in eine Log-Datei oder auf den Bildschirm. Standard istlog.
2. Untergeordnete Tags
- env: Zum Setzen von Umgebungsvariablen.
- remap: Zum Umbenennen von Topic- oder Service-Namen.
- rosparam: Zum Setzen von Parametern.
- param: Zum Setzen von Parametern.
Beispiel:
<launch>
<node name="node1" pkg="my_package" type="node_executable" output="screen" respawn="true" respawn_delay="5">
<param name="param_name" value="param_value"/>
<remap from="/old_topic" to="/new_topic"/>
</node>
</launch>Das <include>-Tag
Das <include>-Tag wird verwendet, um eine andere XML-formatierte Launch-Datei in die aktuelle Launch-Datei einzubinden. Dies ermöglicht modulare und wiederverwendbare Konfigurationen.
1. Attribute
-
file="$(find package_name)/path/to/file.launch"
Gibt den Pfad zur einzubindenden Launch-Datei an. -
ns="namespace" (optional)
Bindet die Datei unter dem angegebenen Namespace ein.
2. Untergeordnete Tags
- env: Zum Setzen von Umgebungsvariablen.
- arg: Zum Übergeben von Argumenten an die eingebundene Launch-Datei.
Beispiel:
<launch>
<include file="$(find my_package)/launch/another_launch_file.launch" ns="my_namespace"/>
</launch>Das <remap>-Tag
Das <remap>-Tag wird verwendet, um ROS-Topic- oder Service-Namen umzubenennen. Dies ist nützlich, um Namenskonflikte zu vermeiden oder Namen über verschiedene Knoten hinweg zu vereinheitlichen.
1. Attribute
-
from="xxx"
Der ursprüngliche Topic- oder Service-Name. -
to="yyy"
Der neue Name für das Topic oder den Service.
2. Untergeordnete Tags
- Keine
Beispiel:
<launch>
<node name="node1" pkg="my_package" type="node_executable">
<remap from="/old_topic" to="/new_topic"/>
</node>
</launch>Das <param>-Tag
Das <param>-Tag wird verwendet, um Parameter auf dem ROS-Parameter-Server zu setzen. Die Quelle des Parameters kann direkt im Tag angegeben oder aus einer externen Datei geladen werden. Wenn es innerhalb eines <node>-Tags verwendet wird, wird der Parameter im privaten Namespace des Knotens gesetzt.
1. Attribute
-
name="namespace/parameter_name"
Der Name des Parameters, der einen Namespace enthalten kann. -
value="xxx" (optional)
Definiert den Wert des Parameters. Wenn weggelassen, muss eine externe Datei als Parameterquelle angegeben werden. -
type="str | int | double | bool | yaml" (optional)
Gibt den Typ des Parameters an. Falls nicht angegeben, versuchtroslaunch, den Typ aus dem Wert abzuleiten:- Zahlen mit einem
.werden als Gleitkomma (double) interpretiert. - Die Strings "true" und "false" werden als boolesche Werte interpretiert (Groß-/Kleinschreibung wird ignoriert).
- Alles andere wird als String interpretiert.
- Zahlen mit einem
2. Untergeordnete Tags
- Keine
Beispiel:
<launch>
<node name="node1" pkg="my_package" type="node_executable">
<param name="namespace/param_name" value="param_value" type="str"/>
</node>
</launch>Das <rosparam>-Tag
Das <rosparam>-Tag erlaubt es, Parameter aus einer YAML-Datei zu laden, in eine YAML-Datei zu exportieren oder zu löschen. Wenn es innerhalb eines <node>-Tags verwendet wird, gelten die Parameter als privat.
1. Attribute
-
command="load | dump | delete" (optional, Standard ist
load)
Gibt den auszuführenden Vorgang an: Parameter aus einer Datei laden, in eine Datei exportieren oder löschen. -
file="$(find package_name)/path/to/file.yaml"
Gibt die YAML-Datei an, aus der Parameter geladen oder in die exportiert werden soll. -
param="parameter_name"
Der Name des Parameters. -
ns="namespace" (optional)
Gibt den Namespace für die Parameter an.
2. Untergeordnete Tags
- Keine
Beispiel:
<launch>
<rosparam file="$(find my_package)/config/params.yaml" command="load" ns="my_namespace"/>
</launch>Das <group>-Tag
Das <group>-Tag dient dazu, Knoten und andere Tags zu gruppieren, und ermöglicht es, einen Namespace oder andere Einstellungen auf die gesamte Gruppe anzuwenden.
1. Attribute
-
ns="namespace" (optional)
Wendet einen Namespace auf alle Knoten und Parameter innerhalb der Gruppe an. -
clear_params="true | false" (optional)
Löscht alle Parameter im Namespace der Gruppe vor dem Start. Mit Vorsicht verwenden, da dies kritische Parameter entfernen kann.
2. Untergeordnete Tags
- Alle Tags außer dem
<launch>-Tag können Kinder von<group>sein.
Beispiel:
<launch>
<group ns="my_namespace" clear_params="true">
<node name="node1" pkg="my_package" type="node_executable"/>
<node name="node2" pkg="my_package" type="node_executable"/>
</group>
</launch>Das <arg>-Tag
Das <arg>-Tag dient zum Definieren dynamischer Argumente, die zur Laufzeit an die Launch-Datei übergeben werden können, ähnlich wie Funktionsparameter. Dadurch wird die Flexibilität von Launch-Dateien erhöht.
1. Attribute
-
name="argument_name"
Der Name des Arguments. -
default="default_value" (optional)
Gibt den Standardwert für das Argument an. -
value="value" (optional)
Gibt den Wert des Arguments an. Kann nicht gleichzeitig mitdefaultverwendet werden. -
doc="description"
Stellt eine Beschreibung des Arguments bereit.
2. Untergeordnete Tags
- Keine
3. Beispiel
Launch-Datei mit Argumentsyntax, hello.launch:
<launch>
<arg name="robot_name" default="my_robot"/>
<param name="robot_name" value="$(arg robot_name)"/>
</launch>Aufruf von der Kommandozeile mit Argumentübergabe:
roslaunch hello.launch robot_name:=robot_valueROS-Workspace-Overlay
Stellen Sie sich vor, Sie haben zwei benutzerdefinierte Workspaces, Workspace A und Workspace B, die beide ein Paket namens turtlesim enthalten. Zusätzlich enthält der systeminterne Workspace ebenfalls ein Paket namens turtlesim. Welches wird verwendet, wenn Sie das Paket turtlesim aufrufen?
Implementierungsschritte
Schritt 0: Workspaces A und B erstellen
Erstellen Sie zunächst zwei separate Workspaces, A und B. Erstellen Sie in jedem Workspace ein Paket namens turtlesim.
Schritt 1: Die Datei ~/.bashrc bearbeiten
Fügen Sie folgende Zeilen in Ihre ~/.bashrc-Datei ein, um die Setup-Dateien beider Workspaces zu sourcen:
source /home/user/path/to/workspaceA/devel/setup.bash
source /home/user/path/to/workspaceB/devel/setup.bashErsetzen Sie /home/user/path/to/ durch die tatsächlichen Pfade Ihrer Workspaces.
Schritt 2: Umgebungsvariablen laden
Öffnen Sie ein neues Terminal und führen Sie folgenden Befehl aus, um die aktualisierten Umgebungsvariablen zu laden:
source ~/.bashrcSchritt 3: ROS-Umgebungsvariablen prüfen
Um die ROS-Paketpfade zu überprüfen, führen Sie aus:
echo $ROS_PACKAGE_PATHErgebnis: Die Ausgabe zeigt die Pfade in folgender Reihenfolge: Workspace B → Workspace A → systeminterner Workspace.
Schritt 4: Das Paket turtlesim aufrufen
Führen Sie nun folgenden Befehl aus, um in das Paket turtlesim zu navigieren:
roscd turtlesimErgebnis: Sie werden in das Paket turtlesim innerhalb von Workspace B geführt.
Umgang mit Namenskonflikten von ROS-Knoten
Szenario
In ROS hat jeder Knoten einen Namen, der bei der Knoteninitialisierung definiert wird. In C++ erfolgt das mit der API ros::init(argc, argv, "node_name");, in Python mit rospy.init_node("node_name"). In der ROS-Netzwerktopologie müssen Knoten eindeutige Namen haben, da das Teilen desselben Namens beim Aufrufen für Verwirrung sorgen kann. Konkret: Wird ein Knoten mit doppeltem Namen gestartet, wird der bestehende Knoten mit diesem Namen automatisch heruntergefahren. Doch was, wenn Sie mehrere Instanzen desselben Knotens ausführen oder Namenskonflikte handhaben müssen?
ROS bietet zwei Strategien für solche Situationen: Namespaces und Name-Remapping.
- Namespaces fügen Knotennamen ein Präfix hinzu.
- Name-Remapping weist einem Knotennamen einen Alias zu.
Beide Strategien können Konflikte bei Knotennamen lösen und können auf mehrere Arten implementiert werden:
- Mit dem Befehl
rosrun. - Über Launch-Dateien.
- Im Code des Knotens.
Dieser Abschnitt zeigt, wie Sie diese drei Methoden verwenden, um Namenskonflikte bei Knoten zu vermeiden.
Beispielszenario
Lassen Sie uns zwei turtlesim_node-Knoten starten. Wenn Sie zwei Terminals öffnen und die Knoten direkt ohne Änderungen starten, wird der erste Knoten beim Start des zweiten heruntergefahren. Sie sehen eine Warnung:
[ WARN] [1578812836.351049332]: Shutdown request received.
[ WARN] [1578812836.351207362]: Reason given for shutdown: [new node registered with same name]Da Knoten nicht denselben Namen teilen können, untersuchen wir verschiedene Strategien zur Lösung dieses Problems.
rosrun für Namespaces und Remapping verwenden
1. Einen Namespace mit rosrun setzen
Sie können einen Namespace für einen Knoten mit folgender Syntax setzen:
rosrun package_name node_name __ns:=/new_namespaceBeispiel:
rosrun turtlesim turtlesim_node __ns:=/xxx
rosrun turtlesim turtlesim_node __ns:=/yyyMit diesen Befehlen laufen beide Knoten ohne Probleme.
Ergebnisse:
Verwenden Sie rosnode list, um die Knoten zu prüfen:
/xxx/turtlesim
/yyy/turtlesim2. Knotennamen mit rosrun umbenennen
Sie können den Namen eines Knotens auch umbenennen, ihm also einen Alias geben, mit folgender Syntax:
rosrun package_name node_name __name:=new_nameBeispiel:
rosrun turtlesim turtlesim_node __name:=t1
rosrun turtlesim turtlesim_node __name:=t2Mit diesen Befehlen laufen beide Knoten mit ihren neuen Namen.
Ergebnisse:
Verwenden Sie rosnode list, um die Knoten zu prüfen:
/t1
/t23. Namespace und Namens-Remapping mit rosrun kombinieren
Sie können beide Techniken kombinieren, indem Sie gleichzeitig einen Namespace setzen und den Knotennamen umbenennen:
rosrun package_name node_name __ns:=/new_namespace __name:=new_nameBeispiel:
rosrun turtlesim turtlesim_node __ns:=/xxx __name:=tnErgebnisse:
Verwenden Sie rosnode list, um den Knoten zu prüfen:
/xxx/tnAlternativ können Sie den Namespace über eine Umgebungsvariable vor dem Start des Knotens setzen:
export ROS_NAMESPACE=xxxxLaunch-Dateien für Namespaces und Remapping verwenden
In Launch-Dateien enthält das <node>-Tag zwei wichtige Attribute: name und ns. Sie werden für das Namens-Remapping bzw. das Setzen von Namespaces verwendet. Mit einer Launch-Datei lassen sich Namespaces und Namens-Remapping leicht handhaben.
1. Beispiel einer Launch-Datei
So können Sie Namespaces und Namens-Remapping in einer Launch-Datei einstellen:
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1" />
<node pkg="turtlesim" type="turtlesim_node" name="t2" />
<node pkg="turtlesim" type="turtlesim_node" name="t1" ns="hello"/>
</launch>In diesem Beispiel ist das Attribut name erforderlich, ns ist optional.
2. Die Launch-Datei ausführen
Führen Sie die Launch-Datei aus und verwenden Sie dann rosnode list, um die Ergebnisse zu sehen:
/t1
/t2
/hello/t1Namespaces und Remapping im Code setzen
Wenn Sie eigene Knoten implementieren, haben Sie mehr Flexibilität, Namespaces und Namens-Remapping direkt in Ihrem Code zu setzen.
1. C++-Implementierung: Namens-Remapping
Sie können einen Namensalias mit folgendem Code setzen:
ros::init(argc, argv, "zhangsan", ros::init_options::AnonymousName);Ausführung:
Dies hängt einen Zeitstempel an den Knotennamen an und stellt seine Eindeutigkeit sicher.
2. C++-Implementierung: Setzen eines Namespaces
Sie können einen Namespace direkt im Code setzen:
std::map<std::string, std::string> map;
map["__ns"] = "xxxx";
ros::init(map, "wangqiang");Ausführung:
Dadurch wird dem Knoten ein Namespace zugewiesen und er kann konfliktfrei laufen.
3. Python-Implementierung: Namens-Remapping
In Python erreichen Sie eine ähnliche Funktionalität mit folgendem Code:
rospy.init_node("lisi", anonymous=True)Topic-Namens-Remapping in ROS
In ROS erlaubt das Topic-Namens-Remapping, den Namen eines Topics zu ändern, das ein Knoten abonniert oder veröffentlicht, ohne den Code des Knotens zu modifizieren. Das ist besonders nützlich, wenn mehrere Knoten integriert werden, die über unterschiedliche Topic-Namen kommunizieren müssen. Es gibt drei Hauptmethoden, Topic-Namen in ROS zu remappen:
- Mit dem Befehl
rosrun. - Über Launch-Dateien.
- Durch direkte Code-Änderung in C++ oder Python.
rosrun zum Remappen von Topics verwenden
Die Syntax zum Remappen eines Topic-Namens mit rosrun lautet:
rosrun package_name node_name old_topic_name:=new_topic_nameBeispiel: Integration von teleop_twist_keyboard mit turtlesim
Es gibt zwei Möglichkeiten, die Kommunikation zwischen dem teleop_twist_keyboard-Knoten und dem turtlesim-Anzeigeknoten einzurichten:
1. Lösung 1: Topic von teleop_twist_keyboard remappen
Bei diesem Ansatz remappen wir das Topic des teleop_twist_keyboard-Knotens auf /turtle1/cmd_vel.
-
Tastatursteuerungsknoten starten:
bashrosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel -
Turtlesim-Anzeigeknoten starten:
bashrosrun turtlesim turtlesim_node
Beide Knoten kommunizieren korrekt über das Topic /turtle1/cmd_vel.
2. Lösung 2: Topic von turtlesim remappen
Alternativ können wir das Topic des turtlesim-Knotens auf /cmd_vel remappen.
-
Tastatursteuerungsknoten starten:
bashrosrun teleop_twist_keyboard teleop_twist_keyboard.py -
Turtlesim-Anzeigeknoten starten:
bashrosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel
Beide Knoten kommunizieren korrekt über das Topic /cmd_vel.
Launch-Dateien zum Remappen von Topics verwenden
Sie können Topics auch in einer Launch-Datei remappen. Die Syntax zum Remappen eines Topics in einer Launch-Datei lautet:
<node pkg="package_name" type="node_type" name="node_name">
<remap from="original_topic" to="new_topic" />
</node>Beispiel: Integration von teleop_twist_keyboard mit turtlesim mittels Launch-Dateien
Auch hier gibt es zwei Lösungen:
1. Lösung 1: Topic von teleop_twist_keyboard remappen
Bei diesem Ansatz remappen wir das Topic des teleop_twist_keyboard-Knotens auf /turtle1/cmd_vel.
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1" />
<node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key">
<remap from="/cmd_vel" to="/turtle1/cmd_vel" />
</node>
</launch>Beide Knoten kommunizieren korrekt.
2. Lösung 2: Topic von turtlesim remappen
Bei diesem Ansatz remappen wir das Topic des turtlesim-Knotens auf /cmd_vel.
<launch>
<node pkg="turtlesim" type="turtlesim_node" name="t1">
<remap from="/turtle1/cmd_vel" to="/cmd_vel" />
</node>
<node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key" />
</launch>Beide Knoten kommunizieren korrekt.
Topics im Code remappen
Der Topic-Name in ROS wird vom Namespace des Knotens, dem Knotennamen und dem Topic-Namen selbst beeinflusst. Topic-Namen lassen sich allgemein in drei Typen einteilen:
- Global: Der Topic-Name ist absolut und beginnt mit
/, sodass er unabhängig vom Namespace des Knotens ist. - Relativ: Der Topic-Name ist relativ und beginnt nicht mit
/, was bedeutet, dass er innerhalb des Namespaces des Knotens interpretiert wird. - Privat: Der Topic-Name ist privat und beginnt mit
~, das heißt, er wird relativ zum privaten Namespace des Knotens aufgelöst.
Lassen Sie uns diese Konzepte anhand von Beispielen in C++ und Python erkunden.
1. C++-Implementierung
Vorbereitung des Beispiels:
-
Den Knoten mit einem Namen initialisieren:
cppros::init(argc, argv, "hello"); -
Verschiedene Arten von Topic-Namen festlegen.
-
Beim Start des Knotens ein
__ns:=xxx-Argument übergeben. -
Nach dem Start des Knotens
rostopicverwenden, um die Topic-Informationen zu prüfen.
Globaler Topic-Name
Globale Topic-Namen beginnen mit / und sind unabhängig vom Namen oder Namespace des Knotens.
-
Beispiel 1:
cppros::Publisher pub = nh.advertise<std_msgs::String>("/chatter", 1000);Ergebnis:
/chatter -
Beispiel 2:
cppros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money", 1000);Ergebnis:
/chatter/money
Relativer Topic-Name
Relative Topic-Namen beginnen nicht mit / und werden relativ zum Namespace des Knotens aufgelöst.
-
Beispiel 1:
cppros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 1000);Ergebnis:
xxx/chatter -
Beispiel 2:
cppros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money", 1000);Ergebnis:
xxx/chatter/money
Privater Topic-Name
Private Topic-Namen beginnen mit ~ und werden relativ zum privaten Namespace des Knotens aufgelöst.
-
Beispiel 1:
cppros::NodeHandle nh("~"); ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 1000);Ergebnis:
/xxx/hello/chatter -
Beispiel 2:
cppros::NodeHandle nh("~"); ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money", 1000);Ergebnis:
/xxx/hello/chatter/money -
Sonderfall: Bei Verwendung von
~wird der Topic-Name als absolut behandelt, wenn er mit/beginnt.cppros::NodeHandle nh("~"); ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money", 1000);Ergebnis:
/chatter/money
Python-Implementierung
Vorbereitung des Beispiels:
-
Den Knoten mit einem Namen initialisieren:
pythonrospy.init_node("hello") -
Verschiedene Arten von Topic-Namen festlegen.
-
Beim Start des Knotens ein
__ns:=xxx-Argument übergeben. -
Nach dem Start des Knotens
rostopicverwenden, um die Topic-Informationen zu prüfen.
Globaler Topic-Name
Globale Topic-Namen beginnen mit / und sind unabhängig vom Namen oder Namespace des Knotens.
-
Beispiel 1:
pythonpub = rospy.Publisher("/chatter", String, queue_size=1000)Ergebnis:
/chatter -
Beispiel 2:
pythonpub = rospy.Publisher("/chatter/money", String, queue_size=1000)Ergebnis:
/chatter/money
Relativer Topic-Name
Relative Topic-Namen beginnen nicht mit / und werden relativ zum Namespace des Knotens aufgelöst.
-
Beispiel 1:
pythonpub = rospy.Publisher("chatter", String, queue_size=1000)Ergebnis:
xxx/chatter -
Beispiel 2:
pythonpub = rospy.Publisher("chatter/money", String, queue_size=1000)Ergebnis:
xxx/chatter/money
Privater Topic-Name
Private Topic-Namen beginnen mit ~ und werden relativ zum privaten Namespace des Knotens aufgelöst.
-
Beispiel 1:
pythonpub = rospy.Publisher("~chatter", String, queue_size=1000)Ergebnis:
/xxx/hello/chatter -
Beispiel 2:
pythonpub = rospy.Publisher("~chatter/money", String, queue_size=1000)Ergebnis:
/xxx/hello/chatter/money
Parameter in ROS setzen
In ROS werden Parameter zur Konfiguration von Knoten zur Laufzeit verwendet. Sie können auf verschiedene Arten gesetzt werden: mit dem Befehl rosrun, in Launch-Dateien oder direkt im Code. Parameter können global, relativ oder privat sein, je nach ihrer Definition.
Parameter mit rosrun setzen
Sie können Parameter beim Starten eines Knotens mit dem Befehl rosrun setzen. Die Syntax zum Setzen von Parametern ist:
rosrun package_name node_name _parameter_name:=parameter_valueBeispiel: Einen Parameter für den Turtlesim-Knoten setzen
Lassen Sie uns den turtlesim_node starten und einen Parameter A = 100 setzen.
rosrun turtlesim turtlesim_node _A:=100Parameter prüfen
Sie können den folgenden Befehl verwenden, um alle Parameter aufzulisten und das Ergebnis zu überprüfen:
rosparam listAusgabe:
/turtlesim/A
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_rErklärung: Der Parameter A ist mit dem Knotennamen (/turtlesim/) versehen, was darauf hinweist, dass rosrun beim Setzen eines Parameters den privaten Namespace-Modus verwendet.
Parameter in Launch-Dateien setzen
Wie zuvor besprochen, können Parameter in Launch-Dateien mit den Tags <param> oder <rosparam> gesetzt werden. Außerhalb des <node>-Tags gesetzte Parameter sind global, während innerhalb des <node>-Tags gesetzte Parameter privat und relativ zum Namespace des Knotens sind.
Beispiel: Parameter mit dem <param>-Tag setzen
Hier ein Beispiel, in dem wir einen globalen und einen privaten Parameter setzen:
<launch>
<param name="p1" value="100" />
<node pkg="turtlesim" type="turtlesim_node" name="t1">
<param name="p2" value="100" />
</node>
</launch>Parameter prüfen
Nach dem Ausführen der Launch-Datei können Sie die Parameter mit folgendem Befehl prüfen:
rosparam listAusgabe:
/p1
/t1/p2Erklärung: Der Parameter p1 ist global, während p2 privat zum Knoten t1 ist, wie der Namespace anzeigt.
Parameter im Code setzen
Das Setzen von Parametern im Code bietet mehr Flexibilität und erlaubt es, globale, relative und private Parameter programmatisch zu definieren.
1. C++-Implementierung
In C++ können Parameter mit der ros::param-API oder über ein ros::NodeHandle-Objekt gesetzt werden.
1.1 ros::param zum Setzen von Parametern verwenden
Die Funktion ros::param::set wird zum Setzen von Parametern verwendet. Das erste Argument der Funktion ist der Parametername, das zweite der Parameterwert. Beginnt der Parametername mit /, ist es ein globaler Parameter. Beginnt er mit ~, ist es ein privater Parameter. Andernfalls ist er relativ.
Beispiel:
ros::param::set("/set_A", 100); // Global, independent of namespace and node name
ros::param::set("set_B", 100); // Relative, dependent on namespace
ros::param::set("~set_C", 100); // Private, dependent on namespace and node nameAngenommen, der Namespace ist xxx und der Knotenname yyy, würde das Prüfen der Parameter mit rosparam list Folgendes anzeigen:
/set_A
/xxx/set_B
/xxx/yyy/set_Cros::NodeHandle zum Setzen von Parametern verwenden
Um Parameter mit ros::NodeHandle zu setzen, erstellen Sie zuerst ein NodeHandle-Objekt und rufen dann die setParam-Methode auf. Beginnt der Parametername mit /, ist er global. Beginnt er nicht mit /, hängt es davon ab, wie das NodeHandle-Objekt erstellt wurde, ob er relativ oder privat ist.
Beispiel:
ros::NodeHandle nh;
nh.setParam("/nh_A", 100); // Global, independent of namespace and node name
nh.setParam("nh_B", 100); // Relative, dependent on namespace
ros::NodeHandle nh_private("~");
nh_private.setParam("nh_C", 100); // Private, dependent on namespace and node nameAngenommen, der Namespace ist xxx und der Knotenname yyy, würde das Prüfen der Parameter mit rosparam list Folgendes anzeigen:
/nh_A
/xxx/nh_B
/xxx/yyy/nh_C2. Python-Implementierung
In Python ist das Setzen von Parametern etwas einfacher als in C++. Die Funktion rospy.set_param wird zum Setzen von Parametern verwendet. Das erste Argument ist der Parametername, das zweite der Wert. Wie in C++ ist der Parameter global, wenn der Name mit / beginnt; mit ~ ist er privat. Andernfalls ist er relativ.
Beispiel:
rospy.set_param("/py_A", 100) # Global, independent of namespace and node name
rospy.set_param("py_B", 100) # Relative, dependent on namespace
rospy.set_param("~py_C", 100) # Private, dependent on namespace and node nameAngenommen, der Namespace ist xxx und der Knotenname yyy, würde das Prüfen der Parameter mit rosparam list Folgendes anzeigen:
/py_A
/xxx/py_B
/xxx/yyy/py_C