Maaliiik / PAR_ROS_project

Repository containing the ROS project for the PAR master
0 stars 0 forks source link

tutoriel prise en main du framework navigation2 #1

Open Maaliiik opened 1 month ago

Maaliiik commented 1 month ago

Make sure u install gazebo, the navigation stack and the slam toolbox

$ sudo apt install ros-iron-navigation2 ros-iron-nav2-bringup

$ sudo apt install ros-iron-gazebo-ros-pkgs

$ sudo apt install ros-iron-navigation2 ros-iron-slam-toolbox

L'objectif de ce premier tuto est une prise en main du stack Navigation2, et de comprendre comment les differents composants interagiisent entre eux. Vu qu'on a pas encore definit de maniere explicite l'application qu'on souhaite concretiser a la fin, je propose qu'on decale la definition de l'URDF pour plus tard, pour qu'on se retrouve pas a devoir le modifier a chaque fois si l'on souhaite changer d'avis.

du coup pour la prise en main de navigation2, on va utiliser l'urdf deja pret du robot turtlebot3 qu'on retrouve sur internet. pour installer les packages necessaires, run this command :

$ sudo apt install ros-humble-turtlebot3*

une fois que c'est fait,on choisi le modele du robot et on lance gazebo et on spawn l'urdf du turtlebot a travers un launch file : export TURTLEBOT3_MODEL=waffle

$ ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py

normalement ca fonctionnera puis faudra faire bouger le robot sur gazebo, et on le fera en envoyant des commandes manuellements sur le clavier $ ros2 run turtlebot3_teleop teleop_keyboard

maintenant on a un robot avec lidar, qui bouge dans une carte. pour bien inspecter ce qui se passe, on peux jetter un coup d'oeil sur les differents noeuds et topics qui sont actives

ros2 topic list ros2 node list blabla

Maaliiik commented 1 month ago

bach nmachou notre robot de maniere autonome, on doit dabord creer une carte de l'environement.

Pour cela, il y'a plusieurs manieres d'utiliser Slam sur ros tel que " slam toolbox "

pour notre cas, on prend : cartographer


$ ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True

note : nous utilisons "use_sim_time" a chaque fois car on est en train d'utiliser le temps de simulation sur gazebo.

sur rviz, tu peux z voir les TFs du robot, ainsi que le LaserScan provenant du capteur Lidar (points rouges). Certains pixels sont déjà gris/noirs. Lorsque tu fais déplacer le robot, les pixels seront classés en trois catégories :

Espace libre (deviendront blancs), Obstacle (deviendront noirs), Espace inconnu (restera gris).

pour enregistrer la carte :

$ ros2 run nav2_map_server map_saver_cli -f my_map

run navigation

$ ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=True map:=path/to/my_map.yaml
Maaliiik commented 1 week ago

Pour créer un service ROS dans un package avec un fichier sum.srv qui prend deux entiers en entrée et renvoie leur somme, ainsi que deux nœuds client et serveur, voici comment structurer ton CMakeLists.txt.

Structure du package

Assure-toi d'avoir la structure suivante pour ton package ROS :

my_sum_package/
├── CMakeLists.txt
├── package.xml
├── srv/
│   └── sum.srv
├── src/
│   ├── client_node.py
│   └── server_node.py
└── scripts/
    ├── client_node.py
    └── server_node.py

Étape 1 : Créer le fichier sum.srv

Dans le dossier srv (à créer si nécessaire), ajoute le fichier sum.srv avec le contenu suivant :

int32 a
int32 b
---
int32 sum

Étape 2 : Contenu du CMakeLists.txt

Assure-toi que ton fichier CMakeLists.txt ressemble à ceci :

cmake_minimum_required(VERSION 3.0.2)
project(my_sum_package)

find_package(catkin REQUIRED COMPONENTS
  rospy
  std_msgs
  message_generation
)

## Déclaration du fichier .srv
add_service_files(
  FILES
  sum.srv
)

## Générer les messages et services
generate_messages(
  DEPENDENCIES
  std_msgs
)

catkin_package(
  CATKIN_DEPENDS rospy std_msgs message_runtime
)

include_directories(${catkin_INCLUDE_DIRS})

## Installation des scripts (client et serveur)
catkin_install_python(PROGRAMS
  scripts/client_node.py
  scripts/server_node.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

Étape 3 : Contenu du package.xml

Dans ton package.xml, assure-toi d'avoir les éléments suivants :

<package format="2">
  <name>my_sum_package</name>
  <version>0.0.1</version>
  <description>Package ROS pour additionner deux entiers</description>

  <maintainer email="ton_email@example.com">Ton Nom</maintainer>
  <license>MIT</license>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>message_generation</build_depend>

  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>
</package>

Étape 4 : Créer les scripts Python pour le serveur et le client

server_node.py

#!/usr/bin/env python3
import rospy
from my_sum_package.srv import sum, sumResponse

def handle_sum_request(req):
    result = req.a + req.b
    rospy.loginfo(f"Received: {req.a} + {req.b} = {result}")
    return sumResponse(result)

def sum_server():
    rospy.init_node('sum_server')
    service = rospy.Service('sum', sum, handle_sum_request)
    rospy.loginfo("Sum service is ready.")
    rospy.spin()

if __name__ == "__main__":
    sum_server()

client_node.py

#!/usr/bin/env python3
import rospy
from my_sum_package.srv import sum, sumRequest

def sum_client(a, b):
    rospy.wait_for_service('sum')
    try:
        sum_service = rospy.ServiceProxy('sum', sum)
        response = sum_service(a, b)
        return response.sum
    except rospy.ServiceException as e:
        rospy.logerr(f"Service call failed: {e}")

if __name__ == "__main__":
    rospy.init_node('sum_client')
    a, b = 3, 5  # Exemple d'entrées
    rospy.loginfo(f"Requesting {a} + {b}")
    result = sum_client(a, b)
    rospy.loginfo(f"Result: {result}")

Étape 5 : Générer les messages et services

Avant de compiler ton package, exécute les commandes suivantes dans ton terminal :

cd ~/catkin_ws
catkin_make
source devel/setup.bash

Étape 6 : Lancer le serveur et le client

Lance d'abord le serveur :

rosrun my_sum_package server_node.py

Dans un autre terminal, lance le client :

rosrun my_sum_package client_node.py

Conclusion

Tu devrais voir le serveur afficher la requête reçue et le client afficher le résultat de l'addition.

Si tu as des questions supplémentaires ou des problèmes pour exécuter le code, fais-le moi savoir ! 🚀

Maaliiik commented 1 week ago

!/usr/bin/env python

import rospy

imports the AddTwoInts service

from package.srv import *

add two numbers using the add_two_ints service

@param x int: first number to add

@param y int: second number to add

def sum_client(): rospy.init_node("sum_client") service = rospy.ServiceProxy('sum', sum) x = 2 y = 3 z = 4 resp = service(x,y,z) print(resp)

if name == "main": sum_client()

Maaliiik commented 1 week ago

publisher

!/usr/bin/env python

import rospy from std_msgs.msg import Int32MultiArray

if name == 'main' : rospy.init_node('send_array' , anonymous=True) pub = rospy.Publisher('chatter' , Int32MultiArray , queue_size = 10 ) rate = rospy.Rate(10) while not rospy.is_shutdown(): int_array_msg = Int32MultiArray() int_array_msg.data = [1, 2, 3, 4, 5] pub.publish(int_array_msg) print(int_array_msg) rate.sleep()

================================

subscriber :

!/usr/bin/env python

import rospy from std_msgs.msg import Int32MultiArray

def callback(msg) : avg = sum(msg.data) / len(msg.data) print("ive heard and computed the average", avg)

if name == 'main': rospy.init_node("receive_int") rospy.Subscriber('chatter' , Int32MultiArray, callback) rospy.spin()

============================ launch file :