void findBall(){ display_clear(); int temptLMSpeed = LM_MINS; // changeable minimum speed for left motor int temptRMSpeed = RM_MINS; // changeable minimum speed for right morot int lastLMSpeed, lastRMSpeed; // motor speed int lastLMPos, lastRMPos; // motor positions int errorX = 0, errorY = 0; // difference of current ball coordinate and target coordinate int objArea; // area of the largest object in sight point2 objCen; // object center coordinate camera_update(); int objNum = get_object_count(GREEN); while(objNum == 0){ camera_update(); objNum = get_object_count(GREEN); } // find a ball in sight objCen = get_object_center(GREEN, 0); errorX = OFFSET_X - objCen.x; errorY = OFFSET_Y - objCen.y; while(!(a_button_clicked())){ camera_update(); objArea = get_object_area(GREEN, 0); while(objArea < 200){ ao(); camera_update(); objArea = get_object_area(GREEN, 0); } // make sure really a ball is in sight objCen = get_object_center(GREEN, 0); errorX = OFFSET_X - objCen.x; errorY = OFFSET_Y - objCen.y; // find differences between coordinates if(errorX > -3 && errorX < 2 && errorY > -3 && errorY < 2) break; int turnLM = -1 * errorX * P_X + errorY * P_Y; int turnRM = errorX * P_X + errorY * P_Y; // turn for LM, RM if(turnLM == lastLMSpeed && lastLMPos == get_motor_position_counter(LM)) temptLMSpeed = temptLMSpeed + 1; if(turnLM == lastLMSpeed && lastLMPos != get_motor_position_counter(LM)) temptLMSpeed = temptLMSpeed - 1; if(turnLM == -1 * lastLMSpeed && lastLMPos != get_motor_position_counter(LM)) temptLMSpeed = temptLMSpeed - 2; if(turnRM == lastRMSpeed && lastRMPos == get_motor_position_counter(RM)) temptRMSpeed = temptRMSpeed + 1; if(turnRM == lastRMSpeed && lastRMPos != get_motor_position_counter(RM)) temptRMSpeed = temptRMSpeed - 1; if(turnRM == -1 * lastRMSpeed && lastRMPos != get_motor_position_counter(RM)) temptRMSpeed = temptRMSpeed - 2; lastLMSpeed = turnLM; lastLMPos = get_motor_position_counter(LM); lastRMSpeed = turnRM; lastRMPos = get_motor_position_counter(RM); // check if speed is too high or low, thus make modification to minimum speed if(turnLM > -1 * temptLMSpeed && turnLM < 0) turnLM = -1 * temptLMSpeed; if(turnLM > 0 && turnLM < temptLMSpeed) turnLM = temptLMSpeed; if(turnRM > -1 * temptRMSpeed && turnRM < 0) turnRM = -1 * temptRMSpeed; if(turnRM > 0 && turnRM < temptRMSpeed) turnRM = temptRMSpeed; // set minimum speed: avoid unmoving motor(LM, turnLM); motor(RM, turnRM); // move } ao(); catchBall(GREEN); // stop and catch }
/*!This method is a simple goalie based on the goalie of the simple Team of FC Portugal. It defines a rectangle in its penalty area and moves to the position on this rectangle where the ball intersects if you make a line between the ball position and the center of the goal. If the ball can be intercepted in the own penalty area the ball is intercepted and catched. */ SoccerCommand Player::deMeer5_goalie( ) { int i; SoccerCommand soc; VecPosition posAgent = WM->getAgentGlobalPosition(); AngDeg angBody = WM->getAgentGlobalBodyAngle(); // define the top and bottom position of a rectangle in which keeper moves static const VecPosition posLeftTop( -PITCH_LENGTH/2.0 + 0.7*PENALTY_AREA_LENGTH, -PENALTY_AREA_WIDTH/4.0 ); static const VecPosition posRightTop( -PITCH_LENGTH/2.0 + 0.7*PENALTY_AREA_LENGTH, +PENALTY_AREA_WIDTH/4.0 ); // define the borders of this rectangle using the two points. static Line lineFront = Line::makeLineFromTwoPoints(posLeftTop,posRightTop); static Line lineLeft = Line::makeLineFromTwoPoints( VecPosition( -50.0, posLeftTop.getY()), posLeftTop ); static Line lineRight = Line::makeLineFromTwoPoints( VecPosition( -50.0, posRightTop.getY()),posRightTop ); if( WM->isBeforeKickOff( ) ) { if( formations->getFormation() != FT_INITIAL || // not in kickoff formation posAgent.getDistanceTo( WM->getStrategicPosition() ) > 2.0 ) { formations->setFormation( FT_INITIAL ); // go to kick_off formation ACT->putCommandInQueue( soc=teleportToPos(WM->getStrategicPosition()) ); } else // else turn to center { ACT->putCommandInQueue( soc = turnBodyToPoint( VecPosition( 0, 0 ), 0 )); ACT->putCommandInQueue( alignNeckWithBody( ) ); } return soc; } if( WM->getConfidence( OBJECT_BALL ) < PS->getBallConfThr() ) { // confidence ball too low ACT->putCommandInQueue( searchBall() ); // search ball ACT->putCommandInQueue( alignNeckWithBody( ) ); } else if( WM->getPlayMode() == PM_PLAY_ON || WM->isFreeKickThem() || WM->isCornerKickThem() ) { if( WM->isBallCatchable() ) { ACT->putCommandInQueue( soc = catchBall() ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else if( WM->isBallKickable() ) { soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 ); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else if( WM->isInOwnPenaltyArea( getInterceptionPointBall( &i, true ) ) && WM->getFastestInSetTo( OBJECT_SET_PLAYERS, OBJECT_BALL, &i ) == WM->getAgentObjectType() ) { ACT->putCommandInQueue( soc = intercept( true ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { // make line between own goal and the ball VecPosition posMyGoal = ( WM->getSide() == SIDE_LEFT ) ? SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_L, SIDE_LEFT ) : SoccerTypes::getGlobalPositionFlag(OBJECT_GOAL_R, SIDE_RIGHT); Line lineBall = Line::makeLineFromTwoPoints( WM->getBallPos(),posMyGoal); // determine where your front line intersects with the line from ball VecPosition posIntersect = lineFront.getIntersection( lineBall ); // outside rectangle, use line at side to get intersection if (posIntersect.isRightOf( posRightTop ) ) posIntersect = lineRight.getIntersection( lineBall ); else if (posIntersect.isLeftOf( posLeftTop ) ) posIntersect = lineLeft.getIntersection( lineBall ); if( posIntersect.getX() < -49.0 ) posIntersect.setX( -49.0 ); // and move to this position if( posIntersect.getDistanceTo( WM->getAgentGlobalPosition() ) > 0.5 ) { soc = moveToPos( posIntersect, PS->getPlayerWhenToTurnAngle() ); ACT->putCommandInQueue( soc ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } } else if( WM->isFreeKickUs() == true || WM->isGoalKickUs() == true ) { if( WM->isBallKickable() ) { if( WM->getTimeSinceLastCatch() == 25 && WM->isFreeKickUs() ) { // move to position with lesser opponents. if( WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, Circle(posRightTop, 15.0 )) < WM->getNrInSetInCircle( OBJECT_SET_OPPONENTS, Circle(posLeftTop, 15.0 )) ) soc.makeCommand( CMD_MOVE,posRightTop.getX(),posRightTop.getY(),0.0); else soc.makeCommand( CMD_MOVE,posLeftTop.getX(), posLeftTop.getY(), 0.0); ACT->putCommandInQueue( soc ); } else if( WM->getTimeSinceLastCatch() > 28 ) { soc = kickTo( VecPosition(0,posAgent.getY()*2.0), 2.0 ); ACT->putCommandInQueue( soc ); } else if( WM->getTimeSinceLastCatch() < 25 ) { VecPosition posSide( 0.0, posAgent.getY() ); if( fabs( (posSide - posAgent).getDirection() - angBody) > 10 ) { soc = turnBodyToPoint( posSide ); ACT->putCommandInQueue( soc ); } ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } } else if( WM->isGoalKickUs() ) { ACT->putCommandInQueue( soc = intercept( true ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } else { ACT->putCommandInQueue( soc = turnBodyToObject( OBJECT_BALL ) ); ACT->putCommandInQueue( turnNeckToObject( OBJECT_BALL, soc ) ); } return soc; }