Операция пространственного распознавания myCobot с использованием RealSense D455
Операция пространственного распознавания myCobot с использованием RealSense D455

1. Введение

Отдел передовых технологий работает над мультимодальным обучением с подкреплением, включая изображения с камер и тактильные датчики. Помимо прочего, для реализации так называемого Sim2Real, в котором результаты обучения с подкреплением в симуляторе также выполняются на реальной машине, роботизированная рука и камера реальной машины должны управляться совместно. Поэтому в данном случае мы протестировали связанный 6-осевой роботизированный манипулятор myCobot (производства Elephant Robotics) и камеру глубины RealSense D455 (производства Intel) с использованием ROS, процесс и результаты будут подробно описаны ниже.

Операционная среда:

PC:Ubuntu 20.04, ROS Noetic, Python 3.8.10

Роботизированная рука: myCobot280 M5Stack

Камера глубины: RealSense D455

В этом блоге описывается, как создать и запустить простую программу, но я предполагаю, что среды ROS и Python уже настроены.

2. Основы работы с коллаборативными роботами

Сначала подготовьте myCobot, но я немного запутался, потому что некоторые детали изменились в процессе использования из-за обновлений прошивки и так далее. Эта работа находится в 2021 Год 3 Оно было завершено около 2 месяцев назад, когда myStudio версия 1.3.<>。Я не думаю, что будут какие-то серьезные изменения,Но если посмотреть на разницу в приезжать,Смотрите официальное описание.

Для запуска myCobot необходимы следующие три подготовки.

● Обновить прошивку(базовый,атом)

● Калибровка суставов роботизированной руки.

● Последовательная связь между манипулятором робота и ПК.

Обновить прошивку

myCobot 280 M5 имеет M5Stack Basic в основании и ATOM (Basic, ATOM) на конце роботизированной руки для записи прошивки в эти два модуля.

Во-первых, используйте USB подключиться к ПК и использование chmod Разрешить чтение и запись на устройство. также,Для последовательной связи USB на Windows или Mac,Требуется установкаспециальный водитель

Язык кода:javascript
копировать
$ sudo chmod 666 /dev/ttyUSB*

Следующий,Загрузите обновленную прошивкуПриложение-myStudio(существовать На момент написания,до настоящего времениверсия3.1.4,Но только для Windows,3.1.3 доступна для Linux).

После извлечения исходного кода и выполнения AppImage запустится Basic и ATOM соответственно. Как показано на рисунке 1 и рисунке 2.

В myStudio 3.1.3 появится экран, показанный на рисунках 3 и 4, затем загрузите последнюю версию Minirobot для Basic и AtomMain для ATOM, выберите Flash и запишите прошивку. После завершения написания с использованием Basic на панели отобразится вывод мини-робота. (Обратите внимание, что если вы не напишете последнюю версию с использованием Basic и ATOM, манипулятор робота может работать некорректно).

После Обновить прошивку следующим шагом будет калибровка угла шарнира.

Калибровка угла шарнира

Сначала выберите «Калибровка» на панели «Основные» и нажмите «ОК».

На каждом сочленении myCobot есть выемка, обозначающая начало координат, как показано на рис. 5, поэтому выемки выравниваются друг с другом вручную.

В этом состоянии выберите «Калибровать сервопривод» на панели «Основные» и нажмите «Далее», чтобы завершить калибровку. Запуск тестового сервопривода позволит двигателю слегка вращаться вокруг выемки, чтобы подтвердить правильную калибровку.

Последовательная связь между манипулятором робота и ПК

Наконец, когда вы запустите транспондер, вы сможете управлять myCobot со своего ПК через последовательную связь. Это легко сделать: просто выберите транспондер на панели «Основные» и нажмите «ОК». Затем на дисплее появится изображение, как показано на рисунке 6. Нажмите кнопку «Основные».

В других меню панели Basic Master Control в Basic управляет ATOM, а Information проверяет правильность подключения каждого соединения. Если myCobot не работает должным образом на вашем компьютере, вы можете проверить, есть ли проблема с самим myCobot.

3. интерфейс Python

После завершения подготовки мы можем управлять myCobot на ПК. На этот раз я попробовал метод работы из скрипта Python с использованием pymycobot и метод работы MoveIt из ROS с использованием библиотеки mycobot_moveit.

первый,Установитьpymycobot。

Язык кода:javascript
копировать
$ pip install pymycobot --upgrade

Вы также можете выбрать из Github Загрузите и установите исходный код.

Примеры сценариев включаются в тестовый каталог при загрузке из исходного кода. Однако в исходном виде это не сработает, поэтому будьте осторожны. Я сделал пример ниже вместо того, чтобы переписывать его.

Язык кода:javascript
копировать
# mycobot_control_test.py#!/usr/bin/env pythonimport time from pymycobot.mycobot import MyCobotfrom pymycobot.genre import Angle, Coord if __name__ == "__main__":port = "/dev/ttyUSB0"mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False) #After the baud rate are the default values #Get the operation of the joint angleprint("get angles")print(" degrees: {}\n".format(mycobot.get_angles()))time.sleep(0.5) print("get radians")print(" radians: {}\n".format(mycobot.get_radians()))time.sleep(0.5) print("send angles: [0, 0, 0, 0, -90, 0]")mycobot.send_angles([0, 0, 0, 0, 0, 0], 80)time.sleep(1.5)mycobot.send_angles([0, 0, 0, 0, -90, 0], 80)print(" Is moving: {}\n".format(mycobot.is_moving()))time.sleep(1.5) print("send radians: [0, 0, 0, 0, 1.57, 0]\n")mycobot.send_radians([0, 0, 0, 0, 1.57, 0], 80)time.sleep(1.5) print("send angle to joint 4: -90\n")mycobot.send_angle(Angle.J4.value, -90, 80)time.sleep(1.5) # Operations to get coordinatesprint("get coordination")print(" coordination {}\n".format(mycobot.get_coords()))time.sleep(0.5) print("send coordination: [50, 50, 300, 0, 0, 0] → [50, 50, 300, 90, 90, 0]\n")coord_list = [50, 50, 300, 0, 0, 0]mycobot.send_coords(coord_lis, 70, 0)time.sleep(3.0)coord_list = [50, 50, 300, 90, 90, 0]mycobot.send_coords(coord_lis ,70, 0)time.sleep(1.5) # Scenarios using grippers# print("open gripper")# mycobot.set_gripper_state(0,0)# time.sleep(1.0)# print("close gripper")# mycobot.set_gripper_state(1,80)# time.sleep(1.0) time.sleep(1.5)print("release all servos")mycobot.release_all_servos()

бегатьmycobot_control_test.pyдокумент

Язык кода:javascript
копировать
$ python3 mycobot_control_test.py

Создайте экземпляр класса MyCobot в модуле mycobot и используйте геттеры и сеттеры для проверки и изменения состояния.

Создать экземпляр

Язык кода:javascript
копировать
mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False)

Установите четыре параметра. Введите значение по умолчанию после скорости передачи данных. порт USB последовательный порт связи。Вы можете пройтисуществоватьв терминалебегатьls / dev /Приходите и посмотритеподключиться список устройств к ПК. существует Linux, если нет другого USB-порта для последовательной связи, то это Воля. dev / ttyUSB0。Я думаюMacиWindowsотличается,Поэтому проверьте соответственно.

О геттерах

get_angles ( ) и get_radians () — функция, которая получает угол соединения в градусах и радианах. Возвращаемое значение представляет собой список из шести значений угла соединения.

Есть еще одинget_coords( )функция,Он получает нижний центр в качестве начала координат.координироватьсистема*кончик средней рукикоординировать。Возвращаемое значение представляет собой 6 Список размеров, содержащий наконечники x、y、z координировать (mm) и направление rx、ry、rz(угол)。существовать Нет MoveIt В этом случае действительно приятно реализовать инверсную кинематику.

*координироватьсистема:к“базовый”Панель задняя,Каждое положительное направление x: вперед, y: влево и з: Вверх. Обратите внимание, что MoveIt Векторы немного отличаются, о чем речь пойдет позже.

О установщике

кстепеньи弧степеньдля单位发送закрывать节角изфункциядаsend_angles ( ) и send_radians ( ),И имеет два типа настройки параметров.

Сначала после указания и отправки всех 6 сустав, первый параметр такой же, как getter То же, поместите в список 6 Значение с плавающей запятой, второй параметр — скорость движения сустава. *(int: 0 ~ 100)。

Язык кода:javascript
копировать
mycobot .send_angles ( [ 0 , 0 , 0 , 0 , 0 , 0 ] , 80 )

Далее вы берете угол сустава и отправляете его. Пожалуйста, укажите код угла шарнира в первом параметре, значение угла во втором параметре и скорость в третьем параметре.

Язык кода:javascript
копировать
mycobot .send_angle ( Angle.J4.value , -90,80 )

Вы также можете получить действие, используя координацию, например геттер. существуют В данном случае помещаются 6 список элементов [x, y, z, rx, ry, rz],Первый параметр согласован,Второй параметр — скорость,Третий параметр — это режим. Есть два типа узоров,0: Угол и 1: Линейный

Язык кода:javascript
копировать
mycobot .send_coords ( [ [ 80 , 50 , 300 , 0 , 90 , 0 ] , 70 , 0 )

Поскольку единицы скорости не указаны подробно в исходном коде, я предполагаю, что вы измеряете их там, где это необходимо.

Другие интерфейсы

Как только роботизированная рука начнет двигаться,Двигатель Воля продолжает подавать крутящий момент, пытаясь сохранить текущее состояние.,Так что, если мы оставим все как есть,Двигатель перегружен. поэтому,Давайтесуществоватьдействовать После завершенияиспользоватьфункцияrelease_all_servos(y)Сбросьте крутящий момент двигателя。

Если робот-манипулятор продолжает работать,и вы приказываете ему выполнить другое действие,произойдет ошибка,После этого Воля переходит к следующему действию. существовать пример сценария,pythonвстроенныйфункцияtime.sleep()Используется для ожидания завершения каждого действия,Но ты можешькиспользоватьфункцияis_moving()Чтобы узнать, исправен ли двигательсуществоватьбегать,чтобы вы могли зацикливаться в то время как и т.д. (Я думаю, что эта функция неправильная,и возвращает постоянно движущееся состояние.

Есть и другие API Может использоваться для включения и выключения питания, изменения LED цвета, а также проверку состояния мотора, но на этот раз я их пропустил, поскольку цель — переместить руку.

4. Стандарты только для чтения

Затем используйте MoveIt в ROS для управления myCobot.

слон роботвыполнитьmycobot action, его можно установить иМожетк Установить

Существует добровольная реализация MoveIt, и я решил ее использовать. Установка основана на вышеизложенном. GitHub Файл Readme написан.

Язык кода:javascript
копировать
$ cd /src$ git clone https://github.com/Tiryoh/mycobot_ros$ git clone https://github.com/nisshan-x/mycobot_moveit$ rosdep update$ rosdep install -i –from-paths mycobot_moveit$ cd .$ catkin_make #Set up work area$ source devel/setup.bash

После завершения установки и настройки рабочего пространства

Язык кода:javascript
копировать
$ roslaunch mycobot_moveit mycobot_moveit_control.launch

MoveIt и Rviz GUI начнется, как показано на рисунке 7 Рассчитайте положение конечного положения руки робота, перетащив зеленый шарик, затем нажмите кнопку плана и выполнения в левом нижнем углу, Rviz. Двигайтесь вместе с настоящим роботом.

* Когда модель и фактическая машина не работают вместе

Я не знаю, является ли это ошибкой, которая возникает во всех средах.,А модели и реальные машины не всегда работают вместе. Это ошибка, возникающая при изменении направления вращения двигателя на противоположное.,Так что это немного сложно,Но сравните, пожалуйста, модель Воли с реальной машиной.,Ищите вращение суставов в противоположных направлениях.

Убедившись, сколько суставов вращается в противоположных направлениях, перепишите файл URDF, описывающий модель робота.

/ src / mycobot_moveit / urdf / mycobot_urdf_gazebo.urdf

Описание определенной совместной информации выглядит следующим образом.

Язык кода:javascript
копировать
mycobot_urdf_gazebo.urdf ~~  <joint name="arm1_joint" type="revolute">        <parent link="body_link" />        <child link="arm1_link" />         <origin xyz="0 0 0.0706" rpy="0 0 0" />         <axis xyz="0 0 1" />        <limit effort="30" lower="-2.88" upper="2.88" velocity="1.5" />     </joint> ~~

Arm1 ~ arm6_joint Те же инструкции。Направление оси вращения установлено на<осьxyz = “0 0 1”> </ось>,А установка 1→-1 инвертирует вращение сустава в противоположную сторону.

В моем окружении кажется, что все суставы, кроме третьего, перевернуты. Я не знаю, связано ли это с индивидуальными различиями сервоприводов роботов или с другими причинами, если знаете, подскажите.

Вот и все, от настройки myCobot до основ работы.

5. Базовые знания реалистичного D455.

На этот раз я тестировал его с D455.,Но в принципе серию D400 можно использовать точно так же. Только D435i и D455 имеют встроенные датчики IMU.,Но в этой статье не используется приезжать (поскольку недостатки накопления ошибок более очевидны, чем преимущества существующего использованияIMU в фиксированном состоянии). В дополнение к серии D400 с инфракрасным стереоскопическим,Еще есть L515 с LiDAR.,Но цель та же. кроме того,Я думаю, что новый работает лучше всего,Так что куплю Д455. Я думаю, что перед покупкой лучше проконсультироваться со средой, которую вы хотите использовать.,Потому что есть некоторые детали (предыдущие модели в основном обратно совместимы,Таким образом, существует компромисс между ценой и производительностью).

Установка программного обеспечения Viewer и основные операции

Установочная библиотека librealsense Чтобы запустить настоящий смысл. Без этого realsense_ros, о котором будет рассказано далее, работать не будет. Возникает вопрос о том, как Linux Документация по его установке. При необходимости Windows начальствоиз Установитьметод также находится там жедокументбиблиотека。

Язык кода:javascript
копировать
# Server Public Key Registration$ sudo apt-key adv –keyserver keyserver.ubuntu.com –recv-key F6E65AC044F831AC80A06380C8B3A55A6F3EFCDE||  Adding a Repository$ sudo add-apt-repository “deb https://librealsense.intel.com/Debian/apt- repo $(lsb_release -cs) main” -u# install lib$ sudo apt install librealsense2-dkms librealsense2- utils# install dev$ sudo apt install librealsense2-dev librealsense2-dbg

После завершения установки запустите RealSense Viewer в терминале, чтобы просмотреть его. Если это не помогло, попробуйте отключить и снова подключить USB-соединение RealSense и перезагрузить компьютер. Если запуск прошел успешно, программа просмотра отобразится, как показано на рисунке 8.

Вы можете использовать 2D | 3D кнопка в 2D и 3D Переключайтесь между зрителями. Кроме того, вы можете просмотреть информацию о глубине и информацию RGB, открыв стереомодуль и камеру RGB слева. существовать 2D , ты можешь 2D Посмотреть в RGB и информация о глубине. В существующем 3D облако точек, оцененное инфракрасной стереокамерой, оценивающей глубину, окрашено в соответствии с информацией о цвете глубины изображения и RGB-камерой и может просматриваться под всеми углами. Кроме того, встроенный IMU датчик D435i и D455 Информацию об отношении также можно получить с помощью модуля движения. Далее давайте рассмотрим использование ROS Пакет realsense_ros Rviz Облако точек. Это можно сделать с помощью apt Установить.

Язык кода:javascript
копировать
$ sudo apt install ros-$ROS_DISTRO-realsense2-camera

Камеры RealSense запускаются на первом терминале и помимо информации с каждой камеры предоставляется цветное облако точек, а на втором терминале запускается Rviz для визуализации.

Язык кода:javascript
копировать
$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$rviz

Чтобы просмотреть облако точек, как показано на рисунке 9, мы будем использовать графический интерфейс для настройки параметров.

первый,потому чтолевая сторонапоказыватьв панелиГлобальные вариантыиз фиксированная рамаДакартина,Пожалуйста, нажмите на него и Воляэто изменилось наcamera_link。

Затем нажмите кнопку «Добавить» в нижней части панели дисплея, и появится новое окно со списком доступных Rviz показано в ROS Тип сообщения. выбирать rviz середина группы PointCloud2 и нажмите OK Воля PointCloud2 Добавить на панель отображения.

также,Если нажать в группе"тема”Столбец правыйизпустойи Выберите, чтобы появитьсяиз /camera/depth/color/points,Тогда облако точек Воляпоказыватьсуществовать Rviz начальство. По умолчанию размер облака точек установлен на 0.01 м, что является большим значением, поэтому облака точек перекрывают друг друга, но если Воля установлено значение 0.001 m Справа и слева вы можете видеть, что облако точек получено очень четко.

также,Если от "Добавить" выберите "TF" и добавьте его,则Можеткпоказыватьположение камерыи направление(ось К)。По умолчанию,RGB происхождение камерыитрехмерныйпроисхождение камерысоответственнопоказыватьсуществоватьмиркоординироватьсистемаи Оптикакоординироватьсистемасередина。(camera_linkПохоже, имеет то же происхождение, что и стереокамеры.)

Сохраните настройки, так как будет сложно каждый раз выскакивать эту кнопку.

Создайте конфигурацию каталога в рабочей области для сохранения настроек в Rviz издокументсередина选择Воля Конфигурация Другойсохранить как,Создать имяизКонфигурациякаталог и сохраните。

Язык кода:javascript
копировать
$ rviz -d .rviz

Если вы что-то измените,则Можетк每次通过保存КонфигурацияОбновите то же самоеиздокумент.Если вы просто смотрите на облако точекиположение камеры,Вы можете легко это сделать с помощью Realsense_viewer.,Но ты можешькиспользовать ROS для обработки необработанных данных. С этого момента это похоже на понимание ROS Упражнение на значение данных сообщения.

(Но лично для меня это большой камень преткновения)

осуществлятьrs_camera.launch после фильтра:=облако точек

давайте посмотрим Отправлено с другого терминала /camera/depth/color/points Исходные данные субъекта.

Язык кода:javascript
копировать
$ rostopic echo /camera/depth/color/points

Конечно, этот массив значений представляет собой данные облака точек,его следует использовать xyz координироватьи Расположениесерединаиз RGB Представление значения, но его трудно прочитать напрямую. Если вы посмотрите на цифры, вы увидите, что каждое значение находится в 0 приезжать 255 диапазон, и подобные значения встречаются регулярно и по регулярной схеме. Но угадайте отсюда x Неразумно представлять, где и где представляет красный цвет.

Итак, сначала выясните, что это за тип сообщения.

Язык кода:javascript
копировать
$ rostopic type /camera/depth/color/pointssensor_msgs/PointCloud2

Теперь мы знаем, что тип сообщения sensor_msgs/PointCloud2。

Кроме того, если вы начинаете с ROS документ Посмотреть вэто,您Можетксмотретьприезжать Следующее содержание。

Язык кода:javascript
копировать
Header header # header uint32 height # number of rows of datauint32 width # Number of columns of dataPointField[] fields # 1 point data structurebool is_bigendian # whether the big enduint32 point_step # number of bytes in a point (number of 8-bit numbers)uint32 row_step # number of data in a row (= width * point_step)uint8[] data # raw data (8bit row_step * height data array)bool is_dense # if true, then no invalid data

Так как это облако точек,Поэтому оно отличается от 2D-изображения.,Что означает порядок данных? Как следует из вопроса,Высота и ширина, кажется, не имеют смысла.

Непонятно, что значит хранить переменную, которую можно вычислить из других значений и вряд ли использовать, но структура такая. Если вы хотите увидеть фактическую ценность каждого из них,

Язык кода:javascript
копировать
$ rostopic echo /camera/depth/color/points/<Variable Name>

Сделав это, активируйте,В данных можно вывести только одну переменную. Например,показыватьразpoint_stepиполе дает。

Язык кода:javascript
копировать
$ rostopic echo /camera/depth/color/points/point_step–20—$ rostopic echo /camera/depth/color/points/fields–name: “x”offset: 0datatype: 7count: 1–name: “y”offset: 4datatype: 7count: 1–name: “z”offset: 8datatype: 7count: 1–name: “rgb”offset: 16datatype: 7count: 1—

Выход Воля потому что point_step = 20, вы можете увидеть данные о прибытии в одну точку, 20 байтовое представление, вы можете увидеть содержимое поля от в этом 20 Как составляются байты.

Значение каждой переменной

имя:выражатьизданныеизимя

Компенсировать:переписыватьсяизбайт

Тип данных:представленныйданныеизкод типа

считать:Включатьизданные Количество предметов

Например,х координироватьсоответствуетот 0 приезжать 3 Данные, код типа 7 (соответствует float32), представляет данные. y и z следует обращаться таким же образом, но RGB Тоже выражается таким же образом. Когда я просматриваю RGB Соответствующий 16 приезжать 19 ценность, есть GBRA Последовательное шестнадцатеричное значение. приезжать float32 Преобразование xyz координироватьи RGB。

Теперь, когда мы знаем, как представлять данные, давайте поработаем с ними.

(Я думаю, что есть более разумный и быстрый способ обработать следующий скрипт, поэтому, если у вас есть какие-либо предложения, пожалуйста)

В каталог скриптов «Воля» добавлен пакет mycobot_test, и туда добавлен скрипт Python.

Язык кода:javascript
копировать
$ cd /src/mycobot_test$ mkdir scripts$ cd scripts$ touch red_point_detection.py$ touch object_position_search.py

Воля Добавлены зависимостиприезжать CMakeLists.txt и упакуйте .xml.

Язык кода:javascript
копировать
# CMakeLists.txtfind_package(catkin REQUIRED COMPONENTS # Add rospy and sensor_msgs modules to be able to import     rospy sensor_msgs ) catkin_package( # Add build package     sensor_msgs ) # Add scripts to the executable directory catkin_install_python(PROGRAMS    DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}/scripts )Python<!-- package.xml --><!-- add -->  <build>rospy</build>   <build>sensor_msgs</build> <!-- package.xml --><!-- add -->  <build>rospy</build>   <build>sensor_msgs</build>

к Внизred_point_detection.pyэто сценарий,Он только извлекает красный цвет из облака точек и создает новое сообщение.

Язык кода:javascript
копировать
#!/usr/bin/env python3 import time, os, sys, signal, threading import numpy as np import rospy from sensor_msgs.msg import PointCloud2  class RedPointsDetectionNode(object):     def __init__(self):         super(RedPointsDetectionNode, self).__init__()         self.data = PointCloud2()         self.point_step = 20         self.R_COL = 18         self.G_COL = 17         self.B_COL = 16         rospy.init_node("red_points_detection_node")         rospy.loginfo("red points detection start")      # Subscriber             def sub_pointcloud(self):         def callback(data):             self.sub_data = data         sub = rospy.Subscriber("camera/depth/color/points", PointCloud2, callback = callback)         rospy.spin()      # Publisher     def pub_red_pointcloud(self):         pub = rospy.Publisher("red_point_cloud", PointCloud2, queue_size = 1)         while not rospy.is_shutdown():             pub_data = self.red_point_detection(self.sub_data)             pub.publish(pub_data)                  def red_point_detection(sub_data):             red_point_data = sub_data             red_pointcloud = np.array([d for d in sub_data.data]).reshape(-1, self.point_step)             r_flags = red_pointcloud < 180             g_flags = red_pointcloud > 150             b_flags = red_pointcloud > 150             R_under_threshold_row = np.where(r_flags)[0][np.where(np.where(r_flags)[1]==self.R_COL)]             G_over_threshold_row = np.where(g_flags)[0][np.where(np.where(g_flags)[1]==self.G_COL)]             B_over_threshold_row = np.where(b_flags)[0][np.where(np.where(b_flags)[1]==self.B_COL)]             not_red_row = np.unique(np.concatenate([R_under_threshold_row, G_over_threshold_row, B_over_threshold_row]))              red_pointcloud = np.delete(red_pointcloud, not_red_row, axis=0).ravel().tolist()             red_point_data.width = int(len(red_pointcloud) / self.point_step)             red_point_data.height = 1             red_point_data.row_step = pub_pc2_data.width * self.point_step             red_point_data.data = red_pointcloud             rospy.loginfo("red pointcloud {}".format(int(len(red_pointcloud) / self.point_step)))             return red_point_data          # node start to subscribe and publish     def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         pub_red_pointcloud = threading.Thread(target = self.pub_red_pointcloud)          sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         pub_red_pointcloud.setDaemon(True)         pub_red_pointcloud.start()          sub_pointcloud.join()         pub_red_pointcloud.join()  if __name__ == "__main__":     color_points_detector = ColorPointsDetectionNode()     color_points_detector.start_node()     pass

Подписчик читаеткамера/глубина/цвет/данные точки,Только издательотданныесередина提取красная точкаираспределениеэтоих。иметь дело скрасная точкакот原始точка云середина删除 RGB ценитьдляf R < 180、G > 150 и B > 150 източка。использоватьHSVСравниватьRGBлучше,На RGB легко влияют условия освещения,Но на этот разсуществоватьиметь дело сPointCloud2данные сложные Преобразовать вHSV, поэтому был отложен. Если это C++, используйте PCL кажется легко сделать python преобразование, но для python Это бесполезно, потому что другие процедуры писать сложно).

После написания,Мобильное рабочее место Volyaits,catkin_make и выполните его.

Язык кода:javascript
копировать
$ roslaunch realsense2_camera rs_camera.launch filters:=pointcloud$ rosrun mycobot_test red_point_detection.py$ rviz -d .rviz

если в Rviz Выберите Добавить место проживания. PointCloud2 в сообщении /red_point_cloud,Вы можете увидеть облако точек, полученное с помощью приезжать.,нравитьсякартина 10 показано.

object_position_search.pyэто сценарий,Используется для нахождения среднего значения извлеченных координированных красных точек.

Язык кода:javascript
копировать
# object_position_search.py#!/usr/bin/env python3 import time, os, sys, signal, threading  import numpy as np  import rospy from sensor_msgs.msg import PointCloud2 import sensor_msgs.point_cloud2 as pc2 from geometry_msgs.msg import Point  class ObjectPositionSearchNode(object):     def __init__(self):         super(ObjectPositionSearchNode, self).__init__()         rospy.init_node("object_position_search_node")         rospy.loginfo("object position search start")         self.object_position = Point()      # Subscriber             def sub_pointcloud(self):         def callback(data):             rospy.loginfo("subscribed pointcloud")             xyz_generator = pc2.read_points(data, field_names = ("x", "y", "z"), skip_nans=True)             xyz_list = [gen for gen in xyz_generator]             list_num = len(xyz_list)             x = np.array([xyz_list[i][0] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])             y = np.array([xyz_list[i][1] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])             z = np.array([xyz_list[i][2] for i in range(list_num) if (xyz_list[i][2] < 1.0 and xyz_list[i][2] > -1.0)])                          self.object_position.x = np.average(x)             self.object_position.y = np.average(y)             self.object_position.z = np.average(z)          sub = rospy.Subscriber("red_point_cloud", PointCloud2, callback = callback)         rospy.spin()          # Publisher     def pub_target_position(self):         pub = rospy.Publisher("object_position", Point, queue_size=1)         while not rospy.is_shutdown():             rospy.loginfo("published object position: {:.5f}, {:.5f}, {:.5f}\n".format(self.object_position.x, self.object_position.y, self.object_position.z))             pub.publish(self.object_position)             def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         pub_target_position = threading.Thread(target = self.pub_target_position)          sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         pub_target_position.setDaemon(True)         pub_target_position.start()          sub_pointcloud.join()         pub_target_position.join()  if __name__ == "__main__":     object_position_searcher = ObjectPositionSearchNode()     object_position_searcher.start_node()     pass

существовать Добегатьred_point_search.pyиз情况Вниз,Запустите новый терминал и запустите его.

Язык кода:javascript
копировать
$ rosrun mycobot_test object_position_search.py

Он принимает среднее значение red_point_cloudкоординировать. и распределяйте их, записывая значения. координировать в метрах, этот скрипт получает 1.0 точки в пределах метров. потому что чтоиспользовать rospy.loginfo Полученная координация протоколируется, поэтому координация выводится на терминал прибытия.

sensor_msgsбиблиотекаесть одинpoint_cloud2модуль,используется дляиметь дело сичитать PointCloud2 данные,Волякоординироватьценитьот 4Byte Преобразовать в float32。Содержание очень простое,Но мне сложно понять хранение этого модуля. Если у вас есть другие сложные данные сообщения,Лучше всего проверить, есть ли в комплекте модуль обработки. Это действительно настройка и обработка данных. Об обработке данных,Я думаю, вам все еще нужно найти метод более быстрой обработки (или улучшенного алгоритма).,Зависит от приложения.

6. Подключите myCobot к RealSense D455 с помощью ROS.

В настоящее время обработка реально-сенсорных данных завершена.,Я хочу объединить его с myCobot. поэтому,самое важноеиздаот Камера RealSenseкоординироватьсистемаприезжатьmyCobotкоординироватьсистемаиз Конвертировать。Rviz Есть один на TF (Transform) показывает ось камеры, но это нужно знать. Как следует из названия, оно описывает координационное преобразование, которое описывает отношения между одной координационной линией и другой координационной линией. Сначала посмотрим, не установлено ли это TF Что происходит.

Язык кода:javascript
копировать
$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ roslaunch mycobot_moveit mycobot_moveit_control.launch

Тогда ты Волясуществовать Rviz См. предупреждение на панели отображения, например, изображение. 11 показано.消息да相机изкаждыйкоординироватьсистема Все Неттрансформироватьприезжатьbase_link(myCobotизисточник)。

поэтому,Давайте создадим пакет,Воля TF (координировать преобразование)от трансляции камеры прибытия myCobot。ужасно жальсуществоватьC++иPythonмеждураз,но на этот раз я Воляиспользоватьroscpp。первый Создать пакет。

Язык кода:javascript
копировать
$ cd <your_ros_ws_for_MyCobot>/src$ catkin_create_pkg tf_broadcaster roscpp$ cd tf_broadcaster$ touch src/tf_broadcaster.cpp

переписатьгенерироватьизtf_broadcaster.cpp CMakeLists.txtpackage.xmlнравиться Внизпоказано.пожалуйста, обрати внимание,Файл C++ — это класс,Потому что он создан для практики создания узлов в существующем классе,Но можно написать проще.

Язык кода:javascript
копировать
// tf_broadcaster.cpp#include <ros/ros.h> #include <geometry_msgs/TransformStamped.h> #include <tf2_ros/static_transform_broadcaster.h> #include <tf2_geometry_msgs/tf2_geometry_msgs.h>  class TfBroadcaster { public:     TfBroadcaster();     ~TfBroadcaster(); // Broadcast     void BroadcastStaticTfFromCameraToMyCobot();  private:     ros::NodeHandle nh_; // TF Broadcaster     tf2_ros::StaticTransformBroadcaster static_tf_broadcaster_; // constant     double PI_ = 3.1419265; };  TfBroadcaster::TfBroadcaster(){} TfBroadcaster::~TfBroadcaster(){}  void TfMyCobotBroadcaster::BroadcastStaticTfFromCameraToMyCobot() {     geometry_msgs::TransformStamped transformStamped;     transformStamped.header.stamp = ros::Time::now();     transformStamped.header.frame_id = "camera_color_frame"; //link     transformStamped.child_frame_id = "base_link";     // son link   // Parallel movement     transformStamped.transform.translation.x = -0.3;     transformStamped.transform.translation.y = -0.3;     transformStamped.transform.translation.z = -0.3;     // Turning back         tf2::Quaternion q;     q.setEuler(0, 0, 0);     transformStamped.transform.rotation.x = q.x();     transformStamped.transform.rotation.y = q.y();     transformStamped.transform.rotation.z = q.z();     transformStamped.transform.rotation.w = q.w();          static_tf_broadcaster_.sendTransform(transformStamped);     }  int main(int argc, char** argv) {     ros::init(argc, argv, "tf_mycobot_broadcaster");     TfMyCobotBroadcaster tf_mycobot_broadcaster;     tf_mycobot_broadcaster.BroadcastStaticTfFromCameraToMyCobot();      ros::Rate loop_rate(10);     while(ros::ok()){         ros::spinOnce();         loop_rate.sleep();     }     return 0; }# CMakeLists.txtcmake_minimum_required(VERSION 3.0.2) project(tf_broadcaster) find_package(catkin REQUIRED COMPONENTS   roscpp geometry_msgs tf2_geometry_msgs) catkin_package( CATKIN_DEPENDS geometry_msgs tf2_geometry_msgs) include_directories(${catkin_INCLUDE_DIRS}) add_executable(tf_mycobot_broadcaster src/tf_mycobot_broadcaster.cpp) target_link_libraries(tf_mycobot_broadcaster ${catkin_LIBRARIES})<!-- package.xml --><?xml version="1.0"?> <package format="2">   <name>tf_broadcaster</name>    <version>0.0.0</version>   <description>The transform broadcaster package</description>   <maintainer email="root@todo.todo">root</maintainer>   <license>TODO</license>    <buildtool_depend>catkin</buildtool_depend>   <depend>tf2_geometry_msgs</depend>   <depend>geometry_msgs</depend> </package>

Как видите, мы установили transformStamped Переменные экземпляра класса и трансляция этого экземпляра. Тип широковещательной переменной — tf2_ros::StaticTransformBroadcaster, но на этот раз мы используем статический TF, поскольку положение иробота камеры фиксировано. Для тех, кто заинтересован, также можно использовать динамику, когда отношения позиций меняются со временем. TF。

существоватьздесь,Отношения между локациями пока неизвестны.,Так что ценность временная,Но мы можем сформировать шоу,Итак, давайте попробуем. также,родительская ссылкаcamera_color_frameвместоcamera_link,因дляродительская ссылкаиз原точка与точка云координироватьсистемасоответствовать。 catkin_makeназад,картинак То же, что и раньшебегать rs_camera.launch и mycobot_moveit_control.launch,исуществовать Другойодин Запустить в терминалеtf_broadcaster。

Язык кода:javascript
копировать
$ rosrun tf_broadcaster tf_broadcaster

Это вещательный имидж-сканер Воля и myCobot base_linkмеждуиз Расположениезакрыватьсистема,поэтомуTFпредупреждение исчезает。если в этом состоянии добавляется облако точек, похожее на картину 12 Конечно, позиционная взаимосвязь между камерой и myCobot является временной, поэтому камера видит положение myCobot в пункте прибытия и Рвизпоказано. в Позиции моделей не пересекаются.

поэтому,Следующийнас Волякалибровкаотсмотреть в камеруприезжатьизроботизотносительная позаи Расположение。

Я думаю, что есть другой способ указать метод позиционных отношений, зафиксировав существующую конкретную позицию с помощью камеры Воля.,Но на этот раз мы отметим три пункта, чтобы определить роботокоординировать,Мы калибруем позиционное соотношение, находя единичный вектор прибытия и вычисляя его относительно кадра камеры.

Некоторые из вас, возможно, заметили приезжать,Предыдущее фото было сделано, когда существование уже было подключено отметка,Но отметка размещена так, как показано на картинке 13.

продовольственная отметка

myCobot Начало координат (внизу в центре) находится на отметке 2 и 3 середина, отметка 1 Отрезок, перпендикулярный началу координат 2 и 3。

1.первый,переписатьred_point_detection.pyисоздаватьblue_point_detection.pyкпосинетьотметкаизточка云。Сценарий здесь опущен,因дляэто只дапереписать Быть извлеченнымиз RGB объем. После этого я подумал, что есть несколько способов получить координированное преобразование, но на этот раз оно было получено с помощью следующего процесса. ОК отметка координировать Подписаться на облако тегированных точек

один. Облако точек Воли, сгруппированное в три (средним методом k)

2. Определите начало координат и единичный вектор отметка 2 и 3 Средняя точка — это начало координат V_robot.

один. Х и Y Орты V_XиV_Y соответственно V_robot →отметка 1、V_robot →отметка 2。

б. Единичный вектор Z — это векторное произведение плоскости и вектора нормали с отметкой.

3. использовать углы Эйлера создать позу камеры приезжатьповорот робота позы theta_1 = Угол возвышения камеры относительно горизонтальной плоскости

a.theta_2 = угол поворота к передней части камеры

b.theta_3 = Угол между камерой и направлением перед роботом

4. Воля V-Z Зарождение направления Преобразовать в myCobot фиксированная база (2,7 сантиметр)

* Ось, от которой начинается вращение Эйлера, произвольна, поэтому результаты будут различаться в зависимости от рассматриваемой библиотеки. (Думаю, не все удосуживаются это сделать, поэтому мне было интересно, передадите ли вы единичный вектор и начало координат двух координационных систем и есть ли какая-нибудь библиотека Воля, Преобразовать которую в TF。

Следующий скрипт Воля добавлен в каталог скриптов приезжать.

Язык кода:javascript
копировать
/*
* Совет: Эта строка кода слишком длинная, и система автоматически комментирует ее, не выделяя. Один клик копировать удалит системные комментарии 
* # mycobot_position_calibration.py#!/usr/bin/env python3 import time, os, sys, signal, threading  import numpy as np  import rospy from sensor_msgs.msg import PointCloud2 from geometry_msgs.msg import Point import sensor_msgs.point_cloud2 as pc2  class MyCobotPositionCalibrationNode(object):     def __init__(self):         super(MyCobotPositionCalibrationNode, self).__init__()         rospy.init_node("mycobot_position_calibration_node")         rospy.loginfo("mycobot position calibration start")      # Subscriber             def sub_pointcloud(self):         def callback(data):             self.data = data             rospy.loginfo("subscribed pointcloud")             xyz_generator = pc2.read_points(self.data, field_names = ("x", "y", "z"), skip_nans=True)             xyz_list = [xyz for xyz in xyz_generator if (abs(xyz[0]) < 0.8 and abs(xyz[1]) < 0.8 and abs(xyz[2]) < 0.8)]             xyz_array = np.array(xyz_list)              if len(xyz_list) > 3:                 marker_centroids = self.kmeans(3, xyz_array)                 rospy.loginfo("\n marker positions\n{}".format(marker_centroids))                 translation = self.cal_translation(marker_centroids)                 rospy.loginfo("\n translation\n{}".format(translation))                          sub = rospy.Subscriber("blue_point_cloud", PointCloud2, callback = callback)         rospy.spin()      # node start     def start_node(self):         sub_pointcloud = threading.Thread(target = self.sub_pointcloud)         sub_pointcloud.setDaemon(True)         sub_pointcloud.start()         sub_pointcloud.join()          # clustering method     def kmeans(self, k, X, max_iter=30): # k: cluster num, X: numpy array         data_size, n_features = X.shape         centroids = X[np.random.choice(data_size, k)]         new_centroids = np.zeros((k, n_features))         cluster = np.zeros(data_size)         for epoch in range(max_iter):             for i in range(data_size):                 distances = np.sum((centroids - X[i]) ** 2, axis=1)                 cluster[i] = np.argsort(distances)[0]             for j in range(k):                 new_centroids[j] = X[cluster==j].mean(axis=0)             if np.sum(new_centroids == centroids) == k:                 break             centroids = new_centroids         max_norm = 0         min_norm = 0         sorted_centroids = []         for centroid in centroids:             norm = centroid[2]             if norm > max_norm:                 sorted_centroids.append(centroid)                 max_norm = norm                 if min_norm == 0:                     min_norm = sorted_centroids[0][2]             else:                 if norm > min_norm and min_norm != 0:                     sorted_centroids.insert(1, centroid)                 else:                     sorted_centroids.insert(0, centroid)                     min_norm = norm         sorted_centroids = np.array(sorted_centroids)          return sorted_centroids      # translation angles calculation     ## calculation     def cal_translation(self, marker_points):         # マーカー1, 2, 3-позиционный вектор         #Position vector of marker 1, 2, 3         a_1, a_2, a_3 = marker_points         # カメラからロボットへのベクトル         #Vector from camera to robot         V_robot = self.cal_robot_position_vector(a_2, a_3)         # Единичный вектор робота XYZ         #XYZ unit vector of the robot         V_X = (a_2 - V_robot) / (np.linalg.norm(a_2 - V_robot))         V_Y = (a_1 - V_robot) / (np.linalg.norm(a_1 - V_robot))         V_Z = self.cal_normal_vector(marker_points)          # Угол подъема камеры относительно горизонтальной плоскости         # Elevation angle of the camera relative to the horizontal plane         theta_1 = - (np.pi/2 - self.cal_subtended_angle(-V_robot, V_Z))         # Угол поворота камеры вперед         #Rotation angle of the camera in the frontal direction        V_Y_camera = np.array([0, 1, 0])         V_Y_camera_rotated = self.cal_rotate_vector_xaxis(V_Y_camera, -theta_1)         theta_2 = - self.cal_subtended_angle(V_Z, -V_Y_camera_rotated)         # Угол между камерой и направлением движения робота вперед         #Angle between the camera and the respective frontal direction of the robot         _, V_robot_projected_to_plane = self.cal_vector_projection(V_robot, V_Z)         theta_3 = self.cal_subtended_angle(V_Y, V_robot_projected_to_plane)         # положение микобота до базовой высоты 0,027 m, Перевод в направлении В_З         # mycobot position at foundation height 0.027 m, parallel to V_Z direction         V_robot = V_robot + 0.027*V_Z          return V_robot, theta_1, theta_2, theta_3       ## vector and angle caluculation     def cal_robot_position_vector(self, a_2, a_3):         return (a_2 + a_3) / 2      def cal_normal_vector(self, marker_points):         a_1 = marker_points[0]         a_2 = marker_points[1]         a_3 = marker_points[2]         A_12 = a_2 - a_1         A_13 = a_3 - a_1         cross = np.cross(A_13, A_12)         return cross / np.linalg.norm(cross)      def cal_subtended_angle(self, vec_1, vec_2):         dot = np.dot(vec_1, vec_2)         norm_1 = np.linalg.norm(vec_1)         norm_2 = np.linalg.norm(vec_2)         return np.arccos( dot / (norm_1 * norm_2) )          def cal_vector_projection(self, org_vec, normal_vec):         # org_vec: вектор, который вы хотите проецировать         # org_vec: the vector you want to project                 # normal_vec: Нормальный вектор плоскости, которую вы хотите проецировать.          # normal_vec: Normal vector of the plane to be projected                projected_to_vertical = np.dot(org_vec, normal_vec) * normal_vec         projected_to_horizontal = org_vec + projected_to_vertical         return projected_to_vertical, projected_to_horizontal      def cal_rotate_vector_xaxis(self, vec, angle):         rotate_mat = np.array([[1, 0, 0], [0, np.cos(angle), np.sin(angle)], [0, -np.sin(angle), np.cos(angle)]])         return vec.dot(rotate_mat)      def cal_rotate_vector_yaxis(self, vec, angle):         rotate_mat = np.array([[np.cos(angle), 0, -np.sin(angle)], [0, 1, 0], [np.sin(angle), 0, np.cos(angle)]])         return vec.dot(rotate_mat)      def cal_rotate_vector_zaxis(self, vec, angle):         rotate_mat = np.array([[np.cos(angle), np.sin(angle), 0], [-np.sin(angle), np.cos(angle), 0], [0, 0, 1]])         return vec.dot(rotate_mat)  if __name__ == "__main__":     mycobot_position_calibrator = MyCobotPositionCalibrationNode()     mycobot_position_calibrator.start_node()      pass
*/

на этот разнасотнедавноизmarker_1Настроить камеруиробот,в соответствии сэтоихиз Расположениезакрыватьсистемаmarker_2иmarker_3,Но следует отметить, что,Необходимо отрегулировать в зависимости от положения камеры.

После завершения строительства в трех терминалах запускаются камера и узлы цветового поиска и калибровки «Волясуществовать» соответственно.

Язык кода:javascript
копировать
$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ rosrun mycobot_test blue_point_detection.py$ rosrun mycobot_test mycobot_position_calibration.py

Это рекордное перевоплощение Воля t_x, y, z (m) и угол Эйлера theta_1, 2, 3 (радиан) приезжать mycobot_position_calibration.py Терминал. Эти ценности потомому чтоточка云данныесобиратьи Колебания из-за кластеризации,Поэтому значения усредняются несколько раз. (существовать в этой настройке,Параллельный переводи угол Эйлера колеблются ок. 1%)

После получения значения перезапишите временное значение в tf_broadcaster.cpp.

Язык кода:javascript
копировать
// tf_broadcaster.cpp~~ # それぞれ t_x,y,z と theta_1,_2,_3 поместите полученное значение в # Put the obtained values in t_x,y,z and theta_1,_2,_3 respectively     transformStamped.transform.translation.x = t_z;     transformStamped.transform.translation.y = -t_x;     transformStamped.transform.translation.z = -t_y;          tf2::Quaternion q;     q.setEuler(theta_1, theta_2, theta_3); ~~

Ясуществоватьнаходясь в поискеотcamera_color_frameприезжатьbase_linkизTF,Группировка точек обнаружения координирует систему camera_length_optical_frame,вычислитьназадxyzРазные направления(я Нет Уведомлениеприезжатьразница,Я запутался) Итак x = t_z,y = - t_x,z = - t_y

После переписывания и catkin_make запустите узел.

Язык кода:javascript
копировать
$ roslaunch realsense2_camera rs_camera.launch filter:=pointcloud$ roslaunch mycobot_moveit mycobot_moveit_control.launch$ rosrun tf_broadcaster tf_broadcaster

Затемотражение Камераироботиз Расположениезакрыватьсистема,роботиRviz Модель робота, показанная на облаке точек, может быть наложена,нравитьсякартина14показано.

картина 14: Значения, полученные при калибровке Воляот, установлены на TF итранслироватьэтои Несовершенный,Но мне удалось удержать отклонение в допустимых пределах.,Чтобы легко доставать и брать предметы.

Вы можете увидеть это при перемещении облака точек и наложенной модели робота.

Суставы myCobot имеют небольшой люфт, что затрудняет точные движения.

потому Облако точек, полученное с помощью чтоот, получено с помощью Преобразовать Система координации вmyCobot, поэтому мы пытаемся позиционировать кончик ВоляmyCobot как объект. (Я пытался картинуиспользовать MoveIt чтобы получить к нему доступ, но он застрял в C++, поэтому я сделал тот, который работает, используя pymycobot Удобный скрипт)

потому то, что координирует, находится в оптической системе камеры, поэтому переведите и поверните их, полученные ранее вmyCobotкоординировать отдел. Воля В каталог сценариев приезжать добавлен следующий контент.

Язык кода:javascript
копировать
# mycobot_reaching.py#!/usr/bin/env python3 import time, os, sys  import numpy as np import quaternion from pymycobot.mycobot import MyCobot  import rospy from geometry_msgs.msg import Point from tf.transformations import quaternion_from_euler  class MyCobotReachingNode(object):     def __init__(self):         super(MyCobotReachingNode, self).__init__()         rospy.init_node("mycobot_reaching_node")         rospy.loginfo("mycobot reaching start")          # переменная-член         # mycobot インスタンス         # member variable         # mycobot instance         port = "/dev/ttyUSB0"         self.mycobot = MyCobot(port, baudrate="115200", timeout=0.1, debug=False)         # Перевод и вращение         # Обратите внимание, что оси XYZ отличаются от раздела 4.2, поскольку оптическая система координат → система координат микобото.         # Translation and rotation         # Note that the XYZ axes are different from those in section 4.2 because the optical coordinate system is a mycoboto coordinate system                 self.translation_from_camera_to_mycobot = np.array([t_x, t_y, t_z])         q = quaternion_from_euler(-theta_2, -theta_3, theta_1)         self.rotation_from_camera_to_mycobot = quaternion.as_quat_array(q)         # subscriber         self.sub_point()      # Subscriber             def sub_point(self):         def callback(data):             rospy.loginfo("subscribed target point")             self.mycobot_move(data)          sub = rospy.Subscriber("object_position", Point, callback = callback)         rospy.spin()      # move mycobot     def mycobot_move(self, point_data):         # Преобразование в систему координат mycobot          # Convert to mycobot coordinate system         target_point = np.array([point_data.x, point_data.y, point_data.z])         target_point -= self.translation_from_camera_to_mycobot         target_point = quaternion.rotate_vectors(self.rotation_from_camera_to_mycobot, target_point)          # *1000 для миллиметровых блоков, x-20 мм для достижения ближе к центру передней части, z+40mm         # *1000 for mm increments, x-20mm, z+40mm for reaching around the center of the front                 coord_list = [target_point[0]*1000-20, -target_point[2]*1000, target_point[1]*1000+40, 0, 90, 0]         self.mycobot.send_coords(coord_list, 70, 0)         time.sleep(1.5)  if __name__ == "__main__":     reaching = MyCobotReachingNode()     pass

На этот раз я, Воля, мобилизовал все библиотеки, которые использую, и сделал Скрипт.

Ты можешь 6 Запустить в терминале rs_camera.launchmycobot_moveit_control.launchtf_broadcasterred_point_detection.pyobject_position_search.pymycobot_reaching.py,Но каждый раз, когда я открываю терминал,Вам всем придется его настроить... отладка будет затруднена.,поэтому请создавать自己иззапускатьдокумент.

Трансфер на рабочее место,Создать каталог и файлы для запуска,И добавьте CMakeLists.txt в путь запуска.

Язык кода:javascript
копировать
$ cd <your_ros_ws_for_MyCobot>/src/mycobot_test$ mkdir launch$ cd launch$ touch mycobot_reaching.launch<!-- mycobot_reaching.launch --><launch>     <include file="$(find mycobot_moveit)/launch/mycobot_moveit_control.launch" />     <include file="$(find realsense2_camera)/launch/rs_camera.launch">         <arg name="filters" value="pointcloud"/>     </include>      <node name="tf_broadcaster" pkg="tf_broadcaster" type="tf_broadcaster" />      <node name="color_points_detectior" pkg="mycobot_test" type="red_points_detection.py" output="screen" />     <node name="object_position_searcher" pkg="mycobot_test" type="object_position_search.py" output="screen" />     <node name="mycobot_reaching_node" pkg="mycobot_test" type="mycobot_reaching.py" /> </launch># CMakeLists.txt~~# Add launch fileinstall(FILES   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch ) ~~

Структура стартового файла очень проста.,Просто расположите файлы запуска узлов, которые вы хотите запускать одновременно, и файлы запуска на вкладке запуска. Узел для выполнения,Пожалуйста, напишите любое имя узла в отметке существования узла.,И напишите имя пакета и имя исполняемого файла, как это делает rosrun. добавить вывод = "экран",Если вы хотите, чтобы вывод отображался в командной строке.

существующий загрузочный файл выполняется при запуске существования, содержит отметку, содержит путь к файлу. Попробуйте catkin_make и запустите его.

Язык кода:javascript
копировать
$ roslaunch mycobot_test mycobot_reaching.launch

Я могу перемещать своего Кобота, чтобы отслеживать красный объект, захваченный RealSense, как в первом фильме.

До реализации проекта было много задержек, и я всегда чувствовал, что недостаточно учился во всех аспектах.

7. Резюме

В этой статье я расскажу, как использовать ROS координировать 6 осевой манипулятор myCobot Глубина камеры Реальный смысл Д455. У меня нет опыта разработки роботов, в том числе ROS. Я не думаю, что есть блог Подвести итог Понял меняприезжатьдо сих порот Начните пробоватьизсодержание,Итак, если вы купили роботизированную руку или камеру глубины, но не знаете, как ею пользоваться,Надеюсь, это поможет тем, кто задается вопросом, как его использовать. кроме того,Если бы кто-то, имеющий опыт разработки роботов или хорошо разбирающийся в обработке данных, мог бы указать, как лучше всего сделать что-то подобное.,Я Воля был бы очень благодарен.

На этот раз я Воля Я существовал в симуляторе, чтобы применить модель обучения с подкреплением для передвижения к myCobot.,и провел эксперимент по сбору,Так что я могу написать еще один блог как часть 2.

ссылка

1. Сунлин Дажи, 2022.12.21, Управляйте myCobot, используя пространственное распознавание с помощью Practice D455. https://blog.albert2005.co.jp/2022/12/21/realsense-d455_mycobot/

2. Альберт Ко. https://www.albert2005.co.jp/english/

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose