Hallo!
mein Projekt findet ihr auf http://arips.roboterbastler.de/?Software:Firefighting , das Video gibts auch hier: http://www.youtube.com/watch?v=rSiB5mmOxaI
MfG Mark
Druckbare Version
Hallo!
mein Projekt findet ihr auf http://arips.roboterbastler.de/?Software:Firefighting , das Video gibts auch hier: http://www.youtube.com/watch?v=rSiB5mmOxaI
MfG Mark
Hallo alle zusammen !!
Hier ist also mein Projekt, mein Ziel war es das projekt so einfach wie möglich zu verwirklichen (das suche und das löschen ohne großes umbauen).
Prinzip: Der RP6 fährt in einem 1*1 Meter größen Areal herum, und orientiert sich mit hilfe der Bumper. Die Wände bestehen aus Schweisserdraht der mithilfe von Klebeband am Boden fixiert ist. Kommt ein Teelicht vor den RP6 erkennt er se durch seine Infrarotsensoren, alle LEDs gehen an und das Servo schließt den Stromkreis durch einen Kipp-Schalter und das Teelicht wird durch den Motor ausgeblasen. Leider musste ich eine Externe Stromquelle für den Motor nehmen, da der RP6 (VDD, GND) bei jedem Motorstart Abstürtzte (denselben Fehler hatte ich aber auch schon bei Großen Servos).
Hier das Video: http://www.youtube.com/watch?v=o2okdm7lwEE
Der Code:
So das war's !Code:#include "RP6RobotBaseLib.h"
uint8_t c;
void teelicht(void)
{
if (!obstacle_left && !obstacle_right && !bumper_left && !bumper_right) //wenn keine Hindernisse vorliegen
{
changeDirection(FWD);
moveAtSpeed(75,75);
}
if (obstacle_left && obstacle_right) //Haben die Infrarotsensoren ein Teelicht geortet
{
DDRC |= SCL;
PORTC &= ~SCL;
setLEDs(0b111111);
move(90, FWD, DIST_MM(50), BLOCKING);
for(c=0; c<50; c++) //Servoposition 1
{
PORTC |= SCL;
sleep(12);
PORTC &= ~SCL;
sleep(190);
}
setLEDs(0b100100); //LEDs blinken im Sekundentakt bis das Teelicht gelöscht ist
mSleep(1000);
setLEDs(0b010010);
mSleep(1000);
setLEDs(0b001001);
mSleep(1000);
setLEDs(0b000000);
for(c=0; c<50; c++) //Servo zurück
{
PORTC |= SCL;
sleep(9);
PORTC &= ~SCL;
sleep(190);
}
move(80, BWD, DIST_MM(100), BLOCKING);
rotate(80, RIGHT, 30, BLOCKING);
}
if (bumper_left) //ist der Linke Bumper gedrückt
{
move(80, BWD, DIST_MM(100), BLOCKING);
rotate(80, RIGHT, 110, BLOCKING);
}
if (bumper_right) //ist der Rechte Bumper gedrückt
{
move(80, BWD, DIST_MM(100), BLOCKING);
rotate(80, LEFT, 110, BLOCKING);
}
if (bumper_left && bumper_right) //sind beide Bumper gedrückt
{
move(80, BWD, DIST_MM(100), BLOCKING);
rotate(80, LEFT, 110, BLOCKING);
}
}
int main(void)
{
initRobotBase();
powerON();
setACSPwrLow(); // ACS auf geringe entfernung einstellen
while(true)
{
teelicht();
task_RP6System();
}
return 0;
}
Gruß Fabi
Hallo
Mein Projekt ist nun zumindest vom Bau und von der Programmierung fertig. Ich habe das Projekt mit den Sichtsensoren umgesetzt und das gesammte Programm nur für die Base geschrieben. Verwendet werden nur 2 kleine Servos. Davon 1 zum Steuern der Luftzufuhr zum Löschen und 1 zum gewegen des Luftschlauches.
Zur Funktion kann ich nur sagen, dass ich das Programm ohne Luft (also ohne Löschen) ausprobiert habe und es findet die Teelichter.
Das Problem besteht jetzt nur darin, dass der Roboter bei jedem Versuch ein Programm zu starten abstürtzt. Noch viel blöder ist, dass das glaube ich meine Schuld ist. Denn da ich das Pneumatikventil nicht rechtzeitig bekommen habe, musst ich auf einen Eigenbau umsteigen und wie ich diesen ausprobieren wollte habe ich einen Kurzschluss auf der Platine produziert.
Nun wird der Roboter von Conrad eingeschickt und wird hoffentlich bald wieder zurückkommen.
MFG
Xandi
Hi,
ich muss leider sagen, dass ich nicht über ein paar Zeichnungen hinausgekommen bin. Ich hatte einfach nicht genug Zeit und war dazu noch viel unterwegs...
Ich bin aber auf jeden Fall sehr begeistert von den Projekten, die bisher präsentiert wurden!!!
Viele Grüße,
jon
Hallo
Bild hier
Aus Zeitgründen habe ich es leider nicht geschafft eine vernünftige Software zu erstellen. Nach Druck auf den linken Bumper wird das hellste Teelicht im Blickbereich angesteuert und beschossen, ein Druck auf den rechten Bumper wiederholt den Schuss. Mein Konzept funktioniert nur im Halbdunkel, aber bei strahlender Sonne braucht man eh keine Teelichter;)
Sensor ist die Projekt-Cam, Ausbläser ist ein Luftballon auf einem PET-Flaschenrest der mit einer Wäscheklammer und zwei Servos gespannt und abgeschossen wird:
Bild hier Bild hier Bild hier
http://www.youtube.com/watch?v=qgmKWWT4lps
http://www.youtube.com/watch?v=l79jabBqgo0
Helferleinkatze ist natürlich auch mit dabei ;)
GrußCode:// Teelicht löschen mit RP6 12.4.2010 mic
#include "RP6RobotBaseLib.h"
#define auf 30
#define zu 12
#define aus 0
#define spannen 14
#define holen 38
uint8_t klammer=0, ziehen=0; // Servos aus
void init(void);
void setMotorPWM(uint8_t power_links, uint8_t power_rechts);
uint16_t richtung(void);
void schuss(void);
int main(void)
{
init();
while(1)
{
writeInteger(richtung(), 10);
writeString_P("\n");
setLEDs(63); // ready
do
{
schuss();
while(!(getBumperRight() || getBumperLeft())); // weiteren Schuss auslösen
}
while(!getBumperLeft()); // nächste Kerze
}
return(0);
}
ISR (TIMER1_OVF_vect)
{
static uint16_t servocount=1;
if(servocount > klammer) PORTC &= ~SCL; else PORTC |= SCL; // PC0 XBUS 10
if(servocount > ziehen) PORTC &= ~SDA; else PORTC |= SDA; // PC1 XBUS 12
if(servocount < 400) servocount++; else servocount=1;
}
void init(void)
{
initRobotBase();
DDRC |= (SCL | SDA); // Servopins auf Ausgang setzen
TIMSK |= (1 << TOIE1); // Die Timer1 Overflow-ISR zur Servoansteuerung
extIntOFF(); // schaltet den E_INT1-Port auf Eingang für den ADC
// ADC interne Referenz 2,56V, Ergebniss linksbündig, Kanal ADC4 (E_INT1)
ADMUX = (1<<REFS1) | (1<<REFS0) | (1<<ADLAR) | 4;
// setzte free running triggern
SFIOR = (0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// kein interupt, Wandler einschalten, prescaller /2
ADCSRA = (0<<ADIE) | (1<<ADEN) | (0<<ADPS2) | (0<<ADPS1) | (1<<ADPS0);
// Autotriggern bedeutet jetzt free running aktivieren, altes Flag löschen
ADCSRA |= (1<<ADATE) | (1<<ADIF);
// Initialisierung starten
ADCSRA |= (1<<ADSC);
// und noch die wohl eher unnötige Initiallesung
while (!(ADCSRA & (1<<ADIF)));
ADCSRA |= (1<<ADIF);
//powerON();
}
// Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
{
extern uint8_t mleft_ptmp, mright_ptmp;
if(power_links > 210) power_links = 210;
if(power_rechts > 210) power_rechts = 210;
mleft_power=mleft_ptmp=power_links;
mright_power=mright_ptmp=power_rechts;
OCR1BL = power_links;
OCR1AL = power_rechts;
if(power_links || power_rechts)
TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
else
TCCR1A = 0;
}
uint16_t richtung(void)
{
uint8_t bildspeicher[100], *bildzeiger; // 100 Byte Bildspeicher sollten reichen
uint8_t zeile, sync, c; // und dürfen NICHT global sein!
uint16_t spalte_max, spaltenwerte[12];
writeString_P("-------------------------\n");
do
{
spalte_max=0;
for(c=0; c<12; c++)
{
setLEDs(c); // working
bildzeiger=&bildspeicher[0]; // Zeiger auf Start des Bildspeicherbereich
zeile=c*20+35; // aktuelle Zeile (35 Zeilen sind der Schrott beim Bildstart)
cli();
do // Warten auf langen Syncbereich = Bildstart
{
sync=0;
while (ADCH > 20); // warten solange Bilddaten erkannt werden
while (ADCH < 30) sync++; // Länge des Sync-Signal zählen
}while (sync < 40); // größer 40 bedeutet Bildstart
while(zeile--)
{
while (ADCH > 20); // Bilddaten
while (ADCH < 30); // Sync
}
do *bildzeiger=ADCH; while(*bildzeiger++ > 20); // schnelle Zeile einlesen
sei();
spaltenwerte[c]=0;
for(zeile=0; zeile<48; zeile++) // 64 Pixel zusammenzählen
{
spaltenwerte[c]+=bildspeicher[zeile];
setLEDs(zeile);
}
if(spaltenwerte[c] > spalte_max) spalte_max=spaltenwerte[c];
}
for(c=0; c<12; c++) // größten Spaltenwert suchen
{
if(spaltenwerte[c] == spalte_max) spalte_max=c;
}
writeString_P("hellste Spalte: ");
writeInteger(spalte_max, 10);
writeString_P(" Spaltenwert: ");
writeInteger(spaltenwerte[spalte_max], 10);
writeString_P("\n");
//if(spaltenwerte[spalte_max] > 3000)
{
if(spalte_max > 6) {setMotorDir(FWD,FWD); setMotorPWM(100,0);}
else if(spalte_max <6) {setMotorDir(BWD,FWD); setMotorPWM(100,0);}
//mSleep(200);
//setMotorPWM(0,0);
//mSleep(500);
else setMotorPWM(0,0);
}
}while(spalte_max !=6);
return(spaltenwerte[spalte_max]); // Summenhelligkeit der Spalte
}
void schuss(void)
{
klammer=auf;
mSleep(500);
ziehen=holen;
mSleep(500);
klammer=zu;
mSleep(300);
ziehen=spannen;
mSleep(500);
klammer=auf;
mSleep(200);
klammer=zu;
mSleep(200);
klammer=0;
}
mic
[Edit]
Ich hab's zerlegt, weil der Ballon kaputt ging. Der kleine Knubbel war im Ballon als Greifpunkt für die Klammer. Das Sieb stammt aus einem Kaffeepad.
Vielleicht bin ich nicht ganz richtig hier im thread, weil ich ja beim Wettbewerb nicht mitgemacht habe.
@radbruch: Ich will aber trotzdem loswerden, wie stark ich Deine Luftspritze finde. Ich mußte zweimal hinschauen; zusammen mit den Ohren und der Beschreibung ließ es sich dann doch einordnen.
Die Lösung hat einfach was. Bin echt beeindruckt. Bild hier
Gruß
Searcher
Hallo
Schade das es nur so wenige Projektpräsentationen gab...
Trotzdem beginnt jetz das Voting also schickt mir bitte als PM eure Meinung wer 1 oder 2 Punkte bekommt (siehe Seite 1 Regeln)
Weitere Projekte können selbstverständlich vorgestellt werden.
Auch die Projektansätze können bewertet werden!
Gruß Thund3r
Das klingt gut, ich habe gestern noch wie verrückt versucht das zum laufen zu bekommen, auch das Video bekomme ich nicht hochgeladen. Ich kann gerne ein paar Fotos online stellen und würde auch gerne noch versuchen das Video online zu stellen.
Mein Projekt funktioniert leider nicht perfekt, ich bin auch noch nicht lange mit dem RP6 vertraut. (Er löscht die Teelichter jedenfalls alle, der Löschvorgang startet nur ein wenig zu oft da ich Probleme mit dem Einstellen der Temperaturwerte habe.
Vielleicht kann mir jemand von euch helfen, ich habe ein 70 Mb großes MP4 Video, das ich hochladen will. Geht das Format und die Größe?
Noch was zum Schema:
Der Roboter fährt eine "8" und misst dabei dauerhaft die Temperaturwerte mittels eines Temperatursensors, der über einen Servomotor positioniert wird. Hat er einen auffälligen Wert gefunden hält er an, richtet sich zur Wärmequelle aus und startet den Löschvorgang.
Danach wird geprüft ob noch ein Feuer vorhanden ist, wenn nicht setzt er die Suchfahrt weiter fort.
Hallo
Ich habe keine Bewertungen abgegeben, weil meiner Meinung nach jeder der es schafft auch ein Gewinner ist.
Für Thund3r spende ich allerdings einen Sonderpunkt für die Organisation des Wettbewerbs.
Gruß
mic