Как заставить сервопривод медленно достигать нужного угла?

Я нашел решение, которое заставляет сервопривод шаг за шагом достигать желаемого угла, но это зависит от текущего угла сервопривода. это код:

    if servo_current angle > servo_desired_angle :
        while(x=true) :
             servo_current_angle -=1 
             duty_cycle = (((12.5-2.5)/(180-0) * servo_current_angle) +2.5 
             p.ChangeDutyCycle (duty_cycle)
             time.sleep(0.01)
             if servo_current angle = servo_desired_angle :
                 x = false 
    elif servo_current_angle < servo_desired_angle :
         while(x=true) :
             servo_current_angle +=1 
             duty_cycle = (((12.5-2.5)/(180-0) * servo_current_angle) +2.5 
             p.ChangeDutyCycle (duty_cycle)
             time.sleep(0.01)
             if servo_current angle = servo_desired_angle :
                 x = false

проблема в том, как узнать servo_current_angle?


person Mohamed Elhadad    schedule 06.07.2017    source источник
comment
Не могли бы вы дать больше информации о вашем оборудовании и вашей общей цели?   -  person mrk    schedule 06.07.2017
comment
Моя общая цель сделать так, чтобы сервопривод не уходил на нужный угол прямо. Я хочу, чтобы он достиг этого угла шаг за шагом, чтобы добиться сглаживания в движении.   -  person Mohamed Elhadad    schedule 06.07.2017


Ответы (2)


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

  • Вы можете добавить собственный энкодер, например, цифровой или оптический энкодер.
  • Вы можете перейти на сервоприводы с замкнутым контуром (намного дороже), в которые встроены энкодеры, такие как линейка Dynamixel.

Чтобы решить вашу проблему более плавного пошагового движения, вам нужно указать ему промежуточные положения между текущим положением и желаемым положением. Думайте об этом как о 20 (в приведенном ниже примере) крошечных шагах вместо одного большого. Для этого используйте цикл для обновления рабочего цикла. Вот пример:

current duty_cycle = 7.5 
desired_duty_cycle = 5.0
steps = 20.0
duty_cycle_delta = (desired_duty_cycle - current_duty_cycle) / steps
while (current_duty_cycle != desired_duty_cycle):
    if (current_duty_cycle > desired_duty_cycle):
        duty_cycle_delta = -duty_cycle_delta
    current_duty_cycle = current_duty_cycle + duty_cycle_delta
    p.ChangeDutyCycle (current_duty_cycle)

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

person TomServo    schedule 06.07.2017
comment
на моем el-cheapo ES08A, который нещадно дергается - person Phlip; 27.10.2020
comment
@Флип Возможно. Этот метод лучше всего работает на цифровых сервоприводах среднего и высшего класса с частотой ~ 60 Гц или выше. Я действительно использовал этот подход на роботе-гексаподе с предварительно рассчитанными кривыми ускорения и замедления Безье между конечными положениями, и он был гладким как шелк с приличными цифровыми сервоприводами на частоте 90 Гц. - person TomServo; 27.10.2020
comment
поскольку требование заключается в прокрутке вперед с заданной скоростью, я смотрю, сможет ли наш специалист по аппаратному обеспечению использовать меньше сервоприводов и больше шагового двигателя ... - person Phlip; 28.10.2020

Как насчет отслеживания текущего положения сервопривода во время выполнения и обновления его по ходу?

Вы можете использовать модуль PWM в RPi.GPIO и вначале переместить сервопривод в исходное положение для начала.

Положение серводвигателя задается длительностью импульса. Сервопривод ожидает получать импульс как минимум каждые 20 миллисекунд. Если этот импульс высок в течение 1 миллисекунды, угол сервопривода будет равен нулю; если это 1,5 миллисекунды, это будет его центральное положение; а если это 2 миллисекунды, то это будет 180 градусов.

Серводвигатели

Программа-пример устанавливает частоту ШИМ на 100 Гц, что будет посылать импульс на сервопривод каждые 10 миллисекунд. Угол преобразуется в рабочий цикл от 0 до 100. Это фактически создает импульсы короче ожидаемого минимального значения в 1 мс и длиннее 2 мс максимум.

Источник здесь

person mrk    schedule 06.07.2017
comment
это из вашего источника: ** обновление определения (я, угол): долг = поплавок (угол) / 10,0 + 2,5 pwm.ChangeDutyCycle (долг) ** я не хочу напрямую обращаться к углу .. в любом случае спасибо: ). - person Mohamed Elhadad; 06.07.2017
comment
Я знаю, что ты это сказал, но в чем твоя проблема? Чтобы узнать начальное положение? - person mrk; 06.07.2017
comment
Я имел в виду текущую позицию во время процесса, а не начальную позицию. Должен ли я сохранить предыдущую желаемую позицию как текущую позицию в eeprom? - person Mohamed Elhadad; 06.07.2017