Чтобы платформа знала, как устроен ваш узел или станок, его не программируют — его описывают файлом. Формат описания — URDF: звенья, шарниры, пределы, точки датчиков. Мы такие модели потребляем: принять файл, связать имена, показать, питать позами с железа. Рисуете вы — в своём инструменте; мы проверяем принесённое и говорим, что не так.
| Понятие | Что это у вас на железе |
|---|---|
| Звено (link) | Твёрдое тело: рама, каретка, плечо, планшайба. Несёт видимую геометрию — примитив или меш. |
| Шарнир (joint) | Подвижная связь двух звеньев: родитель, ребёнок, положение и направление оси. У шарнира есть имя — им его зовёт программа. |
| Пределы (limit) | Границы хода, усилие и скорость. Границы — АБСОЛЮТНЫЕ координаты, а не длина хода. |
| Точка (frame) | Место датчика или исполнителя. В URDF это звено без геометрии, прикреплённое неподвижным шарниром к тому звену, на котором оно физически сидит. |
URDF — дерево: у каждого звена ровно один родитель, корень один. Из этого свойства следует всё остальное на этой странице, включая честную границу в конце.
| Тип | Что значит | У нас | Когда |
|---|---|---|---|
| revolute | вращение с объявленными границами | печатаем · читаем | Поворотный стол, ось-сустав. Требует <limit lower upper>. |
| prismatic | прямолинейный ход с границами | печатаем · читаем | Портальная ось, толкатель, мачта, подъёмная колонна. Требует <limit lower upper>. |
| continuous | вращение без границ | печатаем · читаем | Лента, шнек, шпиндель: паспортного хода у такой оси нет вовсе. Границы не объявляются — только усилие и скорость. |
| fixed | неподвижная связь | печатаем · читаем | Кожух на плече, точка датчика на каретке. Программой не зовётся. |
| floating · planar | шесть / три свободных степени | не печатаем | Подвижным считается всё, что не fixed, — значит такой шарнир на входе потребует связи с каналом наравне с остальными. Обычно это признак, что модель описывает сцену, а не механизм. |
continuous — не третий класс движения, а честная запись случая
«вращение без объявленного предела». У ленты и шнека хода в паспорте нет вовсе, и
revolute заставил бы выдумать границы либо запереть ось нулевым ходом.
Пределы — это абсолютные координаты хода, а не его длина.
Ось, которая ходит от −150 до +150 мм, пишется как
lower="-0.15" upper="0.15", а не как «300». Одно имя с двумя смыслами
однажды сделало рабочий конверт станка вдвое шире реального.
Связка «механизм ↔ управление» держится на одном имени. Поэтому имя шарнира подвижной оси — не подпись для человека, а адрес.
| Что это | Номер | Имя | Где в файле |
|---|---|---|---|
| серво узла автоматики | 0 | srv0 | <joint name="srv0"> |
| серво узла автоматики | 2 | srv2 | <joint name="srv2"> |
| дискретный вход | 1 | di1 | <link name="di1"> — точка датчика |
| дискретный выход | 0 | do0 | <link name="do0"> — точка исполнителя |
| аналоговый вход | 0 | ai0 | <link name="ai0"> — точка замера |
| ось станка | — | X · Y · Z · A · B · C | буква оси: ею зовёт ось управляющая программа |
Ведущих нулей нет. Подпись канала («зажим тисков») именем не является и меняется свободно — иначе переименование тихо переставляло бы шарнир под другой привод. Ваши собственные имена звеньев, материалов и неподвижных деталей — как хотите: договор касается только шарниров подвижных осей и точек каналов.
Сегодня файлом механизма описывается узел автоматики. Станок описывается шаблоном кинематики и паспортом осей — см. типы станков; общее у них одно и то же правило: имя, которым зовёт ось программа, и есть связка с механизмом.
Модель из ROS или от вендора несёт свои 7–36 имён. Переименовывать их руками — стена, а переименовать за вас мы не имеем права: порядок звеньев в дереве и номер привода — разные вещи, и однажды они разойдутся молча.
Поэтому файл приносится вместе с картой {канал: имя в файле}.
Судить первый пункт договора будет карта, а не написание имён внутри файла.
Карта проверяется целиком: непокрытый подвижный шарнир и канал, чьё имя ни к чему
в файле не ведёт, — это названные отказы. Карта едет на бокс отдельным файлом
рядом с механизмом, потому что пакет обязан быть самодостаточным: бокс, получив
чужой файл, должен знать, какой шарнир двигает srv0.
| Формат | Хранилище | Экран | Замечание |
|---|---|---|---|
| .glb | да | да | предпочтительный формат: одно тело, материалы внутри |
| .gltf | да | да | везёт с собой буфер .bin и текстуры .png / .jpg |
| .stl | да | да | голая сетка, без материалов |
| .dae | да | нет | хранилище примет, экран назовёт отказ «формат .dae не читаем» |
| .obj | да | нет | то же: принимается, но не рисуется |
| .bin · .png · .jpg | да | — | спутники glTF: URDF их не называет, тело тянет их само |
Путь меша указывается ровно так, как он написан внутри URDF
(meshes/frame.stl): файлы приезжают тем же запросом, что и текст механизма, —
одна транзакция, один владелец записи. Общий предел на комплект геометрии — 30 МБ.
Принимаются меши только подвижных звеньев. «Подвижное» — это вывод, а не
список исключений: звено подвижно, если путь от корня до него содержит хотя бы один
не-fixed шарнир (кожух, прикрученный fixed к плечу, едет вместе
с плечом и потому подвижен). Не принесённый меш подвижного звена — отказ; меш неподвижной
рамы не кладётся, и об этом говорится строкой предупреждения, а не молчанием.
На бокс уезжают три вещи: текст механизма, таблица имён и принятые меши.
| Тег | Что с ним |
|---|---|
| <collision> | Принимаем и игнорируем: столкновений мы не считаем. Меш, названный только в <collision>, не требуется — платить десятками мегабайт за данные, которые никто не читает, мы не просим. |
| <inertial> | Динамики мы не считаем: копия питается позами с железа, а не решает уравнения движения. |
| <mimic> | НЕ поддержан: сцепленную пару (гантри, параллельный захват, пантограф) покажем как два независимых шарнира. Если в вашей модели ведомый вал идёт за ведущим — на картинке он будет стоять. |
Не тратьте время на подготовку столкновительной геометрии и на массы с тензорами инерции: мы их не читаем. Копия питается позами, приходящими с железа, а не решает физику.
Порядок жёсткий: судья → отказ либо запись. Молчаливого приёма нет, правки принесённого текста нет — ни отступов, ни единиц. Отказ приходит целиком, со всеми замечаниями сразу, а не по одному на попытку.
Шарнир подвижной оси зовётся по договору (srv0, srv1, …) — либо приносится таблица имён. Имя, похожее на адрес, но написанное иначе (servo_0, SRV0, joint3), отвергается с подсказкой точного имени. За вас не переименовываем.
У звена ровно один родитель, корень один, циклов нет.
<limit lower upper> объявлены у revolute и prismatic и заданы абсолютными координатами хода, а не его длиной.
Метры и радианы: URDF — это СИ. Объявить единицы в файле нечем, поэтому проверяется правдоподобие величины — так ловятся миллиметры и градусы, положенные в СИ-поле.
Ни пина, ни слейва, ни шины (lcec, slave, cia402, din-, dout-, ain-). URDF описывает механику; чем канал является электрически (роль, профиль движения) — знает passport.json рядом с механизмом. Куда он подключён на конкретном стенде — не знает и паспорт: узел в каталоге один, стендов много.
Файлы xacro принимаются. Реальные модели ROS почти всегда
приходят макросами и включениями — разворачивание идёт до того же единственного судьи.
Вместе с файлом механизма присылаются его соседи (включения, макросы, параметры).
Аргументы xacro на этом шаге не задаются: берутся умолчания, а объявленные
файлом аргументы называются в ответе — у файла с $(arg …) разворачиваний
несколько, и мы взяли одно.
Пока свой файл не принесён, механизм — наш черновик, напечатанный по паспорту узла: цепочка по порядку приводов, схематичные звенья, и каждое додуманное число названо и в предупреждениях, и комментарием в самом XML. После импорта механизм — ваш файл, и генератор в него больше не пишет; вернуться к черновику можно одним движением.
URDF описывает МЕХАНИКУ узла — звенья, шарниры, пределы хода. Всё, что механикой
не является — роль канала, чем он физически исполнен, профиль его движения, адресное
пространство ячеек, имя и описание узла для человека, — несёт отдельный файл рядом с
механизмом: passport.json. Узел заводится каталогом из пяти файлов,
и ни строкой кода:
mechanism.urdf — механика: звенья, шарниры, пределы хода.mechanism_map.json — имена чужого донора, если файл принесён не наш.passport.json — роли каналов, электрика, ячейки, имя и описание узла.program.plc — логика: что узел делает.Разграничение владения записи жёсткое: поле, которое КРУГ URDF выводит сам (тип шарнира, ход, порядок каналов), в паспорте не дублируется — это была бы вторая правда о том же. Паспорт несёт ровно то, чего URDF не может сказать в принципе.
| Раздел | Поля | Почему не в URDF |
|---|---|---|
| servos | role (ось · сустав · вращение · затяжка), kind (физический механизм: лента, мачта, вилка, шнек…), max_velocity, max_acceleration, max_deceleration, max_torque, rated_torque_nm, lead_mm (ход винта, мм/об), gear_num / gear_den | шарнир задаёт ТИП движения и пределы хода, но не режим привода и не
физику передачи — continuous из файла читается одинаково что у ленты,
что у шпинделя завинчивания |
| outputs | role: grip, clamp, gate, valve, marker, applicator, diverter, vacuum, glue, part_feed | точка исполнителя в URDF есть, а того, ЧТО она делает, файл не говорит — дискретных выходов в дереве звеньев нет вовсе |
| inputs | role: presence, at_position, trigger, verdict, fill_level, force_ok, grip_ok, label_gap | то же для входов: точка датчика есть, смысл сигнала — нет |
| analogs | quantity, units | аналоговых каналов URDF не несёт вовсе |
| grid | cols, rows, levels (адрес: буква A,B,… → X, число 1.. → Y, .N → Z), pitch [dx,dy,dz] мм (без умолчания), origin [x,y,z] мм — координата ячейки A1 | ячеек в URDF нет по определению: стеллаж — не звено и не шарнир,
вывести «восемь столбцов с шагом 700» из механизма не из чего. Именованные точки
(exit1 / home / input) сюда НЕ попадают —
у точки есть родитель-звено, она остаётся <link>-маркером
cell_<имя> в самом механизме; сами ячейки A1…H5 нигде не
хранятся — считаются из шага и начала |
| name / description | две строки, ровно два поля | <robot name=…> в URDF — идентификатор механизма,
а не подпись узла для человека; описания в файле нет вовсе |
lead_mm умолчания не имеет. Ход винта — свойство
ЭКЗЕМПЛЯРА оборудования, не механики. Не назван в паспорте — прямая ось честно остаётся без
хода винта (в 3D не поедет, и это видно) вместо того, чтобы поехать по придуманному числу.
Образец галереи ewellix_lift ровно в этом положении: программа-пример для него
не собрана, потому что lead_mm паспортом не назван.
Чего в паспорте нет и быть не должно — фактов КОНКРЕТНОГО СТЕНДА: слейв, пин, шарнир привода, датум нуля. Узел в каталоге один, стендов, куда его поставят, много; эти числа называет наладчик у железа, а не карточка образца.
Ключ канала паспорта — его ИМЯ (srv0, di0), то же самое, которым
его зовут URDF и программа; отдельного порядкового номера паспорт не хранит.
URDF описывает механику, паспорт — роли и электрику, а что узел
делает называет отдельный текстовый файл рядом с ними: program.plc.
Внутри — ТЕЛО программы на языке лаборатории PLC (том же, на котором пишутся программы
рода motion в /programs/plc): состояния, переходы, движения по
дорожкам.
Объявления оборудования в файле нет. Пролог rig({ axes, outputs,
inputs }) — вторая запись состава узла — платформа ПЕЧАТАЕТ сама из паспорта и
механизма, на место метки // @rig в начале файла. Написать этот пролог рукой
нельзя: состав узла жил бы в двух местах сразу и расходился бы молча, как только один из
них поправят. Метка бывает и в форме // @rig inline — печать входит прямо в
неё, без переноса строки.
Файла нет — программы у узла нет. Не подставляется ни пустой шаблон, ни программа по умолчанию: логика не объявлена, и вывести её из механизма с паспортом не из чего. Это видно строкой на экране узла, а не молчанием.
Файлом программу можно принести не у всякого узла. У
образцов, чья программа-пример ВЫЧИСЛЯЕТСЯ из <limit> принесённого
механизма (motopos_d500, flir_ptu_d46, ewellix_lift),
она остаётся вычисляемой, а не файлом: замените механизм — программа обязана поехать за
новыми пределами хода, а статический текст файла этого не умеет. Это граница формата, а
не недоделанная функция.
Параллельные кинематики в URDF невыразимы. У гексапода подвижная платформа держится на шести штангах — это шесть родителей у одного звена, тогда как дерево допускает ровно одного. Сферических шарниров в URDF нет вовсе. То же у трипода и линейной дельты. Ожидаемое поведение — названный отказ, а не молчание и не картинка, которая врёт. Второй формат входа для замкнутых цепей — ниже, в разделе «Готовится».
Токарный станок, наоборот, ложится на дерево отлично — двумя ветвями от станины:
Осторожно, если шпиндель работает и как ось C. Тип шарнира
называется один раз: шпиндель — это continuous, вращение без границ.
Пределы и подача оси C живут отдельным полем паспорта, а не вторым шарниром на том же
валу. Иначе получится одно имя с двумя смыслами — и разъедется не значение, а смысл.
Интеграторы приносят STEP и чертежи, а не робо-описания. STEP даёт точную геометрию, дерево сборки и имена, но не даёт осей. Планируемый договор: структура сборки совпадает с кинематическим деревом — подсборка становится звеном, её трансформация — положением шарнира; человеку остаются тип шарнира, ось и пределы. Ось размечается кликом по грани, а точные числа берутся из математики B-rep.
Формат входа сменный: внутренняя модель наша, а формат — это парсер. Второй на очереди — SDF (SDFormat): он умеет замкнутые цепи и закрывает ровно ту дыру, где URDF отказывает, — гексапод, трипод, дельту.
Оба пункта в разработке прямо сейчас. Сроков здесь не публикуем; сегодняшний рабочий вход — URDF и xacro.
Девять образцов, которые можно взять и посмотреть, как выглядит правильно описанный узел. Учебные: паспортом оборудования они не являются, числа из них цитировать как замер нельзя.
| Образец | Происхождение | Что показывает |
|---|---|---|
| Конвейер | наш черновик | лента одним серво; геометрии нет — учит договору имён |
| Портал 3 оси + захват | наш черновик | цепочка X→Y→Z и точки каналов |
| Поворотный делительный стол | наш черновик | одна поворотная ось |
| Конвейер с рамой | гибрид | чужой меш рамы (Gazebo Fuel, CC-BY 4.0) + наш подвижный барабан |
| Ewellix TLT | донор ROS | телескопическая подъёмная колонна, две ступени на призматических шарнирах |
| FLIR PTU-D46 | донор ROS | поворотная голова: поворот + наклон |
| Yaskawa MotoPos D500 | донор ROS | сварочный позиционер: наклон + вращение планшайбы |
| Robotiq 2F-85 | донор ROS | двухпальцевый схват: один мотор, ход губок 85 мм |
| Стеллаж-кран | наш черновик | единственный образец с ЯЧЕЙКАМИ: три оси и адресное пространство 8×5 в паспорте, точки exit1/home/input — link-маркерами в механизме |
Доноры взяты из открытых репозиториев ROS с зафиксированным коммитом и датой загрузки; лицензия и источник указаны рядом с каждым. Все образцы проходят ту же дверь, что и ваш файл: образец, не проходящий её, означает ошибку либо в образце, либо в правиле.
Дальше — типы станков и кинематики: какая порода что умеет и почему гексапод программируется движениями, но не режет по G-code.