Зачем нужен Holoscan
Holoscan SDK объединяет управление с малой задержкой и обработку данных с высокой пропускной способностью в одной модели программирования. Она рассчитана на задачи, выполняемые как на процессоре, так и на графическом процессоре. Среда исполнения должна снижать лишние накладные расходы и показывать, как именно запускается приложение.
Операторы можно объединять в разделы: их цепочка выполняется в одном потоке, без переключений между потоками и лишних системных вызовов. Запуск работы задают таймеры или поступление данных, а ограниченные очереди с удалением самых старых элементов не дают устаревшим данным накапливаться.
Существующие алгоритмы можно подключать без переписывания под фреймворк. В Holoscan 5 появилась облегчённая модель программирования, которую проще встраивать в готовые кодовые базы, а обмен данными с графами стал удобнее.
Та же модель подходит для циклов управления моторами на процессоре с частотой 10 кГц, ресурсоёмких вычислений на графическом процессоре и инференса ИИ. Разработчики могут описывать выполнение с помощью операторов, портов и графов, разделять задачи на несколько графов и закреплять разделы за ядрами процессора, контекстами CUDA Green или запускать их как граф CUDA.
Операторы также описывают временные требования. До первого запуска Holoscan компилирует план выполнения: его можно проверить и найти ошибки конфигурации до развёртывания на оборудовании. Встроенные метки NVTX показывают в Nsight Systems работу операторов и передачу сообщений. По ним можно анализировать задержки на стороне процессора и джиттер обновлений, а затем повторять измерения по мере развития приложения.
Манипулятор для управления моментом силы
В примере используют Seeed Studio reBot Arm B601-DM — доступную платформу для освоения современного управления роботами. В недорогих манипуляторах часто стоят высокоредукторные хоббийные сервоприводы, предназначенные только для управления положением. В reBot Arm установлены приводы с квазипрямым приводом (QDD), которые обеспечивают широкую полосу пропускания для управления и измерений. Это полезно для тактильного взаимодействия, совместной работы человека и робота и других задач с управлением моментом силы.
Компенсация гравитации помогает проверить, насколько модель робота соответствует его физической конструкции, ещё до добавления систем восприятия и планирования движения. Управление только положением может скрыть ошибки в осях суставов, смещениях, расположении звеньев, массах и моментах инерции. При компенсации гравитации такие ошибки сразу меняют нужный момент: из-за неверных параметров Денавита — Хартенберга или характеристик масс рука может провисать либо подниматься при смене позы.
Даже если конечной системе компенсация гравитации не нужна, управление моментом силы позволяет настраивать реакцию робота на внешнее воздействие. В этом примере гравитационная составляющая сочетается с небольшой жёсткостью и демпфированием: рука поддерживает собственный вес, но поддаётся руке человека.
Для такого управления нужны быстрые и предсказуемые измерения — сотни или тысячи раз в секунду. Накладные расходы среды исполнения и переключения между потоками добавляют фазовую задержку и джиттер, способные нарушить устойчивость робота.
Обратную динамику рассчитывает Pinocchio. Библиотека загружает модель робота в формате URDF и использует рекурсивный алгоритм Ньютона — Эйлера (RNEA), чтобы вычислять моменты в суставах для заданных положений, скоростей и ускорений. Для чтения показаний суставов и отправки команд моторам применяется библиотека motorbridge.
Настройка примера на Python
В руководстве используется интерфейс Holoscan для Python. В репозитории есть и полная реализация на C++ со своими инструкциями по сборке. Обе версии используют один и тот же контур из трёх операторов.
Для запуска нужна Linux-система с Python 3.12 или новее. Из корня репозитория выполните:
python3.12 -m venv build/python-venv
build/python-venv/bin/python -m pip install --only-binary=:all: -r requirements-python.txt
build/python-venv/bin/python -m pip checkЗатем проверьте последовательный порт и идентификаторы моторов в конфигурационном файле манипулятора. Техническое руководство в репозитории описывает настройку, математическую часть и запуск оборудования.
Чувствительный робот с установленным Holoscan для компенсации силы тяжести в сравнении с роботом, использующим среду выполнения пользовательского скрипта
Источник: developer.nvidia.com
Три оператора контура управления
В Holoscan 5 есть два основных понятия: операторы и графы. Чтение состояния робота, расчёт команды решателем обратной динамики и отправку команды манипулятору разделили на три оператора.
У пользовательских операторов есть три важных метода. В руководстве их перечень обозначен как таблица основных методов, но сами названия в тексте не приведены.
1. Считывание состояния суставов по таймеру
JointStateSourceOp объявляет выход в setup(). Контракт OnClock задаёт запуск каждые 2,5 мс — то есть с частотой 400 Гц. При каждом вызове compute() оператор читает состояние всех семи моторов и отправляет его дальше.
import holoscan as hsdk
class JointStateSourceOp(hsdk.Operator):
state = hsdk.Output("state", hsdk.pyobject)
def setup(self, spec):
spec.output(self.state)
def contract(self):
return hsdk.Contract().trigger(hsdk.OnClock(period=hsdk.time.us(2500)))
def start(self):
self.sequence = 0
def compute(self, ctx):
self.sequence += 1
self.state.emit(robot.read_state(self.sequence))2. Расчёт компенсации при поступлении данных
PinocchioGravityOp объявляет вход для состояния и выход для команды. Оператор OnEach запускает вычисление при поступлении нового состояния. Параметры hsdk.Param задают коэффициенты усиления, масштабирование момента и направление суставов.
class PinocchioGravityOp(hsdk.Operator):
state = hsdk.Input("state", hsdk.pyobject)
command = hsdk.Output("command", hsdk.pyobject)
kp = hsdk.Param(1.5, range=(0.0, 500.0))
kd = hsdk.Param(1.0, range=(0.0, 5.0))
tau_scale = hsdk.Param([1.0] * 6)
joint_direction = hsdk.Param([1.0] * 6)
def setup(self, spec):
spec.input(self.state, queue_depth=1)
spec.output(self.command)
def contract(self):
return hsdk.Contract().trigger(hsdk.OnEach(self.state))
def compute(self, ctx):
state = self.state.receive_data()
command = controller.compute(
state, kp=self.kp, kd=self.kd,
tau_scale=self.tau_scale, joint_direction=self.joint_direction)
self.command.emit(command)Внутри compute() передаёт полученное состояние и текущие параметры вспомогательной функции. Та сопоставляет шесть углов манипулятора модели URDF, проверяет ограничения и получает гравитационные моменты через Pinocchio:
gravity = pin.computeGeneralizedGravity(self.model, self.data, self.q)[self.v_indices]Рассчитанные моменты добавляются в команды моторам как упреждающая компенсация — вместе с положением, скоростью, жёсткостью и демпфированием. Уже первая команда включает гравитационную составляющую и заданные параметры податливости.
3. Отправка команд моторам
MotorCommandSinkOp объявляет один вход и запускается при поступлении команды. Метод compute() передаёт её вспомогательному модулю робота. Тот проверяет, не истекла ли команда, не нарушен ли порядок и не выходит ли она за допустимый диапазон, а затем отправляет пакет моторам.
class MotorCommandSinkOp(hsdk.Operator):
command = hsdk.Input("command", hsdk.pyobject)
def setup(self, spec):
spec.input(self.command, queue_depth=1)
def contract(self):
return hsdk.Contract().trigger(hsdk.OnEach(self.command))
def compute(self, ctx):
robot.send_command(self.command.receive_data())
def stop(self):
robot.disable()После отправки команд всем семи моторам вспомогательный модуль записывает время завершения. Если в течение 100 мс — это значение по умолчанию — не завершится ни одна отправка, сторожевой механизм попытается отключить моторы и остановит граф. Метод stop() оператора также отключает моторы.
Сборка и запуск графа
Операторы соединяют через порты и передают параметры компенсации при создании оператора:
graph = hsdk.Graph("rebot-gravity", default_clock=hsdk.RealtimeClock)
source = graph.op(JointStateSourceOp, "joint_feedback")
gravity = graph.op(PinocchioGravityOp, "gravity", **controller.parameters.operator_kwargs())
sink = graph.op(MotorCommandSinkOp, "motor_commands")
graph.add_flow(source.state, gravity.state, queue_depth=1, queue_policy=hsdk.QueuePolicy.DROP_OLDEST)
graph.add_flow(gravity.command, sink.command, queue_depth=1, queue_policy=hsdk.QueuePolicy.DROP_OLDEST)
graph.partition("control").add(source).add(gravity).add(sink)Раздел запускает обратные вызовы входящих в него операторов последовательно в одном потоке, которым управляет среда исполнения. Все три оператора находятся в разделе control, поэтому передача состояния, расчёт момента и отправка команды обходятся без переключений между потоками. Источник задаёт частоту, а остальные операторы следуют за поступающими данными. Очереди глубиной в один элемент с удалением самых старых данных не дают накапливаться устаревшим отсчётам.
До включения моторов Holoscan компилирует описание в план выполнения, который можно проверить:
plan = hsdk.compile(build_graph(robot, controller))
if not plan:
raise RuntimeError(plan.summary())
prepare_gravity_compensation(robot, controller)
hsdk.run_async(plan)Инициализация модели и моторов происходит в prepare_gravity_compensation() после компиляции графа и непосредственно перед запуском. Обработчики сигнала задают stop_requested при нажатии Ctrl+C. Основной цикл следит за выполнением команд, а менеджер контекста останавливает граф и дожидается завершения его потоков. Управление также охватывает запуск, сторожевые механизмы и завершение работы.
Проверка манипулятора
Перед запуском руку нужно установить в безопасное исходное положение при выключенном питании:
build/python-venv/bin/python python/gravity_compensation.pyКогда появится сообщение Gravity compensation active, руку можно направлять вручную. Перед нажатием Ctrl+C верните её в исходное положение: команда остановки отключает моторы.
Контроллер обновляется по мере изменения крутящих моментов в шарнирах при изменении позы
Источник: developer.nvidia.com
Измерение задержки и джиттера
Holoscan интегрируется с NVIDIA Nsight Systems для анализа работы задач на процессоре и графическом процессоре. Для профилирования не нужны специальные декораторы или собственный код измерения времени: достаточно запустить приложение без изменений.
mkdir -p build/profiles
nsys profile -t nvtx --sample=none --backtrace=none --cpuctxsw=none \
-o build/profiles/gravity-python \
build/python-venv/bin/python python/gravity_compensation.pyСводку по диапазонам времени можно получить стандартной командой:
nsys stats --report nvtx_sum build/profiles/gravity-python.nsys-rep
Временная шкала NVIDIA Nsight Systems (nsys) и трассировка событий NVTX, показывающие длительность задач и задержки операторов
Источник: developer.nvidia.com
Закрепление за ядрами процессора
Интерфейс развёртывания Holoscan позволяет закрепить раздел управления за ядром процессора. В описанных запусках вспомогательные потоки и потоки профилировщика разместили на другом ядре, а два физических ядра вместе с их потоками SMT временно зарезервировали от других приложений с помощью группы управления Linux. Для такой настройки не требуется пересобирать ядро, менять параметры загрузки или перезагружать компьютер. Однако прерывания, таймеры и часть потоков ядра всё равно могут выполняться на зарезервированных ядрах.
Авторы сравнили четыре конфигурации, собрав более миллиона циклов в каждом запуске. Задержка Holoscan измерялась от входа в первый оператор до входа в последний; передача команды мотору в расчёт не включалась. Закреплённые запуски на графике обозначены сплошными линиями, незакреплённые — пунктирными. В источнике результаты также представлены таблицей распределений задержек для конвейеров на C++ и Python, с закреплением и без него, но числовые значения таблицы в тексте не приведены.
При закреплении потоков и изоляции ядер наблюдаемая задержка на уровне p99.99 уменьшилась примерно в 5 раз для C++ и в 9,6 раза для Python. Измерения проводились последовательно, с включённым профилированием; первые десять секунд исключили, а выбросы задержки сохранили.
Обе версии Holoscan вызывают решатель Pinocchio, написанный на C++. Но в Python вокруг Pinocchio и среды исполнения Holoscan добавляются работа интерпретатора, выделение объектов и взаимодействие с глобальной блокировкой интерпретатора — GIL. Для циклов управления на процессоре с бюджетом задержки в микросекунды эти расходы имеют значение. C++ позволяет лучше контролировать выделение памяти и системные вызовы на критическом пути, хотя приведённый пример всё равно выделяет память и не является конвейером без системных вызовов.
Для задач восприятия на графическом процессоре, которые занимают миллисекунды или десятки миллисекунд, небольшие выделения памяти и отдельные системные вызовы на процессоре обычно менее существенны: сами вычисления занимают на порядки больше времени. Python остаётся практичным способом собирать такие пайплайны, если их элементы реализованы на CUDA.
От компенсации гравитации к полному управлению
Базовый контур состоит из трёх операторов Holoscan: один по таймеру считывает состояние суставов, второй рассчитывает гравитационные моменты с помощью Pinocchio, третий отправляет команды моторам. Holoscan проверяет граф до включения моторов, а Nsight Systems позволяет изучить его выполнение.
Компенсация гравитации — основа, а не законченная система управления. В репозитории есть второй пример на Python: он добавляет кинематику и управление импедансом в виде повторно используемых операторов Holoscan. В него можно передать целевые положение и ориентацию, например от обученной политики, сохранив податливость руки при прикосновении.
На этой основе можно развивать обучение с ручным ведением, телеуправление и манипуляции с объектами. Для добавления восприятия предлагается использовать модуль компьютерного зрения Holoscan и компоненты NVIDIA Isaac ROS, где есть повторно используемые операторы Holoscan и эталонные приложения, включая инференс GR00T.
Для продолжения авторы предлагают загрузить SDK Holoscan 5 и воспользоваться полным руководством.
По оценке Dataist, пример показывает, как разделение управления на операторы и проверка графа до запуска помогают контролировать выполнение роботизированного контура. При этом результаты по задержке относятся к последовательным запускам с профилированием, а измеряемый интервал не включает передачу команд моторам.
Удержание декартовых координат в реальном времени с сохранением заданной ориентации и тактильной податливости
Источник: developer.nvidia.com
Читайте также
Новое приложение Medium встраивает ИИ-помощника прямо в процесс написания текста
Раскрыто: Palantir лоббировала министра, добиваясь доступа ИИ-инструментов к записям пациентов GP в NHS
Сменщик Нэнси Пелоси готов взяться за регулирование ИИ
Disney делает ставку на Firefly от Adobe для создания безопасных для бренда ИИ-моделей для своей развлекательной империи
Anthropic включилась в газовую гонку ИИ, купив турбины на $3,4 млрд
Главный специалист Tencent по ИИ: ИИ-биооружие не за горами, но закрывать модели — не выход
Как ИИ помогает создавать инновации в отрасли специальной химии
Решит ли агентная робототехника проблему масштабирования данных в робототехнике?
Automattic запускает платформу для публикации приложений, созданных вайб-кодингом, на фоне меняющегося интернета
Google за год выпустила четыре варианта TPU, усиливая конкуренцию с Nvidia
У экспертов есть партнёры — HOPE поможет сохранить их вместе
Могут ли авторы защититься от обвинений в использовании ИИ с помощью сервисов, фиксирующих историю текста? Достаточно ли этого?
Климатические преимущества ИИ пока не доказаны
Байкеры и защитники насекомых объединились против нового дата-центра Google
Потеряет ли Дженсен Хуанг пост? Джеффри Зонненфельд из Йеля оценивает шансы как 50 на 50
Глава Microsoft AI готов признать за ИИ-агентами права, если увидит убедительные доказательства
Ловушка эффективности: почему оптимизация всего подряд может обернуться серьёзными проблемами
Андрей Карпати за выходные создал платформу отобранных видео с помощью Claude и 20 лет Hacker News
Ужасно, что Google не даёт пользователям просто отключить ИИ-обзоры Google
Мозг как компьютер: метафора сформировала современный ИИ, но может сбивать с толку в споре о сознании
Ежедневные новости об ИИ
Каждый день отбираем важные новости об ИИ и рассказываем главное — без хайпа и воды. Если хотите понимать, что происходит в ИИ раньше остальных, — подписывайтесь.
Только важное — каждый день
В Telegram