Описание: просто робокоп |
Поиск в теме | Версия для печати |
clockworck |
Отправлено: 08 Марта, 2009 - 18:57:55
|
Лейтенант
Сообщений всего: 25
Дата рег-ции: Янв. 2009
|
Дорогие друзья ну подскажите пожалста, как разнообразить поведение робота, как например в си осуществить случайный выбор направления движения, и т.д и т.п.
А еще не скажите для чего нужны переменные которые указаны в программе к роботу на мк,где статья про вращение моторами вперед назад? у меня схема как там: л293д припаяна к тем же выводам мк, у меня так же все те-же номиналы конденсаторов и датчик висит на ноге pd1.Ну я беру и копирую вот это в робота
/*******************************************************
ПРИМЕР 1 :: ВРАЩЕНИЕ МОТОРАМИ ВПЕРЕД-НАЗАД :: MYROBOT.RU
********************************************************/
#include <avr/io.h>
/***************** Функция задержки ****************/
void delay(unsigned short ms) // Минимальная задержка с кварцем 8 МГц - 1 мс
{
unsigned short i, j, k; // объявляем переменные
for (i=0; i<ms; i++) // главный цикл формирования задержки
for (j=0; j<185; j++) // вложенный цикл формирования задержки
k++; // произвольное действие
}
/****************************************************/
int main(void) // начало основной программы
{
DDRC = 0xff; // все выводы порта C сконфигурировать как выходы
while (1) { // Бесконечный цикл
// ---------- вращаем моторы вперед 1 сек ----------
PORTC |= _BV(PC1); // установить "1" на линии 1 порта C
PORTC &= ~_BV(PC2); // установить "0" на линии 2 порта C
PORTC |= _BV(PC3); // установить "1" на линии 3 порта C
PORTC &= ~_BV(PC4); // установить "0" на линии 4 порта C
delay(1000); // ждем 1 сек.
// -------------------------------- ------------------
// ---------- вращаем моторы назад 1 сек ----------
PORTC &= ~_BV(PC1); // установить "0" на линии 1 порта C
PORTC |= _BV(PC2); // установить "1" на линии 2 порта C
PORTC &= ~_BV(PC3); // установить "0" на линии 3 порта C
PORTC |= _BV(PC4); // установить "1" на линии 4 порта C
delay(1000); // ждем 1 сек.
// -------------------------------- ------------------
} // закрывающая скобка бесконечного цикла
} // закрывающая скобка основной программы
у меня ни чего не работает. -я очень растраиваюсь и стераю малопонятные строки с переменными ,и о чудо все работает, еще меняю конечно delay(1000) на _delay_ms();
так зачем сдесь переменные? |
|
|
Белый Волк |
Отправлено: 09 Марта, 2009 - 08:35:32
|
Супермодератор
Сообщений всего: 648
Дата рег-ции: Февр. 2007
|
clockworck
Быстрый алгоритм создания псевдослучайного числа с равномерным распределением:
CODE:
long int x = 1234567089;
long int y = 2249273084;
long int z = 2075489025;
long int w = 1000000007;
unsigned int random(unsigned int max) //Возвращает целое случайное число от 0 до max-1
{
unsigned long t = x ^ (x << 11);
x = y;
y = z;
z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8))) % max;
}
Алгоритм называется XorShift. Обеспечивает (2 в степени 128 - 1) период повторения.
Для того, чтобы выдаваемые случайные числа не повторялись после операции выключение/включение, следует сохранять в какой-либо момент времени в энергонезависимую память микроконтроллера x, y, z, w.
Однако, если делать это каждый раз при обращении к функции, несколько снизится производительность (время обращения к энергонезависимой памяти микроконтроллера для записи одного байта составляет миллисекунды, что иногда может оказаться критичным). Следует проводить такую операцию во время инициализации микроконтроллера при включении. Поскольку, для случая с домашним роботом, указанный период повторения неоправданно велик (10760801423071571527252030441 год по 1000 случайных чисел в секунду), можно записывать в энергонезависимую память только 4 байта, которые будут определять собой новые значения x, y, z и w для каждого нового перезапуска. Конечный код выглядит следующим образом:
CODE:
long int x = 1234567089;
long int y = 2249273084;
long int z = 2075489025;
long int w = 1000000007;
unsigned int random(unsigned int max) //Возвращает целое случайное число от 0 до max-1
{
unsigned long t = x ^ (x << 11);
x = y;
y = z;
z = w;
return (w = (w ^ (w >> 19)) ^ (t ^ (t >> 8))) % max;
}
void EEPROM_write(unsigned int address, unsigned char data)
{
while (EECR & (1 << EEWE));
EEAR = address;
EEDR = data;
EECR |= (1 << EEMWE);
EECR |= (1 << EEWE);
}
unsigned char EEPROM_read(unsigned int address)
{
while (EECR & (1 << EEWE));
EEAR = address;
EECR |= (1 << EERE);
return EEDR;
void random_init()
{
x = EEPROM_read(0);
y = EEPROM_read(1);
z = EEPROM_read(2);
w = EEPROM_read(3);
unsigned int tmp = 1051;
tmp = x = (tmp * 4153 + TCNT0 + x) % (42589);
tmp = y = (tmp * 4153 + TCNT0 + y) % (42589);
tmp = z = (tmp * 4153 + TCNT0 + z) % (42589);
tmp = w = (tmp * 4153 + TCNT0 + w) % (42589);
EEPROM_write(0, random(256));
EEPROM_write(1, random(256));
EEPROM_write(2, random(256));
EEPROM_write(3, random(256));
}
Для организации генерации реальных случайных чисел, можно измерить время в миллисекундах от момента включения робота до момента встречи им первого препятствия и присвоить это значение переменной tmp (вместо 1051), соответственно изменив код.
Код написан для AVR Studio, подходит без изменений для WinAVR. |
|
|
Белый Волк |
Отправлено: 10 Марта, 2009 - 04:15:32
|
Супермодератор
Сообщений всего: 648
Дата рег-ции: Февр. 2007
|
Данную часть кода можно непосредственно вставлять в Ваш, выше, чем Вы впервые обратитесь к функции определения случайного числа.
Для того, чтобы воспользоваться этим, в функции main(), необходимо вызвать инициализацию генератора случайных чисел, записав
После чего, в любом месте программы, где необходимо случайное поведение робота, используйте конструкцию вида:
CODE:
switch(random(5)) //Оператор множественного выбора
{
case 0: PORTD = 3; //в случае, если случайное число равно 0, выполнить действие PORTD=3.
break;
case 1: PORTD = 2; //в случае, если случайное число равно 1
break;
case 2: PORTD = 1; //в случае, если случайное число равно 2
break;
default: PORTD = 0b00001110; //в случае, если случайное число равно любому другому, не указанному ранее в case числу
}
Суть использования в следующем: Вы получаете при помощи обращения к функции random(x) случайное число, которое лежит в диапазоне от 0 до x-1, затем рассматриваете возможные значения случайного числа и задаёте необходимые для каждого значения действвия.
Можете воспользоваться структурой if(){}else{}, вместо предложенной. Например, если стоит выбор, поворот направо или налево, можно использовать:
CODE:
if(random(2))
{//действия для поворота направо}
else
{//действия для поворота налево}
|
|
|
|
Поиск в теме | Версия для печати |
Страниц (5): « 1 [2] 3 4 5 » |
« Делаем роботов » |
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
|
|
|
|
|