Обход массива INT двумя способами - PullRequest
1 голос
/ 14 июня 2011

Обход массива INT двумя способами - это смешной роботизированный код (на языке C).

У меня есть такой массив позиций: int pos[] = {0, 45, 90, 135, 180, 135, 90, 45}; Эти позиции используются для перемещения серводвигателя.

 45   90   135
   \   |   /
    \  |  /
     \ | /
0 ----------- 180

В основном loop() я проверяю расстояние от препятствия, и если оно < xx Cm, мой сервопривод должен поворачиваться на следующий шаг (следующую позицию массива), пока не найдет свободный путь (> xx Cm).

Моя основная задача проста:

int main (int argc, const char * argv[]) { for (;;) find(); }

и моя основная функция (найти) такова:

void find() {
    for ( i=0; i<sizeof(pos); i++ ) // Traversing position array
    {
        distance = rand() % 7; // Simulate obstacle distance

        move( pos[i] );  // Simulate movements

        if (i==sizeof(pos)) { i=1; } // Try to reset the "i" counter. PROBLEM!
        if ( distance<=5 ) continue; // Is there an obstacle?

        sleep(2); // Debug sleep
        find(); // Similar recursion
    }
}

Я не знаю, что не так в этом коде, ноМне нужно двигать сервопривод, пока нет препятствий.


Пример : В позиции 90 я нахожу препятствие.Я хочу зациклить массив слева направо и наоборот контролировать расстояние на каждом шагу.Если я не нахожу автостраду, print("ko") else print("ok").

Как мне исправить этот код для правильной работы?

Ответы [ 5 ]

3 голосов
/ 14 июня 2011

Вы действительно хотите i < sizeof(pos) / sizeof(*pos), а не i < sizeof(pos). Размер массива - это не количество его элементов, а общее количество байтов, которое он занимает в памяти.

sizeof(pos) выход 8 * sizeof(int). Если int равно 4 байта, вы выполняете цикл 32 раза вместо 8.

Кроме того, i == sizeof(pos) никогда не будет истинным в теле цикла, поскольку условие оператора for ограничивает i sizeof(pos) - 1.

1 голос
/ 16 июня 2011

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

int pos[] = {0, 45, 90, 135, 180, -1};

void find()
{
    int i = 0;
    int direction = 1;

    do {
        move(pos[i]);
        i += direction;
        if (pos[i+direction] == -1) direction = -1; 
        if (i==0) direction = 1;
    } while(measure_distance() <= 5); 
}

Вместо рекурсии есть цикл while, который завершается только тогда, когда расстояние больше 5.

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

Движение влево-вправо, вправо-влево происходит из-за использования переменной direction. Довольно легко обнаружить либо начало (i == 0), либо конец массива 'pos' (pos [i + 1] == -1), после чего мы меняем направление.

Также нет необходимости повторять углы после 180 градусов. Последовательность, которую мы получаем:

0 45 90 135 180 135 90 45 0 45 90 ...

Мы можем даже сократить код одной строкой ...

...
if (pos[i+direction] == -1 || i == 0) direction *= -1; 
...

Ура, Johan

0 голосов
/ 14 июня 2011

Это, вероятно, хорошая практика, чтобы сказать: #define POSLENGTH 8 и затем повторить, используя i<POSLENGTH: как уже отмечали другие, использование sizeof(pos), вероятно, не будет работать.

Кроме того, массивы в C основаны на 0: элементы идут 0,1,2,3, ... n-1. Итак, вам нужно сказать:

if (i==POSLENGTH-1) i=0;

0 голосов
/ 14 июня 2011

Попробуйте использовать цикл while вместо цикла for.Увеличивайте значение, когда нет препятствий, и разрывайте, когда вы обнаружите препятствие:

{
    ......
    ......
    i = rand()%7;
    move( pos[i]);

    if (i<5)
        break;
    else
        continue;
    .......
    .......
}

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

0 голосов
/ 14 июня 2011

Не забудьте инициализировать вашу функцию rand, используя

/* initialize random seed: */
srand ( time(NULL) );

distance = rand() % 7;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...