Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
Seminar-HFO
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shashank Suhas
Seminar-HFO
Commits
8c1fef0d
Commit
8c1fef0d
authored
Jun 03, 2015
by
Matthew Hausknecht
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated high level feature set.
parent
372d87a9
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
261 additions
and
145 deletions
+261
-145
src/feature_extractor.cpp
src/feature_extractor.cpp
+129
-0
src/feature_extractor.h
src/feature_extractor.h
+55
-0
src/highlevel_feature_extractor.cpp
src/highlevel_feature_extractor.cpp
+75
-143
src/highlevel_feature_extractor.h
src/highlevel_feature_extractor.h
+2
-2
No files found.
src/feature_extractor.cpp
View file @
8c1fef0d
...
...
@@ -106,9 +106,138 @@ void FeatureExtractor::addNormFeature(float val, float min_val, float max_val) {
void
FeatureExtractor
::
checkFeatures
()
{
assert
(
feature_vec
.
size
()
==
numFeatures
);
for
(
int
i
=
0
;
i
<
numFeatures
;
++
i
)
{
if
(
feature_vec
[
i
]
==
FEAT_INVALID
)
{
continue
;
}
if
(
feature_vec
[
i
]
<
FEAT_MIN
||
feature_vec
[
i
]
>
FEAT_MAX
)
{
std
::
cout
<<
"Invalid Feature! Indx:"
<<
i
<<
" Val:"
<<
feature_vec
[
i
]
<<
std
::
endl
;
exit
(
1
);
}
}
}
bool
FeatureExtractor
::
valid
(
const
rcsc
::
PlayerObject
&
player
)
{
// Check if the player is too far left
const
rcsc
::
Vector2D
&
pos
=
player
.
pos
();
if
(
!
player
.
posValid
()
||
pos
.
x
<
-
ALLOWED_PITCH_FRAC
*
rcsc
::
ServerParam
::
i
().
pitchHalfLength
())
{
return
false
;
}
return
player
.
unum
()
>
0
&&
pos
.
isValid
();
}
float
FeatureExtractor
::
angleToPoint
(
const
rcsc
::
Vector2D
&
self
,
const
rcsc
::
Vector2D
&
point
)
{
return
(
point
-
self
).
th
().
radian
();
}
void
FeatureExtractor
::
angleDistToPoint
(
const
rcsc
::
Vector2D
&
self
,
const
rcsc
::
Vector2D
&
point
,
float
&
ang
,
float
&
dist
)
{
Vector2D
d
=
point
-
self
;
ang
=
d
.
th
().
radian
();
dist
=
d
.
r
();
}
float
FeatureExtractor
::
angleBetween3Points
(
const
rcsc
::
Vector2D
&
point1
,
const
rcsc
::
Vector2D
&
centerPoint
,
const
rcsc
::
Vector2D
&
point2
)
{
Vector2D
diff1
=
point1
-
centerPoint
;
Vector2D
diff2
=
point2
-
centerPoint
;
float
angle1
=
atan2
(
diff1
.
y
,
diff1
.
x
);
float
angle2
=
atan2
(
diff2
.
y
,
diff2
.
x
);
return
fabs
(
angle1
-
angle2
);
}
void
FeatureExtractor
::
calcClosestOpp
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
point
,
float
&
ang
,
float
&
minDist
)
{
minDist
=
std
::
numeric_limits
<
float
>::
max
();
const
PlayerCont
&
opps
=
wm
.
opponents
();
for
(
PlayerCont
::
const_iterator
it
=
opps
.
begin
();
it
!=
opps
.
end
();
++
it
)
{
const
PlayerObject
&
opponent
=
*
it
;
if
(
valid
(
opponent
))
{
float
dist
;
float
th
;
angleDistToPoint
(
point
,
opponent
.
pos
(),
th
,
dist
);
if
(
dist
<
minDist
)
{
minDist
=
dist
;
ang
=
th
;
}
}
}
}
float
FeatureExtractor
::
calcLargestTeammateAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
,
const
Vector2D
&
teammate
)
{
float
angTeammate
=
angleToPoint
(
self
,
teammate
);
float
angTop
=
angTeammate
+
M_PI
/
4
;
float
angBot
=
angTeammate
-
M_PI
/
4
;
return
calcLargestOpenAngle
(
wm
,
self
,
angTop
,
angBot
,
(
self
-
teammate
).
r
());
}
float
FeatureExtractor
::
calcLargestGoalAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
)
{
const
rcsc
::
ServerParam
&
SP
=
rcsc
::
ServerParam
::
i
();
Vector2D
goalPostTop
(
SP
.
pitchHalfLength
(),
SP
.
goalHalfWidth
());
Vector2D
goalPostBot
(
SP
.
pitchHalfLength
(),
-
SP
.
goalHalfWidth
());
float
angTop
=
angleToPoint
(
self
,
goalPostTop
);
float
angBot
=
angleToPoint
(
self
,
goalPostBot
);
//std::cout << "starting: " << RAD_T_DEG * angTop << " " << RAD_T_DEG * angBot << std::endl;
float
res
=
calcLargestOpenAngle
(
wm
,
self
,
angTop
,
angBot
,
99999
);
//std::cout << angTop << " " << angBot << " | " << res << std::endl;
return
res
;
}
float
FeatureExtractor
::
calcLargestOpenAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
,
float
angTop
,
float
angBot
,
float
maxDist
)
{
const
rcsc
::
ServerParam
&
SP
=
rcsc
::
ServerParam
::
i
();
std
::
vector
<
OpenAngle
>
openAngles
;
openAngles
.
push_back
(
OpenAngle
(
angBot
,
angTop
));
const
PlayerCont
&
opps
=
wm
.
opponents
();
for
(
PlayerCont
::
const_iterator
it
=
opps
.
begin
();
it
!=
opps
.
end
();
++
it
)
{
const
PlayerObject
&
opp
=
*
it
;
if
(
valid
(
opp
))
{
float
oppAngle
,
oppDist
;
angleDistToPoint
(
self
,
opp
.
pos
(),
oppAngle
,
oppDist
);
// theta = arctan (opponentWidth / opponentDist)
float
halfWidthAngle
=
atan2
(
SP
.
defaultKickableArea
()
*
0.5
,
oppDist
);
//float oppAngleBottom = oppAngle;
//float oppAngleTop = oppAngle;
float
oppAngleBottom
=
oppAngle
-
halfWidthAngle
;
float
oppAngleTop
=
oppAngle
+
halfWidthAngle
;
//std::cout << " to split? " << oppDist << " " << maxDist << std::endl;
if
(
oppDist
<
maxDist
)
{
splitAngles
(
openAngles
,
oppAngleBottom
,
oppAngleTop
);
}
}
}
float
largestOpening
=
0
;
for
(
uint
i
=
0
;
i
<
openAngles
.
size
();
++
i
)
{
OpenAngle
&
open
=
openAngles
[
i
];
//std::cout << " opening: " << RAD_T_DEG * open.first << " " << RAD_T_DEG * open.second << std::endl;
float
opening
=
open
.
second
-
open
.
first
;
if
(
opening
>
largestOpening
)
{
largestOpening
=
opening
;
}
}
return
largestOpening
;
}
void
FeatureExtractor
::
splitAngles
(
std
::
vector
<
OpenAngle
>
&
openAngles
,
float
oppAngleBottom
,
float
oppAngleTop
)
{
std
::
vector
<
OpenAngle
>
resAngles
;
for
(
uint
i
=
0
;
i
<
resAngles
.
size
();
++
i
)
{
OpenAngle
&
open
=
resAngles
[
i
];
if
((
oppAngleTop
<
open
.
first
)
||
(
oppAngleBottom
>
open
.
second
))
{
resAngles
.
push_back
(
open
);
}
else
{
resAngles
.
push_back
(
OpenAngle
(
open
.
first
,
oppAngleBottom
));
resAngles
.
push_back
(
OpenAngle
(
oppAngleTop
,
open
.
second
));
}
}
openAngles
=
resAngles
;
}
src/feature_extractor.h
View file @
8c1fef0d
...
...
@@ -4,6 +4,8 @@
#include <rcsc/player/player_agent.h>
#include <vector>
typedef
std
::
pair
<
float
,
float
>
OpenAngle
;
class
FeatureExtractor
{
public:
FeatureExtractor
();
...
...
@@ -18,6 +20,54 @@ public:
// How many features are there?
inline
int
getNumFeatures
()
{
return
numFeatures
;
}
public:
// Determines if a player is a part of the HFO game or is inactive.
static
bool
valid
(
const
rcsc
::
PlayerObject
&
player
);
// Returns the angle (in radians) from self to a given point
static
float
angleToPoint
(
const
rcsc
::
Vector2D
&
self
,
const
rcsc
::
Vector2D
&
point
);
// Returns the angle (in radians) and distance from self to a given point
static
void
angleDistToPoint
(
const
rcsc
::
Vector2D
&
self
,
const
rcsc
::
Vector2D
&
point
,
float
&
ang
,
float
&
dist
);
// Returns the angle between three points: Example opponent, self,
// goal center
static
float
angleBetween3Points
(
const
rcsc
::
Vector2D
&
point1
,
const
rcsc
::
Vector2D
&
centerPoint
,
const
rcsc
::
Vector2D
&
point2
);
// Find the opponent closest to the given point. Returns the
// distance and angle (in radians) from point to the closest
// opponent.
static
void
calcClosestOpp
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
point
,
float
&
ang
,
float
&
dist
);
// Returns the largest open (in terms of opponents) angle (radians)
// from self to the slice defined by [angBot, angTop].
static
float
calcLargestOpenAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
,
float
angTop
,
float
angBot
,
float
maxDist
);
// Returns the angle (in radians) corresponding to largest open shot
// on the goal.
static
float
calcLargestGoalAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
);
// Returns the largest open angle from self to a given teammate's
// position.
static
float
calcLargestTeammateAngle
(
const
rcsc
::
WorldModel
&
wm
,
const
rcsc
::
Vector2D
&
self
,
const
rcsc
::
Vector2D
&
teammate
);
// Helper function to split the open angles by the opponent angles
static
void
splitAngles
(
std
::
vector
<
OpenAngle
>
&
openAngles
,
float
oppAngleBottom
,
float
oppAngleTop
);
protected:
// Encodes an angle feature as the sin and cosine of that angle,
// effectively transforming a single angle into two features.
...
...
@@ -49,10 +99,15 @@ protected:
void
checkFeatures
();
protected:
const
static
float
RAD_T_DEG
=
180.0
/
M_PI
;
const
static
float
ALLOWED_PITCH_FRAC
=
0.33
;
int
featIndx
;
std
::
vector
<
float
>
feature_vec
;
// Contains the current features
const
static
float
FEAT_MIN
=
-
1
;
const
static
float
FEAT_MAX
=
1
;
const
static
float
FEAT_INVALID
=
-
2
;
int
numFeatures
;
// Total number of features
// Observed values of some parameters.
const
static
float
observedSelfSpeedMax
=
0.46
;
...
...
src/highlevel_feature_extractor.cpp
View file @
8c1fef0d
...
...
@@ -17,8 +17,11 @@ HighLevelFeatureExtractor::HighLevelFeatureExtractor(int num_teammates,
{
assert
(
numTeammates
>=
0
);
assert
(
numOpponents
>=
0
);
numFeatures
=
num_basic_features
+
features_per_player
*
(
numTeammates
+
numOpponents
);
numFeatures
=
num_basic_features
+
features_per_teammate
*
numTeammates
;
if
(
numOpponents
>
0
)
{
// One extra basic feature and one feature per teammate
numFeatures
+=
1
+
numTeammates
;
}
feature_vec
.
resize
(
numFeatures
);
}
...
...
@@ -28,165 +31,94 @@ const std::vector<float>& HighLevelFeatureExtractor::ExtractFeatures(
const
WorldModel
&
wm
)
{
featIndx
=
0
;
const
ServerParam
&
SP
=
ServerParam
::
i
();
// ======================== SELF FEATURES ======================== //
const
SelfObject
&
self
=
wm
.
self
();
const
Vector2D
&
self_pos
=
self
.
pos
();
const
AngleDeg
&
self_ang
=
self
.
body
();
addFeature
(
self
.
posValid
()
?
FEAT_MAX
:
FEAT_MIN
);
// ADD_FEATURE(self_pos.x);
// ADD_FEATURE(self_pos.y);
// Direction and speed of the agent.
addFeature
(
self
.
velValid
()
?
FEAT_MAX
:
FEAT_MIN
);
if
(
self
.
velValid
())
{
addAngFeature
(
self_ang
-
self
.
vel
().
th
());
addNormFeature
(
self
.
speed
(),
0.
,
observedSelfSpeedMax
);
}
else
{
addFeature
(
0
);
addFeature
(
0
);
addFeature
(
0
);
const
float
self_ang
=
self
.
body
().
radian
();
const
PlayerCont
&
teammates
=
wm
.
teammates
();
float
maxR
=
sqrtf
(
SP
.
pitchHalfLength
()
*
SP
.
pitchHalfLength
()
+
SP
.
pitchHalfWidth
()
*
SP
.
pitchHalfWidth
());
Vector2D
goalCenter
(
SP
.
pitchHalfLength
(),
0
);
// features about self pos
float
r
;
float
th
;
angleDistToPoint
(
self_pos
,
goalCenter
,
th
,
r
);
addNormFeature
(
r
,
0
,
maxR
);
addNormFeature
(
th
,
-
2
*
M_PI
,
2
*
M_PI
);
addNormFeature
(
self_ang
,
-
2
*
M_PI
,
2
*
M_PI
);
// features about our open angle to goal
addNormFeature
(
calcLargestGoalAngle
(
wm
,
self_pos
),
0
,
M_PI
);
//std::cout << "goal angle: " << RAD_T_DEG * features[ind-1] << std::endl;
// teammate's open angle to goal
int
detected_teammates
=
0
;
for
(
PlayerCont
::
const_iterator
it
=
teammates
.
begin
();
it
!=
teammates
.
end
();
++
it
)
{
const
PlayerObject
&
teammate
=
*
it
;
if
(
valid
(
teammate
)
&&
detected_teammates
<
numTeammates
)
{
addNormFeature
(
calcLargestGoalAngle
(
wm
,
teammate
.
pos
()),
0
,
M_PI
);
detected_teammates
++
;
}
}
// Global Body Angle -- 0:right -90:up 90:down 180/-180:left
addAngFeature
(
self_ang
);
// Neck Angle -- We probably don't need this unless we are
// controlling the neck manually.
// std::cout << "Face Error: " << self.faceError() << std::endl;
// if (self.faceValid()) {
// std::cout << "FaceAngle: " << self.face() << std::endl;
// }
addNormFeature
(
self
.
stamina
(),
0.
,
observedStaminaMax
);
addFeature
(
self
.
isFrozen
()
?
FEAT_MAX
:
FEAT_MIN
);
// Probabilities - Do we want these???
// std::cout << "catchProb: " << self.catchProbability() << std::endl;
// std::cout << "tackleProb: " << self.tackleProbability() << std::endl;
// std::cout << "fouldProb: " << self.foulProbability() << std::endl;
// Features indicating if we are colliding with an object
addFeature
(
self
.
collidesWithBall
()
?
FEAT_MAX
:
FEAT_MIN
);
addFeature
(
self
.
collidesWithPlayer
()
?
FEAT_MAX
:
FEAT_MIN
);
addFeature
(
self
.
collidesWithPost
()
?
FEAT_MAX
:
FEAT_MIN
);
addFeature
(
self
.
isKickable
()
?
FEAT_MAX
:
FEAT_MIN
);
// inertiaPoint estimates the ball point after a number of steps
// self.inertiaPoint(n_steps);
// ======================== LANDMARK FEATURES ======================== //
// Top Bottom Center of Goal
rcsc
::
Vector2D
goalCenter
(
pitchHalfLength
,
0
);
addLandmarkFeatures
(
goalCenter
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
goalPostTop
(
pitchHalfLength
,
-
goalHalfWidth
);
addLandmarkFeatures
(
goalPostTop
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
goalPostBot
(
pitchHalfLength
,
goalHalfWidth
);
addLandmarkFeatures
(
goalPostBot
,
self_pos
,
self_ang
);
// Top Bottom Center of Penalty Box
rcsc
::
Vector2D
penaltyBoxCenter
(
pitchHalfLength
-
penaltyAreaLength
,
0
);
addLandmarkFeatures
(
penaltyBoxCenter
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
penaltyBoxTop
(
pitchHalfLength
-
penaltyAreaLength
,
-
penaltyAreaWidth
/
2.
);
addLandmarkFeatures
(
penaltyBoxTop
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
penaltyBoxBot
(
pitchHalfLength
-
penaltyAreaLength
,
penaltyAreaWidth
/
2.
);
addLandmarkFeatures
(
penaltyBoxBot
,
self_pos
,
self_ang
);
// Corners of the Playable Area
rcsc
::
Vector2D
centerField
(
0
,
0
);
addLandmarkFeatures
(
centerField
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
cornerTopLeft
(
0
,
-
pitchHalfWidth
);
addLandmarkFeatures
(
cornerTopLeft
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
cornerTopRight
(
pitchHalfLength
,
-
pitchHalfWidth
);
addLandmarkFeatures
(
cornerTopRight
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
cornerBotRight
(
pitchHalfLength
,
pitchHalfWidth
);
addLandmarkFeatures
(
cornerBotRight
,
self_pos
,
self_ang
);
rcsc
::
Vector2D
cornerBotLeft
(
0
,
pitchHalfWidth
);
addLandmarkFeatures
(
cornerBotLeft
,
self_pos
,
self_ang
);
// Distances to the edges of the playable area
if
(
self
.
posValid
())
{
// Distance to Left field line
addDistFeature
(
self_pos
.
x
,
pitchHalfLength
);
// Distance to Right field line
addDistFeature
(
pitchHalfLength
-
self_pos
.
x
,
pitchHalfLength
);
// Distance to top field line
addDistFeature
(
pitchHalfWidth
+
self_pos
.
y
,
pitchWidth
);
// Distance to Bottom field line
addDistFeature
(
pitchHalfWidth
-
self_pos
.
y
,
pitchWidth
);
}
else
{
addFeature
(
0
);
addFeature
(
0
);
addFeature
(
0
);
addFeature
(
0
);
// Add zero features for any missing teammates
for
(
int
i
=
detected_teammates
;
i
<
numTeammates
;
++
i
)
{
addFeature
(
FEAT_INVALID
);
}
//
======================== BALL FEATURES ======================== //
const
BallObject
&
ball
=
wm
.
ball
();
// Angle and distance to the ball
addFeature
(
ball
.
rposValid
()
?
FEAT_MAX
:
FEAT_MIN
);
if
(
ball
.
rposValid
())
{
addAngFeature
(
ball
.
angleFromSelf
());
addDistFeature
(
ball
.
distFromSelf
(),
maxHFORadius
);
}
else
{
addFeature
(
0
);
addFeature
(
0
)
;
addFeature
(
0
);
}
// Velocity and direction of the ball
addFeature
(
ball
.
velValid
()
?
FEAT_MAX
:
FEAT_MIN
);
if
(
ball
.
velValid
())
{
// SeverParam lists ballSpeedMax a 2.7 which is too low
addNormFeature
(
ball
.
vel
().
r
(),
0.
,
observedBallSpeedMax
);
addAngFeature
(
ball
.
vel
().
th
());
}
else
{
addFeature
(
0
);
addFeature
(
0
);
addFeature
(
0
);
//
dist to our closest opp
if
(
numOpponents
>
0
)
{
calcClosestOpp
(
wm
,
self_pos
,
th
,
r
);
addNormFeature
(
r
,
0
,
maxR
);
//addNormFeature(th,-M_PI,M_PI);
// teammates dists to closest opps
detected_teammates
=
0
;
for
(
PlayerCont
::
const_iterator
it
=
teammates
.
begin
();
it
!=
teammates
.
end
();
++
it
)
{
const
PlayerObject
&
teammate
=
*
it
;
if
(
valid
(
teammate
)
&&
detected_teammates
<
numTeammates
)
{
//addNormFeature(calcClosestOpp(wm,teammate.pos),0,maxR);
calcClosestOpp
(
wm
,
teammate
.
pos
(),
th
,
r
);
addNormFeature
(
r
,
0
,
maxR
);
//addNormFeature(th,-M_PI,M_PI);
detected_teammates
++
;
}
}
// Add zero features for any missing teammates
for
(
int
i
=
detected_teammates
;
i
<
numTeammates
;
++
i
)
{
addFeature
(
FEAT_INVALID
);
}
}
assert
(
featIndx
==
num_basic_features
);
// ======================== TEAMMATE FEATURES ======================== //
// Vector of PlayerObject pointers sorted by increasing distance from self
int
detected_teammates
=
0
;
const
PlayerPtrCont
&
teammates
=
wm
.
teammatesFromSelf
();
for
(
PlayerPtrCont
::
const_iterator
it
=
teammates
.
begin
();
it
!=
teammates
.
end
();
++
it
)
{
PlayerObject
*
teammate
=
*
it
;
if
(
teammate
->
pos
().
x
>
0
&&
teammate
->
unum
()
>
0
&&
detected_teammates
<
numTeammates
)
{
addPlayerFeatures
(
*
teammate
,
self_pos
,
self_ang
);
// open angle to teammates
detected_teammates
=
0
;
for
(
PlayerCont
::
const_iterator
it
=
teammates
.
begin
();
it
!=
teammates
.
end
();
++
it
)
{
const
PlayerObject
&
teammate
=
*
it
;
if
(
valid
(
teammate
)
&&
detected_teammates
<
numTeammates
)
{
addNormFeature
(
calcLargestTeammateAngle
(
wm
,
self_pos
,
teammate
.
pos
()),
0
,
M_PI
);
detected_teammates
++
;
}
}
// Add zero features for any missing teammates
for
(
int
i
=
detected_teammates
;
i
<
numTeammates
;
++
i
)
{
for
(
int
j
=
0
;
j
<
features_per_player
;
++
j
)
{
addFeature
(
0
);
}
addFeature
(
FEAT_INVALID
);
}
// ======================== OPPONENT FEATURES ======================== //
int
detected_opponents
=
0
;
const
PlayerPtrCont
&
opponents
=
wm
.
opponentsFromSelf
();
for
(
PlayerPtrCont
::
const_iterator
it
=
opponents
.
begin
();
it
!=
opponents
.
end
();
++
it
)
{
PlayerObject
*
opponent
=
*
it
;
if
(
opponent
->
pos
().
x
>
0
&&
opponent
->
unum
()
>
0
&&
detected_opponents
<
numOpponents
)
{
addPlayerFeatures
(
*
opponent
,
self_pos
,
self_ang
);
detected_opponents
++
;
// dist and angle to teammates
detected_teammates
=
0
;
for
(
PlayerCont
::
const_iterator
it
=
teammates
.
begin
();
it
!=
teammates
.
end
();
++
it
)
{
const
PlayerObject
&
teammate
=
*
it
;
if
(
valid
(
teammate
)
&&
detected_teammates
<
numTeammates
)
{
angleDistToPoint
(
self_pos
,
teammate
.
pos
(),
th
,
r
);
addNormFeature
(
r
,
0
,
maxR
);
addNormFeature
(
th
,
-
M_PI
,
M_PI
);
detected_teammates
++
;
}
}
// Add zero features for any missing opponents
for
(
int
i
=
detected_opponents
;
i
<
numOpponents
;
++
i
)
{
for
(
int
j
=
0
;
j
<
features_per_player
;
++
j
)
{
addFeature
(
0
);
}
// Add zero features for any missing teammates
for
(
int
i
=
detected_teammates
;
i
<
numTeammates
;
++
i
)
{
addFeature
(
FEAT_INVALID
);
addFeature
(
FEAT_INVALID
);
}
assert
(
featIndx
==
numFeatures
);
checkFeatures
();
//std::cout << "features: " << features.rows(0,ind-1).t();
return
feature_vec
;
}
src/highlevel_feature_extractor.h
View file @
8c1fef0d
...
...
@@ -16,9 +16,9 @@ public:
protected:
// Number of features for non-player objects.
const
static
int
num_basic_features
=
58
;
const
static
int
num_basic_features
=
4
;
// Number of features for each player or opponent in game.
const
static
int
features_per_
player
=
8
;
const
static
int
features_per_
teammate
=
4
;
int
numTeammates
;
// Number of teammates in HFO
int
numOpponents
;
// Number of opponents in HFO
bool
playingOffense
;
// Are we playing offense or defense?
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment