Dans cet article, vous apprendrez comment exporter le code écrit sur les plateformes TheConstruct vers votre machine locale. Que ce soit dans le cadre d’une formation ou en utilisant un Rosject pour simuler un environnement spécifique, de nombreux utilisateurs sur le forum ROS Ignite Academy se demandent comment partager, télécharger ou utiliser leur code sur leur installation locale.
Prérequis
Pour suivre le tutoriel sur votre ordinateur, vous devez configurer votre installation locale.
Vous devez avoir le package Turtlebot3 installé dans votre environnement local afin de lancer la simulation Gazebo du Turtlebot3 et tester le code fourni dans le package. Pour ce faire, vous pouvez suivre les instructions de la documentation Turtlebot3 :https://emanual.robotis.com/docs/en/platform/turtlebot3/simulation/ et construire le code source sur votre machine locale, ou installer directement les packages Turtlebot3 avec cette commande :
# pour installer tous les packages du turtlebot3
$ 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
Maintenant que votre installation locale est prête, je vais vous montrer deux façons de partager vos packages entre les ROSjects ou les cours TheConstruct et votre installation locale.
Téléchargez votre package depuis l’interface web Rosject
La première méthode consiste à télécharger le package directement depuis l’IDE de la plateforme. Pour ce faire, clique droit sur le dossier src qui contient votre package dans votre arborescence de fichier de l’IDE, puis cliquez sur on Download.
Cela devrait lancer le téléchargement dans votre navigateur.
Vous pouvez décompresser le package dans votre workspace ROS2.
Ensuite, compilez le package en utilisant les instructions suivantes dans un terminal local :
$ cd ~/ros2_ws
# compiler le package
$ colcon build
# sourcer le workspace
$ source install/setup.bash
L’avantage principal de cette méthode est sa simplicité d’utilisation. Cependant, elle peut ne pas être adaptée si vous souhaitez pouvoir continuer à faire évoluer le code ou le partager dans le cadre d’un développement collaboratif. C’est pourquoi la deuxième méthode peut être plus adaptée pour les projets.
Configurer un dépôt (repository) GitHub
La deuxième méthode consiste à utiliser un dépôt sur GitHub. L’avantage principal de cette méthode est que vous pouvez versionner votre code et continuer à développer sur plusieurs installations parallèles, facilitant le partage de votre travail. Vous pouvez initialiser votre dépôt GitHub en allant sur https://github.com/, vous connecter, aller dans “Yourrepository” et sélectionner “New”. Ensuite, vous pouvez créer un dépôt qui a le même nom que votre package ROS.
Une fois que le dépôt GitHub est créé, vous devez exécuter ces commandes sur le webshell ROSject :
# go to the directory of your package
$ cd ~/ros2_ws/src/tutorial_local_machine
$ git init
# entrer vos informations
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
# ajouter tous les fichier du package dans votre commit
$ git add --all
# commit et ajouter un message pour décrire l’état d’avancement du projet
$ git commit -m "Initialize the repository"
$ git branch -M main
# lier le dépôt locale à le dépôt distante sur GitHub
$ git remote add origin https://github.com/[YourGithubUserName]/tutorial_local_machine.git
# s’identifier et utiliser le jeton d'accès personnel comme mot de passe
$ git push -u origin main
Une fois les commandes exécutées, votre code devrait être téléchargé sur votre dépôt distant sur GitHub.
Vous pouvez maintenant ouvrir un terminal sur votre machine locale et cloner votre dépôt GitHub dans votre workspace ROS2 local:
$ cd ~/ros2_ws/src/
# cloner la dépôt
$ git clone https://github.com/[YourGithubUserName]/tutorial_local_machine.git
# revenir à la racine du workspace
$ cd ..
# compiler le package
$ colcon build
# sourcer le workspace
$ source install/setup.bash
Lancer la simulation en local et exectuer le code
Maintenant que tout est configuré et que le package est compilé, vous devriez être en mesure d’exécuter le node. Le package du tutoriel contient un node C++ simple pour interagir avec le laserscan et le cmd_vel du Turtlebot3. Le node s’abonne au topic /scan afin de déterminer la distance entre un obstacle en face du robot et publie sur /cmd_vel pour avancer tant que la distance est supérieure à 1,0 mètre. Une fois que la distance est inférieure à 1,0 mètre, il publie une vitesse de 0 pour arrêter le robot.Vous pouvez tester le code en exécutant le fichier launch suivant:
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
Nel caso non si volesse installare ROS Noetic sul proprio sistema e fare il set up dell’ambiente di sviluppo, è possibile utilizzare i Rosject offerti da The Construct per poter testare i contenuti del tutorial o per seguirlo passo passo.
Per fare ciò sarà sufficiente seguire il link indicato nelle risorse e cliccare su “Run”. In questo modo si avrà accesso a una copia del Rosject utilizzato all’interno del tutorial.
Aprire terminal e IDE
Per aprire un nuovo terminale e avere accesso all’IDE forniti dal Rosject, sarà possibile utilizzare la console in basso a destra
Creare un nuovo package
Per poter creare un nuovo package sarà sufficiente spostarsi all’interno del workspace di catkin, e creare il package con l’aiuto di catkin_create_pkg. In questo caso aggiungendo come dependencies rospy (poiché scriveremo in Python) e std_msgs. cd ~/catkin_ws
catkin_create_pkg custom_srv_pkg rospy std_msgs
Creare un nuovo file per la definizione del Service
Quello che bisogna fare ora è creare una cartella che possa contenere i file di definizione dei Service e il file per il nostro Service personalizzato.
Definizione della struttura del Service personalizzato
I servizi sono identificati da due sezioni, divise da un triplo dash (- – -):
Request: inviata da un client a un server, con i parametri necessari all’esecuzione del servizio
Response: ritornata dal server al client, con eventuali risultati dell’esecuzione del servizio
⚠ Request e response possono essere anche vuoti
All’interno delle due sezioni possiamo usare per esempio std_msgs, ma anche altri tipi di messaggio come geometry_msgs.
Andiamo quindi a definire il nostro servizio con i seguenti parametri: # Request
string da_stampare
geometry_msgs/Point punto
---
# Response
float64 somma
bool successo
In questo caso abbiamo una stringa da stampare, un punto tridimensionale, una variabile somma rappresentante la somma delle coordinate del punto e un booleano che indica il successo dell’esecuzione del servizio.
CMakeLists e package.xml
Per permettere la compilazione del servizio e la generazione dei relativi messaggi, bisogna apportare qualche modifica al file CMakeLists e al package.xml.
CMakeLists
Qui sarà necessario includere le seguenti linee:
cmake_minimum_required(VERSION 3.0.2)
project(custom_srv_pkg)
find_package(catkin REQUIRED COMPONENT
rospy
std_msgs
message_generation # per la generazione dei messaggi relativi al servizio
geometry_msgs # poiché abbiamo utilizzato un messaggio di questo tipo
)
add_service_files(
FILES
CustomSrvMsg.srv # il nostro file dove abbiamo definito il servizio
)
generate_messages(
DEPENDENCIES
std_msgs
geometry_msgs # per generare messaggi contenenti geometry_msgs
)
catkin_package(
CATKIN_DEPENDS rospy std_msgs
)
package.xml
All’interno del package.xml dovremo aggiungere le dependencies per la generazione e l’utlizzo dei messaggi relativi al servizio
cd ~/catkin_ws
catkin_make –only-pkg-with-deps custom_srv_pkg
source devel/setup.bash # poiché sono stati generati nuovi messaggi e servizi
Verificare la generazione dei messaggi del Service personalizzato
Per poter verificare la presenza dei messaggi relativi al nostro nuovo messaggio e il loro contenuto possiamo utilizzare i seguenti comandi: rossrv list | grep custom # grep custom è usato per filtrare l’output
# l’output sarà del tipo:
# custom_srv_pkg/CustomSrvMsg
rossrv show custom_srv_pkg/CustomSrvMsg
# l’output sarà del tipo:
# string da_stampare
# geometry_msgs/Point punto
# float64 x
# float64 y
# float64 z
# ---
# float64 somma
# bool successo
Importare i messaggi generati per il servizio
All’interno dello script server.py possiamo importare:
Nel caso di un server:
[NomeDelMessaggioDelServizio]
[NomeDelMessaggioDelServizio]Response
Nel caso di un client:
[NomeDelMessaggioDelServizio]
[NomeDelMessaggioDelServizio]Request
Nel tutorial scriveremo un esempio di un server di Servizi, quindi importeremo i messaggi in questo modo:
from custom_srv_pkg.srv import CustomSrvMsg,CustomSrvMsgResponse
# from custom_srv_pkg.srv import CustomSrvMsg,CustomSrvMsgRequest # nel caso client
Accesso ai parametri di request e response
In una possibile implementazione del nostro server accediamo a request, ricevuto dal client tramite una callback invocata ogni volta che viene richiesto il servizio, e ai relativi parametri.
Possiamo poi istanziare una response (di tipo CustomSrvMsgResponse) e riempirne i campi con le informazioni che ci interessa ritornare al client.
#! /usr/bin/env python
import rospy
from custom_srv_pkg.srv import CustomSrvMsg, CustomSrvMsgResponse
# CustomServiceRequest in caso di un client
def callback(request):
response = CustomSrvMsgResponse()
print(request.da_stampare)
response.somma = request.punto.x + request.punto.y + request.punto.z
response.successo = True
return response
rospy.init_node("service_server")
service = rospy.Service("my_service", CustomSrvMsg, callback)
rospy.spin()
Conclusione
Se siete riusciti a seguire fino a qui sarà possibile compilare il package e eseguire il nodo relativo al Service server. In questo modo sarà reso disponibile il servizio che potrà essere chiamato da linea di comando o da un client.
# terminale 1
roscore
# terminale 2
rosrun custom_srv_pkg server.py # esecuzione del nodo server.py
# terminale 3
rosservice list | grep my # mostra tutti i servizi disponibili contenenti "my"
rosservice call /my_service [TAB] [TAB] # chiama il servizio e precompone la request
کمپیوٹر ویژن روبوٹکس میں ایک اہم حصہ ہے اور روبوٹکس میں کمپیوٹر ویژن الگورتھم کو لاگو کرنے اور جانچنے کے لیے ہمیں اپنے روبوٹ میں ویژن سینسرز (RGB اور RGB-D کیمروں) کو ضم کرنے کی ضرورت ہے۔ اس پوسٹ میں ہم مصنوعی ماحول کو دیکھنے کے لیے Gazebo Simulation میں اپنے روبوٹ میں مصنوعی RGB-D کیمرہ شامل کرنا سیکھیں گے۔
سمولیشن روبوٹک سسٹمز ٹیسٹنگ میں ایک مربوط حصہ ہے، روبوٹکس سسٹمز کے تمام پہلوؤں کو صحیح طریقے سے جانچنے کے لیے، تمام اجزاء کو سمولیشن میں شامل کیا جانا چاہیے (بشمول سینسر، ایکچویٹرز وغیرہ)۔ Gazebo، روبوٹکس میں بڑے پیمانے پر استعمال ہونے والا سمولیشن سافٹ ویئر ہونے کے ناطے، اس میں بنائے گئے زیادہ تر سینسرز کے لیے تعاون حاصل ہے۔
ROS Inside!
Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it, print it, and attach it to your robot. It is really free. Find it in the link below:
ہم RViz میں پوائنٹ کلاؤڈ ڈیٹا کو بھی دیکھ سکتے ہیں۔ ٹرمینل چلائیں اور ٹائپ کریں:
rosrun rviz rviz
یہ RViz کے ساتھ نئے گرافیکل ٹولز ونڈو کو کھولے گا۔ “شامل کریں” پر کلک کریں اور “پوائنٹ کلاؤڈ 2” فیلڈ شامل کریں۔
اس کے بعد، اس موضوع کو منتخب کریں جس پر پوائنٹ کلاؤڈ ڈیٹا شائع کیا گیا ہے جیسا کہ ذیل کی تصویر میں دکھایا گیا ہے۔
آپ پوائنٹ کلاؤڈ ڈیٹا کو دیکھ سکیں گے جو روبوٹ میں کیمرہ فریم کے میدان میں ہے، مندرجہ ذیل ہے۔
حتمی خیالات:
اب جب کہ ہمارے پاس گیزبو ماحول میں اپنے روبوٹ سمولیشن میں کیمرہ فیڈ موجود ہے، ہم اسے مختلف کاموں کو انجام دینے کے لیے استعمال کر سکتے ہیں جیسے کہ کمپیوٹر وژن، آبجیکٹ کا پتہ لگانے، سیمنٹک سیگمنٹیشن، اور لوکلائزیشن وغیرہ۔ یہ بھی نوٹ کریں کہ RViz میں پوائنٹ کلاؤڈ ڈیٹا غلط ہے۔ واقفیت. اس کو حل کرنے کے لیے ہمیں بیس لنک سے کیمرہ لنک میں کچھ سٹیٹک ٹرانسفارمز شامل کرنے ہوں گے (ہم آنے والی پوسٹس میں دیکھیں گے)۔
ROS (Robot Operating System) se está convirtiendo en el “framework” estándar para programar robots. En este tutorial crearemos paso a paso el paquete de configuración de MoveIt usando Moveit Setup Assistant para tu robot. Ten encuesta que se usará ROS Noetic para este tutorial.
PASO 1: Abriendo el rosject
Para seguir este tutorial, necesitamos tener instalado ROS en nuestro sistema, y lo ideal sería tener un catkin_ws (Espacio de Trabajo ROS). Para facilitarte la vida, ya hemos preparado un rosject para eso: https://app.theconstructsim.com/l/5f3d5b06/.
Simplemente copiando el rosject (haciendo clic en el enlace de arriba), tendrás una configuración ya preparada para ti.
Después de haber copiado el rosject a tu propia área de trabajo, deberías ver el botón RUN. Haz clic en ese botón para lanzar el rosject (abajo tienes un ejemplo de rosject).
Tras pulsar el botón RUN, deberías tener cargado el rosject. Ahora, pasemos a la siguiente sección para ponernos manos a la obra.
PASO 2: Iniciando MoveIt Setup Assistant
Para crear un paquete MoveIt para nuestro robot usando el asistente de configuración de MoveIt necesitamos solamente el paquete de descripción de este (que contenga los archivos urdf/xacro y los meshes de ser necesario).
El robot que se usará es el EDO (una paquete de descripción con una versión simplificada).
Para iniciar el asistente ejecutamos el siguiente comando en una terminal:
Con ello se iniciar el asistente y deberíamos ver esta interfaz:
PASO 3: Configurar el paquete con la ayuda del asistente
El asistente de MoveIt tiene múltiples pestañas de configuración. Recorreremos cada una de ellas en orden configurando lo necesario.
Inicio (Start)
En esta parte cargamos la descripción de nuestro robot mediante el archivo urdf/xacro principal.
Para seleccionamos la opción Create New Moveit Configuration Package, luego buscamos el xacro de nuestro robot dándole a Browse y luego le damos a Load Files para cargar nuestro robot.
Esperamos, y si todo esta correcto con nuestro archivo Xacro/URDF se mostrará nuestro robot en la parte derecha.
Autocolisiones (Self-collisions)
En esta parte le decimos a MoveIt que pares de juntas no necesita revisar por colisiones ya que siempre están en colisión, reduciendo así la carga computacional a este proceso.
Aquí solo pulsamos el botón Generate Collision Matrix y la matriz ya se genera automáticamente.
Juntas virtuales (Virtual Joints)
En esta parte creamos una junta virtual entre la base del robot y un sistema coordenado de referencia. Sirve para posicionar el robot en world o una plataforma móvil.
Esta configuración ya se puede hacer desde nuestro archivo xacro (como en este ejemplo), por lo que no se definirá ninguna junta virtual.
Grupos de planificación (Planning groups)
En esta parte se crea los grupos de planificación ya que MoveIt trabaja con grupos para la planificación de movimiento. Típicamente se configura un grupo para las juntas del brazo robótico y otro para el efector final.
Aquí le damos a Add Group, y configuramos las opciones que nos aparecen.
Group Name: Nombre del grupo a elección. Le colocaremos arm.
Kinematic Solver: El plugin encargado de resolver la cinemática del robot. Usaremos KDLKinematicsPlugin.
Group Default Planner: El algoritmo encargado de realizar la planificación de movimiento. Usaremos RRT.
Las demás opciones las dejamos con sus valores por defecto y ahora seleccionaremos las juntas que pertenecerán a este grupo, para ello le damos a Add Joints.
Seleccionamos las juntas que deseamos que pertenezcan al grupo, y le damos a Save.
Debido a que el robot del ejemplo no cuenta con un efector final solo creamos un grupo para el brazo robótico.
Poses del robot (Robot Poses)
En esta parte configuramos posiciones del robot según nuestras necesidades. Para ello asignamos un set de valores de juntas para la pose deseada y le asignamos un nombre.
Le damos a Add Pose, seleccionamos el grupo de planificación (solo tenemos a arm en este caso), le ponemos un nombre (home que siempre es conveniente definirlo) y le damos los valores correspondientes a las juntas moviendo los Sliders o colocando directamente los valores. Le damos a Save para guardar esta pose.
Añadimos otra pose al robot a la que llamaremos Inicio, al que le puedes dar los valores válidos que desees. En la parte derecha puedes ver la pose que robot adopta. Esta pestaña es importante para ver si las juntas de tu robot están correctamente definidas en la descripción.
Efectores final (End Effectors)
En esta parte se añaden los efectores finales definiendo el nombre, el grupo de planificación y el sistema coordenado padre.
Ya que en este ejemplo no contamos con un efector final no lo definiremos.
Juntas Pasivas (Passive Joints)
En esta parte se definen las juntas que no tiene un actuador. Ya que nuestro robot no tiene ese tipo de juntas no definiremos nada en esta pestaña.
Controladores (Controllers)
En esta parte se definen los controladores, los cuales deben ser los adecuados para nuestro robot.
Le damos a Add Controller, le ponemos un nombre a elección, seleccionamos el tipo de controlador y seleccionamos el grupo de planificación al que se aplicará este controlador.
Luego solo seleccionamos el grupos de planificación correspondiente y guardamos. Con ello ya tendríamos el controlador configurado.
Simulación (Simulation)
En esta parte se puede autogenerar los cambios necesarios en el URDF para que los controladores y MoveIt sea compatible con la simulación en Gazebo. Los cambios se muestran en verde luego de darle click a Generate URDF.
Básicamente se añaden inercias, transmisiones y el plugin gazebo_ros_control, sin embargo, todo ello ya esta definido en el xacro de nuestro robot así que no necesitaremos copiar y pegar este URDF generado.
Percepción 3D (3D Perception)
En esta parte se configura el sensor 3D con el cual trabaja nuestro robot. Podemos seleccionar entre 2 tipos de plugins para sensor 3D: PointCloud y Depth Map. Y luego configurar algunos parámetros y el tópico que se usará.
Ya que en este ejemplo el robot no cuenta con un sensor, no lo configuraremos.
Información del autor (Author Information)
En esta parte se inserta el nombre y el correo del creador del paquete.
Archivos de configuración (Configuration Files)
En esta parte se genera el paquete de configuración de MoveIt con todo lo que hemos definido previamente.
Para ello, primero le damos a Browse para seleccionar la carpeta en la que queremos guardar nuestro paquete, debemos elegir un nombre (es común usar la estructura nombreRobot_moveit_config), luego le damos a Generate Package, le damos Ok en la ventana de advertencia que nos aparece (Nos alerta que no definimos juntas virtuales ni efector final) y esperamos a que se genere nuestro paquete.
Una vez generado nuestro paquete le damos a Exit Setup Assistant. Con ello ya tenemos nuestro paquete MoveIt listo para usarse.
Los archivos del paquete los puedes encontrar en la ruta que especificaste anteriormente, esta compuesto de archivos de configuración y launch.
Ejecutar la demo en RViz
Listo! ya tenemos nuestro paquete MoveIt generado, para probarlo ejecutaremos el launch demo.launch con el siguiente comando:
roslaunch edo_moveit_config demo.launch
Con ello se iniciará RViz junto con todo lo necesario para realizar la planificación de movimiento a través de la interfaz que se carga en RViz. En la pestaña Planning de dicha interfaz podemos seleccionar un grupo de planificación, una pose inicial, una pose deseada y darle a planear y ejecutar.
Observarás como el robot se mueve por la ruta planificada. Y así de sencillo!, partiendo de un paquete de descripción de nuestro robot podemos realizar planificación de movimiento gracias al asistente de MoveIt.
Panorama
Em ROS, quando se fala em realizar uma tarefa enquanto uma outra está sendo realizada, estamos falando das “Actions”. Neste artigo, trataremos de um exemplo em ROS com o TurtleBot3 programado em Python. Basicamente, dada uma posição no espaço, teremos que iniciar uma ação que cuidará de calcular o quanto nosso robô está longe da posição inicial enquanto este se movimenta pelo ambiente.
Abrindo o rosject
Para seguir este tutorial, será útil e conveniente usar um rosject (que a grosso modo é um projeto ROS configurado para rodar um exemplo).
Acesse o link: https://app.theconstructsim.com/l/5e7ce8b4/
Clique no botão vermelho “RUN”:
Descobrindo as mensagens associadas:
Abra um terminal clicando no ícone indicado na figura:
Isso significa que você está acessando a pasta de um pacote chamado actionlib. Neste pacote, tipos padrão de mensagens usadas para realizar ações podem ser encontradas e isso nos será útil.
Navegue para a pasta action com o comando:
cd action
Aqui, você encontra um arquivo chamado Test.action. Para visualizá-lo diretamente no terminal, rode:
cat Test.action
O seguinte conteúdo é apresentado:
int32 goal
---
int32 result
---
int32 feedback
Muitas informações importantes são extraídas deste arquivo. Por exemplo, vemos a estrutura padrão de um arquivo de ação que contém objetivo, resultado e feedback separados pelos hífens. Não necessariamente teremos variáveis associadas a esses tipos em todos os arquivos. No nosso exemplo, estamos especialmente interessados no feedback (que não precisa ter esse nome sempre).
Criando um servidor de ações
Clique no ícone para abrir a IDE e navegue nas pastas do workspace para encontrar o arquivo action_server.py.
Neste arquivo, vemos como a informação da ação é utilizada. Por exemplo, precisamos importar as possíveis mensagens, por isso temos:
from actionlib.msg import TestFeedback, TestResult, TestAction
Repare na implementação de variáveis necessárias para o código:
_feedback = TestFeedback()
_result = TestResult()
Gaste alguns minutos lendo o código para entender como a distância para a localização inicial é calculada.
No terminal 1, rode o comando:
roslaunch realrobotlab main.launch
Você será apresentado à uma janela do Gazebo como esta:
Aproxime-se (zoom in) para visualizar o nosso robô no centro da tela:
Inicializando e verificando a ação
No terminal 2, rode o servidor de ações que acabamos de ver:
rosrun basic_project action_server.py
No terminal 3, inicialize a ação publicando na variável goal:
Existem outras formas de se inicializar uma ação por exemplo usando um script dedicado (action client) ou mesmo usando a interface gráfica axclient via comando:
rosrun actionlib_tools axclient.py /record_odom
obs.: Você pode usar o comando anterior no terminal 3 se preferir ao invés do comando de publição no tópico.
Clique no ícone de ferramentas gráficas para visualizar o axclient:
Independentemente da forma como você inicialize o servidor de ações, em um novo terminal (4) você pode verificar a variável feedback sendo atualizada com o valor da distância calculada entre a posição atual e a inicial do robô.
rostopic echo /record_odom/feedback
Para fazer o exemplo mais ilustrativo, você pode mover o robô usando as teclas do seu teclado, isto é, teleoperando o robô. Para teleoperar o robô, abra um novo terminal (5) e rode:
Então, verá como a distância varia no seu terminal dedicado a ecoar tal resultado. Não se perca em meio a tantos terminais abertos simultaneamente. Algo como isto será apresentado na sua tela:
---
header:
seq: 581
stamp:
secs: 1597
nsecs: 72000000
frame_id: ''
status:
goal_id:
stamp:
secs: 1016
nsecs: 62000000
id: "/axclient_5154_1705261443951-1-1016.062"
status: 1
text: "This goal has been accepted by the simple action server"
feedback:
feedback: 58
---
Agora sim, você pode ficar tranquilo sabendo que a ação que você criou estará sempre atenta a quanto seu robô se distanciou da posição inicial. Uma ressalva importante é que neste cálculo simples de distância, os eventuais obstáculos são negligenciados.
Nós esperamos que este post seja útil para você!
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.