418 lines
38 KiB
Markdown
418 lines
38 KiB
Markdown
---
|
||
id: o2ac-repo-review
|
||
title: 'O2AC Assembly Challenge 2021'
|
||
---
|
||
## Предыстория
|
||
|
||

|
||
|
||
Команда O2AC на World Robot Summit 2020 Assembly Challenge состояла из представителей OMRON SINIC X , OMRON , Osaka University, National Institute for Advanced Science and Technology (AIST) и Chukyo University.
|
||
|
||
[Репозиторий](https://github.com/o2ac/o2ac-ur) который недавно был выложен на платформу GitHub данной командой, является их открытым исходным кодом, где представлено множетсво полезных решений в области автоматизированной сборки робототехническим сборочным комплексом. Их решение сводилось к полной автоматизации заранее заданной происзводственной операции. Итак рассмотрим основные фичи, которые были продемонстрированы этой командой
|
||
|
||
1. Всё програмное обеспечение строилось на основе _ROS Kinetic_ в Docker контейнере
|
||
2. Используются одновременно 2 робота-манипулятора без риска столкновения
|
||
3. Вставка детали в отверстие производится с помощью контроля импеданса
|
||
4. Выравнивание детали производится за счёт сестемы технического зрения на библиотеке _OpenCV_
|
||
5. Планирование следующего дейтсвия выполняется в момент выполнения траектории роботом-манипулятором, что оптимизирует общее время выполнения операции
|
||
6. Автоматизированное закручивание винтов
|
||
7. Используется собственно разработанный инструмент для затягивания винтов
|
||
8. Обнаружение и захват деталей расположенных в лотке неструктурировано
|
||
9. Для установленных деталей используется библиотека TF которая содержит локальную систему координат каждого установленного элемента
|
||
|
||
## Обзор репозитория
|
||
|
||
Репозиторий состоит из 19 пакетов, в том числе есть пакеты которые достойны рассмотрения для реализации нашего Робосборщика. Кратко пройдёмся по каждому из них.
|
||
|
||
### aist_modules
|
||
|
||
Данный пакет является метапакетом и разрабатывался членами команды из университета AIST. Он включает себя пакеты для 3D локализации и калибровки камер. Данный пакет можно рассмотреть в качестве альтернативы, но на сегодняшний момент возможно найдутся и другие пакеты которые справятся лучше.
|
||
|
||
### o2ac_assemble_database
|
||
|
||
Данный пакет содержит базу данных, а также классы и их методы для загрузки сборок в сцену планирования MoveIt.
|
||
|
||
Загрузка данных для сборки производится за счёт [Python скрипта](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_assembly_database/src/o2ac_assembly_database/parts_reader.py) `parts_reader.py` который загружает объекты в сцену как объекты с коллизией из исходных `.yaml` файлов в папке `o2ac_assembly_database/config/name_of_config/`. Также в данной базе данных присуствует информация о позиционировании захватного устройства, при захвате детали. Все эти данные загружаются непосредственно на сервер ROS откуда они уже забираются определённой нодой. Такая архитектура свойственна для ROS1, для ROS2 подход координально отличается, потому что параметры загружаются в ноду непосредственно при её запуске.
|
||
|
||
Если предыдущий скрипт брал геометрию каждой детали и публиковал их в сцену MoveIt, то следующий [скрипт](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_assembly_database/src/o2ac_assembly_database/assembly_reader.py) `Assembly_reader.py` делает всё тоже самое, но также ведёт обработку древовидной сборки и публикацию данной сборки в TF формате. То есть прямым образом заносит информацию на сервер какая деталь куда должна устанавливаться. Отдельно интересует данный фрагмент кода:
|
||
|
||
```python
|
||
def get_frame_mating(self, base_object, child_object):
|
||
'''
|
||
Эта функция возвращает сопряжение двух деталей в сборке в виде сообщения geometry_msgs / Transform.
|
||
Вход 'base_object' - это строка, определяющая имя объекта, на который будет помещен дочерний объект.
|
||
Вход 'child_object' - это строка, определяющая имя объекта, который будет помещен в базовый объект.
|
||
Возвращает None, если между двумя объектами не определено сопряжение или объекты не являются частью загруженной сборки.
|
||
'''
|
||
base_object_id = next((part['id'] for part in self._parts_list if part['name'] == base_object), None)
|
||
child_object_id = next((part['id'] for part in self._parts_list if part['name'] == child_object), None)
|
||
transform = next((mating_transform for mating_transform in self.mating_transforms if int(mating_transform.header.frame_id.split('_')
|
||
[1]) == base_object_id and int(mating_transform.child_frame_id.split('_')[1]) == child_object_id), None)
|
||
if transform is not None:
|
||
frame_mating = get_transform(parent_frame=base_object + '/' + '_'.join(transform.header.frame_id.split('_')[2:]),
|
||
child_frame=child_object + '/' + '_'.join(transform.child_frame_id.split('_')[2:]),
|
||
transform=transform.transform)
|
||
return frame_mating
|
||
else:
|
||
return None
|
||
```
|
||
|
||
То есть данный фрагмент кода в соостветсвии с полученной базой данной последовательности сборки проверяет что куда устанавливать, выходом данной функции соответствует переменная `frame_mating` которая "судя по всему" является фреймом стыковки двух деталей.
|
||
|
||
Так как же обрабатывается последовательность сборки двух деталей. Об этом нам скажет следующий фрагмент скрипта:
|
||
|
||
```py
|
||
def get_assembly_tree(self, collision_objects=[]):
|
||
'''
|
||
Возвращает цель сборки в виде древа преобразования TF
|
||
'''
|
||
self.mating_transforms = self._read_frames_to_mate_csv()
|
||
if not self.mating_transforms:
|
||
rospy.loginfo("No assembly tree defined")
|
||
return False
|
||
base_id = int(self.mating_transforms[0].header.frame_id.split('_')[1]) # Имя фрейма - "part_NN _...""
|
||
base_name = next((part['name'] for part in self._parts_list if part['id'] == base_id), None)
|
||
base_object = next((collision_object for collision_object in self._collision_objects if collision_object.id == base_name), None)
|
||
assembly_tree = self._collision_object_to_tf_tree(base_object)
|
||
for mating_transform in self.mating_transforms:
|
||
child_id = int(mating_transform.child_frame_id.split('_')[1])
|
||
child_name = next((part['name'] for part in self._parts_list if part['id'] == child_id), None)
|
||
child_object = next((collision_object for collision_object in self._collision_objects if collision_object.id == child_name), None)
|
||
tree_2 = self._collision_object_to_tf_tree(child_object)
|
||
mating_transform.header.frame_id = mating_transform.header.frame_id
|
||
mating_transform.child_frame_id = mating_transform.child_frame_id
|
||
self._add_part_to_assembly_tree(assembly_tree, tree_2, mating_transform)
|
||
|
||
return assembly_tree
|
||
|
||
```
|
||
|
||
То есть после загрузки данных о деталях как последовательность сборки, формирутеся древо преобразований TF, в котором содержится информация о том что где должно стоять. Также есть интересная [функция](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_assembly_database/src/o2ac_assembly_database/assembly_reader.py#L244-L290), которая непосредственно отвечает за добавление одной последовательности в другую
|
||
|
||
Следующий скрипт `visualise_metadata.py` предназначен лишь для отображения позиция захвата деталей в сцене.
|
||
|
||
Также в пакете присуствуют файлы для описания последовательности сборки:
|
||
|
||
* `'name_of_parts'.yaml` - содержит описание для подфреймов и захватных поз для деталей по именам. Все они загружаются на сервер, где к ним можно получить доступ через `/'assembly_name'/'object_name'/'grasp_name'`. Либо получить все фреймы для захвата детали через `'assembly_name'/'object_name'`
|
||
* `frame_to_mate.csv` - содержит описание стыковки деталей в сборке. Сопряжение определяется между подфреймами двух деталей.
|
||
* `parts_list.yaml` - содержит список деталей в сборке `id`,`name` и `cad` поле
|
||
|
||
### o2ac_dynamixel
|
||
|
||
В рамках проекта Робосборщик, данный пакет не представляет интереса из-за его специфичности. В общем этот пакет является драйвером для двигателя Dynamixel.
|
||
|
||
### o2ac_examples
|
||
|
||
Пакет содержит реализацию подключения физического робототехнического комплекса O2AC и различные примеры с MoveIt. При запуске примеров, он обращается к базе данных, которая использовалась на WRC2020.
|
||
|
||
### o2ac_fastening_tools
|
||
|
||
Этот пакет контролирует крепежные инструменты, которые приводятся в действие двигателем XL320. Он также управляет механизмами всасывания и выпускания.
|
||
|
||
### o2ac_flexbe
|
||
|
||
Данный пакет построен за счёт инструмента налаживания логики конечных автоматов (state machines) под названием Flexbe. К сожалению на данный момент этот инструмент не портирован для ROS2, но является достаточно облегчающим в разработке последовательности действий автоматизированного роботизированного сборочного комплекса.
|
||
|
||
Каждое состояние описывается определёнными функциями в скрипте Python.
|
||
|
||
```py
|
||
def execute(self, userdata):
|
||
|
||
def on_enter(self, userdata):
|
||
|
||
def on_exit(self, userdata):
|
||
|
||
def on_start(self):
|
||
|
||
def on_stop(self):
|
||
```
|
||
|
||
Далее подобные состояния комбинируются за счёт графического интерфейса Flexbe и генерируется повередние робота. Пример графического интерфейса:
|
||
|
||

|
||
|
||
## o2ac_gazebo
|
||
|
||
Данный репозиторий включает сцену симуляции Gazebo для робототехнического сборочного комлпекса O2AC и не включает ничего специфичного, по типу плагинов для данной сцены.
|
||
|
||
## o2ac_moveit_config
|
||
|
||
Содержит стандартный конфигурацию для moveit подготовленную с помощью moveit_setup_assistant. Из нестандартного здесь представлен pilz_industrial_motion_planner который по-умолчанию не включен в moveit и интегрируется одельно, данный планер предоставляет удобный интерфейс реализации декартовых траекторий.
|
||
|
||
## o2ac_msgs
|
||
|
||
Содержит все используемые сообщения, сервисы и действия используемые в проекте. Список следующий:
|
||
|
||
### Сообщения
|
||
|
||
В основном все сообщения основаны на проверки текущей позы манипулятора, список следующий
|
||
|
||
* [Estimated2DPoses.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/Estimated2DPoses.msg)
|
||
* [Estimated2DPosesArray.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/Estimated2DPosesArray.msg)
|
||
* [Estimated3DPoses.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/Estimated3DPoses.msg)
|
||
* [LookObservation.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/LookObservation.msg)
|
||
* [PlaceObservation.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/PlaceObservation.msg)
|
||
* [RobotStatus.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/RobotStatus.msg)
|
||
* [TouchObservation.msg](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/msg/TouchObservation.msg)
|
||
|
||
## Сервисы
|
||
|
||
Также представлен набор сервисом для управления, рассмотрим список
|
||
|
||
* [FindObject.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/FindObject.srv)
|
||
* Принимает на вход
|
||
* `geometry_msgs/PoseStamped` Где ожидается объект
|
||
* `float64` Насколько далеко объект может быть от ожидаемой позиции (в метрах)
|
||
* `string` Деталь для обнаружения, например, "4" для двигателя
|
||
* `string` Камера, которая будет использоваться для распознавания ("phoxi", "a_bot_realsense" ...)
|
||
* Выдаёт на выходе
|
||
* `bool` истина/ложь о факте нахождения объекта
|
||
* `geometry_msgs/PoseStamped` позицию объекта
|
||
* [goToNamedPose.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/goToNamedPose.srv)
|
||
* Принимает на вход
|
||
* `string` Имя заранее определённой позиции в move_group как позицию каждого шарнира
|
||
* `string` Имя группы планирования, заранее определённой в move_group
|
||
* Выдаёт на выходе
|
||
* `bool` успех операции
|
||
* [pc2depth.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/pc2depth.srv)
|
||
* Принимает на входе
|
||
* `string` имя топика, по которому передаётся облако точек
|
||
* Выдаёт на выходе
|
||
* `sensor_msgs/Image` изображение
|
||
* [publishMarker.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/publishMarker.srv)
|
||
* Принимает на вход
|
||
* `geometry_msgs/PoseStamped` позицию для установки маркера в RViz
|
||
* `string` тип маркера
|
||
* Выдаёт на выходе
|
||
* Ничего не выдаёт
|
||
* [sendScriptToUR.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/sendScriptToUR.srv)
|
||
* Принимает на вход
|
||
* Общие параметры
|
||
* `string` имя робота
|
||
* `string` имя исполняемой программы
|
||
* Параметры для спирального поиска и линейного поиска
|
||
* `float64` Сила, которую применяет spiral_search или linear_search в Ньютонах
|
||
* `string` Направление движения робота в spiral_search / linear_search в виде строки (обычно X + или Z-) (НЕ ИСПОЛЬЗУЕТСЯ, если установлен force_direction_vector)
|
||
* `float64[]` То же, что и выше, но как вектор направления [x, y, z] в захвате TCP. РАБОТАЕТ ТОЛЬКО ДЛЯ LINEAR_SEARCH
|
||
* `float64[]` Размер спирали. В м. По умолчанию: 0,0065
|
||
* `float64[]` Как быстро спираль увеличивается в размере за один оборот. В м. По умолчанию: 0,002
|
||
* `float64[]` Угловое приращение (в градусах!), на которое нарезается каждый поворот.
|
||
* `geometry_msgs/Vector3` Для вставки и spiral_search. В Н/м. Система координат звена инструмента.
|
||
* `float64` Скорость, с которой "insert" и linear_search продвигаются вперед. Чем медленне, вероятно, точнее.
|
||
* `float64` Для метода линейного поиска в метрах
|
||
* `bool` peck_mode - использутеся в спиральном поиковом движении
|
||
* `bool` use_base_coords - для линейного поиска (linear_search)
|
||
* Для спирального движения
|
||
* `string` «X», «Y», «Z», «YZ» (45 градусов), «Y30Z60» (30 градусов). В захвате CSYS.
|
||
* `string` "X", "Y", "Z". В захвате CSYS.
|
||
* `float64` Насколько движение продвигается вперед за полный оборот
|
||
* `float64` Когда движение вперед заканчивается
|
||
* `float64` (Максимальная дистанция вставки элемента)
|
||
* `float64` Масса, используемая для контроля импеданса (по умолчанию: 10 кг)
|
||
* Для линейного передвижения реального робота
|
||
* `geometry_msgs/PoseStamped` целевая поза для линейного перемещения
|
||
* `float64` ускорение, параметр move_1 (по умолчанию: 0.5)
|
||
* `float64` скорость, параметр move_1 (по умолчанию: 0.05)
|
||
* Линейное движение
|
||
* `geometry_msgs/Point` для линейного перемещения последнего звена в его координатах (Z+ вперёд)
|
||
* `geometry_msgs/Point` для линейного перемещения в формате UR (угол-ось)
|
||
* `bool` если false, тогда TCP. Если true, тогда точка базы
|
||
* Позиции звеньев
|
||
* `float64` позиции звеньев
|
||
* Для грубой или адаптивной вставки
|
||
* `float64[]` целевая сила для грубого режима
|
||
* `float64[]` целевая поза для грубого режима
|
||
* `float64[]` целевая скорость для грубого режима
|
||
* `float64[]` движение для команды перемещения робота
|
||
* `bool` переключение между точками world и TCP для интерпретации вышеуказанных значений
|
||
* `string` Ось выравнивания UR в грубом режиме
|
||
* Новая поза TCP
|
||
* `float64` устанавливает преобразование из системы координат TCP как позу. С помощью команды URscript set_tcp (tcp_pose)
|
||
* Выдаёт на выходе
|
||
* `bool` успех
|
||
* [visualizePoseBelief.srv](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_msgs/srv/visualizePoseBelief.srv)
|
||
* Принимает на входе
|
||
* `moveit_msgs/CollisionObject` (комментария нет, надо посмотреть состав сообщения)
|
||
* `uint8`
|
||
* `geometry_msgs/PoseWithCovarianceStamped`
|
||
* `duration`
|
||
* `uint8` по умолчанию RPY_COVARIANCE = 0
|
||
* `uint8` по умолчанию LIE_COVARIANCE = 1
|
||
* Выдаёт на выходе
|
||
* Ничего не выдаёт
|
||
|
||
### Действия
|
||
|
||
Действия в ROS являются базовым конструктором связи с состоят из клиента и сервера. Модель такова, что клиент отсылает цель(запрос) серверу, который заточен на выполнение определённой операции и получает результат этого действия. В данном репозитории присутствует огромная библиотека действий, подразделяемая также на общие, техническое зрение и поведение. Рассмотрим список общих действий в проекте:
|
||
|
||
* DynamixelGripperCommand.action
|
||
* ScrewToolControl.action
|
||
* SuctionControl.action
|
||
* changeTool.action
|
||
* estimateTooltipDistance.action
|
||
* insert.action
|
||
* pickScrewFromFeeder.action
|
||
* place.action
|
||
* regrasp.action
|
||
* screw.action
|
||
* suckScrew.action
|
||
* updateDistribution.action
|
||
|
||
Рассмотрим список действия для технического зрения
|
||
|
||
* beltDetection.action
|
||
* checkPickSuccess.action
|
||
* detectAngle.action
|
||
* detectCableTip.action
|
||
* detectObjectTip.action
|
||
* detectOrientation.action
|
||
* get2DPosesFromSSD.action
|
||
* get3DPosesFromSSD.action
|
||
* getGraspCandidates.action
|
||
* getTipDistanceToHole.action
|
||
* localizeObject.action
|
||
* shaftHoleDetection.action
|
||
* shaftNotchDetection.action
|
||
|
||
Рассмотрим список действия поведения робота
|
||
|
||
* AlignBearingHoles.action
|
||
* Fasten.action
|
||
* FastenBearing.action
|
||
* Handover.action
|
||
* Insert.action
|
||
* MoveTo.action
|
||
* Orient.action
|
||
* Pick.action
|
||
* PlayBackSequence.action
|
||
|
||
## o2ac_parts_description
|
||
|
||
Данный пакет не эксплуатировался в последней версии проекта представленной на WRC2020, соответственно опустим
|
||
|
||
## o2ac_routines
|
||
|
||
Данный пакет является основным в перечне и предоставляет скрипты Python и управляющие программы C++ для управления всей роботизированной системой.
|
||
|
||
* taskboard.py и assembly.py запусают конкурсные задания
|
||
* calibration.py и osx_view_testing.py являются процедурами калибровки и тестирования
|
||
* Остальные файлы (например test.py) предназначены для разных тестов и прочего неважного кода.
|
||
|
||
### Класс Controller
|
||
|
||
* [`common.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/common.py) определён в [`base.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/base.py) и предлагает класс для управления всей роботизированной системой. Этот класс ( O2ACCommon) владеет другими классами, которые управляют разными подсистемами:
|
||
* Робот руки (с помощью [`robot_base.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/robot_base.py), [`ur_robot.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/ur_robot.py), [`dual_arm.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/dual_arm.py), [`robotiq_gripper.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/robotiq_gripper.py) и [`ur_force_control.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/ur_force_control.py))
|
||
* Система технического зрения (через [`vision_client.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/vision_client.py))
|
||
* Винтовые инструменты (через [`tools.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/tools.py))
|
||
* [`taskboard.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/taskboard.py) и [`assembly.py`](https://github.com/o2ac/o2ac-ur/blob/main/catkin_ws/src/o2ac_routines/src/o2ac_routines/assembly.py) определены в O2ACCommon с помощью переменных и функций для конкретных задач
|
||
|
||
### Последовательность действий
|
||
|
||
Они реализуют командные последовательности, в которых следующее движение либо планируется, в то время как предыдущее движение выполняется, либо совместные траектории могут сохранены или загружены в или из файла для выполнения, не требуя дополнительного времени на планирование.
|
||
|
||
Для примера см. `subtask_zero` метод в `src/o2ac_routines/src/assembly.py`.
|
||
|
||
Также см. [Pilz_robot_programming](https://github.com/PilzDE/pilz_industrial_motion/tree/melodic-devel/pilz_robot_programming), чтобы узнать об альтернативной реализации Python, которая, вероятно лучше
|
||
|
||
## o2ac_rviz
|
||
|
||
Данный пакет включает в себя виджет для RViz, созданный для манипуляции и отладки процесса сборки. Каждый плагин для RViz пишется с использованием библиотеки Qt и интегрируется за счёт специального файла XML с описанием данного плагина.
|
||
|
||
## o2ac_scene_description
|
||
|
||
Данный пакет включает в себя описание роботизированной системы и сцен. Определения деталей можно найти в o2ac_parts_description. Сцены описаны с помощью фалов xacro (macro XML) и URDF (Unifined Robotic Description Format).
|
||
|
||
## o2ac_skills
|
||
|
||
Данный пакет не эксплуатировался в последней версии проекта представленной на WRC2020, соответственно опустим
|
||
|
||
## o2ac_task_planning
|
||
|
||
Данный пакет не эксплуатировался в последней версии проекта представленной на WRC2020, соответственно опустим
|
||
|
||
## o2ac_vision
|
||
|
||
Этот пакет содержит узлы, которые выполняют и передают дейсвия (actions) для комиьютерного зрения, например:
|
||
|
||
* Обнаружение объектов (SSD)
|
||
* Оценка позы детали (соответствие САПР)
|
||
* Определение позы захвата ремня
|
||
* Оценка вращения подшипника
|
||
|
||
Все навыки зрения основаны на действиях, поэтому расчетам разрешается сбой и тайм-аут.
|
||
|
||
Для этого узлы Python объявляют ряд действий, определенных в o2ac_msgs.
|
||
|
||
### Распознавание деталей
|
||
|
||
Узел распознавания детали состоит из двух компонентов. Один - это обнаружение объекта (Chukyo), другой - оценка позы (AIST).
|
||
|
||
#### Подготовка
|
||
|
||
Для модуля распознавания деталей требуются предварительно обученные шаблоны. Которые загружаются по следующим ссылкам:
|
||
|
||
* Предварительно обученные веса модели SSD. Которые переименовываются и загружаются в `WRS.pth` и помещаются в `wrs_dataset/ssd.pytorch`.
|
||
* Шаблоны изображений для обнаружения мелких деталей:[скачивание](https://drive.google.com/file/d/1EVTEMdHeOtzsVI9YkVpjS8h_67EkjK4k/view)
|
||
* Поместите `templates` в `wrs_dataset/data/`
|
||
* Шаблон изображения для оценки угла Беринга: [скачивание](https://drive.google.com/drive/folders/1qjwkHFLJ4KVpx1_S5BJLbSMZ4lKvtRPZ)
|
||
* Поместить `bearing_template_image.png` и `shaft_template_image.png` в `o2ac_vision/config`.
|
||
|
||
#### Обнаружение объектов
|
||
|
||
Скрипты Python для Single Shot MultiBox Detector (SSD) основаны на [ssd.pytorch](https://github.com/amdegroot/ssd.pytorch) . Этот модуль обнаруживает несколько объектов в лотке. Возвращает список в формате словаря, который содержит рамку выделения, идентификатор класса, состояние (перевернут или нет) и достоверность.
|
||
|
||
#### Оценка позы для мелких деталей
|
||
|
||
Этот компонент оценивает двухмерную позу (x, y, theta) малых целей в системе координат изображения. Он передает выходные данные модуля обнаружения объектов, список ограничивающей рамки и идентификатор класса объекта.
|
||
|
||

|
||
|
||
#### Оценка позиции двигателя и подшипниковой опоры
|
||
|
||
Этот компонент вычисляет угол поворота в плоскости подшипниковой опоры с использованием алгоритма ICP. Возвращает угол поворота против часовой стрелки и горизонтальное смещение.
|
||
|
||

|
||
|
||
### Порядок распознавания (AIST)
|
||
|
||
Вы можете построить порядок дейсвий от получения изображения до распознавания 3D - объектов, а также локализации с использованием `o2ac_vision` пакета, в сочетании с другими пакетами компьютерного зрения, т.е. `aist_depth_filter`, `aist_localization` и `aist_model_spawner`(по желанию). Порядок дейсвтий показан на следующем рисунке:
|
||
|
||

|
||
|
||
где приложение пользователя отображается зеленым цветом. Это клиентский узел, `o2ac_msgs.localizeObjectAction` который определяется как:
|
||
|
||
```shell
|
||
# Goal
|
||
string item_id
|
||
# (optional)
|
||
geometry_msgs/PoseWithCovarianceStamped expected_pose
|
||
---
|
||
# Result
|
||
bool succeeded
|
||
float32[] confidences
|
||
geometry_msgs/PoseStamped[] detected_poses
|
||
# (optional)
|
||
geometry_msgs/PoseWithCovarianceStamped[] detected_poses_with_covariance
|
||
```
|
||
|
||
Клиент запрашивает `/object_recognizer` найти объекты, указанные в `item_id` поле. В это время `item_id` должен быть именем файла сетки (без суффикса) , определенным в `o2ac_parts_description/meshes`, например `01-Base`, `04_37D-GEARMOTOR-50-70`, `08_KZAF1075NA4WA55GA20AA0` и т.д.
|
||
|
||
Порядок распознавания работает следующим образом
|
||
|
||
1. Когда в цели указан ID распознаваемого объекта, объект `/object_recognizer` отправляет цель `o2ac_msgs.get2DPosesFromSSDAction` типа в объект `/object_detector`.
|
||
2. В `/object_detector` ведётся поиск всех известных объектов через [SSD](#обнаружение-объектов), а затем возвращает часть ID и выделающая рамка к `/object_recognizer` для каждого объекта.
|
||
3. Для каждой небольшой детали `/object_detector` также применяет сопоставление с шаблоном, которое определяет ее 2D-положение и ориентацию в выделяющей рамке. Они возвращаются `/object_recognizer` вместе с результатами SSD.
|
||
4. Для круглой ленты `/ object_detector` находит точки захвата, применяя детектор FGE (Fast Graspability Estimation). Точки захвата представлены его двухмерным положением и ориентацией оси движения двухпальцевого захвата. Как правило, на одном ремне можно найти несколько точек захвата. Они возвращаются в `/ object_recognizer` вместе с результатами SSD.
|
||
5. После получения ID детали и выделяющей рамки `/ object_recognizer` дает команду `/depth_filter` создать облако точек в подобласти, соответствующей ограничивающей рамке. Созданное облако точек сохраняется в `~/.ros/scene.ply` в формате Stanford PLY.
|
||
6. Для общих деталей, ни маленьких, ни ленточных, узел `/localization` восстанавливает файл PLY и выполняет трехмерное сопоставление с сетками, хранящимися в `o2ac_parts_description` . Если процесс сопоставления успешен, трехмерное положение и ориентация детали, а также значения достоверности возвращаются в результате типа `o2ac_msgs.localizeObjectAction` . Если найдено несколько поз-кандидатов, они сохраняются в порядке убывания значений достоверности.
|
||
7. Для небольших деталей и ремней узел `/localization` преобразует их 2D-положения и ориентации в 3D-позы в предположении, что объекты лежат на «доминирующей плоскости». `Доминирующая плоскость` определяется по всему изображению глубины с помощью `/depth_filter` с надежной подгонкой плоскости с использованием RANSAC. Обнаруженный самолет публикуется в сообщении типа `aist_depth_filter.FileInfo` и подписывается узлом `/localization`.
|
||
|
||
Пример клиентской программы `o2ac_vision / scripts / o2ac_recognition_client_example.py` показывает, как использовать порядок распознавания из пользовательских прикладных программ. Образец также предоставляет средства для визуализации результатов 3D-локализации с помощью `aist_model_spawner`.
|
||
|
||
## o2ac_visualisation
|
||
|
||
Данный пакет предосатвляет плагин визуализации состояния системы как для облегчения отладки, так и для демонстрации.
|
||
|
||
## wrs_dataset
|
||
|
||
Данный пакет содержит датасет Pytorch, используемые в пакете o2ac_vision для обучения распознавания объектов.
|