Каждый, у кого есть фрезер, знает этот ритуал: положить заготовку, на глаз выставить угол, подвести фрезу к краю, коснуться поверхности заготовки, записать ноль. Мне захотелось, чтобы станок делал это сам: увидел заготовку на столе, понял, как она лежит, и нашёл ноль по высоте без щупа и запустил бы программу сам. Так появился проект SmartLinuxCNC: машинное зрение и бесконтактный Z0 для домашнего ЧПУ фрезера с полем 800 × 600 мм.

В проекте SmartLinuxCNC я разрабатываю систему технического контроля, которая должна дополнить обычный станок с ЧПУ средствами машинного зрения и измерения расстояния. Основная идея — использовать недорогие компоненты: одноплатный компьютер Orange Pi, USB‑вебкамеры, печатные Fiducial markers и компактный ToF‑сенсор. Идея далеко не новая, но именно для домашних станков автоматизация подобного уровня применяется редко. Во‑первых, это несколько сложнее, чем рулить тремя осями. Во‑вторых, это требует дополнительных ресурсов и «домашние» ПК для станков, которые имеют LPT‑выход попросту не обеспечат нужный уровень производительности. Это первая часть большой статьи, пока что без испытаний на самом станке: плата Mesa‑Ethernet ещё в пути, ее нужно будет «поженить» с электроникой станка и сделать ремапинг каналов управления, а потом думать что‑то с системой смены инструмента на базе шпинделя ISO30 и магазина с держателями. Сейчас расскажу же, как выбирал реперные метки, как их печатал, как настраивал Orange Pi с камерой и компьютер с LinuxCNC на борту, и что показали первые реальные кадры в качестве предварительного результата. Включая грабли — их было больше, чем хотелось бы.
Архитектура: зрение отдельно от реального времени
Итак, идея простая — сделать станок (домашний ЧПУ фрезер) более самостоятельным. При этом речь не идёт о замене штатной системы управления станком — всегда можно будет отключить эту «надстройку» и продолжить работу в штатном режиме. Движение осей и исполнение управляющих программ остаются задачей LinuxCNC, работающего на отдельном x64-компьютере. Orange Pi отвечает за обработку изображений, обнаружение маркеров, сбор измерений и передачу результатов в основную систему. Из‑за ограничений по «железной» части принято решение разделить управляющую электронику: станок с драйверами остается как есть, вместо старого ПК с Mach3 приходит более современный с Ethernet интерфейсом и LinuxCNC, а «умное» распознавание живёт отдельно в старенькой Orange Pi PC. В итоге в станок информация попадает только как смещения систем координат. Сейчас архитектура выглядит так:
CNC PC — x86 мини‑ПК (8/512 Гб хватает за глаза), Debian 13 с ядром PREEMPT_RT, LinuxCNC 2.9 и самописная надстройка SmartCNC: супервизор, REST API, веб‑интерфейс.
Orange Pi PC (Allwinner H3, 1 ГБ) — сервис SmartVision на Python + OpenCV: две USB‑камеры, поиск меток, расчёт Z0. Ничем не управляет, только измеряет, отвечает за позиционирование и обратную связь, пересылает координаты на основной ПК.
ESP32-C3 плюс TOF050C — лазерный дальномер с фильтрацией на узле (медиана + Калман), данные идут по CAN на Orange Pi PC, уточняют координаты оси Z с учетом установленной фрезы.
Mesa 7I98 — FPGA‑плата step/dir по Ethernet (драйвер hm2_eth), отдельный сетевой порт на PCIe. Пока это самое простое решение оставить управляющую электронику и драйверы самого станка без изменений. Но нужен будет ремапинг и отработка, включая «навесное» в виде MPG‑пульта и доп. кнопок.
Одна из основных задач системы определять положение контрольных точек по изображению. Для этого используются Fiducial markers (метки) — специальные визуальные маркеры, имеющие заранее известную геометрию и идентификатор. Результаты зрения Orange Pi PC превращаются в обычный G‑code: G10 L2 задаёт смещение и поворот рабочей системы координат, G10 L1 — длину инструмента. Управляющую программу никто не переписывает. Если Orange Pi отвалился, станок остаётся обычным ЧПУ, просто без автопривязки — вот тут уже потребуется оператор.

Какие метки выбрать
Метки нужны, чтобы связать пиксели обзорной камеры с миллиметрами стола. Для реализации рассматривал два распространённых варианта: ArUco и AprilTag. Оба используют кодированные геометрические метки, пригодные для автоматического обнаружения, измерения расстояния и идентификации. Требования получились такие:
ID нельзя перепутать ни при каких условиях: стружка, блики, Т‑пазы, надписи. Неверный ID — это неверная система координат.
Зеркальная копия не должна читаться как другой ID.
Модуль от 2 мм, чтобы печатать на FDM‑принтере. Нужно минимум 6 меток и запас на будущее.
Детектор должен работать в OpenCV на ARM, без экзотики. Все таки это бюджетное решение, без дорогостоящих и без труднодоступных компонентов.
Итого выбрано шесть словарей AprilTag, для каждого 22 условия × 3 кадра = 396 кадров: повороты, перспектива до 55°, размытие, смазывание, шум, JPEG q35, темнота, блик, пыль, масляный налёт, царапины, перекрытие. Плюс 60 кадров без меток — ловить ложные срабатывания.

Крупномодульные 4×4 и 16h5 дают ложные срабатывания на пустом фоне — для координатного репера это приговор. В финал вышли AprilTag 36h11 и ArUco MIP 36h12 с одинаковым счётом. Выбрал AprilTag 36h11: его читает не только cv2.aruco, но и независимая библиотека AprilTag 3 (можно перепроверить), в словаре 587 кодов, а гарантированное расстояние Хэмминга не меньше 11 при любом повороте.

Конструкция метки: цветная FDM печать
Метка представляет собой пластину 80 × 80 × 5 мм, полный тег 10 × 10 модулей по 8 мм. Опорный размер для масштаба — внешний чёрный квадрат 64 мм, белая рамка 8 мм служит «тихой зоной». Чёрный код сделан вставкой заподлицо: 0,6 мм (три слоя) чёрного PETG в белой пластине. Печать лицом вниз на текстурированный PEI: поверхность плоская, без ступенек рельефа, которые давали бы тени при косом свете, и матовая. Битовая матрица берётся прямо из cv2.aruco.generateImageMarker, модель собирается в OpenSCAD скриптом, а рендер каждой метки перед печатью прогоняется через тот же детектор.

Печатаю на цветном 3D принтере, просто указывая различные цвета для экструдера. Нужно сказать, что выбранный PETG оказался не самым оптимальным вариантом — бликует и блестит при ярком освещении. Нужно будет перепечатать для финального теста или же использовать рассеянное освещение над станком.

Orange Pi: от образа до первого кадра
Основа — Armbian trixie minimal для старенькой Orange Pi PC. Конечно, можно выбрать и более современный «одноплатник», но и эта Orange Pi v1.3 вполне справится с выхватыванием кадров из потока USB‑камеры и с простым анализом. Собирается образ Armbian, а пакеты (OpenCV, FastAPI) ставит уже сама плата при запуске. Обновление после установки — скриптом по SSH, без перепрошивки карты.

Когда плата поднялась, камеру удобно изучать базовыми командами:
lsusb # 1bcf:d829 Full HD webcam ls -l /dev/v4l/by-id/ # стабильный путь вместо /dev/videoN v4l2-ctl -d /dev/v4l/by-id/<cam>-index0 --list-formats-ext v4l2-ctl -d /dev/v4l/by-id/<cam>-index0 --list-ctrls python3 -c "import cv2; print(cv2.__version__, hasattr(cv2, 'aruco'))" systemctl status smartvision; journalctl -u smartvision -n 20 curl http://10.77.0.2:8090/scv/v1/heartbeat
Верхняя камера устанавливается на высоте около 1,5 м и должна охватывать рабочую область приблизительно 800 × 600 мм. Вторая камера располагается на каретке портала, рядом со шпинделем, и перемещается вместе с ней по оси Y. Её назначение — наблюдать участок, где выполняются измерения поверхности и определяется исходное положение инструмента (Z0). Что выяснилось сразу:
При 1920 × 1080 при 30 кадрах/с камера даёт только в MJPG, в YUYV — 5 кадров/с. Поэтому использую поток MJPG.
Ручную экспозицию камера игнорирует: при любом значении от 312 до 10 000 кадр одинаковый. Работаем на автоэкспозиции, а значит, свет придётся ставить нормальный. Это следствие экономии при выборе USB камеры, имеет смысл заменить в дальнейшем.

Первый кадр в полутьме: средняя яркость 4 из 255, метки видны только после цифрового усиления.
Сеть: есть нюансы подключения по Ethernet. Пришлось использовать сразу два Ethernet понта — один для работы с Mesa и станком, второй для связи с Orange Pi: USB‑Ethernet для realtime не годится.

LinuxCNC — коротко
CNC PC поднимается из воспроизводимого образа: Debian 13 cloud image + cloud‑init + установщик. Ядро linux‑image‑rt‑amd64 (PREEMPT_RT 6.12). LinuxCNC 2.9.10 ставится из официального репозитория. Супервизор общается с LinuxCNC через Python API (linuxcnc.stat, linuxcnc.command); подтверждение ручной смены инструмента по M6 приходит из веб‑интерфейса. То есть оператор все таки нужен — заменить фрезу, разместить заготовку и так далее.

Разбор реальных кадров
Блик. Лампа над столом дала светлую полосу по‑глянцевому PETG, и одна из двух меток перестала читаться. Помог дополнительный проход детектора: если нужных ID не хватает, кадр выравнивается по локальному контрасту (CLAHE, clip 3.0, сетка 8 × 8). Всего проходов три: исходный кадр, морфологическое открытие против пыли и CLAHE против бликов.

Четыре метки. Для расчёта ориентации и расстояний нужно минимум четыре метки. Центр берётся как пересечение диагоналей (это проективно корректно, в отличие от среднего углов), ориентация — по ребру c0→c1. Для настройки ручного объектива M12 сделал «помощник фокуса»: веб‑MJPEG‑страницу, где над каждой меткой выводится дисперсия лапласиана.

По пяти запросам подряд: найдены все четыре метки, центры гуляют меньше чем на пиксель, масштаб 3,85 пикселя на миллиметр стабилен в пределах ±0,1%. Но есть и честное расхождение: если считать сторону чёрного квадрата равной 64 мм, шаг между центрами плотно сдвинутых пластин выходит 87–90 мм вместо 80. Значит, либо есть зазоры, либо напечатанный квадрат меньше расчётного. Вот так выглядят все четыре метки, задающие ограничения по размеру рабочего стола ЧПУ станка.

Задержка: что она значит для Z0
Заметная задержка видна сразу. Цифры: кадр через API — 2,8 с, запрос поиска меток — 1,0–2,6 с, детектор на кадре 1920 × 1080 — 0,4–0,5 с, а H3 декодирует такой MJPEG примерно на 12 кадрах в секунду. Для ориентации заготовки это неважно: снимок делается один раз перед работой, перед стартом G‑кода. Конечно, для проверки Z0 фреймрейт важнее (можно фрезу сломать), но процедура изначально спроектирована так, что измерение идёт только на неподвижном станке: LinuxCNC опускает шпиндель малыми шагами, а между шагами CNC PC запрашивает измерение. Задержка удлиняет цикл, но не вносит ошибку. Для ускорения в планах: держать камеру открытой и брать свежий кадр, обрабатывать только ROI, снизить разрешение камеры Z0, а грубый подход вести по ToF‑дальномеру. Если и этого не хватит — заменить H3 на плату на что‑то более свежее из одноплатников на базе RK3566 или RK3588.

Что дальше
Поверка меток и измерения показали работоспособность выбранной архитектуры. Такая система вполне сможет стать основой для дальнейшей автоматизации домашнего станка. Но плата Mesa‑Ethernet еще в пути. Дальше — сделать маппинг каналов всех трех осей станка, выставить камеры, свет и фокус уже на самом станке, сделать калибровку камеры и меток, измерить раскладку меток для корректных измерений, испытать ToF сенсор и вторую камеру для Z0. Сам проект достаточно нишевый — вряд ли кто‑то будет сильно модернизировать хоббийный домашний ЧПУ станок, а для промышленных вариантов есть более серьезные решения. Хотя под это дело напрашивается магазин инструментов с автосменой (много не нужно — 2–3 фрезы для грубой и чистовой фрезеровки, отрезки). Если вам такая тема интересна, во второй части будет настройка Mesa и самого станка, испытания.
Комментарии (23)

LinkToOS
23.10.2026 15:48Великоваты метки. Это минимальный возможный размер?

Lexus08 Автор
23.10.2026 15:48Да, можно.
Нужна 4К камера и более шустрый компьютер/ одноплатник. Эта старая orangepi на пределе работает)

Lexus08 Автор
23.10.2026 15:48Размер можно произвольный. Там условие - несколько пикселей на элемент метки для уверенного опознавания

Nikollor48
23.10.2026 15:48Вместо мучений с фильтрами от бликов на глянцевом PETG не проще задуть метки матовым лаком из баллончика или напечатать матовым PLA ?

Lexus08 Автор
23.10.2026 15:48напечатать матовым PLA
Однозначно проще
Как вариант - лазерная гравировка по двух цветному пластику или крашенному алюминию.
Даёт тот же эффект. Можно будет даже уменьшить метки вдвое по размеру (выше советовали закрепить метки на держателях, но тогда нужна будет информация о расстоянии между центрами новых меток. Так как фиксированный метки это одно, а подвижные зажимы - другое)

xSVPx
23.10.2026 15:48Концепция меток вообще не очень понятна, неужели вывернув контрасность нельзя заготовку на столе обнаружить. А откалибровавшись по миллиметровке расстояния измерить...

Lexus08 Автор
23.10.2026 15:48метки заменяют миллиметровку. один раз запишу сколько между центрами, и станок сам уже будет решать , куда конкретно ему двигаться

Lexus08 Автор
23.10.2026 15:48неужели вывернув контрасность нельзя заготовку на столе обнаружить
можно. одно другому не мешает. все такие тут уровень технического зрения (opencv)

ZhenyaRUS39
23.10.2026 15:48Интересно. Спасибо. В виде обучающего материала было бы ещё полезнее. Всегда хотелось разобраться с машинным зрением для детекции предметов/расположений, расстояний.
Вроде платы google coral с tpu хорошо работают с анализом видеопотока.

Lexus08 Автор
23.10.2026 15:48платы google coral с tpu
спасибо .посмотрю. тут играю скорее от бюджета.
Всегда хотелось разобраться с машинным зрением для детекции предметов/расположений, расстояний.
аналогично, уже несколько лет пытался себя заставить разобраться в opencv.
xSVPx
Не очень понятно "зачем". Какой сценарий работы то ? Что хочется в итоге-то получить ?
Lexus08 Автор
Я рассказал про это в начале- чтобы края заготовки самостоятельно искал.
В перспективе можно поставить шпиндель iso30 с автосменой и магазин с разными фрезами
xSVPx
Но зачем ? Чтобы было ?
Найти края при наличии смены инструмента вам поможет банальный зонд, по касанию.
Когда это такой материал как на фото, то простой лазерный указатель вам поможет ;). Если на глаз не видите по фрезе.
Без смены инструмента непонятно что можно в автоматическом режиме сделать полезного...
Lexus08 Автор
Зонд все равно не так работает. Мне его нужно подвести к заготовке и запустить скрипт. А если заготовка ориентирована не строго по осям ? Зонд покажет только 0.0, а тут то техническое зрение реализовано
Lexus08 Автор
Ну грубо говоря, закрепил я 6-8 заготовок на столе. И указал программу для фрезеровки. Процесс длительный, караулить окончание нет желания, я могу пойти по своим делам, а у станка будет веб-доступ и камера. На opencv можно настроить не только выставление размеров, но и оценивать ошибки
xSVPx
Что это за заготовки ? Обычно заготовки имеют какие-то одинаковые размеры с припусками. Иначе их не закрепить.
Собственно зная какими вы их зажали прижимами и в какой они позиции можно знать где примерно их центра и края, и этого обычно вполне достаточно. На прижимах надо было маркировку делать....
В целом если у вас длительная обработка 6-8 заготовок, то указать 6-8 точек привязки в самом начале совершенно не труд.
По сравнению с автосменой это всё ей богу не затруднения...
Работа проведена большая, но смысл от меня ускользает :(. Если нужна большая производительность "труда", то направление выбрано странное
Вот если бы у вас была магнитная плита, вы примагничивали к ней сотни маленьких кубиков, а потом, скажем точки на них гравировпли, то да - имело бы смысл. Насыпал из ведра, вжик, готово. Сгреб в другое ведро, насыпал из первого. (Или вообще конвейер как делают для лазеров).
Но если обрабатывать долго - эффекта не будет.
Lexus08 Автор
Нет, заготовки произвольные.
Сделать метки на прижимах - хорошая мысль, записал
По поводу плиты - заготовки не из металла
Lexus08 Автор
Объясню чуть шире - Станок с удалённым доступом. Чтобы я смог запустить его без личного присутствия. Зонд таких возможностей не дает. Зрение - один из шагов в этом направлении. У меня уже есть 3д принтер с транспортной лентой-рулоном, я также делал удалённый запуск и контроль к нему
xSVPx
Кто будет инструмент удаленно менять и кто заготовки к столу прикручивать ?
Вы пробовали с ним работать ? Обычно если у тебя заготовка неожиданного размера, то может потребоваться прям много времени, десятки минут, чтобы ее надежно зафиксировать. При этом чтобы грубо обозначить центр или край нужны десятки секунд.э и гораздо меньшая квалификация.
Это я про инструмент не говорю (а в плане дуракоустойчивости с ним всё грустно, можно так затянуть, что потом фиг открутишь)
Lexus08 Автор
прикрутить и я могу, а потом по своим делам пойти. программа несколько часов выполняется.
я написал уже про ISO30 - это вполне решаемый вопрос. выставить один раз фрезы в магазине (нужно 3-4 вида для моих задач).
не очень понимаю вопроса. тут комплексная задача, и Z0 только один из шагов решения.
Nikollor48
Человек строит систему для удаленного запуска, чтобы не дежурить у станка с кнопкой паузы
xSVPx
Запустить-то удаленно можно, но это как с умным чайником. Кто-то должен сделать всё остальное, и остального в сотни раз по времени больше. Почему этот кто-то "вкл" не может ткнуть непонятно.
Не стоять с паузой можно, но на мелкой серии надо или чужой станок или стальные нервы иметь :). А вот кто стружку будет сметать :)?
Фрезер не 3д принтер, он требует пригляду и лучше постоянного. ОЦ получше, но даже его лучше не бросать одного
Lexus08 Автор
ну простые деревянные заготовки можно оставить. особенно если их штук 6-8 сразу прикрутить и пусть сутки-двое жужжит. пылесос вроде нашел, но нужно будет подумать, как его прикрутить, не загораживая обзор камере