robossembler.org/docs/technologies/o2ac-repo-review.md
Bill Finger 914e4b8c29 aist_modules и o2ac_assemble_database
добавил небольшой обзор
2021-10-04 19:49:12 +04:00

10 KiB
Raw Blame History

id title
o2ac-repo-review Команда o2ac есть чему поучиться

Предыстория

o2ac_example_2_arm

Команда O2AC на World Robot Summit 2020 Assembly Challenge состояла из представителей OMRON SINIC X , OMRON , Osaka University, National Institute for Advanced Science and Technology (AIST) и Chukyo University.

Репозиторий который недавно был выложен на платформу 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 скрипта parts_reader.py который загружает объекты в сцену как объекты с коллизией из исходных .yaml файлов в папке o2ac_assembly_database/config/name_of_config/. Также в данной базе данных присуствует информация о позиционировании захватного устройства, при захвате детали. Все эти данные загружаются непосредственно на сервер ROS откуда они уже забираются определённой нодой. Такая архитектура свойственна для ROS1, для ROS2 подход координально отличается, потому что параметры загружаются в ноду непосредственно при её запуске.

Если предыдущий скрипт брал геометрию каждой детали и публиковал их в сцену MoveIt, то следующий скрипт Assembly_reader.py предназначен для обработки древовидной сборки и публикацию данной сборки в TF формате. То есть прямым образом заносит информацию на сервер какая деталь куда должна устанавливаться. Отдельно интересует данный фрагмент кода:

    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 которая "судя по всему" является фреймом стыковки двух деталей.

Так как же обрабатывается последовательность сборки двух деталей. Об этом нам скажет следующий фрагмент скрипта:

    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, в котором содержится информация о том что где должно стоять. Также есть интересная функция, которая непосредственно отвечает за добавление одной последовательности в другую

Следующий скрипт visualise_metadata.py предназначен лишь для визуализации объектов в сцене.

o2ac_dynamixel