0 граница
В этой серии руководств четыре главы, а среда такова:
- Убунту22.04
- ros2-скромный
- MoveIt2-скромный
Учебники в официальной документации в основном такие же, от мелодики moveit1 до лисички moveit2, но со времени последнего humble произошли большие изменения, одним из которых является широкое использование лямбда-выражений.
Этот раздел является первым разделом учебника. Предпосылка состоит в том, что вам необходимо заполнить содержимое предыдущего раздела, чтобы установить пакет учебника. Вы можете прочитать это сообщение в моем блоге: https://blog.csdn.net/qq_43557907 /article/details/125636298 Учебник из четырех
разделов Поможет вам написать полную программу управления Moveit, включая планирование траектории, визуализацию RViz, добавление объектов столкновения, захват и размещение.
Для получения дополнительной информации вы можете перейти к официальному документу для просмотра: https://moveit.picknik.ai/humble/index.html
Эта серия блогов является моим личным переводом, который удобен для моего собственного изучения и использования.
1 Создайте пакет зависимостей
Войдите в каталог src в рабочей области, где находится учебник, и создайте новый пакет зависимостей.
ros2 pkg create \
--build-type ament_cmake \
--dependencies moveit_ros_planning_interface rclcpp \
--node-name hello_moveit hello_moveit
Добавьте его во вновь созданный пакет hello_moveit.cpp
, готовый к началу кодирования.
2 Создайте узлы и исполнители 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 Скомпилируйте и запустите
Мы можем попытаться скомпилировать и запустить его, чтобы увидеть, есть ли какие-либо проблемы.
2.2 Код Описание
Вверху находятся стандартные заголовки C++, за которыми следуют заголовки, добавленные для использования с ROS и Moveit.
После этого мы инициализируем rcclcpp и создаем узел.
auto const node = std::make_shared<rclcpp::Node>(
"hello_moveit",
rclcpp::NodeOptions().automatically_declare_parameters_from_overrides(true)
);
Первый параметр — это имя узла. Второй параметр важен для Moveit, потому что мы собираемся использовать параметры ROS.
Наконец, закройте узел.
3 Используйте MoveGroupInterface для планирования и выполнения
Добавьте следующий узел после «Следующий шаг идет здесь» в коде:
// 创建 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 Скомпилируйте и запустите
Откройте файл запуска в руководстве, чтобы запустить узлы rviz и MoveGroup, запустите эту рабочую область в другом терминале и выполните:
ros2 launch moveit2_tutorials demo.launch.py
Затем в Displays
окне ниже MotionPlanning/Planning Request
снимите выделение Query Goal State
.
В третьем источнике терминала и разрешите нашу программу в этом разделе:
ros2 run hello_moveit hello_moveit
Примечание:
Если вы запустите узел hello_moveit без запуска файла запуска, после ожидания в течение 10 секунд будет сообщено о следующей ошибке:
[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.
Это связано с тем, что узел demo.launch.py
запущен MoveGroup
, который предоставляет информацию об описании робота. Когда MoveGroupInterface
он будет построен, он будет искать узел, который публикует тему, описанную роботом, и если не найдет его в течение 10 секунд, он выведет сообщение об ошибке и завершит работу программы.
3.2 Код Описание
Сначала нам нужно создать MoveGroupInterface, этот объект используется для взаимодействия с move_group, чтобы мы могли планировать и выполнять траектории. Обратите внимание, что это единственный изменяемый объект, который мы создаем в программе.
Далее идет второй интерфейс созданного нами MoveGroupInterface "panda_arm"
, представляющий собой объединенную группу, определенную в описании робота, и мы будем управлять ею через MoveGroupInterface.
using moveit::planning_interface::MoveGroupInterface;
auto move_group_interface = MoveGroupInterface(node, "panda_arm");
После этого установите целевую позу и планируйте. Поза отправной точки публикуется через средство публикации состояния, которое можно MoveGroupInterface::setStartState*
изменить с помощью функций (в этом руководстве их нет).
Создавайте инфо-типы target_pose
и схемы с помощью лямбда-выражений.
// 利用 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);
}();
Наконец, в случае успеха план вычисляется, а в случае неудачи возвращается сообщение об ошибке.
// Execute the plan
if(success) {
move_group_interface.execute(plan);
} else {
RCLCPP_ERROR(logger, "Planning failed!");
}
расширить знания
Мы использовали лямбда-выражения для инициализации объектов как констант, что известно как метод IIFE. Подробнее об этом шаблоне читайте в C++ Stories .
Мы также знаем, что в качестве константы можно использовать все что угодно. Подробнее о полезности const здесь .
Следующий шаг
В следующей главе «Визуализация в RViz» мы дополним программу этой главы и создадим визуальные маркеры, чтобы нам было легче понять, что делает MoveIt.