Как рассчитываются дельта-движения?

delta algorithm

На декартовом принтере движения действительно просты. Если мы предположим, что принтер имеет 100 шагов / мм на каждой оси, то перемещение на 10 мм по оси составляет всего 1000 шагов по этой оси.

Движения, которые не выровнены по одной оси, также просты. Переход от x, y = 0,0 к 10,10 будет составлять 1000 шагов по x и y.

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

Итак, каков алгоритм вычисления шагов для данного перемещения для дельта-принтера?

, 👍10

Обсуждение

Это, по-видимому, исключительно теоретический вопрос, который может быть более подходящим для сайта, занимающегося программированием и/или математикой, поскольку то, как микропрограммное обеспечение работает внутри, не имеет отношения к использованию 3D-принтера. С другой стороны, этот вопрос специфичен для 3D-печати и может иметь отношение к кому-то, кто пытается изменить или настроить прошивку своего принтера., @Tom van der Zanden


2 ответа


Лучший ответ:

9

Существует два основных специальных шага в технике, используемой большинством контроллеров 3D-принтеров с открытым исходным кодом:

  1. Разделите каждый линейный сегмент gcode на множество очень маленьких подсегментов ("Сегментация").
  2. Используйте элементарную тригонометрию или теорему Пифагора, чтобы привязать положение экструдера к высоте каретки для каждой из трех башен ("Обратная кинематика"). чтобы найти целевое положение для каждого небольшого сегмента

Обратная кинематика на удивление проста. Виртуальный 90-градусный треугольник строится из двух известных длин, чтобы решить для неизвестной третьей длины:

  • Фиксированная длина плеча дельты - это гипотенуза треугольника
  • Горизонтальное расстояние между соединениями колонн и соединениями концевых эффекторов вычисляется по координатам XY сопла и фиксированному положению колонны, чтобы определить длину нижней стороны треугольника
  • Длина верхней стороны треугольника вычисляется из двух предыдущих с помощью теоремы Пифагора
  • Длина верхней стороны добавляется к высоте сопла Z, чтобы получить необходимую высоту каретки

Я думаю, что лучшей ссылкой с открытым исходным кодом здесь является документ Rostock Kinematics Стива Грейва, rev3, доступный для скачивания здесь: https://groups.google.com/d/msg/deltabot/V6ATBdT43eU/jEORG_l3dTEJ Некоторые релевантные фотографии:

Эти обратные кинематические вычисления выполняются для каждой тележки, чтобы получить целевое положение "пространства для перевозки", и это выполняется для каждого подсегмента пути.

Результаты этих этапов затем могут быть повторно вставлены обратно в стандартные методы интерполяции линейного пути для принтера, в которых он запускает этапы в необходимых соотношениях и с необходимыми скоростями для получения желаемого профиля прямолинейного движения и ускорения / скорости. (Как ЭТО делается - другой вопрос.)

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

*(В любом случае, для соблюдения динамических ограничений применяется постоянная скорость перед замедлением ускорения. Опять же, это тема другого вопроса.)

Сегментация очень похожа на процесс использования многоугольника для аппроксимации окружности. Если грани достаточно малы, многоугольник является хорошим приближением. Более высокие скорости сегментации приводят к меньшей ошибке следования по пути. Основное концептуальное различие между рисованием дуг окружности и траекторий дельта-движения заключается в том, что так называемая "фасетная дуга" с дельта-сегментацией строится в координатах высота-время вместо координат X-vs-Y, которые вы бы использовали для рисования окружности на экране компьютера.

Эта система используется в значительной степени потому, что поддержка принтеров типа Delta изначально была встроена в планировщики движения на основе GRBL, которые были написаны исключительно для прямолинейных траекторий движения в декартовых принтерах. Это была относительно минимальная модификация существующей кодовой базы по сравнению с реализацией полной интерполяции квадратичного пути.

Методы развивались на протяжении многих лет. И часто используются альтернативные подходы: например, dc42 fork RepRapFirmware выполняет точное следование пути без сегментации, пересчитывая правильное время для следующего шага после каждого шага. Это функционально эквивалентно аппроксимации круга с таким большим количеством граней многоугольника, что каждый пиксель на экране получает свою собственную грань. Таким образом, он настолько точен, насколько позволяет разрешение позиционирования двигателей. Недостатком является то, что этот метод без сегментации требует довольно больших затрат процессора, поэтому он работает только на относительно быстрых контроллерах, а не на более старых 8-битных Atmega AVR, которыми сегодня оснащается большинство существующих потребительских / любительских принтеров.

Возможны и другие методы. Академическая литература по параллельному управлению робототехникой - это целый другой мир математических методов и сложности для создания обобщенных алгоритмов управления, которые работают для широкого спектра механизмов роботов. Версия, которую мы используем в 3D-принтерах с открытым исходным кодом, по сравнению с ними довольно проста и специфична для конкретного приложения.


,

2

Я описываю, как это делается в прошивке Marlin.

Первый шаг - разделить линейное перемещение от (x, y, z) до (x', y', z') на множество дискретных сегментов. С этой целью вычисляется количество времени, которое потребовалось бы для перемещения с заданной скоростью, и значение delta_segments_per_second используется для вычисления количества используемых сегментов.

Это делается в функции prepare_move_delta в файле Marlin_main.cpp . Конечные точки каждого из этих сегментов затем передаются функции calculate_delta:

void calculate_delta(float cartesian[3]) {
    // обратная кинематика.
    // Выполните обратную кинематику и поместите результаты в дельту[3]
    // Математика и первая версия были сделаны QHARLEY . Интегрирован в masterbranch 06/2014 и слегка реструктурирован Йоахимом Черни в июне 2014 года

    float SCARA_pos[2];
    static float SCARA_C2, SCARA_S2, SCARA_K1, SCARA_K2, SCARA_theta, SCARA_psi;

    SCARA_pos[X_AXIS] = cartesian[X_AXIS] * axis_scaling[X_AXIS] - SCARA_offset_x;  //Перевести SCARA в стандартный X Y
    SCARA_pos[Y_AXIS] = cartesian[Y_AXIS] * axis_scaling[Y_AXIS] - SCARA_offset_y;  // С коэффициентом масштабирования.

    #if (Linkage_1 == Linkage_2)
      SCARA_C2 = ((sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS])) / (2 * (float)L1_2)) - 1;
    #else
      SCARA_C2 = (sq(SCARA_pos[X_AXIS]) + sq(SCARA_pos[Y_AXIS]) - (float)L1_2 - (float)L2_2) / 45000;
    #endif

    SCARA_S2 = sqrt(1 - sq(SCARA_C2));

    SCARA_K1 = Linkage_1 + Linkage_2 * SCARA_C2;
    SCARA_K2 = Linkage_2 * SCARA_S2;

    SCARA_theta = (atan2(SCARA_pos[X_AXIS], SCARA_pos[Y_AXIS]) - atan2(SCARA_K1, SCARA_K2)) * -1;
    SCARA_psi = atan2(SCARA_S2, SCARA_C2);

    delta[X_AXIS] = SCARA_theta * SCARA_RAD2DEG;  // Умножить на 180/ Пи - тета - угол опорного рычага
    delta[Y_AXIS] = (SCARA_theta + SCARA_psi) * SCARA_RAD2DEG;  // - равен углу дополнительного рычага (инвертированный двигатель)
    delta[Z_AXIS] = cartesian[Z_AXIS];
}

Эта функция обрабатывает геометрию треугольника и вычисления, необходимые для преобразования координат (x, y, z) конечных точек сегмента в соответствующие положения для кареток. Преобразованные координаты затем передаются в plan_buffer_line, который вычисляет шаги, необходимые для каждого шагового двигателя, и фактически выполняет эти шаги.

Точная кинематика, используемая в этой функции, объясняется гораздо более подробно на Marlin github.

Важно отметить, что plan_buffer_line перемещает каретки линейно, и печатающая головка, таким образом, описывает дугу, а не прямую линию. Таким образом, движение по прямой аппроксимируется множеством небольших дуг.

,

Код трудно читаем.Что такое SCARA? Не могли бы вы описать шаги, которые реализует код?, @Lars Pötter