void BH2011GoalSymbols::update() { timeSinceOppGoalWasSeen = (float) frameInfo.getTimeSince(goalPercept.timeWhenOppGoalLastSeen); timeSinceOwnGoalWasSeen = (float) frameInfo.getTimeSince(goalPercept.timeWhenOwnGoalLastSeen); timeSinceAnyGoalWasSeen = timeSinceOppGoalWasSeen < timeSinceOwnGoalWasSeen ? timeSinceOppGoalWasSeen : timeSinceOwnGoalWasSeen; oppGoalWasSeen = timeSinceOppGoalWasSeen < 500; goalWasSeen = timeSinceAnyGoalWasSeen < 500; /* Calculate seen goals in ready state*/ if(gameInfo.state == STATE_READY) { if(frameInfo.getTimeSince(goalPercept.timeWhenOppGoalLastSeen) == 0 || frameInfo.getTimeSince(goalPercept.timeWhenOwnGoalLastSeen) == 0) goalsSeenInReadyState += 1.0; } else { goalsSeenInReadyState = 0; } /* Calculate seen goals since last pickup */ if((groundContactState.noContactSafe && damageConfiguration.useGroundContactDetectionForSafeStates) && (fallDownState.state == FallDownState::upright || fallDownState.state == FallDownState::staggering)) { goalsSeenSinceLastPickup = 0.0; } else { if(frameInfo.getTimeSince(goalPercept.timeWhenOppGoalLastSeen) == 0 || frameInfo.getTimeSince(goalPercept.timeWhenOwnGoalLastSeen) == 0) goalsSeenSinceLastPickup += 1.0; } PLOT("Behavior:goalsSeenSinceLastPickup", goalsSeenSinceLastPickup); /* determine angles to sides of free part of opponent goal */ Vector2<> centerOfOppGoalAbs = Vector2<>((float) fieldDimensions.xPosOpponentGoalpost, (float)(fieldDimensions.yPosLeftGoal + fieldDimensions.yPosRightGoal) / 2.0f); Vector2<> centerOfOppGoalRel = Geometry::fieldCoord2Relative(robotPose, centerOfOppGoalAbs); float leftDistance = abs(centerOfOppGoalAbs.y - freePartOfOpponentGoalModel.leftEnd.y); float rightDistance = abs(centerOfOppGoalAbs.y - freePartOfOpponentGoalModel.rightEnd.y); if(leftDistance < rightDistance) { innerSide = freePartOfOpponentGoalModel.leftEnd; outerSide = freePartOfOpponentGoalModel.rightEnd; } else { innerSide = freePartOfOpponentGoalModel.rightEnd; outerSide = freePartOfOpponentGoalModel.leftEnd; } /* draw angles to free part into worldstate, see draw()-function below */ DECLARE_DEBUG_DRAWING("behavior:GoalSymbols:FreePartAnglesOnField", "drawingOnField"); COMPLEX_DRAWING("behavior:GoalSymbols:FreePartAnglesOnField", drawingOnField()); }
void FreePartOfOpponentGoalProvider::update(FreePartOfOpponentGoalModel& freePartOfOpponentGoalModel) { freePartOfOpponentGoalModel.valid = true; /* setup */ // dimensions of opponent goalline Vector2<> leftOppGoalPostAbs = Vector2<>((float) theFieldDimensions.xPosOpponentGroundline, (float) theFieldDimensions.yPosLeftGoal); Vector2<> rightOppGoalPostAbs = Vector2<>((float) theFieldDimensions.xPosOpponentGroundline, (float) theFieldDimensions.yPosRightGoal); Range<> oppGoallineRange = Range<>(rightOppGoalPostAbs.y, leftOppGoalPostAbs.y); int widthOfOppGoal = theFieldDimensions.yPosLeftGoal - theFieldDimensions.yPosRightGoal; float cellOnOppGoallineWidth = (float) widthOfOppGoal / NUM_OF_CELLS; /* update cells */ // renew cells on opponent goal in which a robot is found std::vector<RobotsModel::Robot>::const_iterator robotIt; for(robotIt = theRobotsModel.robots.begin(); robotIt < theRobotsModel.robots.end(); robotIt++) { // setup position to the sides of where the robot is standing Vector2<> absRobotOnField = Geometry::relative2FieldCoord(theRobotPose, robotIt->relPosOnField); Vector2<> leftRobotEnd = Vector2<>(absRobotOnField.x, absRobotOnField.y + ROBOT_WIDTH / 2); Vector2<> rightRobotEnd = Vector2<>(absRobotOnField.x, absRobotOnField.y - ROBOT_WIDTH / 2); Vector2<> absBallOnField = Geometry::relative2FieldCoord(theRobotPose, theBallModel.estimate.position); // intersection of lines to these ends with opponent groundline Vector2<> leftIntersectOppGroundline, rightIntersectOppGroundline; if( Geometry::getIntersectionOfLines(Geometry::Line(absBallOnField, leftRobotEnd - absBallOnField), Geometry::Line((float) theFieldDimensions.xPosOpponentGroundline, 0, 0, 1), leftIntersectOppGroundline) && Geometry::getIntersectionOfLines(Geometry::Line(absBallOnField, rightRobotEnd - absBallOnField), Geometry::Line((float) theFieldDimensions.xPosOpponentGroundline, 0, 0, 1), rightIntersectOppGroundline) ) { // check if at least one of these intersections is on the inside of the opponent goal if(oppGoallineRange.isInside(leftIntersectOppGroundline.y) || oppGoallineRange.isInside(rightIntersectOppGroundline.y)) { // clip both into the inside of the opponent goal, in case one of them is outside of it float leftIntersectOppGroundlineY = oppGoallineRange.limit(leftIntersectOppGroundline.y); float rightIntersectOppGroundlineY = oppGoallineRange.limit(rightIntersectOppGroundline.y); // check for each cell if it lies within the line between the intersections for(int i = 1; i < NUM_OF_CELLS - 1; i++) { float leftCellEndY = theFieldDimensions.yPosRightGoal + (i + 1) * cellOnOppGoallineWidth; float rightCellEndY = theFieldDimensions.yPosRightGoal + i * cellOnOppGoallineWidth; if( (Range<>(rightIntersectOppGroundlineY, leftIntersectOppGroundlineY).isInside(leftCellEndY) || Range<>(rightIntersectOppGroundlineY, leftIntersectOppGroundlineY).isInside(rightCellEndY)) && cellsOnOppGoalline[i] < MAX_VALUE ) { cellsOnOppGoalline[i] += RENEW_VALUE; } } } } } // left and right ends are always occupied cellsOnOppGoalline[0] = MAX_VALUE; cellsOnOppGoalline[NUM_OF_CELLS - 1] = MAX_VALUE; // aging of unoccupied cells for(int i = 1; i < NUM_OF_CELLS - 1; i++) cellsOnOppGoalline[i] *= AGING_FACTOR; /* calculate which free part is the largest / best */ int currentFreePartSize = 0, currentFreePartHigh = 0, currentFreePartLow = 0; int largestHithertoSize = -1, largestHithertoHigh = -1, largestHithertoLow = -1; int overlapWithLastFreePart = 0; int side = (theRobotPose.translation.y < 0) ? 1 : -1; for( int i = (side > 0) ? 0 : NUM_OF_CELLS - 1; (side > 0) ? (i < NUM_OF_CELLS) : (i >= 0); i += side ) { if(cellsOnOppGoalline[i] < IS_FREE_THRESHOLD) { currentFreePartSize++; if(Range<int>(lastFreePartLow, lastFreePartHigh).isInside(i)) overlapWithLastFreePart++; (side > 0) ? (currentFreePartHigh = i) : (currentFreePartLow = i); } else { // if current free part is significantly larger than the last found one, define it as the new largest free part so far // + add a bonus to the current free part if it significantly overlaps with the last largest free part if(((overlapWithLastFreePart >= currentFreePartSize / 2) ? (currentFreePartSize + NEW_MAX_FREE_THRESHOLD) : currentFreePartSize) > (largestHithertoSize + NEW_MAX_FREE_THRESHOLD / 2)) { largestHithertoSize = currentFreePartSize; largestHithertoHigh = currentFreePartHigh; largestHithertoLow = currentFreePartLow; } currentFreePartSize = 0; overlapWithLastFreePart = 0; (side > 0) ? (currentFreePartLow = i + 1) : (currentFreePartHigh = i - 1); } } // if not even a minimal number of cells is free... if(largestHithertoSize >= MIN_LARGEST_SIZE) { largestFreePartHigh = largestHithertoHigh; largestFreePartLow = largestHithertoLow; freePartOfOpponentGoalModel.isFree = true; } // ...every part of the goal is equally hopeless // (free part will be the whole goal, so one can always shoot into the center, // but set a flag the goal is completely blocked) else { largestFreePartHigh = NUM_OF_CELLS - 2; largestFreePartLow = 1; freePartOfOpponentGoalModel.isFree = false; } // new found largest free part will be the last found in next update lastFreePartHigh = largestFreePartHigh; lastFreePartLow = largestFreePartLow; /* caculate relative position to ends of free part */ Vector2<> leftEndOfFreePartAbs = Vector2<>( (float) theFieldDimensions.xPosOpponentGroundline, theFieldDimensions.yPosRightGoal + (largestFreePartHigh + 1) * cellOnOppGoallineWidth ); Vector2<> rightEndOfFreePartAbs = Vector2<>( (float) theFieldDimensions.xPosOpponentGroundline, theFieldDimensions.yPosRightGoal + largestFreePartLow * cellOnOppGoallineWidth ); freePartOfOpponentGoalModel.leftEnd = Geometry::fieldCoord2Relative(theRobotPose, leftEndOfFreePartAbs); freePartOfOpponentGoalModel.rightEnd = Geometry::fieldCoord2Relative(theRobotPose, rightEndOfFreePartAbs); /* draw absolute position of free part into worldstate, see draw()-function below */ DECLARE_DEBUG_DRAWING("module:FreePartOfOpponentGoalProvider:FreePartOnField", "drawingOnField"); COMPLEX_DRAWING("module:FreePartOfOpponentGoalProvider:FreePartOnField", drawingOnField(freePartOfOpponentGoalModel)); }