Ubuntu 20.04 ROS2 Foxy Install Tutorial

Ubuntu 20.04 ROS2 Foxy Install Tutorial

What we are going to learn:

Installing ROS 2 Foxy on Ubuntu 20.04.

Prerequisites:

Ubuntu 20.04 installed on your computer.

I install ROS 2 Foxy in Docker images, but It is similar at Local Ubuntu, too
If you are using the Ubuntu 20.04 image in a Docker environment, nothing will be installed.
In this case, you can go through several steps for initial setup and then install by following the ROS2 Foxy Install Document above.

If you want to learn more about ROS 2 and dive deeper into robotics, check out the Robotics Developer Masterclass, where you’ll master robotics development from scratch and get 100% job-ready to work at robotics companies.

 

1. Initial Setup:

 

If you’re using the Ubuntu 20.04 image in a Docker environment, run the following commands for initial setup:
apt update
apt install sudo

For local installations, skip this step if sudo is already installed.

If sudo (Super User do) is installed, proceed according to the Document.
I used this link to install ros2 foxy : https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html#install-ros-2-packages

Proceeding through all steps in order is the fastest way to install without errors.

2. Setting Locale to UTF-8:

locale # check for UTF-8

sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

locale # verify settings

3. After confirming UTF-8 with the locale command, proceed with environment settings.

1. Ubuntu Universe repository enable
sudo apt install software-properties-common
sudo add-apt-repository universe

2. add ROS 2 GPG key
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

3. add repository to sources list
echo “deb [arch=$(dpkg –print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main” | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

4. Installing ROS2 Package :
sudo apt update
sudo apt upgrade

Here is really Important step, Binary Install Ros2 foxy. This is not by Source file. I will take more than 10 minutes.
Desktop Install (Recommended): ROS, RViz, demos, tutorials.
sudo apt install ros-foxy-desktop python3-argcomplete

ROS-Base Install (Bare Bones): Communication libraries, message packages, command line tools. No GUI tools.
sudo apt install ros-foxy-ros-base python3-argcomplete

Install Development tools
sudo apt install ros-dev-tools

If you clear all the step, You can use Ros2 Foxy
use this command to check
cd /opt/ros/foxy
You can see /opt/ros/foxy folder.
If you want to check Ros2 is clearly install

4. Environment Setup:

Before Using Ros2 Foxy, You have to Environment setup.
In Document,
source /opt/ros/foxy/setup.bash
use this command, But by this way, You have to do this step all the time you close terminal.
So I recommend you write in ~/.bashrc file.

For this way, You have to install vim
sudo apt install vim

If you successfully install Vim, use this command to open ~/.bashrc
vi ~/.bashrc

You can see the file that write a lot of command, at the end of the file, Input i to change insert mode and write
source /opt/ros/foxy/setup.bash

then use :wq command, save the file.
And use this command to source ~/.bashrc file
source ~/.bashrc
Then You can use ROS2 Foxy, Without working on the source every time

 

5. Verification: To verify a successful installation, run an example:

Now, finally, we can check whether ROS2 is installed properly through one example.

You have to run two terminal.
At one terminal
ros2 run demo_nodes_cpp talker

another Terminal
ros2 run demo_nodes_py listener

You can see that messages are exchanged and the same result is shown. If this example runs well, you have performed a clean installation of ROS2 Foxy. Now you can freely use ROS2 Foxy.

To ensure stability, I’ll guide you through installing ROS2 Foxy on your Ubuntu 20.04 system. If you prefer watching a detailed video tutorial (in Korean), you can check this video below.

Video Tutorial (Korean)

How to manipulate parameters at runtime | ROS2 Humble Python Tutorial

How to manipulate parameters at runtime | ROS2 Humble Python Tutorial

What you will learn:

How to manipulate multiple parameters in ROS2 from the command line using parameter services

Overview

Parameters in ROS 2 can be get, set, listed, and described through a set of services for nodes that are already running. In fact, the well-known and convenient ros2 param command-line tool is a wrapper around these service calls that makes it easy to manipulate parameters from the command-line.

In this tutorial, you will learn how to manipulate multiple parameters in ROS2 from the command line using parameter services rather than ros2 param commands which can only work with one parameter at a time. You will get an introduction to using all of the parameter services via the CLI, not just SetParameters:

  • srv/GetParameterTypes
  • srv/DescribeParameters
  • srv/SetParametersAtomically
  • srv/GetParameters
  • srv/ListParameters
  • srv/SetParameters

Prerequisite:

  • Basic understanding of parameters
  • Familiarity with using the ros2 param command-line tool
  • Basic knowledge of services

If you want to learn more advanced ROS 2 topics, including parameters and more, in a practical, hands-on way, check out the course Intermediate ROS 2: https://app.theconstruct.ai/courses/113

Opening the rosject

In order to follow this tutorial, we need to have ROS2 installed in our system, and ideally a ros2_ws (ROS2 Workspace). To make your life easier, we have already prepared a rosject for that: https://app.theconstruct.ai/l/6111a6de/

Just by copying the rosject (clicking the link above), you will have a setup already prepared for you.

After the rosject has been successfully copied to your own area, you should see a Run button. Just click that button to launch the rosject.

After pressing the Run button, you should have the rosject loaded. Now, let’s head to the next section to get some real practice.

In order to interact with ROS2, we need a terminal.

Let’s open a terminal by clicking the Open a new terminal button.

Open a new Terminal

Create a ROS2 python package with a simple node that has two parameters

Create a python package called python_parameters:

cd ~/ros2_ws/src/
ros2 pkg create --build-type ament_python python_parameters --dependencies rclpy

Create a python node called python_parameters_node.py:

touch python_parameters/python_parameters/python_parameters_node.py

Here is a simple node with two parameters of type string (to paste in python_parameters_node.py):

  • The parameters are:
    • my_parameter with value me and description This parameter is mine!
    • your_parameter with value you and description This parameter is yours!

    You can also have other types as listed in the documentation.

  • The node has a timer callback with a period of 1 second just to log what the current parameters are.
import rclpy
import rclpy.node
from rcl_interfaces.msg import ParameterDescriptor

class MinimalParam(rclpy.node.Node):
    def __init__(self):
        super().__init__('minimal_param_node')
        
        my_parameter_descriptor = ParameterDescriptor(description='This parameter is mine!')
        self.declare_parameter('my_parameter', 'me', my_parameter_descriptor)

        your_parameter_descriptor = ParameterDescriptor(description='This parameter is yours!')
        self.declare_parameter('your_parameter', 'you', your_parameter_descriptor)

        self.timer = self.create_timer(1, self.timer_callback)

    def timer_callback(self):
        my_param = self.get_parameter('my_parameter').get_parameter_value().string_value

        self.get_logger().info('I am %s!' % my_param)

        your_param = self.get_parameter('your_parameter').get_parameter_value().string_value

        self.get_logger().info('You are %s!' % your_param)

def main():
    rclpy.init()
    node = MinimalParam()
    rclpy.spin(node)

if __name__ == '__main__':
    main()

Configure the package and test

Modify setup.py

State the entry point:

    entry_points={
        'console_scripts': [
            'minimal_param_node = python_parameters.python_parameters_node:main',
        ],
    },

Compile the package

cd ~/ros2_ws/
colcon build --packages-select python_parameters

Run the node

In one terminal, start the node:

source ~/ros2_ws/install/setup.bash
ros2 run python_parameters minimal_param_node

You should get something like this:

[INFO] [1713695285.349594469] [minimal_param_node]: I am me!
[INFO] [1713695285.349875641] [minimal_param_node]: You are you!
[INFO] [1713695286.337758113] [minimal_param_node]: I am me!
[INFO] [1713695286.338776447] [minimal_param_node]: You are you!
[INFO] [1713695287.337323765] [minimal_param_node]: I am me!
[INFO] [1713695287.338010397] [minimal_param_node]: You are you!

Setting a parameter using ros2 param set

In a different terminal, get a list of all parameters:

ros2 param list

You should see both my_parameter and your_parameter in the output:

/minimal_param_node:
  my_parameter
  use_sim_time
  your_parameter

The usual way to set parameters dynamically during runtime is to use the ros2 param set. For example we can modify the value of your_parameter to be 'a student':

ros2 param set /minimal_param_node your_parameter 'a student'

You can see that the value of your_parameter has changed:

[INFO] [1713695285.349594469] [minimal_param_node]: I am me!
[INFO] [1713695285.349875641] [minimal_param_node]: You are a student!
[INFO] [1713695286.337758113] [minimal_param_node]: I am me!
[INFO] [1713695286.338776447] [minimal_param_node]: You are a student!
[INFO] [1713695287.337323765] [minimal_param_node]: I am me!
[INFO] [1713695287.338010397] [minimal_param_node]: You are a student!

However if you want to set multiple parameters at once, you need to use the SetParameters service as shown in the following section.

Setting multiple parameters using SetParameters service type

Kill and restart the node to reset the parameter values before continuing onto this section.

Begin by listing all active services along with their types:

ros2 service list -t

You should see 6 services including the one that we need named /minimal_param_node/set_parameters with type rcl_interfaces/srv/SetParameters:

/minimal_param_node/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/minimal_param_node/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/minimal_param_node/get_parameters [rcl_interfaces/srv/GetParameters]
/minimal_param_node/list_parameters [rcl_interfaces/srv/ListParameters]
/minimal_param_node/set_parameters [rcl_interfaces/srv/SetParameters]
/minimal_param_node/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]

Then determine the request message fields by looking at the documentation or running this:

ros2 interface show rcl_interfaces/srv/SetParameters

The result is this:

# A list of parameters to set.
Parameter[] parameters
        string name
        ParameterValue value
                uint8 type
                bool bool_value
                int64 integer_value
                float64 double_value
                string string_value
                byte[] byte_array_value
                bool[] bool_array_value
                int64[] integer_array_value
                float64[] double_array_value
                string[] string_array_value

---
# Indicates whether setting each parameter succeeded or not and why.
SetParametersResult[] results
        bool successful
        string reason

This means we need to send a list of parameters each with a name and value. So our service call should look something like this:

ros2 service call /minimal_param_node/set_parameters rcl_interfaces/srv/SetParameters "{parameters: [{name: 'my_parameter', value: {type: 4, string_value: 'a teacher'}}, {name: 'your_parameter', value: {type: 4, string_value: 'a student'}}]}"

Here, we want to set the my_parameter value to ‘a teacher’ and the your_parameter value to ‘a student’. Note that each value contains a type that we specify using an enumerator integer. In this case, we used 4 to specify the type as a string.

As a result of running the service call, the terminal running the node should look like this

[INFO] [1713695815.623062990] [minimal_param_node]: I am a teacher!
[INFO] [1713695815.623966588] [minimal_param_node]: You are a student!
[INFO] [1713695816.623087905] [minimal_param_node]: I am a teacher!
[INFO] [1713695816.624100118] [minimal_param_node]: You are a student!
[INFO] [1713695817.622963432] [minimal_param_node]: I am a teacher!
[INFO] [1713695817.623739529] [minimal_param_node]: You are a student!

Note that this service only modifies parameters that succeed in being set. For example if you give an incorrect type, then it will not be modified. In the following service call, my_parameter is specified incorrectly as an integer type using 2, whilst your_parameter is correctly specified as a string. Kill and restart the node first to reset the parameter values before running:

ros2 service call /minimal_param_node/set_parameters rcl_interfaces/srv/SetParameters "{parameters: [{name: 'my_parameter', value: {type: 2, string_value: 'a teacher'}}, {name: 'your_parameter', value: {type: 4, string_value: 'a student'}}]}"

As you can see, only your_parameter has changed:

[INFO] [1713748978.412585151] [minimal_param_node]: I am me!
[INFO] [1713748978.413301978] [minimal_param_node]: You are a student!
[INFO] [1713748979.413749236] [minimal_param_node]: I am me!
[INFO] [1713748979.414882976] [minimal_param_node]: You are a student!
[INFO] [1713748980.413437082] [minimal_param_node]: I am me!
[INFO] [1713748980.414682416] [minimal_param_node]: You are a student!

Calling other parameter services

Kill and restart the node to reset the parameter values before continuing onto this section.

SetParametersAtomically

This attempts to set the given list of parameter values just like SetParameters. However if any parameter fails to be set, then none of them are set.

  • Sending the same request from before where my_parameter was set to the wrong type results in none of the parameters being modified.
ros2 service call /minimal_param_node/set_parameters_atomically rcl_interfaces/srv/SetParametersAtomically "{parameters: [{name: 'my_parameter', value: {type: 2, string_value: 'a teacher'}}, {name: 'your_parameter', value: {type: 4, string_value: 'a student'}}]}"
  • This service call (where both types are correct) successfully sets both values.
ros2 service call /minimal_param_node/set_parameters_atomically rcl_interfaces/srv/SetParametersAtomically "{parameters: [{name: 'my_parameter', value: {type: 4, string_value: 'a teacher'}}, {name: 'your_parameter', value: {type: 4, string_value: 'a student'}}]}"

GetParameters

This service call returns a list of parameter values.

ros2 service call /minimal_param_node/get_parameters rcl_interfaces/srv/GetParameters "{names: ['my_parameter', 'your_parameter']}"

GetParameterTypes

This service call returns a list of parameter types.

ros2 service call /minimal_param_node/get_parameter_types rcl_interfaces/srv/GetParameterTypes "{names: ['my_parameter', 'your_parameter']}"

DescribeParameters

This service call returns a list of parameter descriptors.

ros2 service call /minimal_param_node/describe_parameters rcl_interfaces/srv/DescribeParameters "{names: ['my_parameter', 'your_parameter']}"

ListParameters

This service call returns a list of available parameters given an optional list of parameter prefixes. In this case it returns a list of all parameters starting with ‘my’ and ‘your’.

ros2 service call /minimal_param_node/list_parameters rcl_interfaces/srv/ListParameters "{prefixes: ['my', 'your']}"

Now you know how to manipulate parameters at runtime

Congratulations. You now have a basic understanding of parameters.

To learn more advanced topics about ROS 2, have a look at the course below:

We hope this post was really helpful to you.

This tutorial is created by Robotics Ambassador Ernest.

Video Tutorial

ROS2 Service Interface: Paggawa ng Service Server – Filipino ROS2 Tutorial

ROS2 Service Interface: Paggawa ng Service Server – Filipino ROS2 Tutorial

This tutorial is created by Robotics Ambassador 019 Christian

Robotics Ambassador: theconstruct.ai/robotics-ambassador/



Unit 1 Introduksyon sa Kurso

– Buod –

Tinatayang Oras na Kakailanganin: 30 minuto

Mabuhay!

Sa maikling gabay na ito, ating dadaluban nang pahapyaw ang konsepto ng ROS2 Services at kung paano gumawa ng Service Server.

Bilang gabay sa mga tatalakayin ng proyektong ito, sila ay nakalista bilang mga sumusunod:

1. Introduksyon sa Kurso
2. Pagpapahayag ng Konsepto ng ROS2 Services
3. Paglikha at Paggamit ng ROS2 Service sa Pamamagitan ng Isang Service Server

– Dulo ng Buod –

Unit 1.1 Mga Pangangailangan sa Kurso at mga Sanggunian

Para sa kursong ito, tinataya ng may-akda na may kaalaman ka na sa pangunahing operasyong pang-terminal ng mga sistemang gumagana sa Ubuntu 22.04 LTS na OS at maging sa pangunahing nabigasyon and commands na ginagamit sa mga Linux terminals. Kung nais mo pang matuto ng mga programming fundamentals na kailangan para sa pag-aral ng ROS, mangyaring tumungo at tignan ang kursong Code Foundation for ROS Learning Path ng The Construct! Tiyak na matututunan mo ang lahat ng kailangan mong kaalaman upang masimulan mo na ang paggamit ng ROS!

Mga Akdang Kasama sa Code Foundation for ROS Learning Path:
a. Linux for Robotics
b. Python 3 for Robotics
c. Examination

Iba pang mga Sanggunian:
* The Construct Blog
* Course Support of The Construct and Robot Ignite Academy
* The Official Rosbotics Ambassadors Channel

Kung nais mong matuto hinggil sa kung paano gumawa at mag-ayos ng workspace directories sa ROS1 at ROs2, maaari mong tignan ang aking nakarrang gabay na ito: How to Create and Organize Workspaces in ROS1 and ROS2

At kung interesado ka na rin sa kung paano gumawa ng mga packages at nodes sa ROS2, mangyaring tignan mo na rin ang gabay na ito: How to Create Packages and Nodes in ROS2

Sa tutorial na ito, Gagamitin natin ang ROSject platform na handog ng TheConstruct! Subalit, kung nais niyong gumamit ng sariling virtual machine o computer, mangyaring gawing gabay ang OS-to-Distribution compatibilities na siyang ibinahagi ng opisyal na dokumentasyon ng ros.org para sa ROS2 Humble Hawksbill

* ROS2 Humble Hawksbill: PC o Virtual Machine na may Ubuntu 22.04 LTS

Unit 2: ROS2 Services

Noong nakaraan, ating tinalakay ang kalikasan ng iba’t-ibang interfaces na maaari nating gamitin sa ROS2, partikular na ang mga mesages. Ngayon, atin namang tatalakayin ang konsepto ng mga Services!

Bilang panguna, ano nga ba ang mga ROS2 Services?

Kung ating aalalahanin, ang mga ROS2 messages ay naglalaman lamang ng isang lipon ng mga variable na maaari nating gamitin para sa ugnayang publisher-subscriber. At dahil sa ganitong istruktura, masasabing unidirectional lamang ang nagaganap na komunikasyon. Ang kahulugan nito ay walang interaksyon o feedback mechanism na nagaganap sa pagitan ng mga nodes. Ngayon, ang services naman ay siyang nagtataglay ng dalawang pangunahing fields — ang request at response.

Ang request field ay siyang lipon ng mga variable na, mula sa client, ay kukunin ng isang server mula sa isang service, at siyang gagamitin upang makapgpabalik ng tinatawag na response. Maaari natin itong ihalintulad sa proseso ng pagtala natin ng order mula sa isang kainan. Tayo ang nagsisilbing mga client, ang mga staff ang silang itinuturing na service, at ang kainan naman ang mismong server. Bale, magpapadala tayo ng ating request — depende sa kung ano ang ating nais na kainin (request)– at ito naman ay ipapadala sa kusina (server) sa pamamagitan ng mga staff (service), at pagtapos nang lutuin ay siyang ibibigay sa atin (response).

Kung ating ihahalintulad ang arkitektura nito sa ugnayang publisher-subscriber, maituturing nating katimbang ng publisher ang service client na siyang nagpapadala ng mga message. At maituturing nating kahalintulad ng /topic ang /service na siyang nagsisilbing channel upang mapadala at matanggap ang mga ito. Ang pinakamalaking pinagkaiba lamang sa konteksto ng client-server na ugnayan ay ang pagkakaroon ng tinatawag na response. Sa publisher-subscriber, matapos na matanggap ng subscriber ang message mula sa topic, wala na itong ibinabalik na value para sa node na nagpadala ng naturang halaga na iyon; subalit, para naman sa client-server na ugnayan, magpapadala ng request ang client at ibabalik naman ng server ang response.

Ngayon at malinaw na sa atin ang konsepto ng Services at ang Client-Server na uganayan, halina’t gumawa tayo ng Server!

Unit 3: Paglikha at Paggamit ng ROS2 Service sa Pamamagitan ng Isang Service Server

1. Lumikha ng Workspaces folder na siyang maglalaman ng lahat ng ating workspaces

# In Terminal 1
user@user:~$ mkdir Workspaces

2. Sa loob nito, gumawa ng ating workspace folder – ros2_ws – at sa loob ng workspace folder na ito, gumawa ng isa pang ‘src’ folder na siyang maglalaman ng ating package na siyang papangalanang ‘simple_adder’

# In Terminal 1
user@user:~$ cd Workspaces
user@user:~/Workspaces$ mkdir ros2_ws
user@user:~/Workspaces$ cd ros2_ws 
user@user:~/Workspaces/ros2_ws$ mkdir src
user@user:~/Workspaces/ros2_ws$ cd src
user@user:~/Workspaces/ros2_ws/src$ ros2 pkg create simple_adder --build-type ament_python --dependencies rclpy std_msgs example_interfaces

3. Buuin ang naturang workspace

user@user:~/Workspaces/ros2_ws$ colcon build

4. Sa loob nito, gawin natin ang ating server file – simple_adder_server.py – at gawin itong executable

user@user:~/Workspaces/ros2_ws$ cd src/simple_adder/simple_adder
user@user:~/Workspaces/ros2_ws/src/simple_adder/simple_adder$ touch simple_adder_server.py
user@user:~/Workspaces/ros2_ws/src/simple_adder/simple_adder$ chmod +x simple_adder_server.py

5. Source Code para sa simple_adder_server.py

#!/usr/bin/env python3

# Import necessary libraries | I-import ang mga kinakailangang library
import rclpy
from rclpy.node import Node
from example_interfaces.srv import AddTwoInts

class SimpleAdderNode(Node):
    def __init__(self):
        super().__init__("simple_adder")
        
        # Likhain ang server
        self.server_ = self.create_service(AddTwoInts, "add_ints_service", self.callback_add_ints_service)
        
        # Gumawa ng logger upang malaman kung gumagana na ang server
        self.get_logger().info("Add Ints Server Currently Active!")
        
    # Ilikha ang callback para sa ginawang server. Dito mangyayari ang pagproproseso ng requests upang makapagpadala ng response
    def callback_add_ints_service(self, request, response):
        response.sum = request.a + request.b
        self.get_logger().info("The sum of "+str(request.a)+" and "+str(request.b)+" is "+str(response.sum))
        
        return response

def main(args=None):
    rclpy.init(args=args)
    node = SimpleAdderNode()
    rclpy.spin(node)
    rclpy.shutdown()

if __name__=="__main__":
    main()

6. I-install ang node sa loob ng setup.py

# Hanapin ang console scripts sa ilalim ng setup.py at idagdag ang mga ito:
"simple_adder_server=simple_adder.simpler_adder_server:main"

7. Muling buuin ang package

user@user:~/Workspaces/ros2_ws/src/simple_adder/simple_adder$ cd ../../../
user@user:~/Workspaces/ros2_ws$ colcon build --packages-select simple_adder --symlink-install

8. I-source ang workspace

user@user:~/Workspaces/ros2_ws$ source install/setup.bash

9. Patakbuhin ang Node

user@user:~/Workspaces/ros2_ws$ ros2 run simply_adder simple_adder_server

10. Sa isa pang terminal, i-source ang install/setup.bash ng naturang workspace

user@user:~$ cd Workspaces/ros2_ws
user@user:~/Workspaces/ros2_ws$ source install/setup.bash

11. Tawagin ang naturang server

user@user:~/Workspaces/ros2_ws$ ros2 service call add_ints_server example_interfaces/srv/AddTwoInts "{a: 5, b: 10}"

At ayan! Matagumpay tayong nakalikha ng Service Server at matawag ang service nito! Kapag tapos ka nang magsiyasat, maaarin mong pindutin ang “ctrl + c” upang patayin na ang naturang node. At diyan nagtatapos ang ating maikling gabay hinggil sa paggawa ng custom messages! Nawa’y may natutunan kayong bago na makatutulong sa inyong pag-aaral ng ROS!

Para sa iba pang mga ROSject na tulad nito, mangyaring bisitahin ang The Construct. Nag-aalok sila ng napakaraming praktikal na mga gabay sa ROS mula sa mga payak hanggang sa mga konseptong pangbihasa na!

Hanggang sa muli! Ito si Christian C. Anabeza, ang inyong FIlipino Robotics Ambassador!

Video Tutorial

Comment utiliser ROSlibjs avec ROS2 – French ROS2 Tutorial

Comment utiliser ROSlibjs avec ROS2 – French ROS2 Tutorial

This tutorial is created by Robotics Ambassador 023 Enzo

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/
Cours: ROS2 Basics in 5 Days C++: https://app.theconstructsim.com/courses/133

Dans ce tutoriel, nous allons voir comment utiliser ROSLibjs avec ROS2 pour tirer parti de la puissance de ROS dans des applications web et JavaScript. Nous allons mettre en place un exemple simple d’une page HTML utilisant ROSLibjs pour communiquer avec un système ROS2. L’objectif du tutoriel sera d’utiliser un publisher et un subscriber depuis notre page web pour interagir avec un turtlebot3 simulé dans Gazebo.

Prérequis: Utiliser une installation ROS2 avec Gazebo

ROS2

Vous pouvez vous connecter au site TheConstruct pour acceder à des machines virtuelles préconfigurées avec une installation ROS. Ce tutoriel est realisé avec ROS Humble.

Si vous voulez effectuer le tutoriel sur votre installation local, vous devez avoir ROS2 installé (https://docs.ros.org/en/humble/Installation.html), avoir configuré un workspace (https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Creating-A-Workspace/Creating-A-Workspace.html) et avoir installé le turtlebot3.

# pour installer tous les packages du turtlebot3
# remplacez humble par votre distro ROS2
cd ~/ros2_ws
colcon build
source install/setup.bash
sudo apt-get install ros-humble-turtlebot3*
# n'oubliez pas d'exporter le modèle de Turtlebot3 que vous souhaitez utiliser
export TURTLEBOT3_MODEL=waffle_pi

Nous allons ensuite lancer la simulation du turtlebot3 dans gazebo. Le turtlebot3 va publier les topics que nous allons utiliser dans le tutoriel.

Partie 1: Concepts

rosbridge_suite (https://github.com/RobotWebTools/rosbridge_suite) avec le node rosbridge-server fournit un serveur WebSocket qui donne accès aux fonctionnalités de ROS pour des programmes non-ROS. WebSocket est un protocole de communication qui permet une communication bidirectionnelle entre les clients et les serveurs à travers une connexion unique et durable. Des clients roslib ont été développés dans differents languages de programmation (Python, Rust, Java, Javascript). rosbridge_server permet donc une intégration entre ROS avec un large éventail de technologies, notamment des applications Web, des appareils mobiles, des environnements de simulation. Dans ce tutoriel nous allons apprendre à utiliser roslibjs qui permet d’interagir avec l’ecosystème ROS en utilisant Javascript. Nous allons créer ensemble une interface web simple permettant d’interagir avec un robot simulé sur Gazebo.

Partie 2: Implémentation

Nous allons dans un premier temps créer une page web index.html dans le dossier webpage_ws. Cette page web html execute du javascript pour utiliser ROSlibjs et déclarer notre publisher et notre subscriber:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ROS2 ROSLIBjs example</title>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <h1>ROS2 ROSLIBjs example</h1>
    <div class="container">

        <!-- Inputs pour publier le message Twist sur le topic cmd_vel -->
        <div>
            <label for="linearSpeed">Linear Speed:</label>
            <input type="number" id="linearSpeed" step="0.1" value="0">
            <label for="angularSpeed">Angular Speed:</label>
            <input type="number" id="angularSpeed" step="0.1" value="0">
            <!-- Appelle la fonction submitInputsTwist qui va publier un Twist message -->
            <button onclick="submitInputsTwist()">Publish Twist</button>
        </div>

        <!-- Zone de texte pour afficher les messages reçu par le subscriber d'odom -->
        <div>
            <h2>Received Odometry</h2>
            <textarea id="odometryData" readonly></textarea>
        </div>
        
        <!-- Joystick pour controler le robot en publiant sur cmd_vel -->
        <div id="joyDiv" style="width:200px;height:200px;margin-bottom:20px;"></div>
    </div>
    
    
    <!-- Pour importer roslibjs -->
    <script src="https://s3.eu-west-1.amazonaws.com/rosject.io/js/roslib.min.js"></script>

    <!-- La repository github du joystick https://github.com/bobboteck/JoyStick -->
    <script src="https://github.com/bobboteck/JoyStick/releases/download/v2.0.0/joy.min.js"></script>

    <!-- Javascript -->
    <script>

        // On déclare notre client
        var ros = new ROSLIB.Ros();

        var rosbridgeUrl = 'ws://localhost:9090'; // Remplacer localhost:9090 par l'url rosbridge_server URL (et ne pas ajouter:port)

        // Connecte au ROS2 environment
        ros.on('connection', function () {
            console.log('Connected to ROS1 environment.');
        });

        // Gérer les cas de déconnection
        ros.on('error', function (error) {
            console.error('Error connecting to ROS1 environment:', error);
        });

        ros.on('close', function () {
            console.log('Connection to ROS1 environment closed.');
        });

        // Déclare les variable qui permettent d'interagir avec les topics ROS
        var twistTopic = new ROSLIB.Topic({
            ros: ros,
            name: '/cmd_vel',
            messageType: 'geometry_msgs/Twist'
        });

        var odometryTopic = new ROSLIB.Topic({
            ros: ros,
            name: '/odom',
            messageType: 'nav_msgs/Odometry'
        });
        
        // Subscribe au topic odom et définit la fonction callback
        odometryTopic.subscribe(function (message) {
            console.log(message)
            // Change la valeur de la texte area avec le message reçu depuis le topic
            document.getElementById('odometryData').value = JSON.stringify(message, null, 2);
        });

        function publishTwist(linearSpeed, angularSpeed) {
            
            // Declare le Twist message pour pouvoir publier les valeurs en entrée de la fonction
            var twist = new ROSLIB.Message({
                linear: {
                    x: linearSpeed,
                    y: 0,
                    z: 0
                },
                angular: {
                    x: 0,
                    y: 0,
                    z: angularSpeed
                }
            });
            // Publie le Twist message sur le topic cmd_vel
            twistTopic.publish(twist);
        }

        // Connecte au ROS2 environment
        ros.connect(rosbridgeUrl);

        
        // La fonction appellée lorsque Publish Twist est cliqué
        function submitInputsTwist() {

            // Récupère les valeurs des inputs pour linearSpeed et angularSpeed
            var linearSpeed = parseFloat(document.getElementById('linearSpeed').value);
            var angularSpeed = parseFloat(document.getElementById('angularSpeed').value);
            
            publishTwist(linearSpeed, angularSpeed);
        }

        
        
        // Declare le joystick pour publier les données sur cmd_vel
        var Joy1 = new JoyStick('joyDiv', {}, function(stickData) {
            
            // Récupère les valeurs des axes du joysticks
            let angularSpeed = -stickData.x/50;
            let linearSpeed = stickData.y/50;
            
            // Declare le Twist message pour pouvoir le publier
            var twist = new ROSLIB.Message({
                linear: {
                    x: linearSpeed,
                    y: 0,
                    z: 0
                },
                angular: {
                    x: 0,
                    y: 0,
                    z: angularSpeed
                }
            });
            
            // Publie le Twist message sur le topic cmd_vel
            twistTopic.publish(twist);
        });
        
    </script>
</body>
</html>

Pour résumer le code ci-dessus:

  • On écrit notre page HTML qui va servir d’interface utilisateur.
  • Dans notre Javascript, on crée le client websocket ROSLib et on crée les fonctions qui seront appelées pour differents évenements de la websocket (connection, error, close).
  • On déclare ensuite les variables qui vont nous permettre d’interagir avec les topics.
  • On subscribe au topic /odom et on modifie la valeur du textarea odometryData dans le callback.
  • On crée la fonction publishTwist qui est appelée lorsque le bouton Publish Twist est appelé, elle permet de publier les valeurs.
  • On déclare le joystick et on appelle la fonction publishTwist pour publier sur le topic cmd_vel les valeurs des axes du joysticks.

Vous pouvez également ajouter le fichier CSS style.css:

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f5f5f5;
    color: #333;
}

h1 {
    text-align: center;
    margin-top: 20px;
}

.container {
    max-width: 600px;
    display: flex;
    flex-direction: column;
    margin: 20px auto;
    background-color: #fff;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    
    text-align: center;
}

label {
    display: inline-block;
    width: 120px;
    margin-bottom: 10px;
}

input[type="number"] {
    width: 80px;
    padding: 5px;
    border-radius: 5px;
    border: 1px solid #ccc;
    margin-right: 10px;
}

button {
    padding: 8px 16px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

textarea {
    width: 100%;
    height: 150px;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #ccc;
    resize: none;
} 

Voici le visuel de la page web:

Nous allons voir dans la partie suivante comment l’ouvrir en utilisant notre environnement de développement.

Partie 3: Tester le système

Pour tester l’interface exemple du tutoriel, vous devez dans un premier temps lancer la simulation du turtlebot3 avec la commande suivante dans un premier terminal:

export TURTLEBOT3_MODEL=waffle_pi
ros2 launch turtlebot3_gazebo turtlebot3_house.launch.py

Vous devez ensuite lancer rosbridge_server dans un second terminal:

ros2 launch rosbridge_server rosbridge_websocket_launch.xml

Les prochaines étapes sont seulement pour faire fonctionner l’exemple dans un rosject de theConstuct. Dans un nouveau terminal, vous devez lancer un server python pour hoster la page web via l’installation de theConstruct:

python3 -mhttp.server 7000

Ouvrez un terminal et lancez les commandes suivantes:

# pour obtenir l'url de la page web html
webpage_address
# pour obtenir l'adresse de la websocket fournit par l'installation theConstruct
rosbridge_address

Vous devrez utiliser l’adresse websocket rosbridge_address dans la variable rosbridgeUrl du code.

Si vous effectuez le tutoriel sur votre machine locale, vous pouvez ouvrir directement votre page html avec votre navigateur et l’adresse de la websocket ws://0.0.0.0:9090 (port par defaut utilisé par le node rosbridge_server).

Vous pouvez maintenant ouvrir l’interface créée precedemment en ouvrant le ficher index.html dans votre navigateur. Vous devriez obtenir le résultat suivant:

Dans la textarea, vous pouvez voir l’odometry du robot mis à jour à chaque message reçu. Vous devriez pouvoir également pouvoir déplacer le turtlebot3 en utilisant les textes inputs ou le joystick pour publier sur le cmd_vel.

Feedback

Cet article vous a plu ? Avez-vous des questions sur ce qui est expliqué ? Quoi qu’il en soit, n’hésitez pas à laisser un commentaire dans la section des commentaires ci-dessous, afin que nous puissions interagir et apprendre les uns des autres.

Si vous souhaitez en savoir plus sur d’autres sujets liés à ROS, faites-le nous savoir dans l’espace commentaires et nous ferons une vidéo ou un article à ce sujet.
Topics: ROS Q&A | ros2

 

Video Tutorial

لانچ فائل میں ترمیم کیسے کریں – Urdu ROS Tutorial

لانچ فائل میں ترمیم کیسے کریں – Urdu ROS Tutorial

This tutorial is created by Robotics Ambassador Awais

 

Robotics Ambassador: theconstruct.ai/robotics-ambassador/



:آپ اس ٹیوٹوریل میں کیا سیکھیں گے

  فائل پر کیسے جائیں setup.py اپنے پیکیج کی

  فائل میں ضروری ترمیم کیسے کریں setup.py اپنے پیکج کے کامیاب لانچ کے لیے

کو شامل کرنا Node key and value ڈکشنری میں Console_Scripts

 لائن کو شامل کرنا launch .py فہرست میں data_files

جائزہ

فائل پر کیسے جائیں setup.py اپنے پیکج کی

فائل پر جانا ہوگا setup.py تو آئیے اپنے مسئلے پر کام شروع کرتے ہیں۔ سب سے پہلے ہمیں اپنے پیکج کی

فائل عام طور پر ہمارے پیکج کے نام کے فولڈر میں پائی جاتی ہے

(ros2_ws/src/publisher_pkg/setup.py)

فائل میں ضروری ترمیم کیسے کریں۔ setup.py پیکج کے کامیاب لانچ کے لیے 

.کو شامل کرنا  key ‘Node’ میں dictionary “Console_Scripts”

لہذا setup.py فائل میں، آپ کو “console_scripts” میں ایک نئی value شامل کرنی ہوگی جو کہ “entry_points” نامی ڈکشنری میں ہے۔ جو کہ اس    طرح ہوگی:

“Executable_name”=”Package_name”.”Script_name”:main’

لائن کو شامل کرنا “data_files”فہرست میں “launch.py”

درج ذیل لائن کو بھی “data_files” فہرست میں شامل کریں جیسا کہ دکھایا گیا ہے۔

ماڈیولز  درآمد کرنا بھی نہ بھولیں۔ OS اور glob

فولڈر میں کمانڈ کو دوبارہ چلائیں اور غلطی ختم ہو جائے گی۔ “ros2_ws” اس کے بعد

Video Tutorial

 

Pin It on Pinterest