Lerninhalte finden
Features
Entdecke
© StudySmarter 2024, all rights reserved.
Einführung in die Robotik-Frameworks: In dieser Aufgabe soll ein autonomer Roboter in einer simulierten Umgebung mit Hilfe eines Robotik-Frameworks programmiert werden. Der Roboter soll selbstständig navigieren, Hindernissen ausweichen und bestimmte Ziele erreichen. Dafür stehen die Middleware ROS, eine modulare Architektur und Kommunikationsmodelle wie Publisher-Subscriber und Service-Client zur Verfügung. Sensoren und Aktuatoren müssen integriert und korrekt kalibriert werden. Die Entwicklung erfolgt hauptsächlich in C++ und Python, und die Simulation wird in Gazebo durchgeführt. Sicherheitsaspekte wie Fehlertoleranz und die Mensch-Roboter-Interaktion müssen berücksichtigt werden.
Implementiere eine einfache ROS-Node in Python, die als Publisher funktioniert und die Position (x, y) des Roboters in der simulierten Umgebung regelmäßig veröffentlicht. Verwende dazu die ROS-Tutorials und beschreibe Schritt für Schritt den Prozess der Erstellung dieser Node.
Lösung:
Schrittweise Anleitung zur Implementierung einer einfachen ROS-Node in PythonDieser Leitfaden hilft Dir bei der Erstellung einer Python-ROS-Node, die die Position des Roboters in der simulierten Umgebung veröffentlicht. Befolge die folgenden Schritte:
cd ~/catkin_ws/srccatkin_create_pkg my_robot_tutorial rospy std_msgsWechsle anschließend in das neu erstellte Package-Verzeichnis:
cd ~/catkin_ws/src/my_robot_tutorial
mkdir scriptscd scriptstouch position_publisher.pychmod +x position_publisher.pyÖffne die Datei position_publisher.py mit einem Texteditor Deiner Wahl und füge den folgenden Code ein:
#!/usr/bin/env python3import rospyfrom geometry_msgs.msg import Pointdef position_publisher(): rospy.init_node('position_publisher', anonymous=True) pub = rospy.Publisher('robot_position', Point, queue_size=10) rate = rospy.Rate(1) # 1 Hz x = 0.0 y = 0.0 while not rospy.is_shutdown(): point = Point() x += 0.1 y += 0.1 point.x = x point.y = y rospy.loginfo(f'Publishing position: x={point.x}, y={point.y}') pub.publish(point) rate.sleep()if __name__ == '__main__': try: position_publisher() except rospy.ROSInterruptException: pass
find_package(catkin REQUIRED COMPONENTS rospy std_msgs)
cd ~/catkin_wscatkin_make
roscoreÖffne ein zweites Terminal, source Deinen Arbeitsbereich und starte die Node:
source ~/catkin_ws/devel/setup.bashrosrun my_robot_tutorial position_publisher.pyDie Node wird jetzt die Position des Roboters auf dem robot_position Topic veröffentlichen.
Integriere Sensoren (wie Lidar oder Kamera) in die simulierte Roboterumgebung in Gazebo mittels ROS. Erkläre, wie die Sensordaten verarbeitet und mit Hilfe von Datenfusion kombiniert werden können, um eine präzisere Umgebungskarte zu erstellen. Binde dazu relevante ROS-Pakete ein und zeige, wie die Sensordaten in einer ROS-Node abonniert und verarbeitet werden.
Lösung:
Schrittweise Anleitung zur Integration und Verarbeitung von Sensoren in der simulierten Roboterumgebung in Gazebo mittels ROSDieser Leitfaden hilft Dir dabei, Sensoren (zum Beispiel Lidar und Kamera) in eine simulierte Roboterumgebung in Gazebo zu integrieren und die Sensordaten mittels ROS zu verarbeiten und zu fusionieren, um eine präzisere Umgebungskarte zu erstellen. Befolge die folgenden Schritte:
<robot name='my_robot'> <link name='base_link'> ... </link> <!-- Lidar Sensor --> <gazebo> <plugin name='my_lidar' filename='libgazebo_ros_laser.so'> <robotNamespace>/my_robot</robotNamespace> <frameName>base_link</frameName> <topicName>/scan</topicName> <updateRate>10.0</updateRate> </plugin> </gazebo> <!-- Kamera Sensor --> <gazebo> <plugin name='my_camera' filename='libgazebo_ros_camera.so'> <robotNamespace>/my_robot</robotNamespace> <frameName>base_link</frameName> <imageTopicName>/camera/image_raw</imageTopicName> <cameraInfoTopicName>/camera/camera_info</cameraInfoTopicName> </plugin> </gazebo></robot>Speichere dieses Modell und lade es in Gazebo, indem Du Dein Launch-File entsprechend erstellst oder anpasst.
#!/usr/bin/env python3import rospyfrom sensor_msgs.msg import LaserScan, Imagefrom cv_bridge import CvBridge, CvBridgeErrorimport cv2import numpy as npdef callback_lidar(data): # Verarbeitung der Lidar-Daten rospy.loginfo(f'Received Lidar data: {data.ranges}')def callback_camera(data): # Verarbeitung der Kameradaten bridge = CvBridge() try: cv_image = bridge.imgmsg_to_cv2(data, 'bgr8') # Zeige das Bild an cv2.imshow('Camera Image', cv_image) cv2.waitKey(3) except CvBridgeError as e: rospy.logerr(e)def sensor_fusion(): rospy.init_node('sensor_fusion_node', anonymous=True) rospy.Subscriber('/scan', LaserScan, callback_lidar) rospy.Subscriber('/camera/image_raw', Image, callback_camera) rospy.spin()if __name__ == '__main__': try: sensor_fusion() except rospy.ROSInterruptException: pass
roslaunch my_robot_tutorial my_robot_world.launchStarte dann Deine Sensor-Fusion-Node in einem zweiten Terminal:
rosrun my_robot_tutorial sensor_fusion_node.py
Erstelle ein einfaches Bewegungssteuerungsskript in C++, das den Roboter auf Basis der Sensordaten steuert und auf einem vorgegebenen Pfad navigiert. Beschreibe den Aufbau dieses Skriptes und wie die Kommunikation zwischen den einzelnen Modulen (Sensoren, Aktuatoren) erfolgt. Zeige die einzelnen Schritte sowie den Codeausschnitt für die Bewegungssteuerung und Hindernisvermeidung.
Lösung:
Schrittweise Anleitung zur Erstellung eines einfachen Bewegungssteuerungsskripts in C++Dieser Leitfaden hilft Dir bei der Erstellung eines C++-Skripts zur Bewegungssteuerung eines Roboters auf Basis von Sensordaten. Das Skript wird dem Roboter ermöglichen, Hindernissen auszuweichen und einem vorgegebenen Pfad zu folgen.
cd ~/catkin_ws/srccatkin_create_pkg robot_movement_tutorial roscpp std_msgs sensor_msgs geometry_msgsWechsle anschließend in das neu erstellte Package-Verzeichnis:
cd ~/catkin_ws/src/robot_movement_tutorial
mkdir srccd srctouch movement_controller.cppÖffne die Datei movement_controller.cpp mit einem Texteditor Deiner Wahl und füge den folgenden Code ein:
#include <ros/ros.h>#include <sensor_msgs/LaserScan>#include <geometry_msgs/Twist>class RobotController {public: RobotController() { cmd_pub_ = nh_.advertise<geometry_msgs::Twist>("/cmd_vel", 10); laser_sub_ = nh_.subscribe("/scan", 10, &RobotController::laserCallback, this); } void laserCallback(const sensor_msgs::LaserScan::ConstPtr& scan) { bool obstacle = false; for (int i = 0; i < scan->ranges.size(); ++i) { if (scan->ranges[i] < 0.5) { obstacle = true; break; } } geometry_msgs::Twist cmd; if (obstacle) { cmd.linear.x = 0.0; cmd.angular.z = 0.5; // Drehung bei Hindernis } else { cmd.linear.x = 0.2; // Vorwärtsbewegung cmd.angular.z = 0.0; } cmd_pub_.publish(cmd); }private: ros::NodeHandle nh_; ros::Publisher cmd_pub_; ros::Subscriber laser_sub_;};int main(int argc, char** argv) { ros::init(argc, argv, "robot_controller"); RobotController controller; ros::spin(); return 0;}
add_executable(movement_controller src/movement_controller.cpp)target_link_libraries(movement_controller ${catkin_LIBRARIES})
<build_depend>roscpp</build_depend><build_depend>sensor_msgs</build_depend><build_depend>geometry_msgs</build_depend><exec_depend>roscpp</exec_depend><exec_depend>sensor_msgs</exec_depend><exec_depend>geometry_msgs</exec_depend>
cd ~/catkin_wscatkin_make
roslaunch my_robot_tutorial my_robot_world.launchStarte in einem zweiten Terminal die Bewegungssteuerungs-Node:
source ~/catkin_ws/devel/setup.bashrosrun robot_movement_tutorial movement_controller
Diskutiere die Sicherheitsaspekte der Mensch-Roboter-Interaktion in einem öffentlichen Raum. Welche Maßnahmen müssen ergriffen werden, um Fehlertoleranz sicherzustellen und Unfälle zu vermeiden? Entwickle dabei ein Konzept basierend auf ROS, das eine robuste und sichere Interaktion ermöglicht. Berücksichtige dabei sowohl Hardware- als auch Software-basierte Lösungen und erkläre, wie diese in deine bestehende Architektur integriert werden können.
Lösung:
Diskussion der Sicherheitsaspekte der Mensch-Roboter-Interaktion in einem öffentlichen RaumDie Interaktion von Robotern mit Menschen in öffentlichen Räumen stellt besondere Sicherheitsherausforderungen dar. In diesem Kontext müssen Maßnahmen ergriffen werden, um Fehlertoleranz sicherzustellen und Unfälle zu vermeiden. Diese Maßnahmen umfassen sowohl Hardware- als auch Software-basierte Lösungen.
#include <std_msgs/Bool.h>ros::Publisher e_stop_pub = nh.advertise<std_msgs::Bool>("/emergency_stop", 10);std_msgs::Bool e_stop_msg;e_stop_msg.data = true;e_stop_pub.publish(e_stop_msg);
#include <sensor_msgs/LaserScan.h>void lidarCallback(const sensor_msgs::LaserScan::ConstPtr& scan) { // Process scan data if (detectObstacle(scan)) { stopRobot(); }}ros::Subscriber lidar_sub = nh.subscribe("/scan", 10, lidarCallback);
try { // Erhalte Sensor-Daten} catch (const std::exception& e) { ROS_ERROR("Sensor error: %s", e.what()); stopRobot();}
void lidarCallback1(const sensor_msgs::LaserScan::ConstPtr& scan) { // Verarbeite Daten von Lidar 1}void lidarCallback2(const sensor_msgs::LaserScan::ConstPtr& scan) { // Verarbeite Daten von Lidar 2}bool voteForSafetyCheck() { // Implementiere Voting-Logik return (obstacle_detected_by_lidar1 || obstacle_detected_by_lidar2);}ros::Subscriber lidar_sub1 = nh.subscribe("/scan1", 10, lidarCallback1);ros::Subscriber lidar_sub2 = nh.subscribe("/scan2", 10, lidarCallback2);
ROS_INFO("Robot operating normally");if (emergency) { ROS_WARN("Emergency stop activated!");}
Installation und Konfiguration von ROSInstallation und Einrichtung des Robot Operating Systems (ROS) für die Roboterentwicklung.
sudo apt install ros--desktop-full
sudo rosdep init && rosdep update
source /opt/ros//setup.bash
mkdir -p ~/catkin_ws/src && cd ~/catkin_ws/ && catkin_make
source devel/setup.bash
rosdep install --from-paths src --ignore-src -r -y
Stelle sicher, dass die ROS-Umgebung korrekt initialisiert ist. Beschreibe die Schritte und warum jede dieser Schlüsselschritte notwendig ist, um sicherzustellen, dass ROS korrekt funktioniert.
Lösung:
Sicherstellen, dass die ROS-Umgebung korrekt initialisiert istUm sicherzustellen, dass die ROS-Umgebung korrekt initialisiert ist, muss jeder Schritt in der Installations- und Konfigurationsprozedur genau befolgt werden. Hier sind die Schritte und die Erklärungen, warum sie notwendig sind, um sicherzustellen, dass ROS korrekt funktioniert:
sudo apt install ros-<distribution>-desktop-full
Dieser Schritt installiert ROS auf Deinem System. Die Desktop-Full-Version enthält alles, was Du für die Entwicklung und den Betrieb von ROS benötigst, einschließlich GUI-Tools wie Rviz und rqt.sudo rosdep init && rosdep update
rosdep ist ein Befehlszeilentool, das die für Dein System erforderlichen Abhängigkeiten auflöst. Die Initialisierung und das Update von rosdep stellen sicher, dass alle notwendigen Abhängigkeiten und Abhängigkeitspfade korrekt eingerichtet sind.source /opt/ros/<distribution>/setup.bash
Dieser Befehl setzt die notwendigen Umgebungsvariablen, damit ROS auf Deinem System läuft. Dies umfasst das Hinzufügen von ROS-spezifischen Pfaden zur PATH
-Umgebungsvariable und das Festlegen anderer erforderlicher Variablen.mkdir -p ~/catkin_ws/src && cd ~/catkin_ws/ && catkin_make
Catkin ist das Build-System von ROS. Dieser Schritt erstellt einen neuen Workspace, in dem Du Deine ROS-Pakete erstellen und verwalten kannst. Der Befehl catkin_make
baut den Workspace und erstellt alle notwendigen Konfigurationsdateien.source devel/setup.bash
Nach dem Erstellen des Workspaces musst du dieses Skript ausführen, damit die Umgebungsvariablen für Deinen neuen Workspace gesetzt werden. Dies ermöglicht es dir, auf die Pakete und Ressourcen in deinem Workspace zuzugreifen.rosdep install --from-paths src --ignore-src -r -y
Dieser Schritt verwendet rosdep, um alle notwendigen Abhängigkeiten für die Pakete im src
-Verzeichnis Deines Workspaces zu installieren. Dies ist wichtig, um sicherzustellen, dass alle Pakete korrekt gebaut und ausgeführt werden können. Nach der Einrichtung des Catkin-Workspaces soll ein einfaches ROS-Paket erstellt werden. Im Verzeichnis ~/catkin_ws/src
, erstelle ein Paket namens my_robot_package
mit den Abhängigkeiten roscpp
und std_msgs
. Zeige die dazugehörigen Befehle und erkläre kurz die Bedeutung jedes einzelnen.
Lösung:
Erstellen eines einfachen ROS-Pakets nach der Einrichtung des Catkin-WorkspacesUm ein ROS-Paket namens my_robot_package
mit den Abhängigkeiten roscpp
und std_msgs
im Verzeichnis ~/catkin_ws/src
zu erstellen, müssen folgende Schritte ausgeführt werden:
cd ~/catkin_ws/srcDieser Schritt wechselt in das Quellverzeichnis (src) Deines Catkin-Workspaces, in dem sich Deine ROS-Pakete befinden.
catkin_create_pkg my_robot_package roscpp std_msgsDer Befehl
catkin_create_pkg
erstellt ein neues ROS-Paket mit dem Namen my_robot_package
. Die nachfolgenden Argumente roscpp
und std_msgs
legen die Abhängigkeiten fest, die Dein Paket benötigt. Dieser Befehl erzeugt die erforderliche Verzeichnisstruktur und die notwendigen Konfigurationsdateien wie package.xml
und CMakeLists.txt
.cd ~/catkin_wsDieser Schritt bringt Dich zurück zum Hauptverzeichnis des Catkin-Workspaces, damit Du den Build-Prozess starten kannst.
catkin_makeDer Befehl
catkin_make
kompiliert alle Pakete im Catkin-Workspace, einschließlich des neu erstellten Pakets my_robot_package
. Dabei werden auch die Abhängigkeiten geprüft und eingebunden.source devel/setup.bashNachdem das Paket gebaut wurde, sollten die Umgebungsvariablen erneut gesetzt werden, damit die Änderungen an Deinem Workspace aktiv werden. Dies erlaubt ROS, Dein neues Paket zu erkennen und zu nutzen.
Stellen Sie sich vor, Sie haben ein robotisches System, das die Entfernung zu einem Objekt misst und die gemessenen Daten an einen zentralen Rechner sendet, der die Daten weiterverarbeitet und auf diesem basierend Befehle an den Roboter zurücksendet. Die Kommunikation innerhalb dieses Systems erfolgt mittels ROS (Robot Operating System).
Lösung:
#!/usr/bin/env pythonimport rospyfrom sensor_msgs.msg import Range# Definition der Callback-Funktion def sensor_callback(data): rospy.loginfo('Distance: %f', data.range) # Initialisierung des Nodes rospy.init_node('sensor_node', anonymous=True) # Subscriben zum Sensor-Topic rospy.Subscriber('sensor_data', Range, sensor_callback) # ROS-Node ausführen rospy.spin()
Um den Sensor-Node zu starten, kann das folgende Kommando in der Kommandozeile verwendet werden: rosrun sensor_node.py
#!/usr/bin/env pythonimport rospyfrom sensor_msgs.msg import Rangefrom geometry_msgs.msg import Twist # Definition der Callback-Funktion def control_callback(data): cmd = Twist() if data.range < 1.0: cmd.linear.x = 0.0 cmd.angular.z = 1.0 else: cmd.linear.x = 0.5 cmd.angular.z = 0.0 # Publisher cmd_pub = rospy.Publisher('cmd_vel', Twist, queue_size=10) cmd_pub.publish(cmd)# Initialisierung des Nodesrospy.init_node('controller_node', anonymous=True) # Subscriben zum Sensor-Topic rospy.Subscriber('sensor_data', Range, control_callback) # ROS-Node ausführenrospy.spin()
Um den Controller-Node zu starten, kann das folgende Kommando in der Kommandozeile verwendet werden: rosrun controller_node.py
Lösung:
sensor_msgs/Range
sein. Die sensor_msgs/Range
Nachricht hat folgende relevante Datenfelder: header
: enthält Metadaten wie Zeitstempel und den Koordinatenrahmen des Sensorsradiation_type
: Typ der Strahlung (z.B. Ultraschall oder Infrarot)field_of_view
: Öffnungswinkel des Sensorsmin_range
: Minimale Entfernung, die der Sensor messen kannmax_range
: Maximale Entfernung, die der Sensor messen kannrange
: Tatsächliche Entfernungsmessunggeometry_msgs/Twist
sein. Die geometry_msgs/Twist
Nachricht hat folgende relevante Datenfelder: linear
: enthält einen Vektor x, y, z
, der die linearen Geschwindigkeiten in den jeweiligen Achsen angibt (in der Regel wird nur die x
-Achse für Vorwärts-/Rückwärtsbewegungen genutzt)angular
: enthält einen Vektor x, y, z
, der die Winkelgeschwindigkeiten in den jeweiligen Achsen angibt (in der Regel wird nur die z
-Achse für Drehbewegungen um die Vertikale Achse genutzt)sensor_data
Topics helfen die Felder des sensor_msgs/Range
Nachrichtentyps, die Entfernung zu Objekten genau zu bestimmen und diese Information anderen Nodes zur Verfügung zu stellen.cmd_vel
Topics geben die Felder des geometry_msgs/Twist
Nachrichtentyps präzise Befehle zur Steuerung der Bewegung des Roboters. Lineare Geschwindigkeiten steuern die Vorwärts- und Rückwärtsbewegung, während Winkelgeschwindigkeiten die Drehbewegung des Roboters steuern.
Lösung:
SetSensorConfig.srv
-Datei könnte folgendermaßen aussehen: float32 min_range # Minimale Entfernung, die der Sensor messen kann float32 max_range # Maximale Entfernung, die der Sensor messen kann float32 frequency # Messfrequenz --- bool success # Indikator, ob die Konfiguration erfolgreich war string message # Nachricht zur Rückmeldung
Implementierung des Services in ROS:Die Implementierung des Services erfolgt in zwei Schritten: Definition des Service-Servers und Aufruf des Service-Clients.#!/usr/bin/env python import rospy from .srv import SetSensorConfig, SetSensorConfigResponse # Service-Callback-Funktion def handle_set_sensor_config(req): # Hier würden die aktuellen Sensor-Konfigurationen angepasst werden rospy.loginfo('Setting Sensor Config: min_range=%f, max_range=%f, frequency=%f', req.min_range, req.max_range, req.frequency) success = True # Platzhalter logik, um den Erfolg zu bestimmen message = 'Sensor configuration updated successfully' if success else 'Failed to update sensor configuration' return SetSensorConfigResponse(success, message) # Initialisierung des Service-Servers def sensor_config_server(): rospy.init_node('sensor_config_server') service = rospy.Service('set_sensor_config', SetSensorConfig, handle_set_sensor_config) rospy.loginfo('Sensor Config Service is ready.') rospy.spin() if __name__ == '__main__': sensor_config_server()
#!/usr/bin/env python import rospy from .srv import SetSensorConfig # Aufrufen des Service def set_sensor_config_client(min_range, max_range, frequency): rospy.wait_for_service('set_sensor_config') try: set_sensor_config = rospy.ServiceProxy('set_sensor_config', SetSensorConfig) resp = set_sensor_config(min_range, max_range, frequency) return resp.success, resp.message except rospy.ServiceException as e: rospy.logerr('Service call failed: %s', e) if __name__ == '__main__': rospy.init_node('sensor_config_client') success, message = set_sensor_config_client(0.2, 5.0, 10.0) rospy.loginfo('Service response: %s - %s', success, message)
min_range = 0.2
, max_range = 5.0
, frequency = 10.0
success = True
, message = 'Sensor configuration updated successfully'
Du hast ein Projekt, bei dem Du einen mobilen Roboter in einer simulierten Umgebung testen möchtest, bevor Du ihn in der realen Welt einsetzt. Die Simulationssoftware Gazebo bietet Dir hierfür eine Open-Source-3D-Simulationsumgebung, die unter anderem in Kombination mit dem Robot Operating System (ROS) eingesetzt werden kann. Gazebo unterstützt physikalische Simulationen wie Kollision und Trägheit, und es gibt die Möglichkeit, Plug-ins zur Erweiterung der Funktionalität zu nutzen. Zudem können 3D-Objekte und Umgebungen importiert werden, um die Simulation so realitätsnah wie möglich zu gestalten.
Beschreibe die Schritte, die notwendig sind, um einen mobilen Roboter in Gazebo zu erstellen und zu simulieren. Gehe dabei auch auf die Integration mit ROS ein. Erkläre, welche physikalischen Modelle und Simulationen berücksichtigt werden müssen, um eine realistische Umgebung zu schaffen.
Lösung:
Schritte zur Erstellung und Simulation eines mobilen Roboters in Gazebo, inklusive Integration mit ROS: Die Simulation eines mobilen Roboters in Gazebo und dessen Integration mit ROS erfordert mehrere wichtige Schritte. Hier ist ein detaillierter Ablaufplan:
Angenommen, Du hast ein Plug-in entwickelt, das die Funktionalität Deines Roboters erweitern soll. Beschreibe den Prozess der Implementierung und Integration dieses Plug-ins in Gazebo. Welche spezifischen Komponenten müssen angepasst werden und wie wird das Plug-in in der Simulationsumgebung aktiviert?
Lösung:
Prozess der Implementierung und Integration eines Plug-ins in Gazebo:Die Implementierung und Integration eines Plug-ins, das die Funktionalität eines Roboters in Gazebo erweitert, erfordert mehrere Schritte. Hier findest Du eine detaillierte Anleitung zum gesamten Prozess:
#include <gazebo/gazebo.hh>#include <gazebo/physics/physics.hh>namespace gazebo { class MyRobotPlugin : public ModelPlugin { public: void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) { // Initialize model and access properties this->model = _model; this->sdf = _sdf; // Your custom code here } private: physics::ModelPtr model; sdf::ElementPtr sdf; }; GZ_REGISTER_MODEL_PLUGIN(MyRobotPlugin)}
cmake_minimum_required(VERSION 2.8.3)project(my_robot_plugin)find_package(gazebo REQUIRED)include_directories(${GAZEBO_INCLUDE_DIRS})link_directories(${GAZEBO_LIBRARY_DIRS})add_library(MyRobotPlugin SHARED MyRobotPlugin.cc)target_link_libraries(MyRobotPlugin ${GAZEBO_LIBRARIES})
<model name='my_robot'> <plugin name='my_robot_plugin' filename='libMyRobotPlugin.so'> </plugin></model>
#include <gazebo/gazebo.hh>#include <gazebo/physics/physics.hh>#include <ros/ros.h>#include <std_msgs/String.h>namespace gazebo { class MyRobotPlugin : public ModelPlugin { public: void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) { // ROS node handle if (!ros::isInitialized()) { int argc = 0; char** argv = NULL; ros::init(argc, argv,
Mit unserer kostenlosen Lernplattform erhältst du Zugang zu Millionen von Dokumenten, Karteikarten und Unterlagen.
Kostenloses Konto erstellenDu hast bereits ein Konto? Anmelden