Это графическое приложение (GUI) предназначено для сравнения классических методов решения задач вида AX = XB и AX = YB.
Программа принимает на вход файлы с данными точек в формате id, X, Y, Z, RZ, RY, RX (в миллиметрах и градусах; углы заданы в порядке ZYX).
Задачи калибровки вида AX = XB и AX = YB широко применяются в робототехнике, компьютерном зрении и системах навигации (например, калибровка системы "рука–глаз" и калибровка "робот–камера").
На практике их решение связано с рядом принципиальных трудностей.
-
Наличие шума в измерениях
Реальные данные содержат погрешности, обусловленные неточностями сенсоров, ошибками трекинга, калибровки камер, энкодеров и систем локализации. Эти ошибки проявляются как в трансляции, так и во вращении. -
Чувствительность алгоритмов к типу шума
Разные методы по-разному реагируют на некоррелированный случайный шум (гауссов шум) и коррелированные искажения (шум Перлина), что может приводить к существенно различным результатам при одинаковых исходных данных. -
Устойчивость к выбросам и малому числу измерений
Некоторые алгоритмы требуют большого количества пар преобразований для устойчивой работы и чувствительны к выбросам, что ограничивает их применимость в практических сценариях. -
Сложность объективного сравнения методов
В научных публикациях методы часто сравниваются на синтетических или специализированных наборах данных, что затрудняет выбор подходящего алгоритма для конкретной прикладной задачи.
Цель данного приложения — предоставить единый инструмент для объективного сравнения классических методов решения задач AX = XB и AX = YB на одинаковых данных, с возможностью контролируемого добавления шума и оценки точности по набору статистических метрик.
В приложение добавлена возможность тестирования методов на зашумленных данных. Это позволяет оценить устойчивость алгоритмов к различным типам искажений.
- Шум Перлина (Perlin Noise) — плавный "природный" шум, имитирующий органичные искажения (дрожание камеры, плавное движение)
- Гауссов шум (Gaussian Noise) — классический гауссовский шум с нормальным распределением (случайные погрешности сенсоров)
- Загрузите два файла как обычно

- Установите чекбокс "Добавить шум к данным"
- Выберите тип шума из выпадающего списка
- Отрегулируйте уровень шума с помощью ползунка (0.0 - нет шума, 1.0 - максимальный шум)
- Нажмите "Выполнить" для анализа

При включении шума данные из файла 2 будут модифицированы перед анализом. Файл 1 остаётся неизменным, что позволяет оценить влияние шума на точность.
Приложение реализует и сравнивает пять классических методов:
- tsai-lenz [https://kmlee.gatech.edu/me6406/handeye.pdf]
- park-martin [https://ieeexplore.ieee.org/abstract/document/326576]
- daniilidis [https://journals.sagepub.com/doi/abs/10.1177/02783649922066213]
- li-wang-wu [https://academicjournals.org/journal/IJPS/article-full-text-pdf/20DFAEA30999]
- shah [https://asmedigitalcollection.asme.org/mechanismsrobotics/article-abstract/5/3/031007/474841/Solving-the-Robot-World-Hand-Eye-Calibration]
- mean (среднее)
- median (медиана)
- rmse (корень из среднеквадратичной ошибки)
- p95 (95-й процентиль)
- max (максимальная ошибка)
Чтобы запустить программу достаточно открыть в каталоге app нужный файл в соответстии с вашей системой
app.exe
app
Если вы решили собрать проект сами то:
- Убедитесь, что у вас установлен Python
- Создайте виртуальное окружение, если его нет
python -m venv venv
- Активируйте виртуальное окружение:
venv\Scripts\activate
source venv/bin/activate - Установите все нужные зависимости одной командой:
pip install -r requirements.txt
- Запустите приложение командой из корня проекта:
python .\src\app.py
pytest tests/pytest tests/ -vpytest tests/test_utils.pypytest tests/ --cov=src --cov-report=htmltest_utils.py- Тесты вспомогательных функций (преобразования, загрузка CSV, вычисление ошибок)test_algorithms.py- Тесты всех алгоритмов калибровки (tsai-lenz, park-martin, daniilidis, li-wang-wu, shah)test_noise.py- Тесты функций генерации шума (Perlin и Gaussian)test_functions_call.py- Тесты основных функций APItest_end_to_end.py- Сквозные тесты с предварительно сгенерированными файлами тестовых данныхconftest.py- Общие фикстуры pytest и конфигурация
Тестовые данные состоят из пар файлов (например, known_transform_A.txt и known_transform_B.txt):
- Набор данных A: Содержит позы, измеренные в системе координат A (например, в базовой системе координат робота)
- Набор данных B: Содержит те же позы, измеренные в системе координат B (например, в системе координат камеры/датчика)
A и B представляют одну и ту же физическую траекторию, просто выраженную в разных системах координат.
Каждая строка в файле A соответствует той же строке в файле B - они представляют одну и ту же физическую позу в один и тот же момент времени, но измеренную из разных систем отсчета.
Позы в системах A и B связаны соотношением:
B = Y⁻¹ @ A @ X
В тестовых данных Y обычно является единичной матрицей (для простоты), так что:
B = A @ X
Где:
- A = поза в системе координат A
- B = та же поза в системе координат B
- X = преобразование из системы A в систему B (то, что находят алгоритмы калибровки)
- Y = дополнительное преобразование (обычно единичное в тестовых данных)
Представьте руку робота, движущуюся в пространстве:
- Система A: Измерения от датчика базы робота
- Система B: Измерения от камеры, наблюдающей за роботом
- Оба датчика наблюдают одно и то же движение, но сообщают координаты в своих собственных системах отсчета
- Алгоритмы калибровки находят преобразование X, которое конвертирует между этими двумя системами
Поза 0:
Система A: [0.00, 0.00, 0.00] мм
Система B: [49.92, 100.02, 24.93] мм
(Одно и то же физическое местоположение, разные системы координат)
Имея пары поз (A_i, B_i) для i = 1...n, алгоритмы находят:
- X: Преобразование из системы A в систему B
- Y: Дополнительное преобразование (если необходимо)
Такое, что: Y @ B_i = A_i @ X для всех i
Тестовые данные генерируются скриптом generate_test_data.py:
- Создание синтетических траекторий (известное преобразование, круговая, спиральная и т.д.)
- Применение известного преобразования X между системами
- Генерация соответствующих поз в обеих системах
- Добавление шума к позам B для имитации реальных ошибок измерений
- Сохранение файлов в формате:
id X Y Z RZ RY RX
Сгенерированные файлы тестовых данных добавлены в репозиторий для воспроизводимости.
Набор тестов покрывает:
- ✅ Операции с матрицами преобразований (обращение, композиция)
- ✅ Преобразования углов Эйлера
- ✅ Загрузку и парсинг CSV-файлов
- ✅ Вычисление ошибок и статистику
- ✅ Все пять алгоритмов калибровки
- ✅ Генерацию шума (Perlin и Gaussian)
- ✅ Основные функции API
Файл test_end_to_end.py содержит комплексные сквозные тесты, которые:
- Загружают предварительно сгенерированные файлы тестовых данных из
tests/data/ - Тестируют все алгоритмы калибровки на различных траекториях
- Проверяют результаты на соответствие пороговым значениям, специфичным для алгоритмов и уровней шума
- Тестируют с несколькими уровнями шума (0.1мм, 1.0мм, 5.0мм) для обеспечения надежности
Файлы тестовых данных находятся в tests/data/ и включают:
- Небольшие наборы данных:
known_transform(10 поз),circular_trajectory(8 поз) - Большие наборы данных:
helix_trajectory,complex_3d_path,figure8_trajectory(по 1000 поз) - Несколько уровней шума: Каждый набор данных имеет варианты с шумом позиции 0.1мм, 1.0мм и 5.0мм
Если вам нужно перегенерировать файлы тестовых данных:
# Генерация всех тестовых случаев со всеми уровнями шума
python tests/generate_test_data.py --all-levels
# Генерация конкретного тестового случая с определенными уровнями шума
python tests/generate_test_data.py --test-case known_transform --noise-levels 0.1 1.0 5.0- Некоторые алгоритмы (особенно Shah) могут не сходиться при определенных входных данных. Эти случаи корректно обрабатываются пропуском тестов.
- Тесты генерации шума пропускаются, если соответствующие модули недоступны.
- В тестах используются временные файлы, которые автоматически удаляются.
- Файлы тестовых данных добавлены в репозиторий (не генерируются на лету) для воспроизводимости и совместимости с CI/CD.
- При запуске откроется окно приложения.
- Выберите 2 файла с точками в пространстве в указанном формате, используя кнопки "Загрузить файл 1" и "Загрузить файл 2".
- После успешной загрузки пути к выбранным файлам отобразятся рядом с кнопками.
- Отметьте чекбоксы для методов, которые хотите применить. Можно выбрать один или несколько.
- Нажмите кнопку "Выполнить" для запуска вычислений и построения графиков.
- Графики точности (для трансляции и вращения) отобразятся в соответствующих разделах окна с возможностью горизонтальной прокрутки.
- Каждый график сопровождается заголовком и кнопкой "Сохранить" для экспорта изображения в PNG или PDF.
- Приложение написано на Python с использованием Tkinter для графического интерфейса и matplotlib для визуализации графиков.
- Для генерации шума используются библиотеки noise (шум Перлина) и scipy (гауссов шум).
На каждый открытый PR в main выполняется автоматическое тестирование на платформе GitHub Actions. Запускается полный набор тестов, описанный выше.
