ДО курс по робототехнике

5 апреля 2013 г.

NXC: использование циклов

(C)
Продолжение публикации материалов из методички по языку программирования Not eXactly C, подготовленной в рамках учебных курсов Нижегородского Института Информационных Технологий.

Как и в обычном C, в NXC поддерживается несколько видов циклов: for, while, do ... while, repeat.
Есть даже не совсем обычная команда until, которая является макросом к использованию while().

В этой заметке основной акцент сделан не на стандартное поведение программы при использовании циклов, а на особенности, существующие в NXC.

Пример 1. while() как функция
В NXC while может быть использован и как стандартный цикл "выполнять пока", внутри которого выполняются различные действия, так и как функция "выполнять пока", которая возвращает управление программе, только тогда когда не выполняется условие, переданное в данную функцию.

task main() {
    /*
    Программа ниже может быть описана следующим образом:
    - начать движение прямо
    - двигаться до тех пор пока до препятствия больше 10 см.
    - остановится как только до препятствия осталось меньше (либо равно)
      10 см.
    
    Следует отметить, что команда "движение вперед" выполняется не цикле, но
    в цикле уже опрашивается сенсор расcтояния.
    */

    SetSensorLowspeed(S1);
    Wait(100);

    OnFwd(OUT_AB, 50);
    while (SensorUS(S1) > 10);
    Off(OUT_AB);
}

Пример 2. while() в одну строчку
Реализация while() в NXC также поддерживает вызов с блоком повторения, записанным одной командой.
task main() {
    /*
    Движение будет происходить до тех пор пока расстояние до препятствия
    Больше 10 см. Остановка двигателей (Off) уже на другой строчке - он не
    Выполняется в цикле.
    Поскольку для движения используется RotateMotor(), который отдает
    Управление следующей итерации цикла только после того как повернет
    двигатели на 180 градусов, проверка на расстояние может произойти уже
    когда до препятствия останется уже гораздо меньше расстояния. Т.е. за
    эти 180 градусов, робот может пройти через рубеж в 10 см.
    */

    SetSensorLowspeed(S1);
    Wait(100);

    while (SensorUS(S1) > 10)
        RotateMotor(OUT_AB, 50, 180);
    Off(OUT_AB);
}

Пример 3. until()
Как уже было сказано ранее, until() – макрос к функции while(). По сути, он позволяет выполнять повторять предыдущее действие до тех пор, пока условие неверно.
task main() {
    /*
    Движение назад будет происходить до тех пор, пока расстояние до
    препятствия не станет больше 30 см.
    */

    SetSensorLowspeed(S1);
    Wait(100);

    OnRev(OUT_AB, 50);
    until (SensorUS(S1) > 30);

    Off(OUT_AB);
}

Пример 4. Скорость исполнения цикла.
В данном примере не рассматривается никакая особенность циклов. Зато он предназначен для получения ответа на вопрос "сколько итераций цикла исполняется в течение одной секунды".
#define OneSecond 1000

task main() {
    /*
    Перед началом цикла засекаем текущее состояние таймера (Start).
    Затем, проверяем разницу между этим значением и новым состоянием таймера
    Как только разница - 1000 милисикунд - останавливаем цикл.
    Полученные данные выводим на экран.
    */

    Wait(100);

    unsigned long Start = CurrentTick();
    unsigned long Diff;
    unsigned long i = 0;

    do {
        Diff = CurrentTick() - Start;
        i++;
    } while (Diff < OneSecond)

    //     Координата X
    //     |  Координата Y (задается константой, обозначающей номер строки)
    //     |  |          Значение для вывода на экран
    //     |  |          |
    NumOut(0, LCD_LINE1, Start);
    NumOut(0, LCD_LINE2, i);
    Wait(3000);
}

Комментариев нет:

Отправить комментарий