aist_modules и o2ac_assemble_database

добавил небольшой обзор
This commit is contained in:
Ilya Uraev 2021-10-04 19:49:12 +04:00
parent 9daeef70d1
commit 914e4b8c29

View file

@ -4,13 +4,13 @@ title: 'Команда o2ac есть чему поучиться'
---
## Предыстория
![](https://github.com/o2ac/o2ac-ur/raw/main/images/tray_carry.gif)
![o2ac_example_2_arm](https://github.com/o2ac/o2ac-ur/raw/main/images/tray_carry.gif)
Команда 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_
1. Всё програмное обеспечение строилось на основе _ROS Kinetic_ в Docker контейнере
2. Используются одновременно 2 робота-манипулятора без риска столкновения
3. Вставка детали в отверстие производится с помощью контроля импеданса
4. Выравнивание детали производится за счёт сестемы технического зрения на библиотеке _OpenCV_
@ -20,8 +20,75 @@ title: 'Команда o2ac есть чему поучиться'
8. Обнаружение и захват деталей расположенных в лотке неструктурировано
9. Для установленных деталей используется библиотека TF которая содержит локальную систему координат каждого установленного элемента
## Что по репозиторию
Репозиторий состоит из 19 пакетов, в том числе есть пакеты которые достойны рассмотрения для реализации нашего Робосборщика. Кратко пройдёмся по каждому из них
## Обзор репозитория
1. **aist-modules** - Пакет который разрабатывался командой из университета AIST
2.
Репозиторий состоит из 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` предназначен лишь для визуализации объектов в сцене.
### o2ac_dynamixel