ЭМУЛЯТОР МИНИРОБОТОВ

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

СПРАВОЧНИК | ЭМУЛЯТОР AVR GCC

Семейство роботов, управляемых AVR-контроллерами Orangutan, распространяется отечественной фирмой Minirobo.ru, главным дистрибутором фирмы Pololu.

МИГАЕМ СВЕТОДИОДАМИ НА РОБОТЕ

Базовая библиотека Pololu AVR Library содержит подпрограммы управления красным светодиодом, расположен впереди, и зеленым - расположенным за индикаторной панелью. Ознакомление с нею начинается с мигания red и green светодиодами (leds).


#include <pololu/orangutan.h> 

int main(){ 
while(1){ 
 red_led(1);   
 delay_ms(1000); 
 red_led(0);   
 delay_ms(1000); 
 green_led(1); 
 delay_ms(500); 
 green_led(0); 
 delay_ms(500); 
}//while 
}

ВОЗВРАТНО-ПОСТУПАТЕЛЬНОЕ ДВИЖЕНИЕ

Совмещенное программирование возвратно-поступательного движения: iMatLab используется для моделирования динамики и визуализации робота, контроллер отрабатывает программу поутюжить местность переключением скорости.


#include <pololu/orangutan.h>

int main(){
clear(); int T=0; int motorSpeed=0;

while(1){ 
// логика управления,
switch (T){
case  0: motorSpeed=50; break; 
case 10: motorSpeed=0; break; 
case 20: motorSpeed=-50; break;
case 30: motorSpeed=50; T=0; break;
}
set_motors(motorSpeed,-motorSpeed);
delay_ms(100); 
T++;
}//while
}

%math, % ДИНАМИКА РОБОТА (ВИЗУАЛИЗАТОР iMATLAB),

if tick=0, X=200, Robot=robot(8), end,

function: set_motors(motorSpeed1 motorSpeed2), 
X=X+(motorSpeed1-motorSpeed2)/20, moveXat(Robot X), 
show(Robot),  
end,

function: robot(L),
var t X Y C, C=iniFG(0 '#00aaaa' 0 0), 
t=time(2*PI 8), X=fun(220+130*sin(t)), Y=fun(150+130*cos(t)), 
addFG(C 'F' 'F' '#447777' X Y), t=L+5,
addFG(C 'T' 'T' '#222222' [-L-4 -L-4 t t] [-L-2 L+2 L+2 -L-2 ]), 
addFG(C 'T' 'T' '#ff9955' [-L-4 -L-4 t t] [-L L L -L]),
addFG(C 'T' 'T' '#ffbb55' [-L -L L L] [-L L L -L]), t=t+2,
addFG(C 'T' 'T' '#ffbb55' [t t] [-L -L/2]),
addFG(C 'T' 'T' '#ffbb55' [t t] [L/2 L]),
moveX(C 220), moveY(C 140), 
return C, 
end,

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

ПОСТУПАТЕЛЬНОЕ И ВРАЩАТЕЛЬНОЕ ДВИЖЕНИЯ

Совмещенное программирование вращательного движения: iMatLab используется для моделирования динамики и визуализации робота, контроллер отрабатывает программу поворота в разные стороны.


#include <pololu/orangutan.h>

int main() {
clear(); int T=0; int motorSpeed1=0; int motorSpeed2=0;

while(1){ 
// логика управления,
switch (T){
case  0: motorSpeed1=50; motorSpeed2=-50; break; 
case 10: motorSpeed1=50; motorSpeed2=50; break; 
case 20: motorSpeed1=-50; motorSpeed2=50; break;
case 30: motorSpeed1=50; motorSpeed2=-50; T=0; break;
}
set_motors(motorSpeed1,motorSpeed2);
delay_ms(100); 
T++;
}//while
}

%math, % ДИНАМИКА РОБОТА (ВИЗУАЛИЗАТОР iMATLAB),

if tick=0, X=200, Y=150, a=0, Robot=robot(8), 
Robot[1][31]='#ff0000';
Robot[1][35]='#00ff00';
end,

function: set_motors(motorSpeed1 motorSpeed2), 
V=(motorSpeed1-motorSpeed2)/20,
a=a+(motorSpeed1+motorSpeed2)/500, X=X+cos(a)*V, Y=Y+sin(a)*V, 
turnat(Robot a), moveXat(Robot X), moveYat(Robot Y), show(Robot),  
end,

function: robot(L),
var t X Y C, C=iniFG(0 '#00aaaa' 0 0), 
t=time(2*PI 8), X=fun(220+130*sin(t)), Y=fun(150+130*cos(t)), 
addFG(C 'F' 'F' '#447777' X Y), t=L+5,
addFG(C 'T' 'T' '#222222' [-L-4 -L-4 t t] [-L-2 L+2 L+2 -L-2 ]), 
addFG(C 'T' 'T' '#ff9955' [-L-4 -L-4 t t] [-L L L -L]),
addFG(C 'T' 'T' '#ffbb55' [-L -L L L] [-L L L -L]), t=t+2,
addFG(C 'T' 'T' '#ffbb55' [t t] [-L -L/2]),
addFG(C 'T' 'T' '#ffbb55' [t t] [L/2 L]),
moveX(C 220), moveY(C 140), 
return C, 
end,

УПРАВЛЕНИЕ ПО ОПТИЧЕСКОМУ ДАТЧИКУ ДИСТАНЦИИ

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


#include <pololu/orangutan.h>

int main(){
//обращение к АЦП5
set_analog_mode(MODE_8_BIT);
int avg=0; start_analog_conversion(5);  
// переменные фильтра
int sum=0; int samples=0;
// скорости гусениц
int motorSpeed1=0; int motorSpeed2=0;  
while(1){ 
//фильтр накопления АЦП5
if (!analog_is_converting())
{ sum += analog_conversion_result();     
  start_analog_conversion(5);     
  if (++samples == 2)
  { avg = sum/2; samples = 0; sum = 0; 
  // вывод на LCD сигнала датчика расстояния
  clear(); lcd_goto_xy(0,0); print_long(avg); 
  }     
}
//включение поворота на короткой дистанции
motorSpeed1=50; motorSpeed2=-50;
green_led(0); red_led(0);
if (avg>100) 
{ motorSpeed2=50; red_led(1); green_led(1);
}  
set_motors(motorSpeed1,motorSpeed2); 
// задержка визуализации
delay_ms(100);
}//while
}

%math, % ДИНАМИКА РОБОТА (ВИЗУАЛИЗАТОР iMATLAB),

if tick=0, X=200, Y=150, a=0, Robot=robot(8), end,

function: set_motors(motorSpeed1 motorSpeed2), 
V=(motorSpeed1-motorSpeed2)/20,
a=a+(motorSpeed1+motorSpeed2)/500, X=X+cos(a)*V, Y=Y+sin(a)*V, 
turnat(Robot a), moveXat(Robot X), moveYat(Robot Y), 
if FlgRED=1, 
Robot[1][35]='#ff0000', else, 
Robot[1][35]='#ffbb55', end,
if FlgGREEN=1, 
Robot[1][31]='#00ff00', else,
Robot[1][31]='#ffbb55', end,
show(Robot),  
end,

function: lcd_goto_xy(x y), end,  
function: print_long(S), round(S)=?, end, 
function: set_analog_mode(MODE), end, 
function: start_analog_conversion(CANAL), end,
function: analog_is_converting(), return false, end,
//модель выхода датчика дистанции
function: analog_conversion_result(), 
if cos(a)<0, dx=X, else, dx=430-X, end, dx=abs(dx),  
if sin(a)<0, dy=Y, else, dy=300-Y, end,  dy=abs(dy),
if dx>dy, D=150-dy, else, D=150-dx, end,
if D<0, D=0, end,  return round(D),
end,   

function: robot(L),
var t X Y C, C=iniFG(0 '#00aaaa' 0 0), 
t=time(2*PI 8), X=fun(220+130*sin(t)), Y=fun(150+130*cos(t)), 
addFG(C 'F' 'F' '#447777' X Y), t=L+5,
addFG(C 'T' 'T' '#222222' [-L-4 -L-4 t t] [-L-2 L+2 L+2 -L-2 ]), 
addFG(C 'T' 'T' '#ff9955' [-L-4 -L-4 t t] [-L L L -L]),
addFG(C 'T' 'T' '#ffbb55' [-L -L L L] [-L L L -L]), t=t+2,
addFG(C 'T' 'T' '#ffbb55' [t t] [-L -L/2]),
addFG(C 'T' 'T' '#ffbb55' [t t] [L/2 L]),
moveX(C 220), moveY(C 140), 
return C, 
end,

Отражение света под косым углом менее эффективо. Реальный оптический датчик более узконаправлен, поэтому на практике можно применять разновидность этой программы с гистерезисным включением двигателей на реверс с тем, чтобы получить программный поворот на прямой угол при первом же обнаружении препятствия.

Баги библиотеки: экспериментально замечено сбрасывание (reset) основной программы при реверсе одного из двигателей и пользовании LCD (отладочным экраном).

ПРОГРАММИРОВАНИЕ POP-BOT

Для сравнения рассмотрим принципы программирования другого набора мехэлектроники. Программирование pop-bot-ов в проектах, связанных с платами aurdino, ближе к программированию телефонов в том смысле, что программист не пишет всю программу управления устройством в целом. Он пишет лишь скетч: дает основные предписания. Доопределяет содержимое стандартных подпрограмм, из которых главная носит название "цикл" (loop). Ее содержимое выполняется циклически, но сам цикл пользователь нигде не пишет.

Столь же формальной является подпрограмма настройки (setup), в которой указывается назначение даже не портов микропроцессора, а назначение выводов платы. Архитектура микропроцессора при этом вуалируется. Наименования выводов платы несозвучно наименованиям портов. Хотя общая логика остается, линия может доопределяться как вход или выход. Задание (скетч) движения по кругу с остановкой по нажатию кнопки на бампере дает представление об этом методе программирования.


void setup() {
 pinMode(3,OUTPUT); // Motor A
 pinMode(5,OUTPUT); // Motor A
 pinMode(6,OUTPUT); // Motor B
 pinMode(9,OUTPUT); // Motor B 
 pinMode(2,OUTPUT); // Swith Left
 pinMode(4,OUTPUT); // Swith Right
}
void Forward(int Lspeed, int Rspeed) {
 analogWrite(3,Lspeed);
 digitalWrite(5,LOW);
 analogWrite(6,Rspeed);
 digitalWrite(9,LOW);
}
void Motor_Stop() {
 digitalWrite(3,LOW);
 digitalWrite(5,LOW);
 digitalWrite(6,LOW);
 digitalWrite(9,LOW);
}
void loop() {
 Forward(80,255);
 if(digitalRead(4)==0) {
 Motor_Stop();
 while(1);
 }
}

В setup указываются выводы платы, связанные с моторами. При управлении линии "земля" двигателей определяются как LOW, на другие линии подаются сигналы, пропорциональные скоростям вращения колес. Состояние кнопки бампера читается соответствующей подпрограммой.

Линия UART блокирована микросхемой связи по RS232 и не подведена к клеммам, что вызывает некоторое недоумение: столько усилий, и все на программирование, но ведь робот должен еще и наращиваться.



Rambler's Top100