14.20 isBetweenTargetAndBall
This function determines if mypos
is between some target
position and the ball within a degree of leniency based on the threshold
parameter. This function was utilised to optimize the defensive strategy of Public School Heroes. The idea was that if I am between some target position where I should be and the ball then I may as well just go to the ball at this point because I am on the correct side of it. Or in other words I am in between my goal and the ball so a tackle or going to the ball would be beneficial. The function works as follows :
if (distance(A, C) + distance(B, C) == distance(A, B)) return true; // C is on the line. return false; // C is not on the line.
or just: return distance(A, C) + distance(B, C) == distance(A, B);
In our specific case:
- A = VecPosition ball
- B = VecPosition target
- C = VecPosition mypos
The way this works is rather simple. If C lies on the AB line, you’ll get the following scenario:
A-C------B
and, regardless of where it lies on that line, dist(AC) + dist(CB) == dist(AB). For any other case, you have a triangle of some description and ‘dist(AC) + dist(CB) > dist(AB)’:
A-----B
\ /
\ /
C
We take this one step further by including a threshold
parameter. Now instead of checking if (distance(A, C) + distance(B, C) == distance(A, B))
we calculate the difference between distance(A, C) + distance(B, C)
and distance(A, B)
. If this difference is less than some threshold then we return true
meaning we are between the ball and a target else we return false
meaning we are not in between. The reason for this leniency was that there were very few occasions where the agent would lie perfectly between two positions. The closer the value is to 0 the less leniant, it was found that 0.3
was pretty good in most cases.
bool NaoBehavior::isBetweenTargetAndBall(VecPosition target, VecPosition mypos, double threshold){
double distanceballtarget = ball.getDistanceTo(target);
double distanceballmetarget = ball.getDistanceTo(mypos) + mypos.getDistanceTo(target);
double difference = abs(distanceballtarget - distanceballmetarget);
if(difference < threshold){
return true;
}
return false;
}