У каждой породы есть программа, которую человек видит первой, — и та же программа идёт входом приёмочного сценария: создать станок → preflight → запуск → база → отправка → пин HAL. Пример обязан проходить чисто; ожидание записано числами до прогона. 11 пород, своя программа у 10 пород, остальные работают «как фрезер».
/machines: по карточке на породу, зрелость — бейджем.| порода | программа | род | болванка, мм | смены | слово S | конечная поза | зрелость |
|---|---|---|---|---|---|---|---|
| mill-xyz | торцовка (общая: торцовка) | cut | 40 × 30 × 10 | T1 → T2 | 12000 | — | серийный |
| mill-5axis-trunnion | три грани за один установ | cut | 40 × 30 × 10 | T1 → T2 → T2 | 12000 | B = 90 · C = 90 | бета |
| mill-5axis-head | три грани за один установ | cut | 40 × 30 × 10 | T1 → T2 → T2 | 12000 | A = 90 · C = 90 | бета |
| lathe-2axis | вал из прутка | cut | 20 × 20 × 40 | T1 → T2 → T3 | 1200 | — | бета |
| laser-plotter | раскрой лучом | cut | 40 × 30 × 10 | стола нет | 30 | X = 4.9 · Y = 4.9 | бета |
| robot-kr16 | перекладка A→B | motion | 40 × 30 × 10 | стола нет | не пишется | — | R&D |
| kuka-welder | прямой шов 300 мм | motion | 40 × 30 × 10 | стола нет | не пишется | — | R&D |
| robot-hexapod | обход с наклоном платформы | motion | 40 × 30 × 10 | стола нет | не пишется | X = 0 · Y = 0 · Z = 450 | R&D |
| robot-linear-delta | контур дельтой | cut | 40 × 30 × 10 | T1 | 12000 | X = 2 · Y = 2 · Z = 5 | R&D |
| robot-tripod | наклоны головки | motion | 40 × 30 × 10 | стола нет | не пишется | Z = -10 | R&D |
| wire-edm | контур проволокой | cut | 40 × 30 × 10 | стола нет | не пишется | X = 4.875 · Y = 4.875 · Z = 5 | R&D |
«Стола нет» — у головы без стола инструментов (проволока, луч, схват) смены быть не должно; «не пишется» —
порода не печатает слово S, и требовать его значило бы врать про станок. Конечная поза — где обязан
оказаться инструмент по окончании программы: так проверяется доезд замысла до железа у пород без шпинделя.
R&D — кинематика работает на виртуальных осях, на живом железе не проверена. Матрица пород — треугольник, а не квадрат: станок с большими возможностями обязан исполнять примеры менее требовательных.
stock(40, 30, 10);
face({ depth: 0.4 });
drill({ points: [[10, 10], [30, 20]], depth_mm: 3 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Торцовка 0.8 мм | python_face | T1 · Ø12 | depth_mm · feed · plunge_feed · rect · rpm · step_down · step_over · tool_diameter |
| 2 | Сверловка Ø6 | python_drill | T2 · Ø6 | depth_mm · feed · peck_mm · plunge_feed · points · rpm |
stock(40, 30, 10);
face({ depth: 0.4 }); // в нуле ориентации: верх детали
index({ b: 90 }); // боковая грань — под инструмент
drill({ points: [[10, 5]], depth_mm: 3 }); // боковая грань
index({ b: 90, c: 90 }); // та же поза, повёрнута вокруг Z
drill({ points: [[8, 5]], depth_mm: 3 }); // соседняя грань
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Торцовка верха | python_face | T1 · Ø12 | depth_mm · feed · plunge_feed · rect · rpm · step_down · step_over · tool_diameter · work_orientation |
| 2 | Отверстие в боковой грани | python_drill | T2 · Ø6 | depth_mm · feed · peck_mm · plunge_feed · points · rpm · work_orientation |
| 3 | Отверстие в соседней грани | python_drill | T2 · Ø6 | depth_mm · feed · peck_mm · plunge_feed · points · rpm · work_orientation |
stock(40, 30, 10);
face({ depth: 0.4 }); // в нуле ориентации: верх детали
index({ b: 90 }); // боковая грань — под инструмент
drill({ points: [[10, 5]], depth_mm: 3 }); // боковая грань
index({ b: 90, c: 90 }); // та же поза, повёрнута вокруг Z
drill({ points: [[8, 5]], depth_mm: 3 }); // соседняя грань
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Торцовка верха | python_face | T1 · Ø12 | depth_mm · feed · plunge_feed · rect · rpm · step_down · step_over · tool_diameter · work_orientation |
| 2 | Отверстие в боковой грани | python_drill | T2 · Ø6 | depth_mm · feed · peck_mm · plunge_feed · points · rpm · work_orientation |
| 3 | Отверстие в соседней грани | python_drill | T2 · Ø6 | depth_mm · feed · peck_mm · plunge_feed · points · rpm · work_orientation |
bar({ diameter: 20, length: 40 });
turn({ stages: [{ length: 12, diameter: 16 }, { length: 8, diameter: 10 }], tool: T1 });
groove({ z: 4, width: 2, diameter: 12, tool: T2 });
partOff({ z: 20, tool: T3 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Обточка профиля | python_turn_profile | T1 · Ø0 | doc_mm · face · feed · finish_mm · rpm · stages · stock_diameter_mm |
| 2 | Канавка Ø12 | python_groove | T2 · Ø0 | diameter_mm · doc_mm · feed · rpm · stock_diameter_mm · tool_width_mm · width_mm · z_mm |
| 3 | Отрезка на Z20 | python_part_off | T3 · Ø0 | bore_diameter_mm · doc_mm · feed · rpm · stock_diameter_mm · tool_width_mm · z_mm |
stock(40, 30, 10);
contour({ depth_mm: 2 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Раскрой контура | python_contour | — · Ø0.2 | depth_mm · feed · laser_power · offset · polygon · rpm · step_down · tool_diameter |
// ПЕРЕНОС БЕЗ ПЕРЕВОРОТА: взять деталь в точке A и положить в B.
// Ни болванки, ни фрезы: у рода `motion` автор называет ПУТЬ.
const a = [900, -300, 300]; // координаты ЯЧЕЙКИ, не детали
const b = [900, 300, 300];
const h = 150; // высота переноса над захватом, мм
orient([180, 0, 0]); // инструмент вниз
phase('подход');
moveTo([a[0], a[1], a[2] + h]);
jaws('open', { onTheMove: true }); // разводим НА ХОДУ
phase('захват');
moveTo(a, { feed: 1500 });
jaws('close'); // сомкнуть на пролёт детали
dwell(0.3); // дать зажиму сработать до подъёма
phase('перенос');
moveTo([a[0], a[1], a[2] + h], { feed: 1500 });
moveTo([b[0], b[1], b[2] + h]);
phase('укладка');
moveTo(b, { feed: 1500 });
jaws('open'); // отпустить
moveTo([b[0], b[1], b[2] + h], { feed: 1500 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Перекладка A→B | python_motion_path | — · Ø0 | grasp_from · gripper_port · home_abc · home_xyz · path_json |
// ПРЯМОЙ ШОВ: подвести горелку к началу стыка, зажечь дугу, пройти
// шов рабочим ходом, погасить, отойти. Дуга — такое же действие в
// точке, как смыкание губок; новый род для сварки не заводится.
const v = param('подача шва', 480); // 8 мм/с профиля горелки
const a = [900, -150, 300]; // начало стыка, координаты ЯЧЕЙКИ
const b = [900, 150, 300]; // конец стыка
orient([180, 0, 0]); // сопло вниз
phase('подход');
moveTo([a[0], a[1], a[2] + 100]);
moveTo(a, { feed: v });
phase('шов');
weld({ to: b, arc: 3, feed: v }); // зажечь → пройти → погасить
phase('отход');
moveTo([b[0], b[1], b[2] + 100], { feed: v });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Прямой шов 300 мм | python_motion_path | — · Ø0 | arc_port · feed_mm_min · grasp_from · home_abc · home_xyz · orientation_model · path_json |
// ШЕСТЬ СТЕПЕНЕЙ СВОБОДЫ ОДНИМ ПУТЁМ: платформа идёт по квадрату и
// на каждой стороне держит СВОЙ наклон, а в конце разворачивается
// вокруг своей оси. Положение и ориентацию гексапод задаёт вместе —
// это и есть то, чего декартов стол не умеет.
const r = param('полуразмер квадрата', 60); // зона ±120 мм
const z = param('высота обхода', 400); // зона 300…500 мм
const t = param('наклон', 10); // предел ±20°
orient([0, 0, 0]); // платформа горизонтально
phase('выход на высоту обхода');
moveTo([r, 0, z]);
phase('сторона 1');
orient([0, t, 0]);
moveTo([0, r, z], { feed: 1500 });
phase('сторона 2');
orient([t, 0, 0]);
moveTo([-r, 0, z], { feed: 1500 });
phase('сторона 3');
orient([0, -t, 0]);
moveTo([0, -r, z], { feed: 1500 });
phase('сторона 4');
orient([-t, 0, 0]);
moveTo([r, 0, z], { feed: 1500 });
phase('разворот платформы');
orient([0, 0, 15]);
moveTo([0, 0, z], { feed: 1500 });
Паспорт экземпляра при создании станка: {"spindle_max_rpm":24000}.
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Обход с наклоном платформы | python_motion_path | — · Ø0 | grasp_from · home_abc · home_xyz · path_json |
stock(40, 30, 10);
contour({ depth_mm: 2 });
Паспорт экземпляра при создании станка: {"spindle_max_rpm":24000}.
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Контур Ø6 | python_contour | T1 · Ø6 | depth_mm · feed · offset · plunge_feed · polygon · rpm · step_down · tool_diameter |
// ПОДАЧА И ДВА НАКЛОНА. У трипода мировые оси Z A B: он подаёт
// головку вперёд (Z) и наклоняет её (A, B). Осей X и Y у него нет
// вовсе, поэтому программа их и не называет.
const t = param('наклон', 15); // предел породы ±25°
orient([0, 0, 0]); // головка прямо
phase('подача');
moveTo([0, 0, -20]);
phase('наклон A');
orient([t, 0, 0]);
moveTo([0, 0, -40], { feed: 1500 });
phase('наклон B');
orient([0, t, 0]);
moveTo([0, 0, -40], { feed: 1500 });
phase('выравнивание');
orient([0, 0, 0]);
moveTo([0, 0, -20], { feed: 1500 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Наклоны головки | python_motion_path | — · Ø0 | grasp_from · home_abc · home_xyz · path_json |
stock(40, 30, 10);
contour({ depth_mm: 2 });
| шаг | операция | движок | слот · Ø | параметры |
|---|---|---|---|---|
| 1 | Контур электродом | python_contour | — · Ø0.25 | depth_mm · feed · offset · plunge_feed · polygon · step_down · tool_diameter |
Источник: backend/tests/acceptance/species_programs.py :: PROGRAM_FOR, MILL; services/machine_constructors :: list_all() · пересборка: bash /opt/synctwin/site/scripts/refresh-species-programs.sh · снято 2026-09-11.