/* *************************************************************** MODULE: walker AUTOR: Rainer Leonhardt, Uni Stuttgart, 12. May 1997 CHANGES: Thomas Braunl, UWA, 30. Oct. 1997 Thomas Braunl, UWA, 28. Feb. 2000 FUNCITION: This module contains a accumulation of routines to control the walker and always one more routine just to display a menu suitable to the current controllroutine of the walker. basic procedures: layer2: -ultrasonicLeft and ultrasonicRight are two routines, each returns a distance-value for it's side. Parameters are not necessery -liftleg is a funktion that moves a leg of the 6-legged walker to a specified angle in vertical dimension, in a direction, independent on which side or position it occures. Parameters are the Side, Posiotion and Angle: All are scalar variables -movleg is a funktion that moves a leg of the 6-legged walker to a specified angle in horizontal layer, in a direction, independent on which side or position it occures. Parameters are the Side, Posiotion and Angle: All are scalar variables -CheckUltra is a funktion that checks the left and the right ultrasound-sensor, and if there is no obstacle in a certain distance it returns a true value. layer3: -oneStep,turnRight,turnLeft,backStep are control-datafields, necessery for making those steps. -make_n_steps is a funktion, that moves the legs in such sequences that steps are made. Parameters are one of those controll fields, the length (in states-usually 8) and the numer of runs through this controll field. No Obstaclecheck is made -> Useful for turns -make_n_stepsC is a funktion, that moves the legs in such sequences that steps are made. Parameters are one of those controll fields, the length (in states-usually 8) and the numer of runs through this controll field. The value returne is the number of runs that could be made, an obstacle in the way can interrupt the whole run. -basing on this two items the routines for the layer four are implemented: -beetle_steps, beetle_right, beetle_left, beetle_back, beetle_hi_steps, beetle_hi_right beetle_hi_left, beetle_hi_back There allways exists just one Parameter: The numer of this steps, that is wanted to be made -stillstand, stillhistand are procedures, that make the walker stay on his startposition layer4: -gotoxy this routine shall manage that the walker goes from the from-positions to the to-positions (because of the resolution the positions have to be multiplied with 256), orientation can be a value from 0 to 51 demoprocedures: -walker: The Rootmenu to controll the walker. Submenu points: -mov Menu just to check the moving abilities -go: Menu for different modes to walk -leg: Menu to move one leg in a specific way, i.e. one of the possible 5 positions for the leg can get selected. -svo: Menu to move one servo in degrees -fbl: Menu to check the fumble-sensors -usn: Menu to check the ultrasound *************************************************************** */ #include "eyebot.h" #include #include #define FUM_LF -400 #define FUM_RF -401 #define FUM_LM -402 #define FUM_RM -403 #define FUM_LR -404 #define FUM_RR -405 char z; ServoHandle servohandles[12]; PSDHandle psdhandles[2]; int semas[12] ={SER_LFUD,SER_LFFB,SER_RFUD,SER_RFFB,SER_LMUD,SER_LMFB, SER_RMUD,SER_RMFB,SER_LRUD,SER_LRFB,SER_RRUD,SER_RRFB}; int PSDsemas[2]={PSD_FRONTLEFT,PSD_FRONTRIGHT}; int SDsemas[6] ={FUM_LF,FUM_RF,FUM_LM,FUM_RM,FUM_LR,FUM_RR}; /* Semantics for servos, PSDs and sensing devices */ int x=10,y=10; /* actual pos. in local area, resoultion is 256 */ int Orientation=0; /* the resolution of a circle is 52 */ /********** begining of layer one **********/ /*What to get of layer one */ int OSGetSDSignal() /* This routine returns true if a sensordevice exists and is pressed*/ { return (0); } /********** begining of layer two **********/ #define LEFT 0 /* Legselection values*/ #define RIGHT 1 #define FRONT 10 #define MIDDLE 11 #define REAR 12 #define VUP 5 /* Vertical legposition values */ #define UP 4 /* UP position */ #define CN 3 /* CeNtre */ #define DN 2 /* DowN */ #define VDN 1 /* Very DowN */ #define VBK 5 /* Horizontal legposition values */ #define BK 4 /* BacK */ /* CN 3 CeNtre as in up/down */ #define FN 2 #define VFN 1 /* Very FroNt */ typedef int Side; typedef int Position; /* ultrasonic is a prototype of a routine that returns the distance to an obstacle. There are two routines existant, one for the left side and one for the right side, because there are two ultrasonic-sensors */ int ultrasonicLeft(void) { PSDStart(psdhandles[0], FALSE); /* Start measuringprocess */ while (!PSDCheck()); /* value available */ return(PSDGet(psdhandles[0])); /* return measured value */ } int ultrasonicRight(void) { PSDStart(psdhandles[1], FALSE); /* Start measuringprocess */ while (!PSDCheck()); /* value available */ return(PSDGet(psdhandles[1])); /* return measured value */ } /* The routine liftleg shall lift a Leg on the defined side and Position to a specified angle movleg does the same like liftleg just in the other plane If something went wrong an error is signaled through a one in the return variable */ #define KorrFrLeUD 0 /* The bigger the more up */ #define KorrMiLeUD 0 #define KorrReLeUD 0 #define KorrFrRiUD 0 /* The bigger the more down */ #define KorrMiRiUD 0 #define KorrReRiUD 0 #define KorrFrLeFB 255/2 /* The bigger the more backwards */ #define KorrMiLeFB 255/2 #define KorrReLeFB 255/2 #define KorrFrRiFB 255/2 /* The bigger the more foreward */ #define KorrMiRiFB 255/2 #define KorrReRiFB 255/2 int liftleg(Side side, Position position, int hight) /* if a 0 is returned all is OK */ /* otherwise a 1 is returnde */ { if ((hight>5)||(hight<1)) return(1); hight=hight*40; switch (side) /* in hight value between 1 and 5 */ { /* can get used: 1 is very lo */ case LEFT: /* 5 is very high */ switch (position) { case FRONT: /* Here one Leg is selected, 160 is */ return(SERVOSet(servohandles[0],KorrFrLeUD-hight)); /* the central angle, respectively */ break; /* the correcture-factor */ case MIDDLE: return(SERVOSet(servohandles[4],KorrMiLeUD-hight)); break; case REAR: return(SERVOSet(servohandles[8],KorrReLeUD-hight)); break; } case RIGHT: switch (position) { case FRONT: return(SERVOSet(servohandles[2],KorrFrRiUD+hight)); break; case MIDDLE: return(SERVOSet(servohandles[6],KorrMiRiUD+hight)); break; case REAR: return(SERVOSet(servohandles[10],KorrReRiUD+hight)); break; } } return(1); } int movleg(Side side, Position position, int distance) /* if a 0 is returned all is OK */ /* otherwise a 1 is returnde */ { if ((distance>5)||(distance<1)) return(1); distance=distance*10; switch (side) /* like in hight, distance can be */ { /* a value between 1 and 5 */ case LEFT: /* 1 is very rear, 5 is very front, */ switch (position) /* 3 is the centre */ { case FRONT: return(SERVOSet(servohandles[1],KorrFrLeFB+distance)); break; case MIDDLE: return(SERVOSet(servohandles[5],KorrMiLeFB+distance)); break; case REAR: return(SERVOSet(servohandles[9],KorrReLeFB+distance)); break; } case RIGHT: switch (position) { case FRONT: return(SERVOSet(servohandles[3],KorrFrRiFB-distance)); break; case MIDDLE: return(SERVOSet(servohandles[7],KorrMiRiFB-distance)); break; case REAR: return(SERVOSet(servohandles[11],KorrReRiFB-distance)); break; } } return(1); } int CheckleftUltra(void) /* This routine returns a true value if no obstacle is in front of left PSD It should check the left PSD-sensor and if there is */ { return(ultrasonicLeft()>120); /* no obstacle within 30 mm --> return true */ } int CheckrightUltra(void) /* This routine returns "true" if no obstacle is in front of the walker It should check the right PSD-sensor and if there is */ { return(ultrasonicRight()>120); /* no obstacle within 30 mm --> return true */ } int CheckUltra(void) /* This routine returns a true value if no obstacle is in front of the walker It should check the left and the right ultrasound-sensor and if there is no obstacle whithin a certain distance it should return a true value */ { return(CheckleftUltra()&&CheckrightUltra()); } /********** begin of layer three **********/ /* Thesse are the datas for a standard beetle-onestep in layer 3 */ /* The different states of the walker */ int oneStep[8][6][2]= { /* q1 move a leg-trio forward */ {{DN,BK},{CN,FN}, {CN,FN},{DN,BK}, {DN,BK},{CN,FN}}, /* q2 change legtrio: on the flor in the air */ {{DN,BK},{DN,FN}, {DN,FN},{DN,BK}, {DN,BK},{DN,FN}}, /* q3 */ {{CN,BK},{DN,FN}, {DN,FN},{CN,BK}, {CN,BK},{DN,FN}}, /* q4 The of q0 inverse state / Step */ {{CN,CN},{DN,CN}, {DN,CN},{CN,CN}, {CN,CN},{DN,CN}}, /* q5 */ {{CN,FN},{DN,BK}, {DN,BK},{CN,FN}, {CN,FN},{DN,BK}}, /* q6 change leg-trio back */ {{DN,FN},{DN,BK}, {DN,BK},{DN,FN}, {DN,FN},{DN,BK}}, /* q7 */ {{DN,FN},{CN,BK}, {CN,BK},{DN,FN}, {DN,FN},{CN,BK}}, /* q0 */ {{DN,CN},{CN,CN}, {CN,CN},{DN,CN}, {DN,CN},{CN,CN}} /* restart with q1 or not */ }; /* This are the datas for a standard turn-right in layer 3 */ /* The different states of the walker */ int turnRight[8][6][2]= { /* q1 move a legtrio forward */ {{DN,BK},{CN,BK}, {CN,FN},{DN,FN}, {DN,BK},{CN,BK}}, /* q2 change legtrio: on the flor in the air */ {{DN,BK},{DN,BK}, {DN,FN},{DN,FN}, {DN,BK},{DN,BK}}, /* q3 */ {{CN,BK},{DN,BK}, {DN,FN},{CN,FN}, {CN,BK},{DN,BK}}, /* q4 The of q0 inverse state / Step */ {{CN,CN},{DN,CN}, {DN,CN},{CN,CN}, {CN,CN},{DN,CN}}, /* q5 */ {{CN,FN},{DN,FN}, {DN,BK},{CN,BK}, {CN,FN},{DN,FN}}, /* q6 change legtrio back*/ {{DN,FN},{DN,FN}, {DN,BK},{DN,BK}, {DN,FN},{DN,FN}}, /* q7 */ {{DN,FN},{CN,FN}, {CN,BK},{DN,BK}, {DN,FN},{CN,FN}}, /* q0 */ {{DN,CN},{CN,CN}, {CN,CN},{DN,CN}, {DN,CN},{CN,CN}} /* restart with q1 or not */ }; /* These are the datas for a standard turn left in layer 3 */ /* The different states of the walker */ int turnLeft[8][6][2]= { /* q1 move a legtrio forward */ {{DN,FN},{CN,FN}, {CN,BK},{DN,BK}, {DN,FN},{CN,FN}}, /* q2 change legtrio: on the flor in the air */ {{DN,FN},{DN,FN}, {DN,BK},{DN,BK}, {DN,FN},{DN,FN}}, /* q3 */ {{CN,FN},{DN,FN}, {DN,BK},{CN,BK}, {CN,FN},{DN,FN}}, /* q4 The of q0 inverse state / Step */ {{CN,CN},{DN,CN}, {DN,CN},{CN,CN}, {CN,CN},{DN,CN}}, /* q5 */ {{CN,BK},{DN,BK}, {DN,FN},{CN,FN}, {CN,BK},{DN,BK}}, /* q6 change legtrio back*/ {{DN,BK},{DN,BK}, {DN,FN},{DN,FN}, {DN,BK},{DN,BK}}, /* q7 */ {{DN,BK},{CN,BK}, {CN,FN},{DN,FN}, {DN,BK},{CN,BK}}, /* q0 */ {{DN,CN},{CN,CN}, {CN,CN},{DN,CN}, {DN,CN},{CN,CN}} /* restart with q1 or not */ }; /* This are the datas for a beetle-backstep in layer 3 */ /* The different states of the walker */ int backStep[8][6][2]= { {{DN,FN},{CN,BK}, /* q1 move a legtrio forward */ {CN,BK},{DN,FN}, {DN,FN},{CN,BK}}, {{DN,FN},{DN,BK}, /* q2 change legtrio: on floor in the air */ {DN,BK},{DN,FN}, {DN,FN},{DN,BK}}, {{CN,FN},{DN,BK}, /* q3 */ {DN,BK},{CN,FN}, {CN,FN},{DN,BK}}, {{CN,CN},{DN,CN}, /* q4 The of q0 inverse state / Step */ {DN,CN},{CN,CN}, {CN,CN},{DN,CN}}, {{CN,BK},{DN,FN}, /* q5 */ {DN,FN},{CN,BK}, {CN,BK},{DN,FN}}, {{DN,BK},{DN,FN}, /* q6 change legtrio back*/ {DN,FN},{DN,BK}, {DN,BK},{DN,FN}}, {{DN,BK},{CN,FN}, /* q7 */ {CN,FN},{DN,BK}, {DN,BK},{CN,FN}}, {{DN,CN},{CN,CN}, /* q0 */ {CN,CN},{DN,CN}, {DN,CN},{CN,CN}} /* restart with q1 or not */ }; /* This part is important for the beginning to */ int staysolid[1][6][2]= { {{DN,CN},{DN,CN}, /* give the walker a solid position */ {DN,CN},{DN,CN}, {DN,FN},{DN,CN}} }; /* WARNING: This can break the legs of the old walker*/ /* This are the datas for a high beetle-onestep in layer 3 */ /* The different states of the walker */ /* In this case the walker makes extra large, extra high steps */ int oneHiStep[8][6][2]= { {{VDN,VBK},{VUP,VFN}, /* q1 move a legtrio forward */ {VUP,VFN},{VDN,VBK}, {VDN,VBK},{VUP,VFN}}, {{VDN,VBK},{VDN,VFN}, /* q2 change legtrio: on floor in air */ {VDN,VFN},{VDN,VBK}, {VDN,VBK},{VDN,VFN}}, {{VUP,VBK},{VDN,VFN}, /* q3 */ {VDN,VFN},{VUP,VBK}, {VUP,VBK},{VDN,VFN}}, {{VUP,CN},{VDN,CN}, /* q4 The of q0 inverse state / Step */ {VDN,CN},{VUP,CN}, {VUP,CN},{VDN,CN}}, {{VUP,VFN},{VDN,VBK}, /* q5 */ {VDN,VBK},{VUP,VFN}, {VUP,VFN},{VDN,VBK}}, {{VDN,VFN},{VDN,VBK}, /* q6 change legtrio back*/ {VDN,VBK},{VDN,VFN}, {VDN,VFN},{VDN,VBK}}, {{VDN,VFN},{VUP,VBK}, /* q7 */ {VUP,VBK},{VDN,VFN}, {VDN,VFN},{VUP,VBK}}, {{VDN,CN},{VUP,CN}, /* q0 */ {VUP,CN},{VDN,CN}, {VDN,CN},{VUP,CN}} /* restart with q1 or not */ }; /* The different states of the walker */ int turnHiRight[8][6][2]= { {{VDN,BK},{DN,BK}, /* q1 move a legtrio forward */ {DN,FN},{VDN,FN}, {VDN,BK},{DN,BK}}, {{VDN,BK},{VDN,BK}, /* q2 change legtrio: on floor in air */ {VDN,FN},{VDN,FN}, {VDN,BK},{VDN,BK}}, {{DN,BK},{VDN,BK}, /* q3 */ {VDN,FN},{DN,FN}, {DN,BK},{VDN,BK}}, {{DN,CN},{VDN,CN}, /* q4 The of q0 inverse state / Step */ {VDN,CN},{DN,CN}, {DN,CN},{VDN,CN}}, {{DN,FN},{VDN,FN}, /* q5 */ {VDN,BK},{DN,BK}, {DN,FN},{VDN,FN}}, {{VDN,FN},{VDN,FN}, /* q6 change legtrio back*/ {VDN,BK},{VDN,BK}, {VDN,FN},{VDN,FN}}, {{VDN,FN},{DN,FN}, /* q7 */ {DN,BK},{VDN,BK}, {VDN,FN},{DN,FN}}, {{VDN,CN},{DN,CN}, /* q0 */ {DN,CN},{VDN,CN}, {VDN,CN},{DN,CN}} /* restart with q1 or not */ }; /* The different states of the walker */ int turnHiLeft[8][6][2]= { {{VDN,FN},{DN,FN}, /* q1 move a legtrio forward */ {DN,BK},{VDN,BK}, {VDN,FN},{DN,FN}}, {{VDN,FN},{VDN,FN}, /* q2 change legtrio: on floor in air */ {VDN,BK},{VDN,BK}, {VDN,FN},{VDN,FN}}, {{DN,FN},{VDN,FN}, /* q3 */ {VDN,BK},{DN,BK}, {DN,FN},{VDN,FN}}, {{DN,CN},{VDN,CN}, /* q4 The of q0 inverse state / Step */ {VDN,CN},{DN,CN}, {DN,CN},{VDN,CN}}, {{DN,BK},{VDN,BK}, /* q5 */ {VDN,FN},{DN,FN}, {DN,BK},{VDN,BK}}, {{VDN,BK},{VDN,BK}, /* q6 change legtrio back*/ {VDN,FN},{VDN,FN}, {VDN,BK},{VDN,BK}}, {{VDN,BK},{DN,BK}, /* q7 */ {DN,FN},{VDN,FN}, {VDN,BK},{DN,BK}}, {{VDN,CN},{DN,CN}, /* q0 */ {DN,CN},{VDN,CN}, {VDN,CN},{DN,CN}} /* restart with q1 or not */ }; /* The different states of the walker */ int backHiStep[8][6][2]= { {{VDN,FN},{DN,BK}, /* q1 move a legtrio forward */ {DN,BK},{VDN,FN}, {VDN,FN},{DN,BK}}, {{VDN,FN},{VDN,BK}, /* q2 change legtrio: on floor in air */ {VDN,BK},{VDN,FN}, {VDN,FN},{VDN,BK}}, {{DN,FN},{VDN,BK}, /* q3 */ {VDN,BK},{DN,FN}, {DN,FN},{VDN,BK}}, {{DN,CN},{VDN,CN}, /* q4 The of q0 inverse state / Step */ {VDN,CN},{DN,CN}, {DN,CN},{VDN,CN}}, {{DN,BK},{VDN,FN}, /* q5 */ {VDN,FN},{CN,BK}, {DN,BK},{VDN,FN}}, {{VDN,BK},{VDN,FN}, /* q6 change legtrio back*/ {VDN,FN},{VDN,BK}, {VDN,BK},{VDN,FN}}, {{VDN,BK},{DN,FN}, /* q7 */ {DN,FN},{VDN,BK}, {VDN,BK},{DN,FN}}, {{VDN,CN},{DN,CN}, /* q0 */ {DN,CN},{VDN,CN}, {VDN,CN},{DN,CN}} /* restart with q1 or not */ }; /* This part is important for the beginning to */ int stayHisolid[1][6][2]= { {{VDN,CN},{VDN,CN}, /* give the walker a solid position */ {VDN,CN},{VDN,CN}, {VDN,FN},{VDN,CN}} }; /* n is the number of loops over the control array */ /* k is the number of states per control array */ int make_n_steps(int movdata[][6][2],int k,int n) { int i,state; for(i=0;ifromY)) return(1); if ((toX=fromX)&&(toYfromX)&&(toY>=fromY)) return(4); return(0); } int sqr(int x) { return(x*x); } /* This procedure returns the direction in what the walker has */ /* to go. The direction can be a number from 0 to 51 in the */ int seldir(int fromX,int fromY,int toX,int toY) { int direction, Xnorm, Ynorm; /* counter-clockwise. */ Xnorm=((toX-fromX)*256)/sqrt(sqr(toX-fromX)+sqr(toY-fromY)); Ynorm=((toY-fromY)*256)/sqrt(sqr(toX-fromX)+sqr(toY-fromY)); direction=selquad(fromX,fromY,toX,toY); switch(direction) { case 1: for(direction=0;(((XnormQuadrant2[direction][0])&& (YnormQuadrant3[direction][0])&& (Ynorm>Quadrant3[direction][1]))&&(direction<12)); direction++); return(direction+26); case 4: for(direction=0;(((XnormQuadrant4[direction][1]))&&(direction<12)); direction++); return(direction+39); default: return(52); } } /* info information */ void info(int toX, int toY,int toorient) { LCDClear(); LCDMenu(" + "," - ","Nxt","END"); LCDPrintf("Level 4: Info\n"); LCDPrintf("x*256: %d\n",x); LCDPrintf("y*256: %d\n",y); LCDPrintf("toX*256: %d\n",toX); LCDPrintf("toY*256: %d\n",toY); LCDPrintf("Orientation: %d\n",Orientation); LCDPrintf("toorient: %d\n",toorient); } /* Go stright to the aim, if you can or */ /* The quants for one step are 256 */ void gotoxy(int toX,int toY) { int toorient, stepstomake, stepsmade; x=x*256;y=y*256;toX=toX*256;toY=toY*256; while((abs(toX-x)>=256)||(abs(toY-y)>=256)) { toorient=seldir(x,y,toX,toY); /* turn the walker to the right */ info(toX,toY,toorient); /* STATUSINFORMATION */ if (toorient>=Orientation) /* direction */ { if ((toorient-Orientation)<=26) { LCDPrintf("b_hi_left(%d)\n",toorient-Orientation); /* STATUS */ beetle_hi_left(toorient-Orientation); } else { LCDPrintf("b_hi_right(%d)\n",Orientation+52-toorient); /* STATUS */ beetle_hi_right(Orientation+52-toorient); } } else { if ((Orientation-toorient)<=26) { LCDPrintf("b_hi_right(%d)\n",Orientation-toorient); /* STATUS */ beetle_hi_right(Orientation-toorient); } else { LCDPrintf("b_hi_left(%d)\n",toorient+52-Orientation); /* STATUS */ beetle_hi_left(toorient+52-Orientation); } } Orientation=toorient; /* direction end */ info(toX,toY,toorient); /* STATUS */ stepstomake=((sqrt(sqr(toX-x)+sqr(toY-y)))/256); stepsmade=beetle_hi_steps(stepstomake); /* go to the aim */ if (Orientation<13) /* Correct chronological position to actual */ { x=x+stepsmade*Quadrant1[Orientation][0]; y=y+stepsmade*Quadrant1[Orientation][1]; } else if ((Orientation>=13)&&(Orientation<26)) { x=x+stepsmade*Quadrant2[Orientation-13][0]; y=y+stepsmade*Quadrant2[Orientation-13][1]; } else if ((Orientation>=26)&&(Orientation<39)) { x=x+stepsmade*Quadrant3[Orientation-26][0]; y=y+stepsmade*Quadrant3[Orientation-26][1]; } else if ((Orientation>=39)&&(Orientation<52)) { x=x+stepsmade*Quadrant4[Orientation-39][0]; y=y+stepsmade*Quadrant4[Orientation-39][1]; } /* gone to aim and computed new position */ info(toX,toY,toorient); /* STATUS */ if (stepstomake!=stepsmade) /* if the walker stopped at an obstacle */ { /* try to override obstacle - or bypass */ if (ultrasonicLeft()>ultrasonicRight()) /* From here: Go around an obstacle, if it is not overridable */ { /* walk left around */ beetle_hi_left(13); Orientation=((Orientation+13) % 52); } else { /* walk right around */ beetle_hi_right(13); Orientation=((Orientation+52-13) % 52); } stepsmade=beetle_hi_steps(10); if (Orientation<13) /* Correct chronological position to actual */ { x=x+stepsmade*Quadrant1[Orientation][0]; y=y+stepsmade*Quadrant1[Orientation][1]; } else if ((Orientation>=13)&&(Orientation<26)) { x=x+stepsmade*Quadrant2[Orientation-13][0]; y=y+stepsmade*Quadrant2[Orientation-13][1]; } else if ((Orientation>=26)&&(Orientation<39)) { x=x+stepsmade*Quadrant3[Orientation-26][0]; y=y+stepsmade*Quadrant3[Orientation-26][1]; } else if ((Orientation>=39)&&(Orientation<52)) { x=x+stepsmade*Quadrant4[Orientation-39][0]; y=y+stepsmade*Quadrant4[Orientation-39][1]; } /* gone to aim an computed new position */ } } x=x/256; y=y/256; /* Here global variables are saved: x, y, Orientation */ } /********** end of layer four **********/ /* The level4 demonstrates the Layer4 Funktions, i.e. moving of the walker to a specified position */ int lv4menu(int fromx, int fromy, int tox, int toy, int pos) { LCDClear(); LCDMenu(" + "," - ","Nxt","END"); LCDPrintf("Level 4\n"); LCDPrintf("\n"); LCDPrintf("Actual X: %d\n",fromx); LCDPrintf("Actual Y: %d\n",fromy); LCDPrintf("Dest X: %d\n",tox); LCDPrintf("Dest Y: %d\n",toy); LCDPrintf("Start walking\n"); LCDSetChar(3+pos,15,'*'); return(0); } /* @@ int i,state; */ int lv4(void) { int tox=x,toy=y,next=0; lv4menu(x,y,tox,toy,next); while (1==1) { z = KEYGet(); switch (z) { case KEY1: switch (next) { case 0: tox++; break; case 1: toy++; break; } lv4menu(x,y,tox,toy,next); break; case KEY2: switch (next) { case 0: tox--; break; case 1: toy--; break; } lv4menu(x,y,tox,toy,next); break; case KEY3: if (next==1) { next=2; lv4menu(x,y,tox,toy,next); gotoxy(tox,toy); next=0; } else next++; lv4menu(x,y,tox,toy,next); break; case KEY4: return(0); break; default: return(1); break; } } } /* The gopart demonstrates the Layer3 Funktions, i.e. special moving functions of the walker are shown */ int gomenu(void) { LCDClear(); LCDMenu("BTL","TRN","LV4","END"); LCDPrintf("\n"); LCDPrintf("GOmenu\n"); LCDPrintf("\n"); LCDPrintf("-Walk like a\n"); LCDPrintf("beetle,\n"); LCDPrintf("-turn around or\n"); LCDPrintf("-goto layer 4.\n"); return(0); } /* @@ int i,state; */ int go(void) { gomenu(); while (1==1) { z = KEYGet(); switch (z) { case KEY1: beetle_hi_steps(8); /*beetle_steps(8);*/ gomenu(); break; case KEY2: beetle_hi_right(8); gomenu(); break; case KEY3: lv4(); gomenu(); break; case KEY4: return(0); break; default: return(1); break; } } } /* The legpart demonstrates the Layer2 Funktions, i.e. the Legs can get controlled in a state-oriented mode */ int legmenu(int Side, int Position, int Vert, int Horiz, int pos) /* pos refers to the position on the screen */ /* Vert is the vertikal movevalue of the leg */ /* Horiz is the horizontal movevalue of the leg */ /* Side is the side of the walker */ /* Position is the layer of legpairs expl. front*/ { LCDClear(); LCDMenu(" + "," - ","Nxt","END"); LCDPrintf("\n"); LCDPrintf("Legmenu\n"); LCDPrintf("\n"); LCDPrintf("Side: %s\n",(Side?"right":"left")); LCDPrintf("Position: %s\n", ((Position==FRONT)?"frn":((Position==MIDDLE)?"mid":"bak"))); LCDPrintf("Vertikal: %d\n",Vert); LCDPrintf("Horizontal: %d\n",Horiz); LCDSetChar(2+pos,15,'*'); return(0); } int leg(void) { int pos; int Side; int Position; int Values[REAR-FRONT+1][RIGHT-LEFT+1][2]= {{{3,3},{3,3}},{{3,3},{3,3}},{{3,3},{3,3}}}; /* Central Position for all hinges */ pos=0; Side=LEFT; Position=FRONT; legmenu(Side,Position,Values[Position-FRONT][Side][0], Values[Position-FRONT][Side][1],pos); while (1==1) { z = KEYGet(); switch (z) { case KEY1: switch (pos) { case 0: Side=1-Side; break; case 1: if (Position == REAR) Position = FRONT; else Position++; break; case 2: if (Values[Position-FRONT][Side][0]==5) Values[Position-FRONT][Side][0]=1; else Values[Position-FRONT][Side][0]++; liftleg(Side,Position,Values[Position-FRONT][Side][0]); break; case 3: if (Values[Position-FRONT][Side][1]==5) Values[Position-FRONT][Side][1]=1; else Values[Position-FRONT][Side][1]++; movleg(Side,Position,Values[Position-FRONT][Side][1]); break; default: break; } legmenu(Side,Position,Values[Position-FRONT][Side][0], Values[Position-FRONT][Side][1],pos); break; case KEY2: switch (pos) { case 0: Side=1-Side; break; case 1: if (Position == FRONT) Position = REAR; else Position--; break; case 2: if (Values[Position-FRONT][Side][0]==1) Values[Position-FRONT][Side][0]=5; else Values[Position-FRONT][Side][0]--; liftleg(Side,Position,Values[Position-FRONT][Side][0]); break; case 3: if (Values[Position-FRONT][Side][1]==1) Values[Position-FRONT][Side][1]=5; else Values[Position-FRONT][Side][1]--; movleg(Side,Position,Values[Position-FRONT][Side][1]); break; default: break; } legmenu(Side,Position,Values[Position-FRONT][Side][0], Values[Position-FRONT][Side][1],pos); break; case KEY3: if (pos==3) pos=0; else pos++; legmenu(Side,Position,Values[Position-FRONT][Side][0], Values[Position-FRONT][Side][1],pos); break; case KEY4: return(0); break; default: break; } } } /* The servopart demonstrates the Layer1 Funktions, i.e. each Servo can get selected and then the angle installed */ int servomenu(int Nr, int Angle, int pos) { LCDClear(); LCDMenu(" + "," - ","Nxt","END"); LCDPrintf("\n"); LCDPrintf("Servomenu\n"); LCDPrintf("\n"); LCDPrintf("Servo No: %d\n",Nr); LCDPrintf("\n"); LCDPrintf("Angle: %d\n",Angle); LCDSetChar(3+2*pos,15,'*'); return(0); } int servo(void) { int pos=0; /* Cursor position on the LCDisplay */ int Angle[12]; int Servo_Nr=0; for (pos=11;pos>=0;pos--){ Angle[pos]=30; } /*Testangles all to central Posision*/ pos=0; servomenu(Servo_Nr,Angle[Servo_Nr],pos); while (1==1) { z = KEYGet(); switch (z) { case KEY1: if (!pos) { if(Servo_Nr==11) Servo_Nr=0;else Servo_Nr++; /* next servo */ SERVOSet(servohandles[Servo_Nr],Angle[Servo_Nr]); } else { Angle[Servo_Nr]=Angle[Servo_Nr]+10; /* increase angle */ if(Angle[Servo_Nr]>(210)) Angle[Servo_Nr]=210; SERVOSet(servohandles[Servo_Nr],Angle[Servo_Nr]); } servomenu(Servo_Nr,Angle[Servo_Nr],pos); break; case KEY2: if (!pos) { if(!Servo_Nr) Servo_Nr=11;else Servo_Nr--; /* last servo */ SERVOSet(servohandles[Servo_Nr],Angle[Servo_Nr]); } else { Angle[Servo_Nr]=Angle[Servo_Nr]-10; /* decrease angle */ if (Angle[Servo_Nr]<0) Angle[Servo_Nr]=0; SERVOSet(servohandles[Servo_Nr],Angle[Servo_Nr]); } servomenu(Servo_Nr,Angle[Servo_Nr],pos); break; case KEY3: if (pos==1) pos=0; else pos++; servomenu(Servo_Nr,Angle[Servo_Nr],pos); break; case KEY4: return(0); break; default: break; } } } /* this is the main menu for the servo-part i.e. the part where something is moving */ int movemenu(void) { LCDClear(); LCDMenu("GO ","LEG","SVO","END"); LCDPrintf("\n"); LCDPrintf("Movemenu\n"); LCDPrintf("\n"); LCDPrintf("Please select\n"); LCDPrintf("one of the fol-\n"); LCDPrintf("lowing menue\n"); LCDPrintf("points\n"); return(0); } int move(void) { movemenu(); while (1==1) { z = KEYGet(); switch (z) { case KEY1: go(); movemenu(); break; case KEY2: leg(); movemenu(); break; case KEY3: servo(); movemenu(); break; case KEY4: return(0); break; default: break; } } } /* this ist the menu for the fumble, i.e. the fumble outputs can get checked here */ int fumblemenu(int number,int value) { /* LCDClear();*/ LCDMenu(" + "," - ","R ","END"); LCDPrintf("\n"); LCDPrintf("Fumblemenu\n"); LCDPrintf("\n"); LCDPrintf("Acutal fumlbe\n"); LCDPrintf("is Number: %d\n",number); LCDPrintf("The value of it\n"); LCDPrintf("is: %d\n",value); return(0); } int fumble(void) { int number; number = 0; fumblemenu(number,0); while (1==1) { z = KEYGet(); switch (z) { case KEY1: if (number == 5) number=0; else number++; fumblemenu(number,OSGetSDSignal(SDsemas[number])); break; case KEY2: if (number == 0) number=5; else number--; fumblemenu(number,OSGetSDSignal(SDsemas[number])); break; case KEY3: fumblemenu(number,OSGetSDSignal(SDsemas[number])); break; case KEY4: return(0); break; default: break; } } } /* this ist the menu for the ultra-sound */ int ultrasoundmenu(int number,int value) { LCDClear(); LCDMenu(" + "," - ","R ","END"); LCDPrintf("\n"); LCDPrintf("PSD-menu\n"); LCDPrintf("\n"); LCDPrintf("Acutal detector\n"); LCDPrintf("is %s one\n",((!number)?"left":"right")); LCDPrintf("The value of it\n"); LCDPrintf("is: %d\n",value); return(0); } int ultrasound(void) { int number; number = 0; ultrasoundmenu(number,0); while (1==1) { z = KEYGet(); switch (z) { case KEY1: if (number == 1) number=0; else number=1; ultrasoundmenu(number,((number==0)?ultrasonicLeft():ultrasonicRight())); break; case KEY2: if (number == 0) number=1; else number=0; ultrasoundmenu(number,((number==0)?ultrasonicLeft():ultrasonicRight())); break; case KEY3: ultrasoundmenu(number,((number==0)?ultrasonicLeft():ultrasonicRight())); break; case KEY4: return(0); break; default: break; } } } /* This ist the main menu of this demonstration */ int walkermenu(void) { LCDClear(); LCDMenu("MOV","FBL","USN","END"); LCDPrintf("\n"); LCDPrintf("Walkermenu\n"); LCDPrintf("\n"); LCDPrintf("Please select\n"); LCDPrintf("one of the fol-\n"); LCDPrintf("lowing menue\n"); LCDPrintf("points\n"); return(0); } /************* MAIN ***************** */ /* main walker program */ int main () { int i; /* initialization */ LCDPrintf("Init Walker..\n"); /* allocate handels for all servos */ for(i=0;i<=12;i++) servohandles[i]=SERVOInit(semas[i]); stillhistand(); /* allocate handels for all psds */ for(i=0;i<=1;i++) psdhandles[i]=PSDInit(PSDsemas[i]); /* middle position */ LCDPrintf("Servos mid-pos..\n"); for(i=0;i<=12;i++) SERVOSet(servohandles[i],255/2); LCDMenu("GO"," "," "," "); KEYWait(KEY1); walkermenu(); while (1==1) { z = KEYGet(); switch (z) { case KEY1: move(); walkermenu(); break; case KEY2: fumble(); walkermenu(); break; case KEY3: ultrasound(); walkermenu(); break; case KEY4: for(i=1;i<=12;i++) SERVORelease(servohandles[i]); PSDRelease(); return 0; break; default: break; } } }