Как повторить код

Я хочу, чтобы мой двуногий робот продолжал ходить, но он делает только два шага, этот проект двуногого робота важен для моего проекта Capstone. Код ниже — это код, который я использовал

#include <Servo.h> 

int HipR_Pin = 9;
int HipL_Pin = 10;

int KneeR_Pin = 5;
int KneeL_Pin = 6;

int AnkleR_Pin = 3;
int AnkleL_Pin = 11;

Servo HipR;
Servo HipL;

Servo KneeR;
Servo KneeL;

Servo AnkleR;
Servo AnkleL;

void setup() {
  HipR.attach(HipR_Pin);
  HipL.attach(HipL_Pin);
  KneeR.attach(KneeR_Pin);
  KneeL.attach(KneeL_Pin);
  AnkleR.attach(KneeR_Pin);
  AnkleL.attach(KneeL_Pin);
}

void loop() {

  for (int i=0; i < 7; i++)
  {
    RightStep1;
    LeftStep1;
    RightStep2;
    LeftStep2;
    RightStep3;
    LeftStep3;
    RightStep4;
    LeftStep4;
  }
  ;
}

void RightStep1()
{
  HipR.write(80);
  HipL.write(80);
  KneeR.write(100);
  KneeL.write(100);
  AnkleR.write(20);
  AnkleL.write(20);

} 

void LeftStep1()
{
  HipR.write(90);
  HipL.write(90);
  KneeR.write(70);
  KneeL.write(70);
  AnkleR.write(20);
  AnkleL.write(20);

} 

void RightStep2()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(80);
  KneeL.write(80);
  AnkleR.write(10);
  AnkleL.write(10);

} 

void LeftStep2()
{
  HipR.write(60);
  HipL.write(60);
  KneeR.write(90);
  KneeL.write(90);
  AnkleR.write(20);
  AnkleL.write(20);

} 
void RightStep3()
{
  HipR.write(40);
  HipL.write(40);
  KneeR.write(60);
  KneeL.write(60);
  AnkleR.write(10);
  AnkleL.write(10);

} 

void LeftStep3()
{
  HipR.write(50);
  HipL.write(50);
  KneeR.write(70);
  KneeL.write(70);
  AnkleR.write(20);
  AnkleL.write(20);


} 
void RightStep4()
{
  HipR.write(60);
  HipL.write(60);
  KneeR.write(60);
  KneeL.write(60);
  AnkleR.write(10);
  AnkleL.write(10);


} 

void LeftStep4()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(50);
  KneeL.write(50);
  AnkleR.write(20);
  AnkleL.write(20);


}

, 👍0

Обсуждение

При описании проблемы необходимо точно указать, что происходит... «но он движется только дважды» не описывает наблюдаемое действие... потому что это может означать, что робот делает два шага, или что движутся только два сервопривода, или что один сервопривод движется дважды... каждое из этих состояний может быть вызвано различными ошибками программы., @jsotola


4 ответа


0

Чтобы вызвать функцию, необходимо добавить скобки после имени функции.

void loop() {

  for (int i=0; i < 7; i++)
  {
    RightStep1();
    LeftStep1();
    RightStep2();
    LeftStep2();
    RightStep3();
    LeftStep3();
    RightStep4();
    LeftStep4();
  }
  ;//<<--также удалите эту лишнюю точку с запятой
}
,

1

В дополнение к ответу @Gerben, вы не даете времени на завершение своих движений. .write() не ждет завершения движения — он просто устанавливает целевой угол. Вам следует добавить достаточно вызовов delay(...), чтобы дождаться завершения своих движений, прежде чем начинать новое.

,

0

Вместо всех различных ступенчатых функций вы можете лучше параметризовать их, например

void LeftStep4()
{
  HipR.write(70);
  HipL.write(70);
  KneeR.write(50);
  KneeL.write(50);
  AnkleR.write(20);
  AnkleL.write(20);
}

будет

void LeftStep4()
{
  Move(70, 70, 50, 50, 20, 20);
}

и создайте функцию

void Move(int hipR, int hipL, int kneeR, int kneeL, int ankleR, int ankleL)
  HipR.write(hipR);
  HipL.write(hipL);
  KneeR.write(kneeR);
  KneeL.write(kneeL);
  AnkleR.write(ankleR);
  AnkleL.write(ankleL);
}

Другие функции также будут однострочными, как и первая функция LeftStep4.

,

2

Возможно, это не прямой ответ на ваш вопрос, но... когда я вижу это много повторений кода, я не могу не предложить вам попытаться избежать повторяетесь. Все ваши функции Step() делают одно и то же действия, только с другими данными. Затем можно разложить действия на факторы в одну функцию и предоставить ей различные данные в качестве параметров. В C++ есть много способов добиться этого. Я покажу четыре из них. их в порядке от самых элементарных до самых эзотерических.

Самый простой способ — использовать простую функцию и задать ей углы как параметры. Это в основном то, что предлагает ответ Мишеля Кейзерса. Мой взять на себя это было бы

void Step(uint8_t hip, uint8_t knee, uint8_t ankle)
{
    HipR.write(hip);
    HipL.write(hip);
    KneeR.write(knee);
    KneeL.write(knee);
    AnkleR.write(ankle);
    AnkleL.write(ankle);
}

который затем можно использовать в основном цикле как

Step( 80, 100,  20);  // right 1
Step( 90,  70,  20);  // left 1
...

Следующим шагом в модульности кода будет группировка всех углов для один шаг в составную структуру данных, называемую struct, затем Функция для выполнения шага принимает один параметр, которым являются эти данные структура:

struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
};

void doStep(Step s)
{
    HipR.write(s.hip);
    HipL.write(s.hip);
    KneeR.write(s.knee);
    KneeL.write(s.knee);
    AnkleR.write(s.ankle);
    AnkleL.write(s.ankle);
}

Эти структуры будут определены как

Step RightStep1 = { 80, 100,  20};
Step LeftStep1  = { 90,  70,  20};
...

и используется в loop() как

doStep(RightStep1);
doStep(LeftStep1);
...

Еще один шаг — вы можете встроить функцию в структуру данных. Встроенная функция затем становится «методом» структуры данных. который теперь называется «объект»:

struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
    void perform() {
        HipR.write(hip);
        HipL.write(hip);
        KneeR.write(knee);
        KneeL.write(knee);
        AnkleR.write(ankle);
        AnkleL.write(ankle);
    }
};

Структуры можно определять так же, как и раньше, и использовать как

RightStep1.perform();
LeftStep1.perform();
...

Последний прием заключается в том, чтобы заставить сами объекты вести себя как функции, которые могут быть вызваны. Этот тип вызываемого объекта называется «функтор», и это своего рода синтаксический сахар над вызовом метода. Мы просто необходимо переименовать соответствующий метод в operator():

struct Step {
    uint8_t hip;
    uint8_t knee;
    uint8_t ankle;
    void operator()() {
        HipR.write(hip);
        HipL.write(hip);
        KneeR.write(knee);
        KneeL.write(knee);
        AnkleR.write(ankle);
        AnkleL.write(ankle);
    }
};

Структуры по-прежнему определяются таким же образом, но теперь их можно использовать как будто это простые функции:

RightStep1();
LeftStep1();
...

Я предлагаю вам использовать любую технику, которая вам наиболее удобна. Однако существует логическая последовательность: чем больше вы улучшаете свой C++, навыки, тем комфортнее вам будет с новейшими.

,