PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmierbeispiele - Benötige Hilfe



Starbase 12
02.01.2010, 14:17
Bitte um Hilfe!!!


Hallo zusammen,

auch ich habe mir zu Weihnachten den NiboBee gekauft und habe mich sofort ans Zusammenlöten ranbegeben. Als es dann aber in Richtung Programmieren ging, wurde mein Enthusiasmus etwas (wie soll ich sagen?) gebremst. ](*,)

Ich habe mir in dem Programmier-Tutorial alles angeschaut, einiges durchgelesen und/oder abgetippt. Dabei habe ich das ein oder andere Mal auch etwas verändert. Den Grundaufbau der erforderlichen Programmierung verstehe ich also.

Ich hatte davor noch nie großartig mit Programmieren zu tun. Trotzdem fasziniert mich die Robotik und das Drum-Herum sehr.


Zu meinem eigentlichen Problem:

Ich möchte gerne ein Programm schreiben, das in den Grundzügen dem aus dem Tutorial (Hindernisdetektion) entspricht. Hinzu soll aber noch kommen, dass erkannt wird, wenn sich mein Nibo einer Tischkante o.ä. nähert und dann Stopt bzw. ein Stück zurück fährt und die Richtung dementsprechend ändert. Zu Anfang genügt es aber, wenn er einfach anhält.

Könnte mir jemand evtl. ein Programm schreiben, welches das ermöglicht oder erwarte ich einfach zu viel? Für mich als leien wäre es eine Arbeit von Tagen. Vielleicht gibt es aber welche, die sowas vielleicht schon gemacht haben und es netterweise mitteilen, oder jemanden, für den es eine Sache von 5 Minuten ist um so ein Programm abzuändern.


Über Antworten freue ich mich ;-)

Ps: Nachträglich einen guten Rutsch!


Mit freundlichen Grüßen,

Christian




TEILWEISE ABGEÄNDERT: "HINDERNISDETEKTION" (Aus dem Programmier-Tutorial)

#include <nibobee/iodefs.h>
#include <nibobee/motpwm.h>
#include <nibobee/delay.h>
#include <nibobee/sens.h>
#include <nibobee/line.h>
enum {
MODE_STOP,
MODE_DRIVE,
MODE_BACK,
MODE_STEER_R,
MODE_STEER_L,
MODE_AVOID_R,
MODE_AVOID_L
};
int16_t speed_l;
int16_t speed_r;
uint16_t counter_ms;
uint8_t perform_check(uint8_t mode);
uint8_t do_stop();
uint8_t do_drive();
uint8_t do_back();
uint8_t do_steer_r();
uint8_t do_steer_l();
uint8_t do_avoid_r();
uint8_t do_avoid_l();
int main() {
motpwm_init();
sens_init();
line_init();
uint8_t mode;
while(1==1) {
enable_interrupts();
delay(1);
mode = perform_check(mode);
switch (mode) {
case MODE_STOP: mode = do_stop(); break;
case MODE_DRIVE: mode = do_drive(); break;
case MODE_BACK: mode = do_back(); break;
case MODE_STEER_R: mode = do_steer_r(); break;
case MODE_STEER_L: mode = do_steer_l(); break;
case MODE_AVOID_R: mode = do_avoid_r(); break;
case MODE_AVOID_L: mode = do_avoid_l(); break;
}
switch (mode) {
case MODE_STOP: speed_l = 0; speed_r = 0;
break;
case MODE_DRIVE: speed_l = 700; speed_r = 700;
break;
case MODE_BACK: speed_l = -500; speed_r = -500;
break;
case MODE_STEER_R: speed_l = 600; speed_r = 400;
break;
case MODE_STEER_L: speed_l = 400; speed_r = 600;
break;
case MODE_AVOID_R: speed_l = -400; speed_r = -600;
break;
case MODE_AVOID_L: speed_l = -600; speed_r = -400;
break;
}
motpwm_setLeft(speed_l);
motpwm_setRight(speed_r);
}
return 0;
}
uint8_t perform_check(uint8_t mode) {
if (sens_getLeft() && sens_getRight()) {
if ((sens_getLeft()==-1) && (sens_getRight()==-1)) {
mode = MODE_BACK;
} else {
mode = MODE_STOP;
}
}
return mode;
}
uint8_t do_stop() {
if ((sens_getLeft()==0) && (sens_getRight()==0)) {
return MODE_DRIVE;
}
return MODE_STOP;
}
uint8_t do_back() {
if (sens_getLeft()==0) {
return MODE_AVOID_L;
}
if (sens_getRight()==0) {
return MODE_AVOID_R;
}
return MODE_BACK;
}
uint8_t do_drive() {
if (sens_getRight()==1) {
return MODE_STEER_L;
}
if (sens_getLeft()==1) {
return MODE_STEER_R;
}
if (sens_getRight()==-1) {
return MODE_AVOID_L;
}
if (sens_getLeft()==-1) {
return MODE_AVOID_R;
}
return MODE_DRIVE;
}
uint8_t do_steer_r() {
if (sens_getLeft()==0) {
return MODE_DRIVE;
}
return MODE_STEER_R;
}
uint8_t do_steer_l() {
if (sens_getRight()==0) {
return MODE_DRIVE;
}
return MODE_STEER_L;
}
uint8_t do_avoid_r() {
if (counter_ms==0) {
counter_ms=1000;
} else {
counter_ms--;
}
if (counter_ms) {
return MODE_AVOID_R;
} else {
return MODE_DRIVE;
}
}
uint8_t do_avoid_l() {
if (counter_ms==0) {
counter_ms=1000;
} else {
counter_ms--;
}
if (counter_ms) {
return MODE_AVOID_L;
} else {
return MODE_DRIVE;
}
}

m125
02.01.2010, 16:22
Hallo,

ich habe den Nibobee auch erst einige Wochen und bin auch noch am probieren. Ich kann die zwar nicht mit deinem Problem helfen, aber ich habe ein Programm, bei dem der Nibobee bei erreichen einer Tischkante anhält. Vielleicht kannst du ja damit etwas anfangen.



#include <nibobee/iodefs.h>
#include <nibobee/motpwm.h>
#include <nibobee/led.h>
#include <nibobee/line.h>

int main()
{
motpwm_init();
led_init();
line_init();

while(1==1)
{
enable_interrupts();
int16_t speed_l=0;
int16_t speed_r=0;
int16_t lval = line_get(LINE_L);
int16_t cval = line_get(LINE_C);
int16_t rval = line_get(LINE_R);

if
(lval+cval+rval < 200)
{
led_set(LED_L_RD, 0);
led_set(LED_R_RD, 0);
speed_r=0, speed_l=0;
}
else
{
led_set(LED_L_RD, 1);
led_set(LED_R_RD, 1);
speed_r=400, speed_l=400;
}
motpwm_setLeft(speed_l);
motpwm_setRight(speed_r);
}

return 0;

}


Viele Grüße,
Manuel

gagu1
02.01.2010, 17:36
Ich habe ein Programm gebastelt, welches den Nibobee im Kreis fahren lässt. Stösst er auf ein Hindernis oder bleibt er stecken (Motor steht still), so versucht er sich durch Rückwärtsfahren und Drehen zu befreien.


/* NIBOBee fährt nach Fühleranstoß im Kreis. Stößt er an oder bleibt ein Motor hängen, so setzt er kurz zurück */

#include <nibobee/iodefs.h>
#include <nibobee/sens.h>
#include <nibobee/motpwm.h>
#include <nibobee/led.h>
#include <nibobee/delay.h>
#include <nibobee/odometry.h>

/* Funktionen zur Steuerung der Fahrt
fahre(1) - im Uhrzeigersinn,
fahre(-1) - gegen die Uhr,
fahre(0) - rückwärts,
rote Lampe leuchtet auf der Kurven- Innen- Seite */
int fahre(int8_t richtung) {
switch(richtung) {
case 1:
motpwm_setLeft(400); /* Kreis im Uhrzeigersinn */
motpwm_setRight(350);
led_set(LED_L_RD, 0);
led_set(LED_R_RD, 1);
break;
case -1: /* Kreis gegen die Uhr */
motpwm_setLeft(350);
motpwm_setRight(400);
led_set(LED_L_RD, 1);
led_set(LED_R_RD, 0);
break;
case 0: /* volle Kraft zurück */
motpwm_setLeft(-1024);
motpwm_setRight(-1024);
led_set(LED_L_RD, 1);
led_set(LED_R_RD, 1);
delay(800);
motpwm_setLeft(1000); /* und ein bischen drehen */
motpwm_setRight(-1000);
delay(150);
break;
}
return 0;
}

/* Hauptprogramm */
int main() {
motpwm_init();
sens_init();
enable_interrupts();
odometry_init();

int odo_l = 0; /* Variablen für die Odometriezählwerte */
int odo_l_merk = 0;
int odo_r = 0;
int odo_r_merk = 0;
int loop = 0; /* Variable, die bei jedem Programmdurchlauf erhöht wird */

/* warte, bis ein Fühler betätigt wird */
while((sens_getLeft()==0) && (sens_getRight()==0));

/* jetzt gehts los! */
while(1==1) { /* Endlosschleife */
switch (sens_getLeft()) { /* linker Fühler */
case 1: fahre(1);
break;
case -1: fahre(0); /* bin angestoßen, also zurück */
delay(500);
fahre(1);
break;
}
switch (sens_getRight()) { /* rechter Fühler */
case 1: fahre(-1);
break;
case -1: fahre(0); /* bin angestoßen, also zurück */
delay(500);
fahre(-1);
break;
}
loop++; /* Programmdurchläufe zählen, als Ersatz für Zeitgeber */
odo_l = odometry_getLeft(0); /* Odometrie einlesen */
odo_r = odometry_getRight(0);

/* prüfe bei jedem 10000sten Durchlauf ob der Odowert sich auch geändert hat,
also der Motor noch drehen kann */
if (loop == 10000) { /* diesen Wert habe ich einfach ausprobiert */
if (odo_l == odo_l_merk) { /* linker Motor steht */
fahre(0); /* fahre rückwärts */
fahre(-1); } /* fahre weiter im Kreis */
odo_l_merk = odo_l;
if (odo_r == odo_r_merk) { /* dito für den rechten Motor */
fahre(0);
fahre(1); }
odo_r_merk = odo_r;
loop = 0;
} ;

if ((odo_l/10)%2) led_set(LED_L_YE, 1); /* laß die gelben Lampen blinken, je nach Odometer */
else led_set(LED_L_YE, 0);
if ((odo_r/10)%2) led_set(LED_R_YE, 1);
else led_set(LED_R_YE, 0);
}
return 0;
}

m125
02.01.2010, 17:45
Ich habe ein Programm gebastelt, welches den Nibobee im Kreis fahren lässt. Stösst er auf ein Hindernis oder bleibt er stecken (Motor steht still), so versucht er sich durch Rückwärtsfahren und Drehen zu befreien.


/* NIBOBee fährt nach Fühleranstoß im Kreis. Stößt er an oder bleibt ein Motor hängen, so setzt er kurz zurück */

#include <nibobee/iodefs.h>
#include <nibobee/sens.h>
#include <nibobee/motpwm.h>
#include <nibobee/led.h>
#include <nibobee/delay.h>
#include <nibobee/odometry.h>

/* Funktionen zur Steuerung der Fahrt
fahre(1) - im Uhrzeigersinn,
fahre(-1) - gegen die Uhr,
fahre(0) - rückwärts,
rote Lampe leuchtet auf der Kurven- Innen- Seite */
int fahre(int8_t richtung) {
switch(richtung) {
case 1:
motpwm_setLeft(400); /* Kreis im Uhrzeigersinn */
motpwm_setRight(350);
led_set(LED_L_RD, 0);
led_set(LED_R_RD, 1);
break;
case -1: /* Kreis gegen die Uhr */
motpwm_setLeft(350);
motpwm_setRight(400);
led_set(LED_L_RD, 1);
led_set(LED_R_RD, 0);
break;
case 0: /* volle Kraft zurück */
motpwm_setLeft(-1024);
motpwm_setRight(-1024);
led_set(LED_L_RD, 1);
led_set(LED_R_RD, 1);
delay(800);
motpwm_setLeft(1000); /* und ein bischen drehen */
motpwm_setRight(-1000);
delay(150);
break;
}
return 0;
}

/* Hauptprogramm */
int main() {
motpwm_init();
sens_init();
enable_interrupts();
odometry_init();

int odo_l = 0; /* Variablen für die Odometriezählwerte */
int odo_l_merk = 0;
int odo_r = 0;
int odo_r_merk = 0;
int loop = 0; /* Variable, die bei jedem Programmdurchlauf erhöht wird */

/* warte, bis ein Fühler betätigt wird */
while((sens_getLeft()==0) && (sens_getRight()==0));

/* jetzt gehts los! */
while(1==1) { /* Endlosschleife */
switch (sens_getLeft()) { /* linker Fühler */
case 1: fahre(1);
break;
case -1: fahre(0); /* bin angestoßen, also zurück */
delay(500);
fahre(1);
break;
}
switch (sens_getRight()) { /* rechter Fühler */
case 1: fahre(-1);
break;
case -1: fahre(0); /* bin angestoßen, also zurück */
delay(500);
fahre(-1);
break;
}
loop++; /* Programmdurchläufe zählen, als Ersatz für Zeitgeber */
odo_l = odometry_getLeft(0); /* Odometrie einlesen */
odo_r = odometry_getRight(0);

/* prüfe bei jedem 10000sten Durchlauf ob der Odowert sich auch geändert hat,
also der Motor noch drehen kann */
if (loop == 10000) { /* diesen Wert habe ich einfach ausprobiert */
if (odo_l == odo_l_merk) { /* linker Motor steht */
fahre(0); /* fahre rückwärts */
fahre(-1); } /* fahre weiter im Kreis */
odo_l_merk = odo_l;
if (odo_r == odo_r_merk) { /* dito für den rechten Motor */
fahre(0);
fahre(1); }
odo_r_merk = odo_r;
loop = 0;
} ;

if ((odo_l/10)%2) led_set(LED_L_YE, 1); /* laß die gelben Lampen blinken, je nach Odometer */
else led_set(LED_L_YE, 0);
if ((odo_r/10)%2) led_set(LED_R_YE, 1);
else led_set(LED_R_YE, 0);
}
return 0;
}



Hallo,

habe dein Programm ausprobiert, jedoch leuchten bei mir die Leds nur schwach. Bei anderen Programmen funktionieren sie einwandfrei.
Weiß jemand Rat?

Viele Grüße,
Manuel

Starbase 12
02.01.2010, 18:12
Hallo Leute,

vielen Dank für eure Antworten. Sie haben mir sehr geholfen. Ich bin überrascht, dass es welche gibt, die sich tatsächlich total gut damit auskennen.

Also noch einmal vielen, vielen Dank an alle!

Wer möchte kann natürlich noch weitere Programme posten. Ich denke, dass sich noch viele andere darüber freuen werden.


MfG Christian

m125
02.01.2010, 18:31
Hallo,

habe jetzt auch mein Problem im obigen Programm mit den schwachen Leds gelöst. Im Hauptprogramm fehlt noch led_init();

Viele Grüße,
Manuel

Marlon
03.01.2010, 02:20
Mein Programm kann genau dass was du willst:
An Tischkanten/Hindernissen anhalten,zurückfahren und drehen.
Ausserdem sucht es einen Weißen Punkt und hält da an.
Das Programm ist komplett selbst geschrieben weil mir das Beispielprogramm in dem Tuorial einfach zu kompliziert und undurchsihchtig war.

Jedoch habe ich einen weiteren Testsensot eingebaut weil meine Biene sich immer an Tischbeinen etc festgefahren hat (keine auslösung der Taster).
Dieser neue Taster wurde in die Libaries eingearbeitet wie die anderen nur als sens_getCenter().
Jedoch hab ich damit noch einige Probleme weil ich den nicht genauso ansprechen kann wie die anderen. In meinem Code geht es nur mit der if anweisung
Jedoch nicht mit so wie zB bei sens_getCenter() in der check() Funktion.
Vieleicht kann sich das ja jemand mal anschauen. Und mir erklären was ich falsch gemacht habe, bzw wie es besser geht (immerhin funzt es ja^^)

Programm:


#include <nibobee/iodefs.h>
#include <nibobee/motpwm.h>
#include <nibobee/delay.h>
#include <nibobee/sens.h>
#include <nibobee/led.h>
#include <nibobee/odometry.h>
#include <nibobee/line.h>

#define speed 500



uint8_t check()
{
if ((sens_getLeft()==0) && (sens_getRight()==0))
{
return (0);
}

if ((sens_getLeft()==-1) && (sens_getRight()==-1))
{
return (1);
}

if ((sens_getLeft()==-1) && (sens_getRight()==0))
{
return (2);
}

if ((sens_getLeft()==0) && (sens_getRight()==-1))
{
return (3);
}

if ((sens_getLeft()==1) && (sens_getRight()==0))
{
return (4);
}

if ((sens_getLeft()==0) && (sens_getRight()==1))
{
return (5);
}
return(0);
}

int right(int time,int backtime)
{
motpwm_setLeft(0);
motpwm_setRight(0);
delay(200);
motpwm_setLeft(-400);
motpwm_setRight(-400);
delay(backtime);
motpwm_setLeft(-300);
motpwm_setRight(300);
delay(time);
motpwm_setLeft(0);
motpwm_setRight(0);
return(0);
}

int left(int time,int backtime)
{
motpwm_setLeft(0);
motpwm_setRight(0);
delay(200);
motpwm_setLeft(-400);
motpwm_setRight(-400);
delay(backtime);
motpwm_setLeft(300);
motpwm_setRight(-300);
delay(time);
motpwm_setLeft(0);
motpwm_setRight(0);
return(0);
}

void end()
{
motpwm_stop();
while(1==1)
{
led_set(LED_L_RD,1);
led_set(LED_R_RD,1);
led_set(LED_L_YE,1);
led_set(LED_R_YE,1);
delay(300);
led_set(LED_L_RD,0);
led_set(LED_R_RD,0);
led_set(LED_L_YE,0);
led_set(LED_R_YE,0);
delay(300);
}
}

int main()
{
motpwm_init();
sens_init();
led_init();
odometry_init();
enable_interrupts();
line_init();
uint8_t mode;
uint16_t step;
uint16_t moto=speed;

int countdown;

for(countdown=2000;countdown>10; countdown/=1.5)
{
led_set(LED_L_RD,1);
delay(countdown/2);
led_set(LED_L_RD,0);
led_set(LED_R_RD,1);
delay(countdown/2);
led_set(LED_R_RD,0);
}
odometry_reset();


while(1==1)
{


for(step=0;step<5000;step++)
{
mode=check();
switch (mode)
{
case 1: right(600, 600); break;
case 2: left (600, 600); break;
case 3: left (1200,600); break;
case 4: left (200, 100); break;
case 5: right(200, 100); break;
case 0: motpwm_setRight(speed);motpwm_setLeft(moto);break;
}
if (sens_getCenter()==1) {right(600, 1000);}

if ((line_get(LINE_L)<50)||(line_get(LINE_C)<50)||(line_get(LINE_R)<50)){right(1200,600);}
if ((line_get(LINE_L)>900)||(line_get(LINE_C)>900)||(line_get(LINE_R)>900)){end(0);}
}

if((odometry_getLeft(0)) < (odometry_getRight(0))) {moto=moto+10;}
if((odometry_getLeft(0)) > (odometry_getRight(0))) {moto=moto-10;}

if((odometry_getLeft(0)==0)||(odometry_getRight(0) ==0))
{
motpwm_setRight(-800);motpwm_setLeft(-800);
delay(2000);
odometry_reset();
}
else
{
odometry_reset();
}
}
return(0);
}


sens.c

#include "nibobee/iodefs.h"
#include "nibobee/sens.h"
#include "nibobee/extern.h"

#ifdef __cplusplus
extern "C" {
#endif



void sens_init() {
set_output_group(IO_SENS);
set_output_groupbit(IO_EXT,IO_EXT_BIT_0);
extern_init();
}

int8_t sens_getLeft () {
uint8_t val = IO_SENS_PIN & (_BV(IO_SENS_BIT_LEFT1) | _BV(IO_SENS_BIT_LEFT2));
if (val==_BV(IO_SENS_BIT_LEFT1)) return -1;
if (val==_BV(IO_SENS_BIT_LEFT2)) return 1;
return 0;
}

int8_t sens_getRight ()
{
uint8_t val = IO_SENS_PIN & (_BV(IO_SENS_BIT_RIGHT1) | _BV(IO_SENS_BIT_RIGHT2));
if (val==_BV(IO_SENS_BIT_RIGHT1)) return -1;
if (val==_BV(IO_SENS_BIT_RIGHT2)) return 1;
return 0;
}
int8_t sens_getCenter()
{
if (PINA & (1<<1))
{
return(1);
}
else
{
return(0);
}
}

extern.h

void extern_init()
{
DDRA = 0x01000000;
PORTA= 0x01000000;
}

Starbase 12
03.01.2010, 11:07
Danke Marlon,

wie ist das doch gleich mit den genauen Projekteinstellungen?
Bevor man sein Projekt beginnt zu schreiben muss man doch u.a. irgendeine
genaue Reihenfolge festlegen (libnibobee_line.a, libnibobee_base.a, libnibobee_utils.a).

Bei welchen Programmen muss diese Reihenfolge geändert werden? Nur sobald man die Linien-Sensoren mit lädt?


LG Christian

gagu1
03.01.2010, 17:56
Danke Manuel (m125), den init der LEDs hatte ich vergessen.

Marlon
03.01.2010, 19:10
die Reihenfolge ist schon richtig zumindestens funktioniert sie bei mir.

Starbase 12
03.01.2010, 19:17
die Reihenfolge ist schon richtig zumindestens funktioniert sie bei mir.ja okay. Thx

waschtl
03.01.2010, 20:11
Nabend,
ich wollte für meinen Blödsinn nicht noch n extra Thread aufmachen, und paks einfach mal hier mit rein. Ist absolut sinnfrei und die Idee kam mir gerade beim Fernsehen.

Meine Biene denkt sie wäre KITT (http://de.wikipedia.org/wiki/Knight_Rider#K.I.T.T.) :-b



#include <nibobee/iodefs.h>
#include <nibobee/led.h>
#include <nibobee/delay.h>

int main(){
led_init();
uint8_t dir = 0; //Richtung 0-> von links nach recht
// 1-> von rechts nach links
while(1){
if (dir == 0){
for (uint8_t i=0; i<5; i++){
for (uint8_t j=0; j<5; j++){ // LEDs zurücksetzten
led_set(j, 0);
}
led_set(i, 1);
delay(100);
}
dir=1;
}
else{
for (uint8_t i=5; i>0; i--){
for (uint8_t j=0; j<5; j++){ //LEDs zurücksetzen
led_set(j-1, 0);
}
led_set(i, 1);
delay(100);
}
dir=0;
}
}
return 0;
}