Разобрался с питанием. Теперь разбираюсь со скоростью поворота сервоприводов. Заметил что если залить в программу скрипт " переменную скорость сервопривода" то они работают гораздо быстрее например вот этот http://forums.trossenrobotics.com/showt ... #post48865 но поворот происходит очень резко и происходит раздвоение маркера как шлейф. Из за этого камера поворачивается часто пролетая дальше мимо истинной цели. Как можно сделать поворот быстрым но не таким резким?
Ну так в том скрипте кроме переменных, указывающих угол поворота сервомоторов (TURRET_V_CONTROL, TURRET_H_CONTROL) есть ещё переменные указывающие скорость вращения сервомоторов (TURRET_V_SPEED, TURRET_H_SPEED от 1 до 100). Только вот непонятно, куда в “Sparkfun Arduino” модуле эти значения передать. Похоже, из этого модуля нельзя управлять скоростью Ну или придётся в скрипте «поколдовать» над шагом приращения переменных TURRET_V_CONTROL, TURRET_H_CONTROL, так, что бы он изменялся по мере приближения к цели
Скорость поворота меня устраивает. С перескоком камеры дальше маркера разобрался.
Теперь пока волнуют очень следующие проблемы. 1. Как сделать что бы камера сразу поворачивалась а не с такими задержками при перестановке маркера. 2. Как постоянно маркер держать в центре квадрата. 3. Если скажем 20 секунд нет маркера в кадре как сделать чтобы камера переходила в режим сканирования и начинала медленно поворачиваться по горизонтали?
if step_counter =< 0 then step_counter = round(exp(-(dXr*dYr)*reaction*0.7)*15)
if dX > threshold then ' The object is at left side turret_h = turret_h - delta_h
if turret_h < turret_min then turret_h = turret_min end if
if dX < -threshold then ' The object is at right side turret_h = turret_h + delta_h
if turret_h > turret_max then turret_h = turret_max end if
if dY > threshold then ' The object is at the bottom turret_v = turret_v - delta_v
if turret_v < turret_min then turret_v = turret_min end if
if dY < -threshold then ' The object is at the top turret_v = turret_v + delta_v
if turret_v > turret_max then turret_v = turret_max end if else step_counter = step_counter - 1 end if
' Is the target locked? if dX < threshold and dX > -threshold and dY < threshold and dY > -threshold then status = "Target is locked" turret_f = 1 else status = "Tracking" turret_f = 0 end if else ' Back to the center if object is lost if turret_h > 0 then turret_h = turret_h - 1 if turret_h < 0 then turret_h = turret_h + 1 if turret_v > turret_v_initial then turret_v = turret_v - 1 if turret_v < turret_v_initial then turret_v = turret_v + 1
unsigned int crc; unsigned int command; unsigned int channel; unsigned int value; unsigned int valueLow; unsigned int valueHigh; unsigned int streamDigital; unsigned int streamAnalog; unsigned int lastDigital; unsigned int lastAnalog[8]; unsigned int heartBeat=0; unsigned int defaultServo[14];
void initialize() { int i; for (i=2;i<14;i++) pinModes[i]=-1; streamDigital=0; streamAnalog=0; lastDigital=-1; for (i=0;i<8;i++) lastAnalog[i]=-1; for (i=0;i<12;i++) defaultServo[i]=1500; }
void readPacket() { // get header byte // 128 (bit 8) flag indicates a new command packet .. that // means the value bytes can never have 128 set! // next byte is the command 0-8 // next byte is the channel 0-16
do { while (Serial.available() <= 0) continue; command = Serial.read(); } while ((command&128)==0);
command^=128;
while (Serial.available() <= 0) continue; channel = Serial.read(); }
int readValuePacket() { unsigned int valueLow; unsigned int valueHigh;
// wait for value low byte while (Serial.available() <= 0) continue; valueLow = Serial.read(); if (valueLow&128) return 0;
// wait for value high byte while (Serial.available() <= 0) continue; valueHigh = Serial.read(); if (valueHigh&128) return 0;
// wait for crc byte while (Serial.available() <= 0) continue; crc = Serial.read(); if (crc&128) return 0;
if (crc!=(((128|command)^channel^valueLow^valueHigh)&127)) return 0;
value = valueLow|(valueHigh<<7);
return 1; }
void loop() { while (Serial.available()>0) { readPacket();
heartBeat=0;
switch (command) { // init case ARDUINO_GET_ID: initialize(); Serial.print("ARDU"); break; // servo case ARDUINO_SET_SERVO: if ((channel>=3)&&(channel<=11)) { if (readValuePacket()) { if (pinModes[channel]!=1) { servos[channel].attach(channel); pinModes[channel]=1; } servos[channel].writeMicroseconds(value); writeValuePacket(value); } } break; //digital stream case ARDUINO_SET_DIGITAL_STREAM: if (readValuePacket()) { streamDigital = value; writeValuePacket(value); lastDigital=-1; } break; //set digital high case ARDUINO_SET_DIGITAL_HIGH: if ((channel>=2)&&(channel<14)) { if (pinModes[channel]!=2) { if (pinModes[channel]==1) servos[channel].detach();
pinMode(channel, OUTPUT); pinModes[channel]=2; if (streamDigital&(1<<channel)) streamDigital^=1<<channel; }
digitalWrite(channel, HIGH); writePacket(); } break; //set digital low case ARDUINO_SET_DIGITAL_LOW: if ((channel>=2)&&(channel<14)) { if (pinModes[channel]!=2) { if (pinModes[channel]==1) servos[channel].detach();
pinMode(channel, OUTPUT); pinModes[channel]=2;
if (streamDigital&(1<<channel)) streamDigital^=1<<channel; } digitalWrite(channel, LOW); writePacket(); } break; //analog stream case ARDUINO_SET_ANALOG_STREAM: if (readValuePacket()) { streamAnalog = value; writeValuePacket(value); for (channel=0;channel<8;channel++) lastAnalog[channel]=-1; } break; case ARDUINO_SET_ANALOG: if (readValuePacket()) { if ((channel>=3)&&(channel<=11)) { if (pinModes[channel]!=2) { if (pinModes[channel]==1) servos[channel].detach();
pinMode(channel, OUTPUT); pinModes[channel]=2; } analogWrite(channel, value); writeValuePacket(value); } } break; case ARDUINO_SET_SERVO_DEFAULT: if ((channel>=3)&&(channel<=11)) { if (readValuePacket()) { defaultServo[channel] = value; writeValuePacket(value); } } break; case ARDUINO_HEARTBEAT: break; } }
if ((heartBeat++)>25000) { int i; for (i=3;i<12;i++) { if (pinModes[i]==1) servos[i].writeMicroseconds(defaultServo[i]); else if (pinModes[i]==2) analogWrite(i, 0); } }
for (channel=0;channel<8;channel++) { if (streamAnalog&(1<<channel)) { value = analogRead(channel); // only send value if it has changed if (value!=lastAnalog[channel]) { command = ARDUINO_ANALOG_STREAM; writeValuePacket(value);
lastAnalog[channel]=value; } } }
if (streamDigital) { value=0; for (channel=2;channel<14;channel++) { if (streamDigital&(1<<channel)) { if (pinModes[channel]!=3) { if (pinModes[channel]==1) servos[channel].detach();
' Back to the center if object is lost if turret_h > 0 then turret_h = turret_h - 1 if turret_h < 0 then turret_h = turret_h + 1 if turret_v > turret_v_initial then turret_v = turret_v - 1 if turret_v < turret_v_initial then turret_v = turret_v + 1
можно и кинект, хотя у него предостаточно минусов. есть ещё asus xtion, в некоторых моментах он даже поприятней будет. а можно и просто hd вебкамеру или обычную cctv взять.
Если честно - у меня ощущение, что это далеко не предел для AVM Navigator, по крайней мере потенциал у алгоритма огромный, но и есть над чем работать. Ближайшее время завершим типовую доступную платформу для дальнейшего развития проекта. Кроме того - скорее всего сделаем компактную недорогую платформу для алгоритма.
Проект [[Open Robotics]] - Универсальные модули для построения роботов