Desbravando espaços com o BB8 e ROS em C++ via Actions personalizadas – ROS Portuguese Tutorial

Desbravando espaços com o BB8 e ROS em C++ via Actions personalizadas – ROS Portuguese Tutorial

This tutorial is created by Robotics Ambassador Anderson

Robotics Ambassador Program https://www.theconstruct.ai/robotics-ambassador/

 

O que nós vamos aprender:

  1. Configurar e criar um pacote em ROS para um robô BB-8.
  2. Criar e configurar mensagens de Action para controlar o movimento do robô.
  3. Escrever um servidor de ações em C++ para processar os comandos recebidos.
  4. Compilar e lançar a simulação do robô BB-8 no Gazebo.
  5. Enviar comandos para o robô BB-8 via terminal e receber feedback de sua posição no espaço tridimensional.

Lista de recursos usados neste post:

  1. Use este rosject: https://app.theconstruct.ai/l/60394ad6/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS Courses: ROS Basics in 5 Days (C++) https://app.theconstructsim.com/courses/56

Panorama

Bem-vindo! Neste tutorial, iremos mergulhar nos recursos de Actions no ROS, com foco no ROS 1 Noetic e em um dos robôs mais encantadores disponíveis na plataforma: o BB-8 do universo de Star Wars. Vamos explorar como usar Actions para enviar comandos personalizados que permitem ao BB-8 executar ações específicas, como caminhar, girar e parar, em resposta a objetivos definidos. Ao longo do processo, você aprenderá a criar mensagens customizadas para interagir com o BB-8 de maneira controlada e divertida.

Abrindo o rosject

Para acompanhar este tutorial utilize o rosject acessando o link fornecido e clique no botão vermelho

https://app.theconstruct.ai/l/60394ad6/

Criando o pacote

Abra um terminal e cole os comandos abaixo para criar o pacote e os arquivos necessários para a simulação.

roscd; cd ..; cd src/bb8; catkin_create_pkg bb8_action_pkg roscpp actionlib actionlib_msgs geometry_msgs std_msgs
cd bb8_service_pkg; mkdir action;
cd action; touch CustomActionMsg.action; cd ..;
cd src; touch bb8_service_server.cpp; chmod +x *.cpp

Novos arquivos aparecerão na árvore de pastas em sua IDE.

Configurando as mensagens de Action
Mensagens de Action são compostas pelos elementos goal, result e feedback. No caso da nossa aplicação, trataremos cada um dos elementos como uma string diferente. Salve o arquivo CustomActionMsg.action incluindo o seguinte conteúdo:

string goal
---
string result
---
string feedback

Preparando para compilar

Para atualizar seu CMakeList.txt, é crucial copiar o seguinte conteúdo e colá-lo no arquivo, substituindo o que estiver presente.

cmake_minimum_required(VERSION 3.0.2)
project(bb8_action_pkg)
find_package(catkin REQUIRED COMPONENTS
actionlib
actionlib_msgs
geometry_msgs
roscpp
std_msgs
)
add_action_files(
FILES
CustomActionMsg.action
)
generate_messages(
DEPENDENCIES
geometry_msgs# std_msgs
actionlib_msgs
)
catkin_package(
CATKIN_DEPENDS actionlib actionlib_msgs roscpp
)
include_directories(
${catkin_INCLUDE_DIRS}
)
add_executable(bb8_action_server src/bb8_action_server.cpp)
add_dependencies(bb8_action_server ${bb8_action_server_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(bb8_action_server
${catkin_LIBRARIES}
)
add_dependencies(bb8_action_server bb8_action_pkg_generate_messages_cpp)

Escrevendo o servidor de ações

Agora, vamos para a etapa em que os comandos são enviados ao servidor do ações. No diretório ‘src’, abra o arquivo bb8_action_server.cpp e adicione o seguinte código.
#include "geometry_msgs/Twist.h"
#include "nav_msgs/Odometry.h"
#include <actionlib/server/simple_action_server.h>
#include <bb8_action_pkg/CustomActionMsgAction.h>
#include <ros/ros.h>
class MoveAction {
protected:
ros::NodeHandle nh_;
actionlib::SimpleActionServer<bb8_action_pkg::CustomActionMsgAction> as_;
std::string action_name_;
bb8_action_pkg::CustomActionMsgFeedback feedback_;
bb8_action_pkg::CustomActionMsgResult result_;
ros::Publisher pub;
ros::Subscriber sub;
geometry_msgs::Twist mov;
nav_msgs::Odometry odom;
ros::Rate *rate_;
public:
MoveAction(std::string name)
: as_(nh_, name, boost::bind(&MoveAction::Callback, this, _1), false),
action_name_(name) {
as_.start();
rate_ = new ros::Rate(1);
pub = nh_.advertise<geometry_msgs::Twist>("cmd_vel", 1000);
sub = nh_.subscribe("/odom", 1000, &MoveAction::odomCallback, this);
}
void Callback(const bb8_action_pkg::CustomActionMsgGoalConstPtr &goal) {
ROS_INFO("Goal received: %s", goal->goal.c_str());
while (ros::ok() && !as_.isPreemptRequested()) {
if (goal->goal == "walk") {
mov.linear.x = 0.5;
mov.angular.z = 0;
pub.publish(mov);
} else if (goal->goal == "turn") {
mov.linear.x = 0;
mov.angular.z = 1;
pub.publish(mov);
usleep(2000000);
} else if (goal->goal == "stop") {
mov.linear.x = 0;
mov.angular.z = 0;
pub.publish(mov);
}
feedback_.feedback =
"Received position: x=" + std::to_string(odom.pose.pose.position.x) +
", y=" + std::to_string(odom.pose.pose.position.y) +
", z=" + std::to_string(odom.pose.pose.position.z);
as_.publishFeedback(feedback_);
rate_->sleep();
}
if (as_.isPreemptRequested()) {
ROS_INFO("Goal preempted.");
as_.setPreempted();
} else {
ROS_INFO("Goal succeeded.");
result_.result = "Action completed.";
as_.setSucceeded(result_);
}
}
void preemptCallback() {
ROS_INFO("Goal preempted.");
as_.setPreempted();
}
void odomCallback(const nav_msgs::Odometry::ConstPtr &msg) { odom = *msg; }
};
int main(int argc, char **argv) {
ros::init(argc, argv, "node_action");
MoveAction server("action_custom_msg_as");
ros::spin();
return 0;
}

Compilando o pacote e lançando a simulação

Em um terminal, inicie o Gazebo usando o comando apropriado para visualizar o robô BB-8 pronto para operação. Isso abrirá a janela do Gazebo.

roslaunch bb_8_gazebo main.launch

No segundo terminal, execute o seguinte comando para compilar apenas o pacote que criamos. Isso economiza tempo, já que compilará apenas um pacote em vez de todos os existentes.

cd ~/catkin_ws/; catkin_make --only-pkg-with-deps bb8_action_pkg; source devel/setup.bash

Se tudo foi feito corretamente, o prompt não acusará nenhum erro:

Rodando o servidor de serviços

No terminal 3, execute o comando para iniciar o servidor de ações:

rosrun bb8_action_pkg bb8_action_server

Não se preocupe com este terminal, abra um novo para prosseguir com os passos deste tutorial.

Invocando o feedback da ação

Abra um quarto terminal para receber feedback do robô com informações sobre sua localização no espaço tridimensional. Essas atualizações são recebidas a cada dois segundos, permitindo que você saiba a posição do robô mesmo que ele não esteja visível.

rostopic echo action_custom_msg_as/feedback

Não se preocupe se nada aparecer inicialmente, pois o servidor ainda não está em execução, então não haverá feedback disponível ainda. Isso é normal.

Chamando a ação criada

No quinto terminal, execute o seguinte comando:

rostopic pub action_custom_msg_as/goal bb8_action_pkg/CustomActionMsgActionGoal

Após digitar o comando, não pressione ‘Enter’. Em vez disso, pressione ‘Tab’ duas vezes para autocompletar com os elementos necessários. Em seguida, você poderá selecionar o goal desejado, como ‘turn’, ‘walk’ ou ‘stop’.”

O robô deve se mover de acordo.

Visualizando o feedback

De volta ao terminal 4 temos:

As informações de odometria sempre indicarão onde seu robô está localizado, mesmo que a visualização seja obstruída por um Star Destroyer. Aliás, este método é excelente para explorar e localizar aquela entrada secreta em uma colossal nave inimiga.

Esperamos que este tutorial seja útil e que você se divirta trabalhando com o BB-8, um robô incrível tanto em termos gráficos quanto funcionais.

 Vídeo no YouTube

Este foi o post de hoje. Lembre-se que nós temos uma versão deste post em vídeo no YouTube.

Se você gostou do conteúdo, por favor, considere se inscrever no nosso canal do YouTube. Estamos publicando novos conteúdos quase todos os dias.

Continue avançando no seu aprendizado de ROS.

Comment créer des bibliothèques avec ROS2 C++ – French ROS Tutorial

Comment créer des bibliothèques avec ROS2 C++ – French ROS 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

Introduction

Le but de ce tutoriel est d’apprendre à créer et utiliser des bibliothèques dans les packages ROS2 C++. Lors du développement d’un projet, il est essentiel de garder son code structuré pour assurer un développement efficace. L’utilisation de bibliothèque (ou library) est indispensable pour cela car cela permet de regrouper les codes sources en fonction de leurs usages et donc de séparer des fonctionnalités distinctes. La création de bibliothèques est donc essentielle pour rendre votre code plus structuré, modulaire et réutilisable. Nous allons donc voir ensemble comment déclarer et faire appel une library dans les packages ROS2 C++. Nous allons dans un premier temps voir comment simplement utiliser un header dans un package ROS2 puis nous déclarerons la même bibliothèque dans un package indépendant et utiliserons celle ci dans un autre package.

Pré-requis

Pour lancer et tester le code, vous devez lancer la simulation du turtlebot3 sur gazebo. Pour faire cela, entez les commandes suivantes dans le terminal:

(more…)

Simulação do BB8 com ROS Noetic: Mensagens Customizadas em C++ para Services | Portuguese ROS Tutorial

Simulação do BB8 com ROS Noetic: Mensagens Customizadas em C++ para Services | Portuguese ROS Tutorial

O que nós vamos aprender:

  1. Entender o funcionamento dos serviços no ROS Noetic, e como eles podem ser utilizados para controlar o robô BB-8.
  2. Desenvolver mensagens customizadas em C++ para enviar comandos específicos ao BB-8.
  3. Configurar e compilar um pacote ROS do zero, incluindo a criação de serviços e mensagens de serviço.
  4. Lançar e interagir com a simulação do BB-8 no Gazebo, utilizando os comandos desenvolvidos para controlar o robô.
  5. Escrever e rodar um servidor de serviços em ROS, que permitirá enviar comandos para o BB8.

Lista de recursos usados neste post:

  1. Use este rosject: https://app.theconstructsim.com/l/5e7ce8b4/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS Courses: ROS Basics in 5 Days (C++) https://app.theconstructsim.com/courses/56

Panorama

Olá! Hoje vamos explorar os serviços do ROS, focando no ROS 1 Noetic e em um dos robôs mais fascinantes disponíveis na plataforma: o BB-8 de Star Wars. Utilizaremos os serviços para criar comandos que permitam ao BB-8 desenhar formas no chão ou seguir trajetórias específicas, como quadrados ou círculos, por meio de mensagens customizadas.

Abrindo o rosject

Para acompanhar este tutorial, utilize um rosject, que é essencialmente um projeto ROS configurado para rodar um exemplo. Acesse o link fornecido e clique no botão vermelho.

https://app.theconstructsim.com/l/5fc3aef0/

Criando o pacote

Inicie abrindo um terminal e siga os comandos abaixo para criar o pacote e os arquivos necessários para nossa aplicação.

roscd; cd ..; cd src/bb8; catkin_create_pkg bb8_service_pkg roscpp std_msgs
cd bb8_service_pkg; mkdir srv;
cd srv; touch bb8ServiceMessage.srv; cd ..;
cd src; touch bb8_service_server.cpp; chmod +x *.cpp

Você notará que novos arquivos surgirão na árvore de pastas da janela IDE.

Configurando a mensagens de serviço
As mensagens de serviço incluem sempre os requests e responses. Para comandar o BB-8, trataremos isso como uma string. Edite o arquivo bb8ServiceMessage.srv com o seguinte conteúdo:

string command # A string command representing the action
---
bool success # Did it achieve it?

Preparando para compilar

É importante modificar o CMakeList.txt copiando e colando o conteúdo abaixo, substituindo o conteúdo existente.

cmake_minimum_required(VERSION 3.0.2)
project(bb8_service_pkg)

find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)

add_service_files(
FILES
bb8ServiceMessage.srv
)

generate_messages(
DEPENDENCIES
std_msgs
)

catkin_package(
CATKIN_DEPENDS roscpp
)

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(bb8_service_server src/bb8_service_server.cpp)
add_dependencies(bb8_service_server ${bb8_service_server_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(bb8_service_server
${catkin_LIBRARIES}
)

Não esqueça de adicionar as três linhas indicadas no final do package.xml. Atençã0, não substitua todo o conteúdo do arquivo! Apenas adicione as linhas:

<build_depend>message_generation</build_depend>
<build_export_depend>message_runtime</build_export_depend>
<exec_depend>message_runtime</exec_depend>

 Escrevendo o servidor de serviços

Agora, você pode prosseguir para a parte onde os comandos são recebidos pelo servidor do serviço. Na pasta src, abra o arquivo bb8_service_server.cpp e insira o conteúdo necessário.

#include "geometry_msgs/Twist.h"
#include "ros/ros.h"
#include <bb8_service_pkg/bb8ServiceMessage.h>
#include
#include

ros::Publisher pub;
geometry_msgs::Twist mov;

using namespace std;

bool my_callback(bb8_service_pkg::bb8ServiceMessage::Request &req,
bb8_service_pkg::bb8ServiceMessage::Response &res) {

ROS_INFO("The Service has been called");

if (req.command == "square") {
int j = 0;
while (j < 4) {
// straight
mov.linear.x = 0.5;
mov.angular.z = 0.0;
pub.publish(mov);
usleep(4000000);

// spin
mov.linear.x = 0;
mov.angular.z = 1.0;
pub.publish(mov);
usleep(2000000);
j++;
}
}

if (req.command == "circle") {
mov.linear.x = 1.5;
mov.angular.z = 1.5;
pub.publish(mov);
usleep(6000000);
}

if (req.command == "dance") {
int j = 0;
while (j < 4) {
mov.linear.x = 1.5;
mov.angular.z = 0.5;
pub.publish(mov);
usleep(2000000);

mov.linear.x = -0.5;
mov.angular.z = -1.0;
pub.publish(mov);
usleep(3000000);
j++;
}
}

mov.linear.x = 0;
mov.angular.z = 0;
pub.publish(mov);
ROS_INFO("Finished service");

res.success = true;
return res.success;
}

int main(int argc, char **argv) {
ros::init(argc, argv, "server_node");
ros::NodeHandle nh;

ros::ServiceServer my_service = nh.advertiseService("/move_bb8", my_callback);
pub = nh.advertise("cmd_vel", 1000);
ROS_INFO("Service Ready");
ros::spin();

return 0;
}

Compilando o pacote e lançando a simulação

No terminal 1, xecute o comando abaixo para compilar apenas o pacote que criamos, economizando tempo.

cd ~/catkin_ws/; catkin_make --only-pkg-with-deps bb8_service_pkg; source devel/setup.bash

Se tudo foi feito corretamente, você não verá nenhum erro no prompt:

Após a compilação, inicie o Gazebo com o comando apropriado para visualizar o robô BB-8 preparado para funcionar.

roslaunch bb_8_gazebo main.launch

Isto fará aparecer a janela do Gazebo.

Rodando o servidor de serviços

No terminal 2, execute o comando para iniciar o servidor de serviços:

rosrun bb8_service_pkg bb8_service_server

Uma mensagem confirmará que o serviço está pronto.

Chamando o serviço criado

Utilize um terceiro terminal para enviar comandos ao BB-8. Por exemplo, para fazê-lo se mover em um quadrado ou círculo, ou até mesmo dançar, use os comandos apropriados.

rosservice call /move_bb8 "command: 'square'"
rosservice call /move_bb8 "command: 'circle'"
rosservice call /move_bb8 "command: 'dance'"

Esperamos que este post seja útil e que você se divirta trabalhando com o BB-8, um robô incrível tanto em termos gráficos quanto funcionais.

 Vídeo no YouTube

Este foi o post de hoje. Lembre-se que nós temos uma versão deste post em vídeo no YouTube.

Se você gostou do conteúdo, por favor, considere se inscrever no nosso canal do YouTube. Estamos publicando novos conteúdos quase todos os dias.

Continue avançando no seu aprendizado de ROS.

Video Tutorial

How to use C++ and Python in the same ROS 2 package –  English ROS 2 Tutorial

How to use C++ and Python in the same ROS 2 package – English ROS 2 Tutorial

What we are going to learn:

  1. How to set up the package architecture to accommodate C++ and Python in the same package
  2. How to configure this package (by modifying package.xml and CMakeLists.txt)
  3. How to compile and run Python and C++ nodes from this package

If you want to learn ROS 2 Python in a practical, hands-on way, check out the course
ROS 2 Basics in 5 Days: https://app.theconstruct.ai/courses/132

In this course, you’ll cover the foundational concepts needed to start working with ROS 2, as well as more advanced topics, all while engaging in hands-on practice.

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.theconstructsim.com/l/5e01d324/

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 ( see this example).

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

 

Setup the package architecture

Create a standard C++ package


With dependencies on rclpy and rclcpp:

With dependencies on rclpy:

cd ~/ros2_ws/src/
ros2 pkg create cpp_py_pkg –build-type ament_cmake –dependencies rclpy rclcpp

Run the “tree . command to see the folder structure. If you don’t have the command installed, you can install it using:

sudo apt-get update
sudo apt-get install -y tree

You should be able to see this structure which you are already familiar with:

cpp_py_pkg/
├── CMakeLists.txt
├── include
│ └── cpp_py_pkg
├── package.xml
└── src

Add a C++ node and header

cd cpp_py_pkg/
touch src/cpp_node.cpp
touch include/cpp_py_pkg/cpp_header.hpp

In order to compile the package later, we need at least a main function in the C++ node. For this tutorial for simplicity, we can just add this minimal code to the cpp_node.cpp file:

#include “rclcpp/rclcpp.hpp”
// Include your header file to use it
#include “cpp_py_pkg/cpp_header.hpp”
int main(int argc, char **argv)
{
// Initiate ROS communications
    rclcpp::init(argc, argv);
// Instantiate the node
    auto node = std::make_shared<rclcpp::Node>(“my_node_name”);
// Make the node spin
    rclcpp::spin(node);
// Shutdown ROS communications
    rclcpp::shutdown();
    return 0;
}


Add a Python node and module to import

For Python, we need to create additional folders first:

mkdir cpp_py_pkg
touch cpp_py_pkg/__init__.py
mkdir scripts

Then we can add the files:

touch cpp_py_pkg/module_to_import.py
touch scripts/py_node.py


You have to add a shebang line first thing in the py_node.py file otherwise you will get an error when trying to run the node:

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
# Import a specific function/class from your module
# from cpp_py_pkg.module_to_import import …
def main(args=None):
# Initiate ROS communications
    rclpy.init(args=args)
# Instantiate the node
    node = Node(‘my_node_name’)
# Make the node spin
    rclpy.spin(node)
# Shutdown ROS communications
    rclpy.shutdown()
if __name__ == ‘__main__’:
    main()

 

Final package architecture

Run the “tree . command to see the folder structure. I have added additional comments and files to make it clearer:

cpp_py_pkg/
# –> package info, configuration, and compilation
├── CMakeLists.txt
├── package.xml
# Python stuff
# –> empty init file & any python library or module files we want to import
├── cpp_py_pkg
│ ├── __init__.py
│ └── module_to_import.py
│ └── another_module_to_import.py
# –> python executables/nodes
├── scripts
│ └── py_node.py
# Cpp stuff
# –> cpp header files
├── include
│ └── cpp_py_pkg
│ └── cpp_header.hpp
│ └── another_cpp_header.hpp
# –> cpp executables/nodes
└── src
└── cpp_node.cpp

The CMakeLists.txt and package.xml will be shared by Python and C++, which is what we will edit in the next section to configure the package for both Python and C++.

Configure the package

package.xml


Add a buildtool_depend tag for ament_cmake_python:

<buildtool_depend>ament_cmake_python</buildtool_depend>

So your package.xml should look like this:

<?xml version=”1.0″?>
<?xml-model href=”http://download.ros.org/schema/package_format3.xsd” schematypens=”http://www.w3.org/2001/XMLSchema”?>
<package format=”3″>
<name>cpp_py_pkg</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email=”user@todo.todo”>user</maintainer>
<license>TODO: License declaration</license>

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>ament_cmake_python</buildtool_depend>

<depend>rclpy</depend>
<depend>rclcpp</depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>

cd ~/ros2_ws/
colcon build –packages-select py_pkg

 

CMakeLists.txt

Add this external dependency:

find_package(ament_cmake_python REQUIRED)

Add this for C++:

# Include Cpp “include” directory
include_directories(include)

# Create Cpp executable and link with dependencies
add_executable(cpp_executable src/cpp_node.cpp)
ament_target_dependencies(cpp_executable rclcpp)

# Install Cpp executables in the ros2_ws/install/cpp_py_pkg/lib/cpp_py_pkg/ folder
install(TARGETS
cpp_executable
DESTINATION lib/${PROJECT_NAME}
)

Add this for Python:

# Install Python modules
ament_python_install_package(${PROJECT_NAME})

# Install Python executables in the ros2_ws/install/cpp_py_pkg/lib/cpp_py_pkg/ folder
install(PROGRAMS
scripts/py_node.py
DESTINATION lib/${PROJECT_NAME}
)

So your CMakeLists.txt should look like this:

source ~/.bashrc # . ~/.bashrc

So your CMakeLists.txt should look like this:

cmake_minimum_required(VERSION 3.8)
project(cpp_py_pkg)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES “Clang”)
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclpy REQUIRED)
find_package(rclcpp REQUIRED)
find_package(ament_cmake_python REQUIRED)

# Include Cpp “include” directory
include_directories(include)

# Create Cpp executable and link with dependencies
add_executable(cpp_executable src/cpp_node.cpp)
ament_target_dependencies(cpp_executable rclcpp)

# Install Cpp executables in the ros2_ws/install/cpp_py_pkg/lib/cpp_py_pkg/ folder
install(TARGETS
cpp_executable
DESTINATION lib/${PROJECT_NAME}
)

# Install Python modules
ament_python_install_package(${PROJECT_NAME})

# Install Python executables in the ros2_ws/install/cpp_py_pkg/lib/cpp_py_pkg/ folder
install(PROGRAMS
scripts/py_node.py
DESTINATION lib/${PROJECT_NAME}
)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()

Compile package, then run C++ node and Python node

cd ~/ros2_ws/
colcon build –packages-select cpp_py_pkg

Source ROS2 environment and start C++ node in one terminal:

source ~/ros2_ws/install/setup.bash
ros2 run cpp_py_pkg cpp_executable

Source ROS2 environment and start Python node in another terminal:

source ~/ros2_ws/install/setup.bash
ros2 run cpp_py_pkg py_node.py

That’s it! If there are no errors when you run the nodes then it means that it was successful (remember that our nodes do not do anything except spin).

Congratulations. You now know how to use C++ and Python in the same ROS 2 package.

To learn more 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

Launch files en paquetes de C++ ROS 2 Humble – ROS Spainish Tutorial

Launch files en paquetes de C++ ROS 2 Humble – ROS Spainish Tutorial

This tutorial is created by Rosbotics Ambassador 025 Miguel

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)


Que vamos a aprender

  1. Como crear un launch file
  2. Como importar nuestros archivos de tipo launch en un paquete de C++ usando buenas practicas
  3. Como compilar nuestro entorno de ROS 2 Humble
  4. Como ejecutar nuestros launch files

Lista de recursos usados en este post

  1. Usa este rosject: https://api.robotigniteacademy.com/l/5f308d0d/
  2. The Construct: https://app.theconstructsim.com/
  3. Cursos de ROS 2:
    1. Fundamentos de ROS 2 en 5 dias (C++): https://api.robotigniteacademy.com/courses/133

Abrir el rosject:

Para poder seguir al pie de la letra este tutorial , necesitamos tener ROS 2 Humble instalado en nuestro equipo, ademas de un entorno de ROS 2 configurado. Para hacer nuestra vida mas fácil, ya tenemos preparado un rosject preparado: https://api.robotigniteacademy.com/l/5f308d0d/

Solo copiando el rosject (abriendo el enlace de arriba), vas a tener el entorno configurado.

Luego de que el rosject haya sido copiado sin problemas en tu área, podrás ver un botón en rojo que dice  ejecuta. Solo oprime ese botón para poder arrancar el entorno.

 

Crear un paquete de ROS 2 en C++:

Para crear un paquete de ROS 2, necesitas tener un entorno de ROS 2, y para eso, necesitamos una terminal.

Vamos a abrir una terminal oprimiendo el botón de abrir nueva terminal.

Ya estando en la terminal, para poder crear nuestro paquete debemos movernos a la carpeta src de nuestro entorno.

$ cd ros2_ws/src

Y ya estando en la carpeta, podemos crear nuestro paquete con compilación de tipo cmake:

$ ros2 pkg create launch_cmake –build-type ament_cmake –dependencies rclcpp std_msgs

Preparar nuestro paquete para usar archivos tipo launch

Ya que creamos nuestro paquete vamos a entrar y crear una carpeta launch donde vamos a crear nuestros launch files:

$ cd launch_cmake

$ mkdir launch

Ahora ya que no es el punto de este tutorial, vamos a copiar unos nodos que se encuentran en otro paquete de nuestro entorno clonado

$ cp ~/ros2_ws/src/paquete_cpp/src/* src/

y vamos a importar estos nodos en nuestro paquete, para eso debemos oprimir el botón de Editor de código, buscamos nuestro paquete y editamos el archivo CMakeLists.txt

Para poder que nuestro paquete reconozca los nodos vamos a añadir estas lineas de codigo justamente debajo de los find_package(…):

add_executable(publisher src/publisher.cpp)
ament_target_dependencies(publisher rclcpp std_msgs)
install(TARGETS
    publisher
    DESTINATION lib/${PROJECT_NAME}
)
add_executable(subscriber src/subscriber.cpp)
ament_target_dependencies(subscriber rclcpp std_msgs)
install(TARGETS
    subscriber
    DESTINATION lib/${PROJECT_NAME}
)
teniendo eso vamos a crear un archivo en la carpeta launch, el cual se va a llamar launchcpp.launch.py como pueden observar la extensión es .py ya que ROS 2 usa Python 3 como interprete de archivos tipo launch. Con el archivo creado, vamos a llenar de codigo nuestro launch:
import os
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
    return LaunchDescription([
        Node(
            package=’launch_cmake’,
            executable=’publisher’,
            name=’publisher’,
            output=’screen’,
        ),
        Node(
            package=’launch_cmake’,
            executable=’subscriber’,
            output=’screen’,
            name=’subscriber’,
        )
    ])
Ya teniendo nuestro launch file que ejecuta nuestros dos nodos, debemos importarlo en el CMakeList.txt para poder permitir al paquete detectarlo, para eso inmediatamente debajo de lo que pusimos para nuestros nodos, vamos a poner la carpeta donde alojamos los launch files:
install(DIRECTORY
   launch
   DESTINATION share/${PROJECT_NAME}
)

como podemos observar, en este ultimo trozo de código estamos diciéndole a nuestro paquete que necesitamos tener disponible en la carpeta compartida share todos los archivos que se encuentren en la carpeta launch.

Compilar entorno y ejecutar launch file

Por ultimo, debemos comprobar que todo salió bien, para eso vamos a abrir de nuevo la terminal y compilamos nuestro entorno:

$ cd ~/ros2_ws

$ colcon build –packages-select launch_cmake

$ source install/setup.bash

Y ejecutamos nuestro launch file:

$ ros2 launch launch_cmake launchcpp.launch.py

Video Tutorial

 

Pin It on Pinterest