{"id":1672,"date":"2025-08-12T06:59:43","date_gmt":"2025-08-12T06:59:43","guid":{"rendered":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/"},"modified":"2025-08-12T06:59:43","modified_gmt":"2025-08-12T06:59:43","slug":"creating-a-simple-teleoperation-system-with-ros-2","status":"publish","type":"post","link":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/","title":{"rendered":"Creating a Simple Teleoperation System with ROS 2"},"content":{"rendered":"<h1>Creating a Simple Teleoperation System with ROS 2 \ud83c\udfaf<\/h1>\n<p>Ever dreamed of controlling a robot from afar? \u2728 With the Robot Operating System (ROS) 2, that dream can become a reality! This tutorial will guide you through building a simple <strong>ROS 2 Teleoperation System<\/strong>, allowing you to remotely control a robot&#8217;s movements. We&#8217;ll cover everything from setting up your ROS 2 environment to writing the necessary Python code. Get ready to dive in and unlock the power of remote robotics!<\/p>\n<h2>Executive Summary<\/h2>\n<p>This article provides a comprehensive guide to creating a basic teleoperation system using ROS 2. We&#8217;ll explore the fundamental concepts of ROS 2, including nodes, topics, and message types.  You will learn how to implement a simple controller to drive your robots remotely. The tutorial covers setting up the ROS 2 environment, creating custom message types for teleoperation commands, writing Python nodes for reading input (e.g., keyboard commands) and controlling the robot, and testing the system. By following this guide, you&#8217;ll gain a solid understanding of teleoperation principles and practical experience with ROS 2, enabling you to build more complex robotic control systems in the future. This project provides a stepping stone to more advanced robotics applications, fostering innovation and accessibility within the field.<\/p>\n<h2>Setting up Your ROS 2 Environment<\/h2>\n<p>Before we begin, you&#8217;ll need a working ROS 2 environment. This involves installing ROS 2 and setting up your workspace. Let&#8217;s walk through the essentials.<\/p>\n<ul>\n<li><strong>Install ROS 2:<\/strong> Follow the official ROS 2 installation instructions for your operating system (Ubuntu is commonly used). You can find them on the ROS 2 website. <\/li>\n<li><strong>Create a ROS 2 Workspace:<\/strong>  A workspace is where you&#8217;ll store your ROS 2 packages. Use the following commands in your terminal:\n<pre><code>mkdir -p ros2_ws\/src\ncd ros2_ws\nros2 pkg create --build-type ament_python my_teleop_pkg --dependencies rclpy geometry_msgs<\/code><\/pre>\n<\/li>\n<li><strong>Source the ROS 2 Environment:<\/strong>  Each time you open a new terminal, you need to source the ROS 2 environment:\n<pre><code>source \/opt\/ros\/humble\/setup.bash  # Or your ROS 2 version\nsource install\/setup.bash<\/code><\/pre>\n<\/li>\n<li><strong>Verify the Installation:<\/strong> Run a simple ROS 2 command to ensure everything is working:\n<pre><code>ros2 run turtlesim turtlesim_node<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>Creating Custom Message Types for Teleoperation<\/h2>\n<p>To send teleoperation commands to the robot, we&#8217;ll define a custom message type. This allows us to specify the desired robot velocity.<\/p>\n<ul>\n<li><strong>Define the Message:<\/strong> Create a `Teleop.msg` file in your `my_teleop_pkg\/msg` directory. Here&#8217;s an example:\n<pre><code># my_teleop_pkg\/msg\/Teleop.msg\nfloat64 linear_velocity\nfloat64 angular_velocity<\/code><\/pre>\n<\/li>\n<li><strong>Update `package.xml`:<\/strong> Add the necessary dependencies to your `package.xml` file:\n<pre><code> &lt;buildtool_depend&gt;ament_cmake&lt;\/buildtool_depend&gt;\n  &lt;build_depend&gt;rosidl_default_generators&lt;\/build_depend&gt;\n  &lt;exec_depend&gt;rosidl_default_runtime&lt;\/exec_depend&gt;\n  &lt;member_of_group&gt;rosidl_interface_files&lt;\/member_of_group&gt;<\/code><\/pre>\n<\/li>\n<li><strong>Update `CMakeLists.txt`:<\/strong> Configure CMake to generate the message interfaces:\n<pre><code>find_package(rosidl_default_generators REQUIRED)\n\nrosidl_generate_interfaces(${PROJECT_NAME}\n  \"msg\/Teleop.msg\"\n  DEPENDENCIES geometry_msgs\n)<\/code><\/pre>\n<\/li>\n<li><strong>Build the Package:<\/strong>  From your workspace root, build the package:\n<pre><code>colcon build<\/code><\/pre>\n<\/li>\n<li><strong>Source the Workspace Again:<\/strong> Don&#8217;t forget to source the workspace after building.\n<pre><code>source install\/setup.bash<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>Writing the Teleoperation Node (Python)<\/h2>\n<p>Now, let&#8217;s create a Python node that reads keyboard input and publishes the teleoperation commands using our custom message type.<\/p>\n<ul>\n<li><strong>Create the Python Script:<\/strong> Create a file named `teleop_node.py` in the `my_teleop_pkg\/my_teleop_pkg` directory.<\/li>\n<li><strong>Implement the Node:<\/strong> Here&#8217;s a sample script:\n<pre><code class=\"language-python\"># my_teleop_pkg\/my_teleop_pkg\/teleop_node.py\nimport rclpy\nfrom rclpy.node import Node\nfrom my_teleop_pkg.msg import Teleop\nimport sys\n\nclass TeleopNode(Node):\n    def __init__(self):\n        super().__init__('teleop_node')\n        self.publisher_ = self.create_publisher(Teleop, 'teleop_commands', 10)\n        timer_period = 0.1  # seconds\n        self.timer = self.create_timer(timer_period, self.timer_callback)\n        self.linear_velocity = 0.0\n        self.angular_velocity = 0.0\n\n    def timer_callback(self):\n        msg = Teleop()\n        msg.linear_velocity = self.linear_velocity\n        msg.angular_velocity = self.angular_velocity\n        self.publisher_.publish(msg)\n        #self.get_logger().info('Publishing: Linear: %f, Angular: %f' % (msg.linear_velocity, msg.angular_velocity))\n\n\ndef main(args=None):\n    rclpy.init(args=args)\n    teleop_node = TeleopNode()\n\n    print(\"Use 'w', 'a', 's', 'd' to control the robot.\")\n    print(\"Press 'q' to quit.\")\n\n    try:\n        while rclpy.ok():\n            rclpy.spin_once(teleop_node)\n            char = input(\"Enter command: \")\n            if char == 'w':\n                teleop_node.linear_velocity = 0.5\n                teleop_node.angular_velocity = 0.0\n            elif char == 's':\n                teleop_node.linear_velocity = -0.5\n                teleop_node.angular_velocity = 0.0\n            elif char == 'a':\n                teleop_node.linear_velocity = 0.0\n                teleop_node.angular_velocity = 0.5\n            elif char == 'd':\n                teleop_node.linear_velocity = 0.0\n                teleop_node.angular_velocity = -0.5\n            elif char == 'q':\n                break\n            else:\n                teleop_node.linear_velocity = 0.0\n                teleop_node.angular_velocity = 0.0\n\n\n    except KeyboardInterrupt:\n        pass\n\n    teleop_node.destroy_node()\n    rclpy.shutdown()\n\n\nif __name__ == '__main__':\n    main()\n<\/code><\/pre>\n<\/li>\n<li><strong>Make the Script Executable:<\/strong>\n<pre><code>chmod +x my_teleop_pkg\/my_teleop_pkg\/teleop_node.py<\/code><\/pre>\n<\/li>\n<li><strong>Update `setup.py`:<\/strong> Add the script to the entry points in `setup.py`:\n<pre><code class=\"language-python\">entry_points={\n        'console_scripts': [\n            'teleop_node = my_teleop_pkg.teleop_node:main',\n        ],\n    },<\/code><\/pre>\n<\/li>\n<li><strong>Rebuild the Package:<\/strong>\n<pre><code>colcon build<\/code><\/pre>\n<\/li>\n<li><strong>Source the Workspace Again:<\/strong>\n<pre><code>source install\/setup.bash<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>Creating a Robot Control Node (Python)<\/h2>\n<p>This node subscribes to the `teleop_commands` topic and controls the robot&#8217;s movement based on the received commands. For simplicity, we&#8217;ll simulate robot control by printing the received velocities.<\/p>\n<ul>\n<li><strong>Create the Python Script:<\/strong> Create a file named `robot_control_node.py` in the `my_teleop_pkg\/my_teleop_pkg` directory.<\/li>\n<li><strong>Implement the Node:<\/strong> Here&#8217;s a sample script:\n<pre><code class=\"language-python\"># my_teleop_pkg\/my_teleop_pkg\/robot_control_node.py\nimport rclpy\nfrom rclpy.node import Node\nfrom my_teleop_pkg.msg import Teleop\n\nclass RobotControlNode(Node):\n    def __init__(self):\n        super().__init__('robot_control_node')\n        self.subscription = self.create_subscription(\n            Teleop,\n            'teleop_commands',\n            self.listener_callback,\n            10)\n        self.subscription  # prevent unused variable warning\n\n    def listener_callback(self, msg):\n        self.get_logger().info('Received: Linear: %f, Angular: %f' % (msg.linear_velocity, msg.angular_velocity))\n        # Here, you would implement the actual robot control logic\n        # For example, send commands to motors based on msg.linear_velocity and msg.angular_velocity\n\n\ndef main(args=None):\n    rclpy.init(args=args)\n    robot_control_node = RobotControlNode()\n    rclpy.spin(robot_control_node)\n    robot_control_node.destroy_node()\n    rclpy.shutdown()\n\nif __name__ == '__main__':\n    main()\n<\/code><\/pre>\n<\/li>\n<li><strong>Make the Script Executable:<\/strong>\n<pre><code>chmod +x my_teleop_pkg\/my_teleop_pkg\/robot_control_node.py<\/code><\/pre>\n<\/li>\n<li><strong>Update `setup.py`:<\/strong> Add the script to the entry points in `setup.py`:\n<pre><code class=\"language-python\">entry_points={\n        'console_scripts': [\n            'teleop_node = my_teleop_pkg.teleop_node:main',\n            'robot_control_node = my_teleop_pkg.robot_control_node:main',\n        ],\n    },<\/code><\/pre>\n<\/li>\n<li><strong>Rebuild the Package:<\/strong>\n<pre><code>colcon build<\/code><\/pre>\n<\/li>\n<li><strong>Source the Workspace Again:<\/strong>\n<pre><code>source install\/setup.bash<\/code><\/pre>\n<\/li>\n<\/ul>\n<h2>Testing the Teleoperation System \u2705<\/h2>\n<p>Finally, let&#8217;s test our <strong>ROS 2 Teleoperation System<\/strong>. Launch the robot control node in one terminal and the teleoperation node in another. Use the keyboard to send commands and observe the output in the robot control node&#8217;s terminal.<\/p>\n<ul>\n<li><strong>Launch Robot Control Node:<\/strong>\n<pre><code>ros2 run my_teleop_pkg robot_control_node<\/code><\/pre>\n<\/li>\n<li><strong>Launch Teleoperation Node:<\/strong>\n<pre><code>ros2 run my_teleop_pkg teleop_node<\/code><\/pre>\n<\/li>\n<li><strong>Control with Keyboard:<\/strong> In the teleoperation node&#8217;s terminal, use &#8216;w&#8217;, &#8216;a&#8217;, &#8216;s&#8217;, &#8216;d&#8217; to control the robot (simulated in this case), and &#8216;q&#8217; to quit.<\/li>\n<li><strong>Observe Output:<\/strong> Observe the output in the robot control node&#8217;s terminal. It should print the received linear and angular velocities based on your keyboard inputs.<\/li>\n<\/ul>\n<h2>FAQ \u2753<\/h2>\n<h3>Q: What is ROS 2 and why should I use it for robotics?<\/h3>\n<p>ROS 2 (Robot Operating System 2) is a flexible framework for writing robot software. It provides tools and libraries for hardware abstraction, device drivers, communication between processes, and much more.  Using ROS 2 simplifies the development of complex robotic systems by providing a standardized platform and a rich ecosystem of packages. ROS 2 is used by researchers and professionals alike to build everything from autonomous vehicles to industrial robots.<\/p>\n<h3>Q: What if I encounter errors during the installation or build process?<\/h3>\n<p>Errors during installation or building can be frustrating, but they are often easily resolved.  Double-check that you have followed the instructions carefully, particularly regarding dependencies and environment setup. Consult the ROS 2 documentation and online forums for solutions to common errors.  Ensure you source the ROS 2 workspace every time you open a new terminal and before running any ROS 2 commands.<\/p>\n<h3>Q: How can I extend this simple teleoperation system to control a real robot?<\/h3>\n<p>To control a real robot, you would replace the simulated robot control logic in the `robot_control_node.py` with code that interfaces with the robot&#8217;s hardware. This typically involves using robot-specific drivers and libraries to send commands to the robot&#8217;s motors or actuators. You would need to adapt the message types and control algorithms to match the specific requirements of your robot.<\/p>\n<h2>Conclusion<\/h2>\n<p>Congratulations! \ud83c\udf89 You&#8217;ve successfully built a simple <strong>ROS 2 Teleoperation System<\/strong>. This tutorial provided a foundational understanding of ROS 2 concepts and practical experience in creating a remote control system. By defining custom message types, implementing Python nodes, and understanding the communication flow, you&#8217;ve taken a significant step towards mastering ROS 2 for robotics applications. This knowledge can be applied to more complex projects, like controlling robots in DoHost data centers for remote maintenance or creating immersive remote-controlled vehicles. Keep experimenting, and you&#8217;ll be amazed at what you can achieve! \ud83d\udcc8<\/p>\n<h3>Tags<\/h3>\n<p>    ROS 2, teleoperation, robotics, Python, robot control<\/p>\n<h3>Meta Description<\/h3>\n<p>    Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Creating a Simple Teleoperation System with ROS 2 \ud83c\udfaf Ever dreamed of controlling a robot from afar? \u2728 With the Robot Operating System (ROS) 2, that dream can become a reality! This tutorial will guide you through building a simple ROS 2 Teleoperation System, allowing you to remotely control a robot&#8217;s movements. We&#8217;ll cover everything [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6401],"tags":[6517,12,6516,1424,1420,1033,6493,6497,6494,6515],"class_list":["post-1672","post","type-post","status-publish","format-standard","hentry","category-robotics","tag-message-types","tag-python","tag-remote-control","tag-robot-control","tag-robot-operating-system","tag-robotics","tag-ros-2","tag-ros-2-nodes","tag-ros-2-tutorial","tag-teleoperation"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.0 (Yoast SEO v25.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Creating a Simple Teleoperation System with ROS 2 - Developers Heaven<\/title>\n<meta name=\"description\" content=\"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating a Simple Teleoperation System with ROS 2\" \/>\n<meta property=\"og:description\" content=\"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/\" \/>\n<meta property=\"og:site_name\" content=\"Developers Heaven\" \/>\n<meta property=\"article:published_time\" content=\"2025-08-12T06:59:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/via.placeholder.com\/600x400?text=Creating+a+Simple+Teleoperation+System+with+ROS+2\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/\",\"url\":\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/\",\"name\":\"Creating a Simple Teleoperation System with ROS 2 - Developers Heaven\",\"isPartOf\":{\"@id\":\"https:\/\/developers-heaven.net\/blog\/#website\"},\"datePublished\":\"2025-08-12T06:59:43+00:00\",\"author\":{\"@id\":\"\"},\"description\":\"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.\",\"breadcrumb\":{\"@id\":\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/developers-heaven.net\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating a Simple Teleoperation System with ROS 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/developers-heaven.net\/blog\/#website\",\"url\":\"https:\/\/developers-heaven.net\/blog\/\",\"name\":\"Developers Heaven\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/developers-heaven.net\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Creating a Simple Teleoperation System with ROS 2 - Developers Heaven","description":"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/","og_locale":"en_US","og_type":"article","og_title":"Creating a Simple Teleoperation System with ROS 2","og_description":"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.","og_url":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/","og_site_name":"Developers Heaven","article_published_time":"2025-08-12T06:59:43+00:00","og_image":[{"url":"https:\/\/via.placeholder.com\/600x400?text=Creating+a+Simple+Teleoperation+System+with+ROS+2","type":"","width":"","height":""}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/","url":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/","name":"Creating a Simple Teleoperation System with ROS 2 - Developers Heaven","isPartOf":{"@id":"https:\/\/developers-heaven.net\/blog\/#website"},"datePublished":"2025-08-12T06:59:43+00:00","author":{"@id":""},"description":"Build a simple teleoperation system with ROS 2! Learn how to control robots remotely using Python, ROS 2 nodes, and custom message types.","breadcrumb":{"@id":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/developers-heaven.net\/blog\/creating-a-simple-teleoperation-system-with-ros-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/developers-heaven.net\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating a Simple Teleoperation System with ROS 2"}]},{"@type":"WebSite","@id":"https:\/\/developers-heaven.net\/blog\/#website","url":"https:\/\/developers-heaven.net\/blog\/","name":"Developers Heaven","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/developers-heaven.net\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/posts\/1672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/comments?post=1672"}],"version-history":[{"count":0,"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/posts\/1672\/revisions"}],"wp:attachment":[{"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/media?parent=1672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/categories?post=1672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/developers-heaven.net\/blog\/wp-json\/wp\/v2\/tags?post=1672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}