Quadruped и millis

Тема в разделе "Arduino & Shields", создана пользователем Tes1a, 17 апр 2016.

  1. Tes1a

    Tes1a Нерд

    Здравствуйте проблема такая,пишу код для квадропода, хочу реализовать функцию движения через millis, но ни как не получается придумать способ,помогите пожалуйста.

    Пример движения вперед
    Код (C++):
    void forward()
    {


    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
     
      }

    // передвинуть переднее правое и левое заднее бедро вперед, переднее левое и заднее правое бедро назад

        for(i = 0 ; i<=44; i++){

                    servo11.write(90 + i + 7);//плб
                    servo22.write(50 + i );//ппб
                    servo33.write(93 - i - 4);//злб
                    servo44.write(138 - i  );//зпб

                 

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
       
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
       
      }
    // передвинуть вперед переденее левое и заднее правое бедро, переднее правое и заднее левое бедро назад
    for(i = 0 ; i<=44; i++){

            servo11.write(141 - i - 7);//плб
                    servo22.write(94 - i );//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(94 + i);//зпб

                   

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
       
      }


    }


    void left()
    {
    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
       
      }

    // передвинуть переднее правое и левое  бедро вперед, заднее левое и правое бедро назад

        for(i = 0 ; i<=44; i++){

                    servo11.write(141 - i - 7);//плб
                    servo22.write(50 + i + 1);//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(138 - i - 11);//зпб

                   

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
     
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
       
      }
    // передвинуть вперед заднее левое и заднее правое бедро, переднее правое и левое бедро назад
    for(i = 0 ; i<=44; i++){


    servo11.write(90 + i + 7);//плб
    servo22.write(95 - i - 1);//ппб
    servo33.write(93 - i - 4);//злб
    servo44.write(83 + i +11);//зпб

                 

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
       
      }

     
    }
     
  2. REm

    REm Гик

    тебе требуется алгоритм без delay?
     
  3. Tes1a

    Tes1a Нерд

    да,за место delay использовать millis
     
  4. Tes1a

    Tes1a Нерд

    прошу прощения за алгоритм,не тот вставил))

    Код (C++):
    void forward()
    {


    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
        delay(10);
      }

    // передвинуть переднее правое и левое заднее бедро вперед, переднее левое и заднее правое бедро назад

        for(i = 0 ; i<=44; i++){

            servo11.write(90 + i + 7);//плб
                    servo22.write(50 + i );//ппб
                    servo33.write(93 - i - 4);//злб
                    servo44.write(138 - i  );//зпб

                    delay(10);

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
        delay(10);
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
        delay(10);
      }
    // передвинуть вперед переденее левое и заднее правое бедро, переднее правое и заднее левое бедро назад
    for(i = 0 ; i<=44; i++){

            servo11.write(141 - i - 7);//плб
                    servo22.write(94 - i );//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(94 + i);//зпб

                    delay(10);

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
        delay(10);
      }


    }
     
  5. ostrov

    ostrov Гуру

    Для начала: какова роль этих задержек? Чтобы сервы успели повернуться на заданный угол? Что вы хотите добиться заменой задержки через delay на задержку через millis? Одновременно эти последовательные команды выполняться все равно не должны и не могут. Никаких параллельных операций программа не производит. Зачем что то менять?
     
  6. Tes1a

    Tes1a Нерд

    Роль этих задержек - управление скоростью вращения серв,что из листинга видно. Одновременно не будут эти 2 ф-ии(delay and millis) выполняться, должна выполняться только millis. Программа производит параллельные операции,просто я о них не упомянул, потому что это было с моей точки зрение лишне,"есть delay и нужно его заменить на millis" - вот и все что нужно, поэтому так и написал. А параллельная операция - опрос дальномера. Проблема в том, что из - за delay дальномер ждет пока закончится выполнение ф-ии, как я думаю.
     
  7. ostrov

    ostrov Гуру

    Вы вырезали из приведенной программы опрос дальномера? Как он осуществляется?

    Вообще, я бы подумал о том, чтобы завести функции движения сервами в функцию вызываемую по прерыванию таймера. Каждые 10мс. В глобальных переменных задаются значения куда сервам стремиться и каждый вызов смещает их туда куда надо. В том же виде как сейчас с трудом представляю чем millis() может быть полезным. Вызывать опрос дальномера внутри цикла? Так и в таком виде можно, особенно если он УЗ.
     
    Последнее редактирование: 18 апр 2016
  8. Tes1a

    Tes1a Нерд

    Код (C++):
    #include <Wire.h>
    #include <Multiservo.h>


    Multiservo servo1;//переднее левое колено
    Multiservo servo2;//переднее правое колено
    Multiservo servo3;//заднее левое колено
    Multiservo servo4;//заднее правое колено
    Multiservo servo11;//переднее левое бедро
    Multiservo servo22;//переднее правое бедро
    Multiservo servo33;//заднее левое бедро
    Multiservo servo44;//заднее правое белро

    int i;



    int trigPin = 9;
    int echoPin = 8;

    long distance;



    void setup()
    {

      pinMode(trigPin,OUTPUT);
      pinMode(echoPin,INPUT);

      Wire.begin();

      servo1.attach(17);
      servo1.write(90);

      servo2.attach(16);
      servo2.write(90);

      servo3.attach(15);
      servo3.write(97);

      servo4.attach(14);
      servo4.write(83);

      servo11.attach(13);// переднее левое бедро
      servo11.write(90);

      servo22.attach(12);// переднее правое бедро
      servo22.write(50);

      servo33.attach(11);// заднее левое бедро
      servo33.write(93);

      servo44.attach(10);// заднее правое бедро
      servo44.write(90);
     
    }




    long getEchoTiming() {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      long duration = pulseIn(echoPin,HIGH,500000);
      return duration;
    }


    long getDistance() {
      long distacne_cm = getEchoTiming()/29/2;
      return distacne_cm;
    }



    void forward()
    {


    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
        delay(10);
      }

    // передвинуть переднее правое и левое заднее бедро вперед, переднее левое и заднее правое бедро назад

        for(i = 0 ; i<=44; i++){

            servo11.write(90 + i + 7);//плб
                    servo22.write(50 + i );//ппб
                    servo33.write(93 - i - 4);//злб
                    servo44.write(138 - i  );//зпб

                    delay(10);

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
        delay(10);
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
        delay(10);
      }
    // передвинуть вперед переденее левое и заднее правое бедро, переднее правое и заднее левое бедро назад
    for(i = 0 ; i<=44; i++){

            servo11.write(141 - i - 7);//плб
                    servo22.write(94 - i );//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(94 + i);//зпб

                    delay(10);

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
        delay(10);
      }


    }


    void left()
    {
    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
        delay(10);
      }

    // передвинуть переднее правое и левое  бедро вперед, заднее левое и правое бедро назад

        for(i = 0 ; i<=44; i++){

                    servo11.write(141 - i - 7);//плб
                    servo22.write(50 + i + 1);//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(138 - i - 11);//зпб

                    delay(10);

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
        delay(10);
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
        delay(10);
      }
    // передвинуть вперед заднее левое и заднее правое бедро, переднее правое и левое бедро назад
    for(i = 0 ; i<=44; i++){


    servo11.write(90 + i + 7);//плб
    servo22.write(95 - i - 1);//ппб
    servo33.write(93 - i - 4);//злб
    servo44.write(83 + i +11);//зпб

                    delay(10);

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
        delay(10);
      }

     
    }


    void right()
    {
    // поднять вверх переднее левое колено и правое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
        delay(10);
      }

    // передвинуть передние правое и левое  бедро вперед, заднее левое и правое бедро назад

        for(i = 0 ; i<=44; i++){

                    servo11.write(141 - i - 7);//плб
                    servo22.write(50 + i + 1);//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(138 - i - 11);//зпб

                    delay(10);

                  }
    // опустить преднее левое и заднее правое колено
      for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
        delay(10);
      }
    // поднять переднее правое колено и заднее левое

    for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
        delay(10);
      }
    // передвинуть назад переденее левое и правое бедро, задние правое и левое бедро вперед
    for(i = 0 ; i<=44; i++){


    servo11.write(90 + i + 7);//плб
    servo22.write(95 - i - 1);//ппб
    servo33.write(93 - i - 4);//злб
    servo44.write(83 + i +11);//зпб

                    delay(10);

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
        delay(10);
      }

     
    }


    void back()
    {


    // поднять вверх переднее правое колено и левое нижнее колено
      for(i = 0 ; i<=25; i++){

      servo2.write(90 - i);
     
      servo3.write(90 + i);
     
        delay(10);
      }

    // передвинуть переднее правое и левое заднее бедро назад, переднее левое и заднее правое бедро вперед

        for(i = 0 ; i<=44; i++){

                    servo11.write(141 - i - 7);//плб
                    servo22.write(94 - i );//ппб
                    servo33.write(45 + i + 4);//злб
                    servo44.write(94 + i  );//зпб

                    delay(10);

                  }
    // опустить преднее правое и заднее левое колено
      for(i = 0 ; i<=25; i++){

      servo2.write(65 + i);
     
      servo3.write(115 - i);
     
        delay(10);
      }
    // поднять переднее левое колено и заднее правое

    for(i = 0 ; i<=25; i++){

      servo1.write(90 + i);
     
      servo4.write(83 - i);
     
        delay(10);
      }
    // передвинуть назад переденее левое и заднее правое бедро, переднее правое и заднее левое бедро вперед
    for(i = 0 ; i<=44; i++){

            servo11.write(90 + i + 7);//плб
                    servo22.write(50 + i );//ппб
                    servo33.write(93 - i - 4);//злб
                    servo44.write(138 - i);//зпб

                    delay(10);

                  }
    // опустить вниз

        for(i = 0 ; i<=25; i++){

      servo1.write(115 - i);
     
      servo4.write(58 + i);
     
        delay(10);
      }


    }




    void loop()
    {

    distance = getDistance();

    if(distance<10){

      back();

                   }
    else{


      if(distance<30){

        left();
                     }
      else{
     
        if(distance<40){
          right();
                       }
        else{

          forward();
            }
          }
        }

    }

     
    вот весь код
     
  9. Tes1a

    Tes1a Нерд

    я не совсем понял о чем вы
     
  10. ostrov

    ostrov Гуру

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

    Я не вник с принципом работы вашей механики, но подозреваю, что вы хотите чтобы сервы реагировали более оперативно. Значит два варианта - либо уменьшить время выполнения маневра, то есть двигать по чуть чуть, либо двигать в прерываниях. Опросили датчик, в зависимости от результатов выставили векторы (направления) куда сервам двигаться. Функция вызываемая автоматически каждые,например, 10 мс дает команде сервам двигаться куда им положенно. Это происходит быстро, команды получены, сервы поехали, в это время опрашивается дальномер и так далее. Единственно что потребуется, это придумать алгоритм для движения серв - куда они должны двигаться все восемь в какой ситуации. Иначе только рывками и с задержками.
     
  11. Tes1a

    Tes1a Нерд

    я понял, в каком направлении двигаться,спасибо.
     
  12. REm

    REm Гик

    а вариант "мигание светодиода без delay" не подходит?
    до 10 таймеров работает на 328 atmega
     
  13. ostrov

    ostrov Гуру

    У него другой случай. Там взаимоисключающие параграфы.
     
  14. REm

    REm Гик

    не сталкивался с таким)
    дальномер вешал на основе того примера, работал вроде нормально. И вторая часть кода срабатывала так же без задержки.