ООО «СинкТвин Технологии» +7 925 353-56-35 info@synctwin.ru
Документация / Станок и программы / Справочник / Механизм

Механизм — это данные, а не код

Чтобы платформа знала, как устроен ваш узел или станок, его не программируют — его описывают файлом. Формат описания — URDF: звенья, шарниры, пределы, точки датчиков. На одной этой спине стоят все три рода оборудования — узел автоматики, станок и навесная голова: один дом файла, один интерфейс приёма, одна проверка. Глаголы платформы четыре: принять файл · связать имена · показать · питать позами с железа. Своего файла нет — механизм печатаем мы, и он остаётся черновиком, пока вы не принесёте свой.

Из чего состоит

Четыре понятия

ПонятиеЧто это у вас на железе
Звено (link)Твёрдое тело: рама, каретка, плечо, планшайба. Несёт видимую геометрию — примитив или меш.
Шарнир (joint)Подвижная связь двух звеньев: родитель, ребёнок, положение и направление оси. У шарнира есть имя — им его зовёт программа.
Пределы (limit)Границы хода, усилие и скорость. Границы — АБСОЛЮТНЫЕ координаты, а не длина хода.
Цвет (material)Цвет звена берётся из файла: <material><color rgba> в URDF или материал внутри .glb. Первым спрашивается сам файл меша, и только если он о цвете промолчал — <material> визуала. Звено, цвета не назвавшее, рисуется нейтральным серым — своей палитры по номеру звена мы не подставляем. Отделка (полупрозрачность, блеск) при этом наша: копия остаётся прибором, а не картинкой, и текстуры из файла на экран не попадают. Белый цвет считается «не назван»: это умолчание и URDF, и glTF, и отличить его от молчания нечем.
Точка (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». Одно имя с двумя смыслами однажды сделало рабочий конверт станка вдвое шире реального.

Имена

Имя шарнира — то, чем его зовёт программа

Связка «механизм ↔ управление» держится на одном имени. Поэтому имя шарнира подвижной оси — не подпись для человека, а адрес.

ГдеИмяЧто этоГде в файлеСинонимы
узел автоматикиsrv0, srv1, …серво: подвижный шарнир<joint name="srv0">servo0 · joint0
узел автоматикиdi0, di1, …дискретный вход<link name="di0"> — точка датчикаinput0
узел автоматикиdo0, do1, …дискретный выход<link name="do0"> — точка исполнителяoutput0
узел автоматикиai0, ai1, …аналоговый вход<link name="ai0"> — точка замераanalog0
станокA · B · C · U · V · X · Y · Zось породы: имя шарнира — буква оси<joint name="X">—
навесноеjaws · rotate · tilt · tool_spin · turret_index · wireось головы: ключ оси<joint name="jaws">, корень механизма — tool0—

Ведущих нулей нет. Подпись канала («зажим тисков») именем не является и меняется свободно — иначе переименование тихо переставляло бы шарнир под другой привод. Ваши собственные имена звеньев, материалов и неподвижных деталей — как хотите: договор касается только шарниров подвижных осей и точек каналов.

Правило одно на все три рода: имя, которым ось зовёт программа, и есть связка с механизмом. Что чем зовётся — см. типы станков.

Три рода

Один механизм на узел, станок и голову

Дом файла один (mechanisms), интерфейс приёма один, судья один. Различается только то, чем зовутся шарниры и откуда берётся наш черновик.

РодИмена шарнировЧерновик печатается изИнтерфейс приёма
Узел автоматикиsrv0 · di0 · do0 · ai0 паспорта узла: цепочка по порядку приводов /api/automation/rigs/{id}/mechanism
СтанокA · B · C · U · V · X · Y · Z шаблона кинематики породы и ходов осей двойника; цепь кончается стыком tool0 /api/machines/{id}/mechanism
Навесноеjaws · rotate · tilt · tool_spin · turret_index · wire записи справочника: вид головы и вылет TCP; корень — тот же tool0 /api/effector-configs/{id}/mechanism

GET отдаёт принесённый файл байт в байт, а не принесён — заводской черновик. Чем именно отвечено, говорит заголовок X-Mechanism-Source: imported | generated: гадать по содержимому не нужно.

Тип станка пользовательским файлом не переопределяется. Число подвижных шарниров обязано совпасть с числом осей породы: завели шестиосевой — значит шесть. Не совпало — отказ словами, с обоими числами.

Заводской черновик — схема верных пропорций, а не чертёж. Честно известны две вещи, и обе из двойника: ход по осям и, если порода назвала, края звеньев. Поперечных размеров станины в двойнике нет — они выведены долей хода и названы комментарием прямо в XML.

Чужая модель

Таблица имён вместо переименования

Модель из ROS или от вендора несёт свои 7–36 имён. Переименовывать их руками — стена, а переименовать за вас мы не имеем права: порядок звеньев в дереве и номер привода — разные вещи, и однажды они разойдутся молча.

Поэтому файл приносится вместе с картой {канал: имя в файле}. Судить первый пункт договора будет карта, а не написание имён внутри файла.

{ "mechanism": "mechanism.urdf", "joints": { "srv0": "lift_lower_joint", "srv1": "lift_upper_joint" } }

Карта проверяется целиком: непокрытый подвижный шарнир и канал, чьё имя ни к чему в файле не ведёт, — это названные отказы. Карта едет на бокс отдельным файлом рядом с механизмом, потому что пакет обязан быть самодостаточным: бокс, получив чужой файл, должен знать, какой шарнир двигает srv0.

Геометрия

Меши: что принимаем и что показываем

ФорматХранилищеЭкранЗамечание
.glbдадапредпочтительный формат: одно тело, материалы внутри
.gltfдадавезёт с собой буфер .bin и текстуры .png / .jpg
.stlдадаголая сетка, без материалов
.daeдадаCOLLADA, родной формат мешей в донорских URDF: и хранится, и рисуется — поворот из <up_axis> берётся из файла
.objдадаголая сетка без материалов: и хранится, и рисуется
.stepдадаобменный формат CAD: тело, а не сетка — триангулируется при показе
.stpдадато же, что .step — второе написание того же формата
.igesдадаобменный формат CAD старшего поколения: поверхности, материалов нет
.igsдадато же, что .iges — второе написание того же формата
.bin · .png · .jpgда—спутники glTF: URDF их не называет, тело тянет их само

Путь меша указывается ровно так, как он написан внутри URDF (meshes/frame.stl): файлы приезжают тем же запросом, что и текст механизма, — одна транзакция, один владелец записи. Общий предел на комплект геометрии — 30 МБ.

Принимаются меши подвижных звеньев и опорного — того самого корня дерева, подошвы, на которой механизм стоит. «Подвижное» — это вывод, а не список исключений: звено подвижно, если путь от корня до него содержит хотя бы один не-fixed шарнир (кожух, прикрученный fixed к плечу, едет вместе с плечом и потому подвижен). Не принесённый меш такого звена — отказ; меш прочего неподвижного (кожух, декор) не кладётся, и об этом говорится строкой предупреждения, а не молчанием.

Геометрию импорт не снимает. Запрос без поля meshes — в том числе загрузка одного файла механизма — оставляет уже лежащие меши на месте и говорит об этом строкой. Заменить геометрию можно тем же запросом (поле meshes), снять — только вместе с механизмом.

На бокс уезжают три вещи: текст механизма, таблица имён и принятые меши.

Не требуем

Что мы принимаем и игнорируем

ТегЧто с ним
<collision>Принимаем и игнорируем: столкновений мы не считаем. Меш, названный только в <collision>, не требуется — платить десятками мегабайт за данные, которые никто не читает, мы не просим.
<inertial>Динамики мы не считаем: копия питается позами с железа, а не решает уравнения движения.
<mimic>НЕ поддержан: сцепленную пару (гантри, параллельный захват, пантограф) покажем как два независимых шарнира. Если в вашей модели ведомый вал идёт за ведущим — на картинке он будет стоять.

Не тратьте время на подготовку столкновительной геометрии и на массы с тензорами инерции: мы их не читаем. Копия питается позами, приходящими с железа, а не решает физику.

Импорт

Что проверяет интерфейс приёма

Порядок жёсткий: судья → отказ либо запись. Молчаливого приёма нет, правки принесённого текста нет — ни отступов, ни единиц. Отказ приходит целиком, со всеми замечаниями сразу, а не по одному на попытку.

1

Имена

Шарнир подвижной оси зовётся по договору (srv0, srv1, …) — либо приносится таблица имён. Имя, похожее на адрес, но написанное иначе (servo_0, SRV0, joint3), отвергается с подсказкой точного имени. За вас не переименовываем.

проверяется
2

Дерево

У звена ровно один родитель, корень один, циклов нет.

проверяется
3

Пределы

<limit lower upper> объявлены у revolute и prismatic и заданы абсолютными координатами хода, а не его длиной.

проверяется
4

Единицы

Метры и радианы: URDF — это СИ. Объявить единицы в файле нечем, поэтому проверяется правдоподобие величины — так ловятся миллиметры и градусы, положенные в СИ-поле.

проверяется
5

Внутри нет железа

Ни пина, ни слейва, ни шины (lcec, slave, cia402, din-, dout-, ain-). URDF описывает механику; чем канал является электрически (роль, профиль движения) — знает passport.json рядом с механизмом. Куда он подключён на конкретном стенде — не знает и паспорт: узел в каталоге один, стендов много.

проверяется

Файлы xacro принимаются. Реальные модели ROS почти всегда приходят макросами и включениями — разворачивание идёт до того же единственного судьи. Вместе с файлом механизма присылаются его соседи (включения, макросы, параметры). Аргументы xacro на этом шаге не задаются: берутся умолчания, а объявленные файлом аргументы называются в ответе — у файла с $(arg …) разворачиваний несколько, и мы взяли одно.

Пока свой файл не принесён, механизм — наш черновик, напечатанный по паспорту узла: цепочка по порядку приводов, схематичные звенья, и каждое додуманное число названо и в предупреждениях, и комментарием в самом XML. После импорта механизм — ваш файл, и генератор в него больше не пишет; вернуться к черновику можно одним движением.

Паспорт

Четвёртый файл каталога — passport.json

URDF описывает МЕХАНИКУ узла — звенья, шарниры, пределы хода. Всё, что механикой не является — роль канала, чем он физически исполнен, профиль его движения, адресное пространство ячеек, имя и описание узла для человека, — несёт отдельный файл рядом с механизмом: passport.json. Узел заводится каталогом из пяти файлов, и ни строкой кода:

  • mechanism.urdf — механика: звенья, шарниры, пределы хода.
  • меши — видимая геометрия звеньев.
  • mechanism_map.json — имена чужого донора, если файл принесён не наш.
  • passport.json — роли каналов, электрика, ячейки, имя и описание узла.
  • program.plc — логика: что узел делает.

Разграничение владения записи жёсткое: поле, которое КРУГ URDF выводит сам (тип шарнира, ход, порядок каналов), в паспорте не дублируется — это была бы вторая правда о том же. Паспорт несёт ровно то, чего URDF не может сказать в принципе.

РазделПоляПочему не в URDF
servosrole (ось · сустав · вращение · затяжка), kind (физический механизм: лента, мачта, вилка, шнек…), max_velocity, max_acceleration, max_deceleration, max_torque, rated_torque_nm, lead_mm (ход винта, мм/об), gear_num / gear_den шарнир задаёт ТИП движения и пределы хода, но не режим привода и не физику передачи — continuous из файла читается одинаково что у ленты, что у шпинделя завинчивания
outputsrole: grip, clamp, gate, valve, marker, applicator, diverter, vacuum, glue, part_feed точка исполнителя в URDF есть, а того, ЧТО она делает, файл не говорит — дискретных выходов в дереве звеньев нет вовсе
inputsrole: presence, at_position, trigger, verdict, fill_level, force_ok, grip_ok, label_gap то же для входов: точка датчика есть, смысл сигнала — нет
analogsquantity, units аналоговых каналов URDF не несёт вовсе
gridcols, 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 — идентификатор механизма, а не подпись узла для человека; описания в файле нет вовсе
{ "version": 1, "name": "Кран-штабелёр (склад)", "description": "Рельсовый ASRS-кран: рельс + мачта + вилка + захват.", "servos": [ { "channel": "srv0", "label": "нижняя ступень", "role": "linear_axis", "kind": "mast" }, { "channel": "srv1", "label": "верхняя ступень", "role": "linear_axis", "kind": "mast" } ], "outputs": [], "inputs": [], "analogs": [], "grid": { "cols": 8, "rows": 5, "levels": 1, "pitch": [700.0, 400.0, 0.0], "origin": [0.0, 0.0, 0.0] } }

lead_mm умолчания не имеет. Ход винта — свойство ЭКЗЕМПЛЯРА оборудования, не механики. Не назван в паспорте — прямая ось честно остаётся без хода винта (в 3D не поедет, и это видно) вместо того, чтобы поехать по придуманному числу. Образец галереи ewellix_lift ровно в этом положении: программа-пример для него не собрана, потому что lead_mm паспортом не назван.

Чего в паспорте нет и быть не должно — фактов КОНКРЕТНОГО СТЕНДА: слейв, пин, шарнир привода, датум нуля. Узел в каталоге один, стендов, куда его поставят, много; эти числа называет наладчик у железа, а не карточка образца.

Ключ канала паспорта — его ИМЯ (srv0, di0), то же самое, которым его зовут URDF и программа; отдельного порядкового номера паспорт не хранит.

Программа

Пятый файл каталога — program.plc

URDF описывает механику, паспорт — роли и электрику, а что узел делает называет отдельный текстовый файл рядом с ними: program.plc. Внутри — ТЕЛО программы на языке лаборатории PLC (том же, на котором пишутся программы рода motion в /programs/plc): состояния, переходы, движения по дорожкам.

Объявления оборудования в файле нет. Пролог rig({ axes, outputs, inputs }) — вторая запись состава узла — платформа ПЕЧАТАЕТ сама из паспорта и механизма, на место метки // @rig в начале файла. Написать этот пролог рукой нельзя: состав узла жил бы в двух местах сразу и расходился бы молча, как только один из них поправят. Метка бывает и в форме // @rig inline — печать входит прямо в неё, без переноса строки.

Файла нет — программы у узла нет. Не подставляется ни пустой шаблон, ни программа по умолчанию: логика не объявлена, и вывести её из механизма с паспортом не из чего. Это видно строкой на экране узла, а не молчанием.

// @rig machine({ title: 'Конвейер — счёт деталей', initial: 'ход', states: { 'ход': { lanes: { лента: [spin(1, 30)] }, on: { 'счётчик ↑': 'посчитали' }, }, 'посчитали': { wait: 0.4, on: { done: 'ход' }, }, }, })

Файлом программу можно принести не у всякого узла. У образцов, чья программа-пример ВЫЧИСЛЯЕТСЯ из <limit> принесённого механизма (motopos_d500, flir_ptu_d46, ewellix_lift), она остаётся вычисляемой, а не файлом: замените механизм — программа обязана поехать за новыми пределами хода, а статический текст файла этого не умеет. Это граница формата, а не недоделанная функция.

Шестой файл — program.spec.json, и его не пишут руками

Текст program.plc — единственный ИСТОЧНИК; рядом с ним лежит program.spec.json — то же самое, разобранное в шаги. Он нужен потому, что собирает шаги ОДИН движок, и живёт он в браузере: без этого файла узел из каталога пришлось бы сперва открыть в лаборатории и сохранить, иначе играть было нечем.

Это порождённый файл, а не вторая правда. Правят только program.plc, а спеку пересобирают — команда пересборки записана в самом файле, в поле _source. Прогон сверяет её с исходником байт в байт и краснеет, если текст поправили, а спеку не пересобрали.

Пересборки требует и смена СОСТАВА узла в passport.json — каналы, выходы, входы: спека несёт отпечаток обоих входов сразу, текста программы и состава. Поэтому «поправил паспорт — пересобери спеку» — то же правило, что и для текста.

Граница формата

Что URDF не выражает — и мы это не скрываем

Замкнутую цепь дерево не выражает. У гексапода подвижная платформа держится на шести штангах — это шесть родителей у одного звена, тогда как дерево допускает ровно одного. Сферических шарниров в URDF нет вовсе.

Из этого не следует, что параллельной машине механизма не полагается. 3 породы из 15 объявлены параллельными (Гексапод (платформа Стюарта, 6 ног) · Линейная дельта (3 каретки, уровневая платформа) · Трипод (3-PRS наклонная голова, Sprint-Z3-класс)), и механизм им печатается: их A/B/C наклоняют платформу вокруг её же центра, поэтому совпадение пивотов — правда о машине, а не потеря геометрии. Отказом это было до 06.09, и отказ врал.

Род цепи объявляет порода, а не число поворотных осей. Настоящие штанги такой машины приходят готовым мешем, а не печатью тел: то, что дерево выразить не может, приносится геометрией, а не выдумывается структурой.

Токарный станок, наоборот, ложится на дерево отлично — двумя ветвями от станины:

станина ├── каретка Z (prismatic) → салазки X (prismatic) → резцедержка └── шпиндель (continuous) → патрон → заготовка

Осторожно, если шпиндель работает и как ось C. Тип шарнира называется один раз: шпиндель — это continuous, вращение без границ. Пределы и подача оси C живут отдельным полем паспорта, а не вторым шарниром на том же валу. Иначе получится одно имя с двумя смыслами — и разъедется не значение, а смысл.

STEP

Механизм из сборки STEP

Интеграторы приносят STEP, а не робо-описания. Договор жёсткий и проверяется интерфейсом: структура сборки — это кинематическое дерево. Подсборка цепи становится звеном, её трансформация — положением шарнира; всё, что внутри подсборки, — тело звена.

Родитель и origin приходят из структуры даром. Человеку остаются три вещи: тип шарнира, ось и пределы. Дальше — тот же единственный судья и тот же дом, что у принесённого URDF.

Отказ говорит, что сделать, и называет узлы из вашей же модели: «в корне 47 деталей и ноль подсборок — сгруппируйте подвижные узлы». Замкнутую цепь договор не спасает: у платформы гексапода шесть родителей, дерева нет в принципе, и здесь отказ честен.

Ручки: POST /api/automation/rigs/{id}/mechanism/from-step и POST /api/machines/{id}/step. Сегодняшние входы механизма — URDF, xacro и STEP.

Образцы

Галерея готовых механизмов

11 образцов, которые можно взять и посмотреть, как выглядит правильно описанный узел. Часть — наши черновики, часть — доноры ROS. Учебные: паспортом оборудования они не являются, числа из них цитировать как замер нельзя.

ОбразецЧто показываетФайлы каталогаМешей
Рука ALLEXсемиосевой манипулятор, вырезанный из чужого гуманоидамеханизм · паспорт · программа · спека8
Конвейер (транспортёр)ЧЕРНОВИК, напечатанный намимеханизм · паспорт · программа · спека—
Конвейер с рамойГИБРИД: чужой меш + наше подвижное звеномеханизм · паспорт · программа · спека1
Ewellix TLTЛИНЕЙНАЯ ОСЬ (телескопическая подъёмная колонна), 2 ступенимеханизм · карта имён · паспорт51
FLIR PTU-D46ПОВОРОТНАЯ ГОЛОВА (pan-tilt), 2 осимеханизм · карта имён · паспорт5
Портал 3 оси + захватЧЕРНОВИК, напечатанный намимеханизм · паспорт · программа · спека—
KUKA KR16РУКА как узел автоматики, 6 поворотных осеймеханизм · карта имён · паспорт · программа · спека6
MotoPos D500ПОЗИЦИОНЕР (поворотно-наклонный стол), 2 осимеханизм · карта имён · паспорт6
Robotiq 2F-85ЗАХВАТ (двухпальцевый параллельный), ОДИН приводмеханизм · карта имён · паспорт13
Поворотный делительный столЧЕРНОВИК, напечатанный намимеханизм · паспорт · программа · спека—
Кран-штабелёр (склад)ЧЕРНОВИК, напечатанный намимеханизм · паспорт · программа · спека—

Доноры взяты из открытых репозиториев ROS с зафиксированным коммитом и датой загрузки; лицензия и источник указаны рядом с каждым. Все образцы проходят тот же интерфейс приёма, что и ваш файл: образец, не проходящий её, означает ошибку либо в образце, либо в правиле.

Дальше — типы станков и кинематики: какая порода что умеет и почему гексапод программируется движениями, но не режет по G-code.