// res3.c MR 06/12/99 // // Robot Environment Shell around robot brain program. // // Compile & link this (on LINUX) with // ``gcc res3.c -o res3 -lcurses''. // // // 07/12/99 : With name of brain program as res2 argument. // 16/12/99 : New communication protocol with brain program, and // with 'smell food' and without 'air' sensor. // 28/12/99 : Protocol "#n" (where n is a real > 0.0) instead of // "#Good"/"#Bad". Issue a "#n" with n near 0.95 or 0.99 // on a motor action not immmediately resulting in // bumping into a wall or food pellet. /* ---------------------------------------------------------------------- Copyright (C) 1999 Menno Rubingh This source code / program is free software; you are allowed to redistribute it and/or to modify it under the terms of the GNU Public Licence (GNU GPL) as published by the Free Software Foundation. See the file 'COPYING' which should have accompanied this source file. This program comes with ABSOLUTELY NO WARRANTY. ---------------------------------------------------------------------- */ #include #include #include typedef int _bool; // ------------------------------ screen output ----------------------------- // // The functions below provide a platform-independent API to do // output of characters to the screen, where characters are placed // at definite positions on the screen. (No scrolling, not ``stream''- // based). // // (The implementation below is for the linux/unix ``curses'' library.) // // Note: The keyboard INPUT function that is used in the code below // is the ``curses'' function // // char getch( void ); // // the DOS library contains exactly that same function, with // exactly the same name and prototype. #include void screenInit( void ) { initscr(); cbreak(); noecho(); } void screenEnd( void ) { endwin(); } int maxx( void ) { return COLS; } int maxy( void ) { return LINES; } void putCharAt( int x, int y, char c ) { mvaddch( y, x, c ); } void mvCursorTo( int x, int y ) { move( y, x ); } // ----- // // Some more handy screen output functions built upon the functions // defined above: // void msgPrintf( int y, const char * fmt, ... ) { //Print one line a la printf(). int x; char buf[80]; va_list valst; va_start( valst, fmt ); vsprintf( buf, fmt, valst ); x = 0; while ( buf[x] != '\0' ) { putCharAt( x++, y, buf[x] ); } while ( x = maxx() ) { x = 0; y++; } } } // --------------------------------------------------------------------------- // ----------------------- robot environment simulation ---------------------- typedef enum { NORTH, EAST, SOUTH, WEST, N_OR } orient_t; static const char rchar[N_OR] = { '^', '>', 'v', 'x + x_fwd[p->or]; int y = p->y + y_fwd[p->or]; if ( ! inRoom( x, y ) || map[x][y] == WALL ) { return 1; } return 0; } _bool seefood( const robot_t * p ) //Return 1 if food on either of the 3 squares immediately in // front of the robot. { int x = p->x; int y = p->y; int i; for ( i = 0; i or]; y += y_fwd[p->or]; if ( inRoom(x,y) && map[x][y] == FOOD ) { return 1; } } return 0; } _bool smellfood( const robot_t * p ) //Return 1 if food on one of the squares horizontally or // vertically bordering the square the robot occupies. { int x, y; x = p->x + 1; y = p->y; if ( inRoom(x,y) && map[x][y] == FOOD ) { return 1; } x = p->x - 1; y = p->y; if ( inRoom(x,y) && map[x][y] == FOOD ) { return 1; } x = p->x; y = p->y + 1; if ( inRoom(x,y) && map[x][y] == FOOD ) { return 1; } x = p->x; y = p->y - 1; if ( inRoom(x,y) && map[x][y] == FOOD ) { return 1; } return 0; } //------ robot movement: ------ typedef enum { NONE, GOOD, BAD } bir_t; //built-in reaction bir_t move_FWD( robot_t * p ) { if ( wallahead( p ) ) { msgPrintf( maxy()-1, "BUMP !!! OUCH !!!" ); return BAD; } p->x += x_fwd[p->or]; p->y += y_fwd[p->or]; assert ( inRoom( p->x, p->y ) ); if ( map[p->x][p->y] == FOOD ) { msgPrintf( maxy()-1, "YUMMY !!!" ); //Remove food item putItemIntoMap( p->x, p->y, EMPTY ); return GOOD; } return NONE; } bir_t move_TURN( robot_t * p ) { p->or = ( p->or + 1 ) % N_OR; return NONE; } // ----------------------------------- main ---------------------------------- //Includes for fork(), pipe(), usleep(), execlp(): #include #include #include #include #include #include #include //------------- void sendCmd( const char * cmd, int * fifoTF, int * fifoFF, _bool * pFWD, _bool * pTURN, int y1, int y2 ) //y1,y2: y-coordinates where (between which) to print response // received from brain program on screen. { char c; int nread; char bufFF[1024]; /*To read input from Brain Program ('BP')*/ *pFWD = 0; *pTURN = 0; /* * Send line with cmd to 'BP' */ write( fifoTF[1], cmd, strlen(cmd) ); /* * Receive response from 'BP' */ while ( nread = read( fifoFF[0], bufFF, sizeof(bufFF)-1 ), nread == -1 && errno == EAGAIN ) { usleep(1000); /*usleep(): Arg in microseconds*/ } while ( nread > 0 ) { dumpText( y1, y2, /*10, maxy()-4,*/ bufFF, nread ); bufFF[nread] = '\0'; if ( strstr( bufFF, "MOTOR_fwd" ) ) { *pFWD = 1; } if ( strstr( bufFF, "MOTOR_turn" ) ) { *pTURN = 1; } nread = read( fifoFF[0], bufFF, sizeof(bufFF) ); } } int main( int argc, char ** argv ) { const char * pBrainProgName; char bufFU[80]; /*To read input from user (stdin)*/ char bufFF[1024]; /*To read input from 'Brain Program'*/ int fifoTF[2]; /*To Brain Program*/ int fifoFF[2]; /*From Brain Program*/ int pid; robot_t robot = { 0, 0, //Initial coordinates of position of robot in room. EAST //Initial orientation of robot. }; _bool dummy1, dummy2; // Do cmd line args if ( argc