Роботы
Для описания параметров звеньев написан класс core.robot.base.Link
.
Он хранит внутри себя следующие поля:
- Путь к модели
- Название
- Матрица преобразования из СК мира в СК звена для неиерархичных звеньев (для удобства)
- Тензор инерции звена
- Координаты центра масс
Для работы с сочленениями реализовано два класса:
core.robot.base.Joint
и core.robot.base.JointParams
.
Первый отвечает за преобразование угла поворота звена в матрицу перехода из системы координат (СК) предыдущего звена в СК следующего.
Второй хранит в себе неизменяемые параметры звена:
- максимальное по модулю ускорение
- максимальная по модулю скорость
- максимальный угол
- минимальный угол
- индекс сочленения
Матрицы преобразования
Матрица преобразования состоит из четырёх столбцов и четырёх строк
Чтобы получить координаты вектора в новой СК, нужно умножить матрицу преобразования на его значение () в исходной СК:
Т.к. каждое сочленение core.robot.base.Joint
характеризуется осью вращения
и углом поворота , то матрица преобразования вычисляется по формуле:
Для вычисления матрицы преобразования и её производных необходимо сначала
задать угол поворота jointAngle
и ось вращения axis
, после чего
вызвать метод
/**
* Получить матрицу преобразования сочленения
* @return матрица преобразования сочленения
*/
Eigen::Matrix4d getTransformMatrix() { return parentTransform * getRotMatrix4x4(axis, jointAngle); }
parentTransform
- это матрица преобразования из СК родительского сочленения в СК текущего.
Также дополнительно хранится матрица преобразования из СК сочленения в СК следующего за ним звена
linkTransform
Некоторые сочленения могут быть виртуальными, поэтому добавлен флаг
/**
* Флаг, что сочленение является виртуальным и не связано со звеном
*/
bool isVirtual;
Также сочленение может быть связано со звеном, но при этом не иметь возможности менять угол поворота. Чаще всего это полезно при сложной геометрии звена робота.
/**
* Флаг, является ли сочленение фиксированным (без привода)
*/
bool isFixed;
Для решения задач динамики и оптимизации бывают полезны частные производные матриц преобразования звеньев по соответствующему углу:
в классе Joint
данная логика реализована в соответствующих методах:
/**
* Получить первую производную матрицы преобразования сочленения
* @return первая производную матрицы преобразования сочленения
*/
Eigen::Matrix4d getDiffTransformMatrix() { return parentTransform * getDiffRotMatrix4x4(axis, jointAngle); }
/**
* Получить вторую производную матрицы преобразования сочленения
* @return вторая производную матрицы преобразования сочленения
*/
Eigen::Matrix4d getDiff2TransformMatrix() { return parentTransform * getDiff2RotMatrix4x4(axis, jointAngle); }
Реализация методов getDiffRotMatrix4x4
, getDiff2RotMatrix4x4
и других, необходимых
для работы с матрицами, находится в core.misc.matrixMath
Иерархия классов
Для работы с роботом как с объединением звеньев и
сочленений написан базовый класс core.robot.base.BaseRobot
.
У него прописаны все базовые методы для работы с роботом, но при этом он является абстрактным. Для его использования необходимо унаследовать новый класс от него и реализовать метод загрузки из файла:
/**
* @brief загрузить параметры робота из файла
*
* Загрузить параметры робота из файла, нужно заполнить следующие поля:
* _jointParams, _links, _nonHierarchicalLinks, path
* @param path путь к файлу описания робота
*/
virtual void loadFromFile(std::string path) = 0;
Основным классом для работы с роботами является core.robot.URDFRobot
.
Он использует файлы расширения *.urdf
. Подробнее с его
описанием можно ознакомиться здесь.
Для чтения модели используется немного устаревшая библиотека urdf_reader
без
ROS
(пакет project.urdf_reader
). Более актуальную версию можно скачать здесь
Также для тестов был написан робот core.robot.DHRobot
, использующий
параметры Денавита-Хартенберга.
Его описание получилось несколько громоздким. Это вызвано тем,
что необходимо было согласовать матрицы преобразования urdf
робота и
робота с параметрами Денавита-Хартенберга.
Частные производные
Матрицу преобразования можно вычислить, последовательно перемножив матрицы преобразования, зависящие только от угла поворота -го звена и матрицы перехода между звеньями :
Если взять от этой формулы частную производную по , то от этой координаты зависит только соответствующая матричная функция , все остальные множители при дифференцировании можно воспринимать как постоянные.
Поэтому при вычислении достаточно просто заменить -ю матричную функцию на её производную:
Для частной производной второго порядка в случае заменить -ю и -ю матричные функции её производными (не теряя общности, будем считать, что ):
Если , то необходимо заменить только -ю матричную функцию её второй производной:
Чтобы вычислить производную по матрице преобразования того или иного звена, достаточно найти производную матрицы поворота (смещение закладывается в матрицах ).
Поворот каждого звена описывается осью и углом поворота вокруг неё. Тогда можно матрицу преобразования можно найти по формуле: