[MoveIt2-humble] Tutorial de introducción (traducido del documento oficial) 1: El primer programa C++ MoveIt

0 frontera

Hay cuatro capítulos en esta serie de tutoriales, y el entorno es:

  • Ubuntu22.04
  • ros2-humilde
  • MoveIt2-humilde

Los tutoriales en la documentación oficial son básicamente los mismos desde el melódico de moveit1 hasta el foxy de moveit2, pero ha habido grandes cambios desde el último humilde, uno de los cuales es el uso generalizado de expresiones lambda.

Esta sección es la primera sección del tutorial. La premisa es que debe completar el contenido de la sección anterior para instalar el paquete del tutorial. Puede leer la publicación de mi blog: https://blog.csdn.net/qq_43557907/article /detalles/125636298 Tutorial de cuatro
secciones Lo llevará mano a mano para escribir un programa completo de control de Moveit, que incluye planificación de trayectoria, visualización de RViz, adición de objetos de colisión, agarre y colocación.

Para obtener más información, puede ir al documento oficial para ver: https://moveit.picknik.ai/humble/index.html
Esta serie de blogs es mi traducción personal, que es conveniente para mi propio aprendizaje y uso.

1 Crear un paquete de dependencia

Ingrese al directorio src debajo del espacio de trabajo donde se encuentra el tutorial y cree un nuevo paquete de dependencia.

ros2 pkg create \
 --build-type ament_cmake \
 --dependencies moveit_ros_planning_interface rclcpp \
 --node-name hello_moveit hello_moveit

Agréguelo al paquete recién creado hello_moveit.cpp, listo para comenzar a codificar

2 Crear nodos y ejecutores de ROS

#include <memory>

#include <rclcpp/rclcpp.hpp>
#include <moveit/move_group_interface/move_group_interface.h>

int main(int argc, char * argv[])
{
    
    
  // 初始化 ROS 并创建节点
  rclcpp::init(argc, argv);
  auto const node = std::make_shared<rclcpp::Node>(
    "hello_moveit",
    rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)
  );

  // 创建一个 ROS logger
  auto const logger = rclcpp::get_logger("hello_moveit");

  // Next step goes here

  // 关闭 ROS
  rclcpp::shutdown();
  return 0;
}

2.1 Compilar y ejecutar

Podemos intentar compilarlo y ejecutarlo para ver si hay algún problema.

2.2 Descripción del código

En la parte superior están los encabezados estándar de C++, seguidos de los encabezados agregados para usar con ROS y Moveit.

Después de esto, inicializamos rclcpp y creamos el nodo.

auto const node = std::make_shared<rclcpp::Node>(
  "hello_moveit",
  rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)
);

El primer parámetro es el nombre del nodo. El segundo parámetro es importante para Moveit porque vamos a usar parámetros ROS.

Finalmente, cierre el nodo.

3 Utilice MoveGroupInterface para planificar y ejecutar

Agregue el siguiente nodo después de "El siguiente paso va aquí" en el código:

// 创建 MoveIt 的 MoveGroup 接口
using moveit::planning_interface::MoveGroupInterface;
auto move_group_interface = MoveGroupInterface(node, "panda_arm");

// 设置目标位姿
auto const target_pose = []{
    
    
  geometry_msgs::msg::Pose msg;
  msg.orientation.w = 1.0;
  msg.position.x = 0.28;
  msg.position.y = -0.2;
  msg.position.z = 0.5;
  return msg;
}();
move_group_interface.setPoseTarget(target_pose);

// 创建一个到目标位姿的规划
auto const [success, plan] = [&move_group_interface]{
    
    
  moveit::planning_interface::MoveGroupInterface::Plan msg;
  auto const ok = static_cast<bool>(move_group_interface.plan(msg));
  return std::make_pair(ok, msg);
}();

// 计算这个规划
if(success) {
    
    
  move_group_interface.execute(plan);
} else {
    
    
  RCLCPP_ERROR(logger, "Planing failed!");
}

3.1 Compilar y ejecutar

Abra el archivo de inicio en el tutorial para iniciar los nodos rviz y MoveGroup, obtenga este espacio de trabajo en otro terminal y ejecute:

ros2 launch moveit2_tutorials demo.launch.py

Luego, en Displaysla ventana de abajo MotionPlanning/Planning Request, anule la selección Query Goal State.

En una tercera terminal fuente y permitir nuestro programa en este apartado:

ros2 run hello_moveit hello_moveit

Nota:

Si ejecuta el nodo hello_moveit sin ejecutar el archivo de inicio, se informará el siguiente error después de esperar 10 segundos:

[ERROR] [1644181704.350825487] [hello_moveit]: Could not find parameter robot_description and did not receive robot_description via std_msgs::msg::String subscription within 10.000000 seconds.

Esto se debe a que demo.launch.pyse inicia el nodo MoveGroup, que proporciona información de descripción del robot. Cuando MoveGroupInterfaceesté construido, buscará el nodo que publica el tema descrito por el robot, si no lo encuentra en 10 segundos, imprimirá un mensaje de error y finalizará el programa.

3.2 Descripción del código

Primero necesitamos crear MoveGroupInterface, este objeto se usa para interactuar con move_group para que podamos planificar y ejecutar trayectorias. Tenga en cuenta que este es el único objeto mutable que creamos en el programa.

La siguiente es la segunda interfaz de MoveGroupInterface que creamos "panda_arm", que es el grupo conjunto definido en la descripción del robot, y lo operaremos a través de MoveGroupInterface.

using moveit::planning_interface::MoveGroupInterface;
auto move_group_interface = MoveGroupInterface(node, "panda_arm");

Después de eso, establezca la pose y el plan objetivo. La pose del punto de partida se publica a través del editor estatal conjunto, que se puede MoveGroupInterface::setStartState*cambiar usando las funciones en (ninguna en este tutorial)

Cree infotipos target_posey esquemas utilizando expresiones lambda.

// 利用 lambda 函数来创建目标位姿
auto const target_pose = []{
    
    
  geometry_msgs::msg::Pose msg;
  msg.orientation.w = 1.0;
  msg.position.x = 0.28;
  msg.position.y = -0.2;
  msg.position.z = 0.5;
  return msg;
}();
move_group_interface.setPoseTarget(target_pose);

// 利用 lambda 函数来创建到目标位姿的规划
// 注:这里使用了 C++ 20标准的新特性
auto const [success, plan] = [&move_group_interface]{
    
    
  moveit::planning_interface::MoveGroupInterface::Plan msg;
  // 强制类型转换
  auto const ok = static_cast<bool>(move_group_interface.plan(msg));
  return std::make_pair(ok, msg);
}();

Finalmente, el plan se calcula si tiene éxito y se devuelve un mensaje de error si el plan falla.

// Execute the plan
if(success) {
    
    
  move_group_interface.execute(plan);
} else {
    
    
  RCLCPP_ERROR(logger, "Planning failed!");
}

ampliar conocimientos

Usamos expresiones lambda para inicializar objetos como constantes, lo que se conoce como técnica IIFE. Obtenga más información sobre este patrón en Historias de C++ .

También sabemos que todo se puede usar como una constante Lea más sobre la utilidad de const aquí .

Próximo paso

En el próximo capítulo , Visualización en RViz , enriqueceremos el programa en este capítulo y crearemos marcadores visuales para que nos sea más fácil saber qué está haciendo MoveIt.

Supongo que te gusta

Origin blog.csdn.net/qq_43557907/article/details/125679824
Recomendado
Clasificación