/***********************************************************************/ /** @name imageLib.c Contains application specific image processing process. Uses LibVision library. @author Birgit Graf, UWA, 1998, modified 2000 (Mk3/4) */ /***********************************************************************/ /*@{*/ #include "global.h" #include "imageVis.h" #include "LibVision.h" #include "servos.h" #include "driveglobal.h" /* global variables */ VIS_RGBSpace RGBSpace; /* User's RGB space */ BYTE MY_COLOUR_CLASS=1; /* This example handles only one class */ BYTE FoundClass; /* Colour class found */ /** Ball coordinates when ball has been detected (position on field) */ float ball_x, ball_y; void Init_Camera() { int error=VIS_InitCam(NORMAL); if (error==INITERROR) { VIS_ErrorDisplay(" Cam Init.", INITERROR, "");} /*- Fill the hue conversion table and initialise the algorithm defaults -*/ VIS_Init(); /*- Fill the user's RGB space with zeros -*/ VIS_ColClear(&RGBSpace); /*- set ball colour -*/ LCDClear(); Set_BallColour(); Set_CameraParams(); } void Set_BallColour() { /* Finding the median hue and filling the RGBSpace */ VIS_ColInit(&RGBSpace, MY_COLOUR_CLASS); if (USE_AUDIO) AUBeep(); LCDClear(); } void Set_CameraParams() { /* calibrate camera */ VIS_CamCal(&RGBSpace, MY_COLOUR_CLASS); /* init distance table */ VIS_InitDistance(); if (USE_AUDIO) AUBeep(); LCDClear(); } /***********************************************************************/ /** Transform local to global Position. change local dx, dy from robot position into global coordinates @author Thomas Braunl */ /***********************************************************************/ void local2global(PositionType pos, PositionType local, PositionType *global) { float cosphi, sinphi; cosphi = cos(pos.phi); sinphi = sin(pos.phi); global->x = pos.x + cosphi*local.x + sinphi*local.y; global->y = pos.y + cosphi*local.y + sinphi*local.x; global->phi = 0.0; } /***********************************************************************/ /** Get ball coordinates. Get position of ball on field as found out in image processing routines and orientation of ball towards goal. Called by PPdrive_field() and PPdrive_goal(). @see PPdrive_field() @see PPdrive_goal() @param *ball pointer to array containing coordinates of ball @return ball position and orientation towards goal in referenced parameter */ /***********************************************************************/ void get_ball_coord(PositionType *ball) { ball->x = ball_x; ball->y = ball_y; ball->phi = -atan2(ball_y, LENGTH - ball_x); /* neg: angle ball to goal */ } /***********************************************************************/ /** Check for ball. Analyse picture by calling find_object and checking camera position, set see_ball_flag and respectively. Process started by main(). @see main() */ /***********************************************************************/ void PPball_test() { PositionType rob_pos, camera_pos; int x_middle = 0, y_middle = 0, ball_size = 0; /* parameters of ball */ image greyimg; colimage ColPic; /* User's colour image */ VIS_Object Object; /* User's object */ VIS_Distance ObjDist; /* distance to ball */ /* ball coordinates (camera's / robot's local/ global coord.syst.) */ PositionType cam_local, rob_local, global; int factor = 0; /* counts pictures without ball */ int frame_counter, new_counter; /* to calculate frame rate */ int new_angle; frame_counter = OSGetCount(); while(!end_flag) { /* LCDPrintf("ball\n"); */ new_counter = OSGetCount(); LCDSetPos(5, 10); /* print frame rate */ if (new_counter != frame_counter) LCDPrintf("f:%1.1f\n", 100.0 / (float)(new_counter - frame_counter)); frame_counter = new_counter; got_ball_flag = FALSE; /* Get a picture */ CAMGetColFrame(&ColPic, 0); IPColor2Grey(&ColPic, &greyimg); /* Find class */ FoundClass=VIS_ColFind(&ColPic, &RGBSpace, &Object, MY_COLOUR_CLASS); if (FoundClass == MY_COLOUR_CLASS) { /* set ball parameters */ x_middle = Object.bot; ball_size= (Object.right - Object.left); y_middle = Object.left + ball_size/2; VIS_MarkObject(greyimg, x_middle, y_middle, ball_size); LCDPutGraphic(&greyimg); VIS_GetPosition(&Object, &ObjDist); /* ------ see ball -> set coordinates and see_ball_flag ------ */ cam_local.x = (float)ObjDist.d_row / 1000; /* x position from robot in m */ cam_local.y = -(float)ObjDist.d_col / 1000; /* y position from robot in m */ camera_pos.x = 0; camera_pos.y = 0; camera_pos.phi = (float) cam_pos / 180 * PI; /* camera orientation */ local2global(camera_pos, cam_local, &rob_local); /* get local coordinates (consider camera pos)*/ get_pos (&rob_pos); local2global(rob_pos, rob_local, &global); /* get global coordinates */ ball_x = global.x; ball_y = global.y; LCDSetPos(1, 10); LCDPrintf("Ball:\n"); LCDSetPos(2, 10); LCDPrintf("(%d, \n", (int)(100 * ball_x)); LCDSetPos(3, 10); LCDPrintf("% 2d) \n", (int)(100 * ball_y)); /* check whether ball is in field */ /* if ((global.x > 0.0) && (global.x < LENGTH) && (fabs(global.y) < WIDTH2)) { */ see_ball_flag = TRUE; /* really seeing ball -> set flag + coordinates */ if (USE_AUDIO) AUBeep(); factor = 3; /* allow factor pictures without ball before looking elsewhere */ /* KEYWait(ANYKEY); LCDClear(); new_angle = DiscAtan((int) (1000.0 * rob_local.y), (int) (1000.0 * rob_local.x)) * 180 / PI; not accurate enough!!! */ new_angle = atan(rob_local.y/rob_local.x) * 180 / PI; /* LCDPrintf("cx: %d,cy: %d\n", (int) (100 * cam_local.x), (int) (100 * cam_local.y)); LCDPrintf("cam angle: %d\n", cam_pos); LCDPrintf("rx: %d,ry: %d\n", (int) (100 * rob_local.x), (int) (100 * rob_local.y)); LCDPrintf("rob angle: %d\n", (int) (rob_pos.phi * 180 / PI)); LCDPrintf("gx: %d,gy: %d\n", (int) (100 * global.x), (int) (100 * global.y)); LCDPrintf("new angle: %d\n", new_angle); KEYWait(ANYKEY); */ move_camera(new_angle); /* LCDClear(); LCDMenu("", "", "STOP", ""); */ if (hypot(rob_local.x, rob_local.y) < GOT_BALL) got_ball_flag = TRUE; /* } else no ball (found object out of field, propably yellow goal) */ /* { LCDPutGraphic(&greyimg); LCDSetPos(1, 10); LCDPrintf(" \n"); LCDSetPos(2, 10); LCDPrintf(" \n"); LCDSetPos(3, 10); LCDPrintf(" \n"); move_camera(0); see_ball_flag = FALSE; lost ball */ /* } */ } else /* no ball */ { if (factor) /* keep on looking to presumed ball position */ factor --; else { LCDPutGraphic(&greyimg); LCDSetPos(1, 10); LCDPrintf(" \n"); LCDSetPos(2, 10); LCDPrintf(" \n"); LCDSetPos(3, 10); LCDPrintf(" \n"); move_camera(0); see_ball_flag = FALSE; /* lost ball */ } } OSReschedule(); } end_flag += 1; OSKill(0); } /*@}*/