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

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем avex, 7 май 2017.

  1. mcureenab

    mcureenab Гуру

    Плохо что у вас края графика резко вниз идут. Погрешность измерения джойстка в этих областях будет давать сильный разброс в повороте сервы. Если конечно вы используете самые крайние положения.
     
  2. avex

    avex Нерд

    Спасибо за ссылку и пример! Вот это я понимаю гуру.
    Нашел в калькуляторе по ссылке приемлемую формулу чуть вытянутого по х эллипса - x^2/3+y^2/2=1
    Теперь бы перевести в код.
    Что означает f в Вашей формуле?
     
  3. avex

    avex Нерд

    Эти участки совсем не принципиальны, можно уменьшить углы. Самое важное - чтобы наверху была вытянутая дуга, рисунок - лишь иллюстрация желаемого. Главное - чтобы большей части хода движения джойстика соответствовали небольшие углы сервы - до 15-20 градусов.
     
  4. ostrov

    ostrov Гуру

    Еще в институте писал программу, которая подбирает ближайшую формулу кривой с коэффициентами по заданным точкам. Наверняка сейчас есть подобные онлайн.
     
  5. mcureenab

    mcureenab Гуру

    Поправил - 8100.0f и 100.0f
    f - литерал типа float. без суффикса будет double.
     
  6. mcureenab

    mcureenab Гуру

    Ссылку дал выше, но этот подход вряд ли подойдет. Тут скорее всего критично, чтобы кривая проходила хотя бы через крайние точки. А "ближайшая кривая" может проходить рядом.
     
  7. avex

    avex Нерд

    Допустимо, если серва не дотянется до нуля и развёрнутого угла на 2-5 градусов. Важнее плавность ее движения при средних положениях джойстика.
    Не могли бы Вы завернуть предложенную формулу (Вашу или мою) в код? Дальше я бы поэкспериментировал и нашёл в калькуляторе оптимальную формулу.
     
  8. mcureenab

    mcureenab Гуру

    Только он через нужные точки не проходит.
     
  9. avex

    avex Нерд

    Те точки были представлены для примера. Условно, требуется, чтобы при отклонении джойстика в ту или иную сторону на 60-70% от его хода, серва отклонялась в соответствующую сторону на заданный угол - скажем, 15-20%. Эти проценты - вопрос дальнейшей оптимизации. На первом этапе важен код.
     
  10. mcureenab

    mcureenab Гуру

    Код (C++):

        long joystick;
        const float a2 = pow((2400 - 600)/2, 2);
        const float b2 = pow(90, 2);

        float x = joystick - 1500; // калибровка 0: ( 2400 - 600 ) / 2  = 900; 600 + 900 = 1500.
        float serv = sqrt( b2 - b2 / a2 * pow(x, 2) );

     
     
    Последнее редактирование: 8 май 2017
    avex нравится это.
  11. avex

    avex Нерд

    Спасибо огромное! Пойду пробовать!
     
  12. ostrov

    ostrov Гуру

    Может все таки таблицу? 90 элементов типа byte и 90 типа unsigned int, не так уж и много. Если немного математики добавить, то и второй массив загнать в byte можно.
     
  13. avex

    avex Нерд

    Вот знать бы как)) Хоть простенький пример, а там и попробовать можно было бы.
     
  14. mcureenab

    mcureenab Гуру

    С коэффициентом b2 ничего не сделаешь, это средняя точка сервы - 90 градусов.
    Знаечние a2 и средней точки (1500) тоже определяется размахом значений джойстика.
    Т.е. параметры эллипса жестко заданы характеристиками оборудования.
     
  15. mcureenab

    mcureenab Гуру

    Код (C++):
    long joystick
    ...
    static const int8_t servo_f[] = { 0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180 };
    //
    uint8_t index = map(joystick, 600, 2400, 0, sizeof(servo_f) - 1);
    int8_t servo = servo_f[index];
     
    Последнее редактирование: 8 май 2017
  16. avex

    avex Нерд

    Компилятор не принимает последнюю строчку кода (с эллипсом):
    invalid operands of types 'float' and 'int' to binary 'operator^'
     
  17. mcureenab

    mcureenab Гуру

    Опечатки поправил.

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

    avex Нерд

    Я про последнюю строчку из 30 комментария - её компилятор не принимает.
    Вот весь код:
    Код (C++):
    #include <Servo.h>
    #define joy1x A0
    int pot1x;
    Servo servo1x;
       
    void setup()
    {
      servo1x.attach(5);
    }

    void loop()
    {
      pot1x = analogRead(joy1x);
     
      const float a2 = ((2400 - 600)/2)^2;
      const float b2 = (90)^2;

      float x = pot1x - 1500; // калибровка 0: ( 2400 - 600 ) / 2  = 900; 600 + 900 = 1500.
      float serv = sqrt( b2 - b2 / a2 * x^2 );

      servo1x.write(serv);
    }
     
  19. mcureenab

    mcureenab Гуру

  20. ostrov

    ostrov Гуру

    Завтра попробую написать пример, сегодня уже некогда. Ничего сложного там нет, два массива или один двухмерный, в одном точки входящие (от джойстика), во втором результат. Может быть потребуется интерполяция на случай если входящие точки будут где то между табличными значениями.
     
    avex нравится это.