Программа движения описывает путь навесного органа — схвата, струбцины, горелки — по местам рабочей ячейки. Ниже: чем этот род программ отличается от реза, из каких глаголов собирается путь, что в каждом глаголе называет технолог, а что выводит платформа, и где программа отказывает вместо того, чтобы догадаться.
Род программы задаёт ДВИЖОК, а не технология и не навесное. Проверка одна: меняет ли смена навесного саму траекторию. Да — это рез, нет — движение. Сварка отдельным родом не является.
| Род | Траектория | Координаты | Инструмент | Кому доступен |
|---|---|---|---|---|
| cut — рез | ВЫВОДИТСЯ из объёма детали | координаты детали, Z0 — верх болванки | стол слотов, M6 / T / G43 | кинематикам, у которых есть решатель в LinuxCNC (3 оси, 5 осей, токарная) |
| motion — движение | НАЗЫВАЕТ автор, каждая ось по своему заданию | координаты ячейки, места по имени | слотов нет вовсе — у схвата и горелки их не бывает | любому механизму, включая трёхосевой фрезер |
Род — это ПОЛЕ программы, а не вывод из списка генераторов. Он выбирается один раз, при создании программы, вместе с оборудованием. Пока род выводили из имени генератора, вывод жил в трёх местах независимо и разъехался.
Имя шарнира — то, чем его зовёт программа. У узла автоматики это каналы srv0, di0, do0; у станка — буква оси. Навязывать одной породе имена другой платформа не станет.
Один шаг замысла автора — не одна строка G-code: смыкание губок и поворот разворачиваются в несколько кадров.
Раскрываются в те же элементарные действия. Второй истины про путь нет: макро не печатает кадры мимо общего движка.
Место и груз. Координаты места живут в двойнике и замеряются обучением; программа называет только имя.
Начальная точка («дом»), места ячейки и база программы раздаются генератору из двойника — в тексте программы их не набивают.
Место ячейки по ИМЕНИ: тиски, кантователь, паллета, сварочный стол.
имя места
координаты — из двойника станка (замеряются обучением)
Ограничение. имени нет в двойнике — отказ со списком того, что есть; молчаливого отката на числа не бывает
Деталь в ячейке: габарит, место и местный ноль губок. Не заготовка реза — форма не нужна.
габарит, место, сторона захвата
.grip (середина боковых граней), .above(h), .top, .center, .width (пролёт по оси захвата)
Ограничение. место — это ОПОРА под деталью: низ = at, верх = at + толщина
Ориентация навесного — модальная, как в G-code: названа один раз, дальше едет сама.
углы кисти, градусы
в кадр попадает только при СМЕНЕ; своего хода глагол не делает
Ограничение. не назвали вовсе — поза берётся из начальной точки двойника, а не выдумывается
Ход до точки. Без подачи — рапид (G0); названа подача — рабочий ход (G1).
точка: p.grip · p.above(60) · place(…) · [x, y, z]
G0/G1, штамп ориентации, кэш координат места
Ограничение. числовая точка отсчитывается от БАЗЫ программы, если она обучена; ход по имени места за базой не едет
Развести / свести губки. onTheMove — команда уходит ПЕРЕД предыдущим ходом, рука не останавливается.
состояние; пролёт и усилие — по желанию
пролёт по умолчанию — ширина груза part().width; зазор и усилие — из паспорта головы
Ограничение. «свести», когда пролёт не назван и не встречался раньше, — отказ. Зазор на раскрытие не выдумывается: паспорта нет — числа в кадре нет, бит размыкания есть всегда
Кантование: НА СКОЛЬКО повернуть от текущей ориентации.
приращение углов
абсолютная поза кисти, всегда рабочий ход
Ограничение. только БОКОВОЙ захват — взятую сверху деталь держит прижим, оси переворота у неё нет; рапид кистью роняет деталь, поэтому его тут не бывает
Выдержка на месте — дать губкам сомкнуться до подъёма.
секунды
—
Ограничение. не названы ни в действии, ни в наладке — отказ, а не выдуманная длительность
Метка фазы: ни кадра, ни времени. По ней плеер подписывает шкалу и рисует границы.
имя фазы словами
—
Ограничение. фаза без имени — отказ
Сглаживание ломаной: through — кривая идёт ЧЕРЕЗ точки, near — срезает углы.
режим и плечо скругления, мм
сама кривая — цепочка тех же ходов
Ограничение. крайние точки пути и точки действий (губки, выдержка) не двигаются ни в одном режиме; действие между переездами разрывает цепочку
Сменить ОПОРНУЮ ГРАНЬ детали одним глаголом: взять, поднять, развернуть, положить.
РЕЗУЛЬТАТ — какая грань станет опорной
ось, угол, высота разворота и новая высота детали над опорой
Ограничение. только боковой захват; высота разворота ниже минимума (полудиагональ + зазор) — отказ с числом. После кантования ноль детали недействителен
Обход головы ВОКРУГ детали: точка едет по дуге, голова всю дугу смотрит на поверхность.
вокруг чего, отступ или радиус, сектор
радиус из полудиагонали детали + отступ; шаг раскладки — из допуска на хорду, а не из числа сегментов
Ограничение. деталь не трогается, губки обязаны быть пусты; дуга сквозь габарит детали — отказ с числами
Короткая запись типового пути: подвести → развести → взять → поднять → (перевернуть) → опустить → отпустить.
точки A и B, порт схвата, ширина детали
весь скелет пути; раскрытие и усилие — из паспорта головы
Ограничение. порт схвата ОБЯЗАТЕЛЕН и не угадывается; кантовать (turn) умеет только боковой захват
Сварной шов роботом. around — обвар по контуру детали: сопло наклонено наружу и доворачивается на углу.
точки шва либо деталь для обвара, выход дуги
путь горелки, наклон на сторонах контура, тепловложение из режима
Ограничение. выход дуги ОБЯЗАТЕЛЕН и не подставляется: на руке со схватом порт 0 — это клапан губок. Режим по имени, которого у головы нет, — отказ со списком
Кольцевой шов на стыке труб: кольцо задаётся трубой, а не набивается точками.
центр стыка, ось, диаметр, отступ сопла
радиус (dia/2 + standoff), точка старта — дальняя от робота, раскладка из допуска
Ограничение. глагол НЕ обещает полный круг: каждая точка решается той же обратной кинематикой, что и отправка на станок; дуга обрывается там, где рука встаёт, остаток кольца сообщается углом
Отказ — там, где догадка стоила бы детали или железа. Предупреждение — там, где написанное бывает законным замыслом, но молчать о нём нельзя.
| Ситуация | Реакция | Почему так |
|---|---|---|
| Кантование при захвате сверху | отказ | взятой сверху деталью кантовать нечем — нужен боковой захват |
| Свести губки, не назвав пролёт | отказ | пролёт детали не выдумывается: это её размер, а не константа платформы |
| Путь варит, а выход дуги не привязан | отказ | подстановка порта означала бы, что вместо дуги дёрнется клапан губок |
| Дуга и губки на одном выходе | отказ | зажигание дуги сомкнуло бы схват |
| Дуга зажжена и не погашена | отказ | горелка уехала бы в начальную точку горящей — это не бывает ничьим замыслом |
| Ход назвал место, которого нет в двойнике | отказ с именем места | «поехать примерно туда, где было раньше» — ровно та мина, ради которой места и заведены |
| Парковка назначена туда, где губки работают с деталью | отказ с числами | «дом» внутри оснастки не отделяет руку ни от детали, ни от следующей программы цепочки |
| Начальная точка не задана | предупреждение | программа стартует оттуда, где рука стоит сейчас, — в цепочку её ставить нельзя |
| Путь заканчивается сомкнутыми губками | предупреждение | деталь уедет в начальную точку вместе с рукой. Законный замысел (передать дальше), поэтому не отказ — но и не молчание |
| В пути есть кантование | предупреждение | смещение детали при развороте зависит от вылета схвата — этого числа программа не знает |
Кантование делает ноль детали недействительным. В проекте-цепочке между переворотом и следующим резом по той же детали обязателен автопоиск заготовки касаниями на том же станке — без него планировщик пакет не соберёт. Нарушение этого правила проявляется не отказом стенда, а запоротой деталью.
// Переворот детали на месте, шаг за шагом.
const v = param('подача переноса', 1200, { min: 100, max: 4000, step: 50 });
const h1 = param('подход', 120, { min: 20, max: 400, step: 10 });
const h2 = param('разворот', 150, { min: 20, max: 600, step: 10 });
// Груз и местный ноль губок. Место ячейки — по имени, а не координатами.
const p = part({
size: [200, 100, 50],
at: place('mill-1.vise'),
grip: 'side', // струбцина охватывает боковые грани
});
phase('подвод');
moveTo(p.above(h1)); // подход над деталью, рапидом
jaws('open', { onTheMove: true }); // разводим НА ХОДУ — рука не встаёт
phase('захват');
moveTo(p.grip, { feed: v }); // опуститься на местный ноль губок
jaws('close'); // сомкнуть на пролёт детали
dwell(0.3); // дать зажиму сработать до подъёма
phase('переворот');
moveTo(p.above(h2), { feed: v });
rotate({ a: 180 }); // кантовать — всегда рабочим ходом
phase('укладка');
moveTo(p.grip, { feed: v });
jaws('open');
phase('возврат');
moveTo(p.above(h2)); // дальше рука сама уйдёт в парковку Тот же переворот одним глаголом: flip({ onto: 'opposite', feed: v }) — высоту разворота, ось и угол платформа посчитает сама из габарита детали.
( flip-clamp — robot motion path, 14 действий ) ( ORIENTATION_MODEL: flange_roll ) ( TOOL_AXIS: 0.000000 0.000000 -1.000000 ) ( grasp = side, axis = x, jaw span 200.000 mm, port P0 ) ( gripper = DO P0 [M64 clamp / M65 release] ) G21 G90 G17 G94 G54 M65 P0 ( разжать губки перед выходом в начальную точку ) G0 X0.000 Y0.000 Z400.000 A180.000 B0.000 C0.000 ( в начальную точку ) ( phase: подвод ) … G1 A0.000 B0.000 C180.000 F1200 ( turn the part over ) … G0 X0.000 Y0.000 Z400.000 ( возврат в начальную точку — деталь уже отпущена ) M30
Шапка несёт то, чего по одним координатам не восстановить: конвенцию ориентации, направление оси инструмента, способ захвата и порт схвата. Программа начинается и заканчивается в начальной точке — только тогда её можно ставить в цепочку в любом порядке.