/***********************************************************************/ /** @name sensors.c Contains functions read sensors. @author Thomas Braunl & Birgit Graf , UWA, 1998 */ /***********************************************************************/ /*@{*/ #include "global.h" #include "general.h" /** threshold for obstacle avoidance (dist in mm) */ #define obstacle_thresh 120 /** handles for PSD sensors */ PSDHandle psd_front, psd_left, psd_right; /***********************************************************************/ /** Init PSD. Init PSD senors that are used in the program. Called by main(). @see main() */ /***********************************************************************/ int InitPSD() { psd_front = PSDInit(PSD_FRONT); psd_left = PSDInit(PSD_LEFT); psd_right = PSDInit(PSD_RIGHT); PSDStart(psd_front|psd_left|psd_right, TRUE); return 0; } /***********************************************************************/ /** Check PSD sensors. Check psd sensors and set obstacle_flag respectively. Called by PPobstacle_test() @see PPobstacle_test() @return with which sensor obstacle has been detected or 0 if none */ /***********************************************************************/ int psd_test() { int new_obstacle = ((PSDGet(psd_front) < obstacle_thresh) && !see_ball_flag); int side_psd = (4 * (PSDGet(psd_right) - 50 < obstacle_thresh) + (2 * PSDGet(psd_left) < obstacle_thresh)); if (new_obstacle && !obstacle_flag) /* new obstacle detected -> stop */ VWSetSpeed(vw, 0, 0); return new_obstacle + side_psd; /* 1: front, 2: left, 4: right psd sensor */ } float min_psd(float thresh, int sensor) { float dist; switch (sensor) { case 1: dist = (float) PSDGet(psd_front) / 1000.0; break; case 2: dist = (float) PSDGet(psd_left) / 1000.0; break; case 4: dist = (float) PSDGet(psd_right) / 1000.0; break; default: dist = 100.0; break; } if (dist < thresh) return dist; else return thresh; } /***********************************************************************/ /** Check for obstacles. Check psd sensors and check wheather the robot's wheels have stalled - this would indicate that the robot has run into an obstacle. Set obstacle_flag respectively. Process started by main(). @see main() */ /***********************************************************************/ void PPobstacle_test() { /* robot position */ PositionType pos; /* distance from robot middle to detected obstacle */ float obstacle_dist; /* distance to wall when position value can be reset */ float reset_dist; int psd_detected = FALSE; /* flag to show whether psd sensors have detected obstacle */ int stall_detected = FALSE; /* flag to show whether stallchecker has detected obstacle */ while(!end_flag) { /* ----- check for obstacles (stall or front psd) ----- */ if (!I_am_goalie()) psd_detected = psd_test(); else psd_detected = FALSE; stall_detected = (VWStalled(vw)); if (stall_detected) { VWSetSpeed(vw, 0.0, 0.0); AUTone(1200,200); } /* detected obstacle with front psd sensor or stallchecker */ obstacle_flag = obstacle_flag || stall_detected || (psd_detected == 1); /* ----- reset position (stall or any psd sensor) ----- */ if (stall_detected || psd_detected) { obstacle_dist = ROBWIDTH2; /* distance to obstacle if robot ran into it (stallchecker aktiv) */ if (psd_detected) { obstacle_dist += min_psd((float)obstacle_thresh / 2000.0, psd_detected); /* add distance between robot and obstacle (psd value) */ AUTone(1000,200); } reset_dist = 0.1 + obstacle_dist; /* threshold for resetting position (robot close to wall) */ /* ----- reset position ----- */ VWGetPosition(vw, &pos); /* left or right sidewall */ if (fabs(pos.y) > WIDTH2 - reset_dist) pos.y = fsign(pos.y) * (WIDTH2 - obstacle_dist); /* field's end on opponent's side */ if (pos.x > LENGTH - reset_dist) pos.x = LENGTH - obstacle_dist; /* field's end on our side */ else if (pos.x < reset_dist) pos.x = obstacle_dist; VWSetPosition(vw, pos.x, pos.y, pos.phi); } OSReschedule(); } end_flag += 1; OSKill(0); } /*@}*/