NXC: работаем с цветовым сенсором.



Среда NXT-G привлекательна тем, что она позволяет сосредоточиться программисту на самом алгоритме, и практически не задумываться о таких вещах, свойственных текстовым языкам, как инициализация, синтаксис и т.п. Она предоставляет простой и удобный доступ практически ко всем возможностям моторов и сенсоров, без необходимости помнить вызовом какой процедуры или функции это происходит.  

Поэтому, если вы программируете на текстовых средах, довольно часто для поиска решения проблемы по работе какого-то сенсора, которая бы на NXT-G не заняла бы у вас и одной минуты, необходимо потратить значительное количество времени.
Так, например, работая с языком NXC, вы еще достаточно легко можете найти готовый код для работы со стандартным цветовым сенсором:

taskmain(){ SetSensorColorFull(S1); ColorSensorReadType csr; csr.Port = S1; while(1) {   SysColorSensorRead(csr);   if(csr.Result == NO_ERR) {       NumOut(0, LCD_LINE1, csr.ColorValue);   }   Wait(1000); }}

 

В то время как, поиск примера по работе с ним в режиме светового сенсора займет определенное количество времени.
Чтобы облегчить эту задачу, можете изучить приведенный ниже пример:

taskmain(){ SetSensorColorRed(S1); Wait(500); while(1) {   NumOut(0, LCD_LINE1, SENSOR_1);   Wait(300); }}

 

И на будущее, если у вас возникли какаие-то вопросы связанные с использованием того или иного языка программирования - идите на форум The MindBOARDS Community. И если вы там не найдете готовый ответ - не стесняйтесь, спрашивайте. Там сидит довольно много широко известных в Lego мире разработчиков, которые смогут дать вам квалифицированный ответ.

NXC: датчики, енкодеры, кнопки - взаимодействуем с внешним миром

  Программирование робота, в большинстве случаев, - изменение поведения робота как реакция на информацию, пришедшую к управляющему устройству с датчиков и сенсоров. Эта заметка рассматривает примеры опроса датчиков в языке Not eXactly C, а также некоторые особенности, которые необходимо учитывать при работе с ними.

Пример 1. Датчик расстояния
Для датчика расстояния (ультразвуковой) используются специальные функции для его инициализации и опроса.

taskmain() { /* Робот ждет пока перед ним не окажется предмет (ближе чем 20 см.), после чего отодвигается от предмета на 50 см. */ //Говорим, что медленный (ультразвуковой) сенсор установлен в первый //порт. SetSensorLowspeed(S1); Wait(100); while(true) {   //Опрашиваем порт первый, как ультразвуковой датчик   //Ждем, пока расстояние до предмета не станет меньше 20 см.   until(SensorUS(S1) < 20);    //Отодвигаемся назад до тех пор, пока расстояние до предмета не   //станет больше 50 см.   OnRev(OUT_AB, 50);   until(SensorUS(S1) > 50);   //Явно останавливаем двигатели   Off(OUT_AB); }}

Пример 2. Измерение отраженного света.
Работа датчика в режиме измерения отраженного света (пространство перед датчиком дополнительно освещается светодиодом) позволяет повысить его чувствительность. Без использования этого режима, решение такой задачи как распознавание цвета или градаций серого была бы довольно трудно выполнима – обычно окружающий свет не имеет достаточной интенсивности, поэтому соседние градации цветов сливались бы один цвет при измерении. К тому же, измерения при неравномерном освещении давали бы разный результат для одного и того же предмета. Поэтому использование дополнительной подсветки – наиболее частый вариант при управлении роботом с помощью датчика освещенности.

taskmain() { /* Робот двигается пока поверхность под световым сенсором не потемнеет. */ //Говорим, что cветовой сенсор установлен в третий порт. SetSensorLight(S3); Wait(500); //Двигаемся вперед, пока значение сенсора в третьем порту не станет     //меньше 55 процентов. OnFwd(OUT_AB, 50); until(Sensor(S3) < 55); Off(OUT_AB);}

Пример 3. Измерение окружающего света
В некоторых задачах, дополнительная подсветка только мешает. Например, определить какое место в комнате самое темное. Для этого нужно измерять именно окружающее освещение.

taskmain() { /* Робот отображает на экране текущую освещенность. */ //Говорим, что cветовой сенсор установлен в третий порт //лампа подсветки - неактивна SetSensorType(S3, SENSOR_TYPE_LIGHT_INACTIVE); //Сенсор, устанавливаемый через SetSensorType по-умолчанию показывает //ненормализованные данные (не путать с RAW). Переводим, его в режим для //считывания процентов. SetSensorMode(S3, SENSOR_MODE_PERCENT); Wait(500); while(true) {  //Выводим на эркан текущие показатели сенсора, перед выводом -  //очищаем экран (4-ый параметр - true)  NumOut(0, LCD_LINE1, Sensor(S3), true);   Wait(50); }}

Пример 4. Использование необработанных данных
По умолчанию, датчики выдают измерения в процентах. В то время как NXC предоставляет возможность использовать необработанные (RAW) данные. Преимущество – очевидно – поскольку необработанные данные могут быть в диапазоне от 0 до 1023, измерения будут в 10 раз чувствительнее.

taskmain() { /* Робот отображает на экране показания отраженного света.     Темная поверхность:   1-ая строка (проценты): значения маленькие (<50%)   2-ая строка (raw): значения большие (>600) Светлая поверхность:   1-ая строка (проценты): значения маленькие (>50%)   2-ая строка (raw): значения большие (<400) */     //Говорим, что cветовой сенсор установлен в третий порт SetSensorLight(S3); Wait(500); while(true) {  //Выводим на эркан в первой строке текущие показатели сенсора в  //процентах, перед выводом - очищаем эркан (4-ый параметр - true)  NumOut(0, LCD_LINE1, Sensor(S3), true);  //Выводим на эркан во второй строке текущие необработанные показатели  //сенсора, экран не очищается (4-ый параметр не указывается - берется  //значение по-умолчанию false)  NumOut(0, LCD_LINE2, SensorRaw(S3));   //Чтобы избежать мерцания цифр на экране, делаем небольшую паузу.  Wait(50); }}

Пример 5. Датчик вращения двигателя (енкодер)
Поскольку датчик вращения двигателя (енкодер) скрыт от глаз конструктора, часто о его существовании забывают. Тем не менее, с помощью этого датчика можно решать множество задач: для определения столкновения с препятствием, для синхронизированного движения моторов, для контроля положения двигателя в одном положении с использованием регуляторов и т.п.

taskmain() { /* Робот начинает двигаться, затем, в цикле дважды опрашивается датчик     поворота двигателя с небольшой паузой. Поскольку пауза происходит параллельно движению двигателя (использование функции OnFwd), оценивается поворот двигателя, произошедший во время этой паузы. Если поворот меньше ожидаемого, то скорее всего робот наткнулся на препятствие - препятствие мешает провернуться двигателю. После     обнаружения такой ситуации - движение прекращается. */ intStart; intDiff; intDesired; //Переменная используется, чтобы при первой итерации цикла определить //поворот двигателя во время паузы и взять этот поворот за эталон intiter = 0; OnFwd(OUT_AB, 40); do{   //Считываем показание датчика поворота перед паузой   Start = MotorRotationCount(OUT_A);   Wait(100);   //Считываем показание датчика после паузы и определяем угол поворота   Diff = MotorRotationCount(OUT_A) - Start;   //Если это первая итерация цикла - принять угол поворота за эталон   if(iter == 0) {       Desired = Diff * 8 / 10;       //Указать, что больше в этот 'if' заходить не надо       iter = 1;   } } while(Diff > Desired) //Если угол поворота двигателя меньше эталона Off(OUT_AB);}


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

#define OneSecond 1000 taskmain() { /* В каждой итерации цикла опрашивается датчик расстояния. Количество итераций определяется выяснением, сколько миллисекунд прошло с начала работы программы. Как только количество миллисекунд становится больше 1000 - цикл прерывается. Поскольку ультразвуковой сенсор является низкоскоростным устройством, его опрос вызывает задержку. Результат показывает, что ультразвуковой сенсор может быть опрошен 34 раза за одну секунду. Т.е. задержка опроса сенсора составляет - 1000/34 = 30 миллисекунд. */ //Указываем, что низкоскоростной сенсор (ультразвуковой) установлен в //первый порт SetSensorLowspeed(S1); Wait(100); //Считываем начальное показание внутреннего таймера unsigned longStart = CurrentTick(); unsigned longDiff; unsigned longi = 0, value; do{   //Опрашиваем сенсор, его показания не важны для данной программы,   //важен факт его вызова   value = SensorUS(S1);   //Вычисляем разницу между начальным показанием таймера и текущим   Diff = CurrentTick() - Start;   i++; } while(Diff < OneSecond) //Повторять, пока разница - меньше секунды NumOut(0, LCD_LINE1, i); Wait(3000);}

Пример 7. Определение цвета
Работа с датчиком цвета практически не отличается от работы с датчиком освещенности, следует только помнить, что в датчике цвета светодиодов три.

taskmain(){ /Инициализация датчика в первом порту - включить все три светодиода SetSensorColorFull(S1); while(1) {   //Опрашиваем датчик и выводим на экран определившийся цвет   NumOut(0, LCD_LINE1, Sensor(S1));   Wait(1000); }}

 

Пример 8. Опрос датчика цвета в режиме датчика освещенности
В определенных задачах датчик цвета может заменить датчик освещенности.

taskmain(){ //Инициализация датчика в первом порту - включить красный светодиод SetSensorColorRed(S1); while(1) {   //Опрашиваем датчик и выводим на экран значения отраженного   //света в процентах и "сырых" показаниях   NumOut(0, LCD_LINE1, Sensor(S1));   NumOut(0, LCD_LINE2, SensorRaw(S1));   Wait(1000); }}

 

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

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

Есть даже не совсем обычная команда until, которая является макросом к использованию while().

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

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

taskmain() { /* Программа ниже может быть описана следующим образом: - начать движение прямо - двигаться до тех пор пока до препятствия больше 10 см. - остановится как только до препятствия осталось меньше (либо равно) 10 см.     Следует отметить, что команда "движение вперед" выполняется не цикле, но в цикле уже опрашивается сенсор расcтояния. */ SetSensorLowspeed(S1); Wait(100); OnFwd(OUT_AB, 50); while(SensorUS(S1) > 10); Off(OUT_AB);}

Пример 2. while() в одну строчку
Реализация while() в NXC также поддерживает вызов с блоком повторения, записанным одной командой.

taskmain() { /* Движение будет происходить до тех пор пока расстояние до препятствия Больше 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(). По сути, он позволяет выполнять повторять предыдущее действие до тех пор, пока условие неверно.

taskmain() { /* Движение назад будет происходить до тех пор, пока расстояние до препятствия не станет больше 30 см. */ SetSensorLowspeed(S1); Wait(100); OnRev(OUT_AB, 50); until(SensorUS(S1) > 30); Off(OUT_AB);}

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


Дата добавления: 2018-05-12; просмотров: 495; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!