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
ac50eb1d
Commit
ac50eb1d
authored
Aug 07, 2017
by
drallensmith
Browse files
Options
Browse Files
Download
Plain Diff
Merge in Reorient (add_preprocess_action) to help with testing without fullstate
parents
09d1c9f4
b9f7aa36
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
312 additions
and
42 deletions
+312
-42
doc/manual.pdf
doc/manual.pdf
+0
-0
doc/manual.tex
doc/manual.tex
+22
-20
example/defense_python_long_2v2.sh
example/defense_python_long_2v2.sh
+1
-0
example/hand_coded_defense_agent.py
example/hand_coded_defense_agent.py
+11
-6
example/high_action_random_agent.py
example/high_action_random_agent.py
+89
-0
example/high_level_random_agent.py
example/high_level_random_agent.py
+9
-3
example/python_agents_rpass_3v3.sh
example/python_agents_rpass_3v3.sh
+14
-0
example/random_high_action_2v1.sh
example/random_high_action_2v1.sh
+13
-0
hfo/hfo.py
hfo/hfo.py
+15
-7
src/agent.cpp
src/agent.cpp
+128
-0
src/agent.h
src/agent.h
+1
-0
src/common.hpp
src/common.hpp
+6
-1
tests/test_with_server.py
tests/test_with_server.py
+3
-5
No files found.
doc/manual.pdf
View file @
ac50eb1d
No preview for this file type
doc/manual.tex
View file @
ac50eb1d
...
@@ -594,6 +594,8 @@ faithfully report which action spaces were used.
...
@@ -594,6 +594,8 @@ faithfully report which action spaces were used.
\item
{
\textbf
{
Go
\_
To
\_
Ball
}
(): Makes the agent go towards the ball.
}
\item
{
\textbf
{
Go
\_
To
\_
Ball
}
(): Makes the agent go towards the ball.
}
\item
{
\textbf
{
Mark
\_
Player
}
(uniform
\_
number): Moves the agent so as to mark the player
\item
{
\textbf
{
Mark
\_
Player
}
(uniform
\_
number): Moves the agent so as to mark the player
with the specified uniform number.
}
with the specified uniform number.
}
\item
{
\textbf
{
Reorient
}
(): Deal with loss of self or ball localization information and with
some other situations; a modified version of the non-ball-dependent parts of Dribble.
}
\end{itemize}
\end{itemize}
...
@@ -611,29 +613,29 @@ below the table for the action abbreviations and notes.
...
@@ -611,29 +613,29 @@ below the table for the action abbreviations and notes.
\begin{center}
\begin{center}
{
\footnotesize
{
\footnotesize
\begin{tabular}
{
r | c c c c | c c c c | c c c c c c c c c
}
\begin{tabular}
{
r | c c c c | c c c c | c c c c c c c c c
c
}
Action
&
Da
&
Tu
&
Ta
&
K
&
KT
&
MT
&
DT
&
I
&
M
&
S
&
P
&
Dr
&
C
&
RG
&
DG
&
G
&
MP
\\
Action
&
Da
&
Tu
&
Ta
&
K
&
KT
&
MT
&
DT
&
I
&
M
&
S
&
P
&
Dr
&
C
&
RG
&
DG
&
G
&
MP
&
Re
\\
\hline
\hline
\hline
\hline
Self position invalid
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N?
&
N?
&
N
&
N?
&
N?
&
Y
&
?
&
N
&
N
&
N
&
N
\\
Self position invalid
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N?
&
N?
&
N
&
N?
&
N?
&
Y
&
?
&
N
&
N
&
N
&
N
&
Y
\\
Self velocity invalid
&
N
&
Y?
&
Y?
&
Y
&
?
&
N
&
N
&
N
&
N
&
?
&
?
&
Y
&
Y
&
N
&
N
&
N
&
N
\\
Self velocity invalid
&
N
&
Y?
&
Y?
&
Y
&
?
&
N
&
N
&
N
&
N
&
?
&
?
&
Y
&
Y
&
N
&
N
&
N
&
N
&
Y
\\
Ball position invalid
&
Y
&
Y
&
Y?
&
N
&
N
&
Y
&
N
&
N
&
N
&
N
&
N
&
Y
&
N
&
N
&
N
&
N
&
N
\\
Ball position invalid
&
Y
&
Y
&
Y?
&
N
&
N
&
Y
&
N
&
N
&
N
&
N
&
N
&
Y
&
N
&
N
&
N
&
N
&
N
&
Y
\\
Ball velocity invalid
&
Y
&
Y
&
Y
&
?
&
?
&
Y
&
Y
&
N?
&
?
&
N
&
N?
&
Y?
&
Y?
&
Y
&
Y
&
Y
&
Y
\\
Ball velocity invalid
&
Y
&
Y
&
Y
&
?
&
?
&
Y
&
Y
&
N?
&
?
&
N
&
N?
&
Y?
&
Y?
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Teammate loc invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
N
&
Y?
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Teammate loc invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
N
&
Y?
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Team. unum invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Team. unum invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Opponent loc invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y?
&
Y
&
N
&
Y?
&
Y
&
Y?
&
Y
&
Y
&
Y
&
Y
&
N
\\
Opponent loc invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y?
&
Y
&
N
&
Y?
&
Y
&
Y?
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
\\
Opp. unum invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
\\
Opp. unum invalid
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
\\
\hline
\hline
Ball kickable
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
N
&
*
&
Y
&
Y
&
Y
&
Y
&
?
&
?
&
N
&
Y
\\
Ball kickable
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
Y
&
N
&
*
&
Y
&
Y
&
Y
&
Y
&
?
&
?
&
N
&
Y
&
N
\\
Ball not kickable
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
\\
Ball not kickable
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
\\
\hline
\hline
Frozen
&
N
&
N
&
N
&
N
&
N
&
N
&
N?
&
N
&
N?
&
N
&
N
&
Y
&
N?
&
N
&
N
&
N
&
N
\\
Frozen
&
N
&
N
&
N
&
N
&
N
&
N
&
N?
&
N
&
N?
&
N
&
N
&
Y
&
N?
&
N
&
N
&
N
&
N
&
Y
\\
Colliding w/ball
&
Y
&
Y
&
?
&
N
&
Y
&
N
&
Y
&
Y
&
Y
&
?
&
Y
&
Y
&
?
&
?
&
?
&
N
&
?
\\
Colliding w/ball
&
Y
&
Y
&
?
&
N
&
Y
&
N
&
Y
&
Y
&
Y
&
?
&
Y
&
Y
&
?
&
?
&
?
&
N
&
?
&
N
\\
Colliding w/player
&
Y
&
Y
&
?
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
?
&
N
&
Y
&
?
&
?
&
?
&
Y
&
?
\\
Colliding w/player
&
Y
&
Y
&
?
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
?
&
N
&
Y
&
?
&
?
&
?
&
Y
&
?
&
N
\\
Colliding w/post
&
Y
&
Y
&
N?
&
Y
&
Y
&
Y
&
N
&
Y
&
Y
&
?
&
N
&
Y
&
?
&
Y
&
Y
&
Y
&
Y
\\
Colliding w/post
&
Y
&
Y
&
N?
&
Y
&
Y
&
Y
&
N
&
Y
&
Y
&
?
&
N
&
Y
&
?
&
Y
&
Y
&
Y
&
Y
&
N
\\
\hline
\hline
Offense
&
Y
&
Y
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N
&
Y
&
N
\\
Offense
&
Y
&
Y
&
N
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
Y
&
N
&
N
&
N
&
Y
&
N
&
Y
\\
Defense, not goalie
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
N
&
Y
&
Y
&
N
&
N
&
N
&
N
&
Y
&
?
&
Y
&
Y
\\
Defense, not goalie
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
N
&
Y
&
Y
&
N
&
N
&
N
&
N
&
Y
&
?
&
Y
&
Y
&
Y
\\
Goalie (defense)
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
N
&
Y
&
?
&
N
&
N
&
N
&
Y
&
?
&
?
&
?
&
N
\\
Goalie (defense)
&
Y
&
Y
&
Y
&
N
&
N
&
Y
&
N
&
Y
&
?
&
N
&
N
&
N
&
Y
&
?
&
?
&
?
&
N
&
Y
\\
\end{tabular}
\end{tabular}
}
}
\end{center}
\end{center}
...
@@ -641,7 +643,7 @@ Goalie (defense) & Y & Y & Y & N & N & Y & N & Y & ? & N & N &
...
@@ -641,7 +643,7 @@ Goalie (defense) & Y & Y & Y & N & N & Y & N & Y & ? & N & N &
\begin{itemize}
[noitemsep]
\begin{itemize}
[noitemsep]
\item
{
Da:
\,
Dash; Tu:
\,
Turn; Ta:
\,
Tackle; K:
\,
Kick
}
\item
{
Da:
\,
Dash; Tu:
\,
Turn; Ta:
\,
Tackle; K:
\,
Kick
}
\item
{
KT:
\,
Kick
\_
To; MT:
\,
Move
\_
To; DT:
\,
Dribble
\_
To; I:
\,
Intercept
}
\item
{
KT:
\,
Kick
\_
To; MT:
\,
Move
\_
To; DT:
\,
Dribble
\_
To; I:
\,
Intercept
}
\item
{
M:
\,
Move; S:
\,
Shoot; P:
\,
Pass; Dr:
\,
Dribble; C:
\,
Catch; RG:
\,
Reduce
\_
Angle
\_
To
\_
Goal; DG:
\,
Defend
\_
Goal; G:
\,
Go
\_
To
\_
Ball; MP:
\,
Mark
\_
Player
}
\item
{
M:
\,
Move; S:
\,
Shoot; P:
\,
Pass; Dr:
\,
Dribble; C:
\,
Catch; RG:
\,
Reduce
\_
Angle
\_
To
\_
Goal; DG:
\,
Defend
\_
Goal; G:
\,
Go
\_
To
\_
Ball; MP:
\,
Mark
\_
Player
; Re: Reorient
}
\end{itemize}
\end{itemize}
\section
{
Developing a New Agent
}
\section
{
Developing a New Agent
}
...
...
example/defense_python_long_2v2.sh
View file @
ac50eb1d
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
# Change to a different seed for different experiments!
# Change to a different seed for different experiments!
./bin/HFO
--offense-npcs
=
2
--defense-agents
=
1
--defense-npcs
=
1
--trials
5000
--headless
--seed
1500348586
--no-logging
--hfo-logging
&
./bin/HFO
--offense-npcs
=
2
--defense-agents
=
1
--defense-npcs
=
1
--trials
5000
--headless
--seed
1500348586
--no-logging
--hfo-logging
&
# Sleep is needed to make sure doesn't get connected too soon, as unum 1 (goalie)
# Sleep is needed to make sure doesn't get connected too soon, as unum 1 (goalie)
sleep
15
sleep
15
./example/hand_coded_defense_agent.py &> agent1.txt &
./example/hand_coded_defense_agent.py &> agent1.txt &
...
...
example/hand_coded_defense_agent.py
View file @
ac50eb1d
...
@@ -104,7 +104,7 @@ def do_defense_action(state_vec, hfo_env,
...
@@ -104,7 +104,7 @@ def do_defense_action(state_vec, hfo_env,
# if get high_level working for invalid
# if get high_level working for invalid
if
(
min
(
agent_pos_x
,
agent_pos_y
,
ball_pos_x
,
ball_pos_y
)
<
-
1
):
if
(
min
(
agent_pos_x
,
agent_pos_y
,
ball_pos_x
,
ball_pos_y
)
<
-
1
):
hfo_env
.
act
(
hfo
.
MOVE
)
# will be Reorient in that version
hfo_env
.
act
(
add_num_times
(
hfo
.
REORIENT
,
num_times_overall
))
return
return
ball_toward_goal
=
ball_moving_toward_goal
(
ball_pos_x
,
ball_pos_y
,
ball_toward_goal
=
ball_moving_toward_goal
(
ball_pos_x
,
ball_pos_y
,
...
@@ -118,11 +118,16 @@ def do_defense_action(state_vec, hfo_env,
...
@@ -118,11 +118,16 @@ def do_defense_action(state_vec, hfo_env,
if
not
ball_sorted_list
:
# unknown opponent positions/unums
if
not
ball_sorted_list
:
# unknown opponent positions/unums
print
(
"No known opponent locations (btg {0!r}; bng {1!r}; "
.
format
(
ball_toward_goal
,
print
(
"No known opponent locations (btg {0!r}; bng {1!r}; "
.
format
(
ball_toward_goal
,
ball_nearer_goal
)
+
ball_nearer_goal
)
+
"ball xy {0:n}, {1:n}; ball old xy {2:n}, {3:n})"
.
format
(
ball_pos_x
,
"ball xy {0:n}, {1:n}; ball old xy {2:n}, {3:n}
; kickable {4:n}
)"
.
format
(
ball_pos_x
,
ball_pos_y
,
ball_pos_y
,
old_ball_pos_x
,
old_ball_pos_x
,
old_ball_pos_y
))
old_ball_pos_y
,
if
ball_toward_goal
:
state_vec
[
5
]))
if
((
min
(
agent_pos_x
,
agent_pos_y
,
ball_pos_x
,
ball_pos_y
)
<=
-
1
)
or
(
max
(
agent_pos_x
,
agent_pos_y
,
ball_pos_x
,
ball_pos_y
)
>=
1
)):
# remove if get high-level working for invalid
hfo_env
.
act
(
add_num_times
(
hfo
.
REORIENT
,
num_times_overall
))
elif
ball_toward_goal
:
if
ball_nearer_goal
:
if
ball_nearer_goal
:
hfo_env
.
act
(
add_num_times
(
hfo
.
REDUCE_ANGLE_TO_GOAL
,
num_times_overall
))
hfo_env
.
act
(
add_num_times
(
hfo
.
REDUCE_ANGLE_TO_GOAL
,
num_times_overall
))
else
:
else
:
...
...
example/high_action_random_agent.py
0 → 100755
View file @
ac50eb1d
#!/usr/bin/env python
from
__future__
import
print_function
# encoding: utf-8
# Before running this program, first Start HFO server:
# $> ./bin/HFO --offense-agents 1
import
argparse
import
itertools
import
random
try
:
import
hfo
except
ImportError
:
print
(
'Failed to import hfo. To install hfo, in the HFO directory'
\
' run:
\"
pip install .
\"
'
)
exit
()
def
main
():
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
'--port'
,
type
=
int
,
default
=
6000
,
help
=
"Server port"
)
parser
.
add_argument
(
'--seed'
,
type
=
int
,
default
=
None
,
help
=
"Python randomization seed; uses python default if 0 or not given"
)
parser
.
add_argument
(
'--no-reorient'
,
action
=
'store_true'
,
help
=
"Do not use the new Reorient action"
)
parser
.
add_argument
(
'--record'
,
action
=
'store_true'
,
help
=
"Doing HFO --record"
)
parser
.
add_argument
(
'--rdir'
,
type
=
str
,
default
=
'log/'
,
help
=
"Set directory to use if doing HFO --record"
)
args
=
parser
.
parse_args
()
if
args
.
seed
:
random
.
seed
(
args
.
seed
)
# Create the HFO Environment
hfo_env
=
hfo
.
HFOEnvironment
()
# Connect to the server with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
if
args
.
record
:
hfo_env
.
connectToServer
(
hfo
.
LOW_LEVEL_FEATURE_SET
,
'bin/teams/base/config/formations-dt'
,
args
.
port
,
'localhost'
,
'base_left'
,
False
,
record_dir
=
args
.
rdir
)
else
:
hfo_env
.
connectToServer
(
hfo
.
LOW_LEVEL_FEATURE_SET
,
'bin/teams/base/config/formations-dt'
,
args
.
port
,
'localhost'
,
'base_left'
,
False
)
if
args
.
seed
:
print
(
"Python randomization seed: {0:d}"
.
format
(
args
.
seed
))
for
episode
in
itertools
.
count
():
num_reorient
=
0
num_move
=
0
num_had_ball
=
0
status
=
hfo
.
IN_GAME
while
status
==
hfo
.
IN_GAME
:
# Get the vector of state features for the current state
state
=
hfo_env
.
getState
()
# Perform the action
# 8 is frozen; 0 is self position valid, 1 is self velocity valid, 54 is ball velocity valid
if
(((
state
[
8
]
>
0
)
or
(
min
(
state
[
0
],
state
[
1
],
state
[
54
])
<
0
))
and
not
args
.
no_reorient
):
hfo_env
.
act
(
hfo
.
REORIENT
)
num_reorient
+=
1
elif
state
[
12
]
>
0
:
# State[12] is 1 when the player can kick the ball
if
random
.
random
()
<
0.5
:
# more efficient than random.choice for 2
hfo_env
.
act
(
hfo
.
SHOOT
)
else
:
hfo_env
.
act
(
hfo
.
DRIBBLE
)
num_had_ball
+=
1
# 50 is ball position valild
elif
(
state
[
50
]
<
0
)
and
not
args
.
no_reorient
:
hfo_env
.
act
(
hfo
.
REORIENT
)
num_reorient
+=
1
else
:
hfo_env
.
act
(
hfo
.
MOVE
)
num_move
+=
1
# Advance the environment and get the game status
status
=
hfo_env
.
step
()
# Check the outcome of the episode
print
(
"Episode {0:d} ended with status {1}"
.
format
(
episode
,
hfo_env
.
statusToString
(
status
)))
print
(
"
\t
Had ball: {0:d}; Reorient: {1:d}; Move: {2:d}"
.
format
(
num_had_ball
,
num_reorient
,
num_move
))
# Quit if the server goes down
if
status
==
hfo
.
SERVER_DOWN
:
hfo_env
.
act
(
hfo
.
QUIT
)
exit
()
if
__name__
==
'__main__'
:
main
()
example/high_level_random_agent.py
View file @
ac50eb1d
#!/usr/bin/env python
#!/usr/bin/env python
from
__future__
import
print_function
# encoding: utf-8
# encoding: utf-8
# Before running this program, first Start HFO server:
# Before running this program, first Start HFO server:
...
@@ -23,9 +24,9 @@ def main():
...
@@ -23,9 +24,9 @@ def main():
parser
.
add_argument
(
'--seed'
,
type
=
int
,
default
=
None
,
parser
.
add_argument
(
'--seed'
,
type
=
int
,
default
=
None
,
help
=
"Python randomization seed; uses python default if 0 or not given"
)
help
=
"Python randomization seed; uses python default if 0 or not given"
)
parser
.
add_argument
(
'--record'
,
action
=
'store_true'
,
parser
.
add_argument
(
'--record'
,
action
=
'store_true'
,
help
=
"
D
oing HFO --record"
)
help
=
"
If d
oing HFO --record"
)
parser
.
add_argument
(
'--rdir'
,
type
=
str
,
default
=
'log/'
,
parser
.
add_argument
(
'--rdir'
,
type
=
str
,
default
=
'log/'
,
help
=
"Set directory to use if doing
HFO
--record"
)
help
=
"Set directory to use if doing --record"
)
args
=
parser
.
parse_args
()
args
=
parser
.
parse_args
()
if
args
.
seed
:
if
args
.
seed
:
random
.
seed
(
args
.
seed
)
random
.
seed
(
args
.
seed
)
...
@@ -42,6 +43,10 @@ def main():
...
@@ -42,6 +43,10 @@ def main():
hfo_env
.
connectToServer
(
hfo
.
HIGH_LEVEL_FEATURE_SET
,
hfo_env
.
connectToServer
(
hfo
.
HIGH_LEVEL_FEATURE_SET
,
'bin/teams/base/config/formations-dt'
,
args
.
port
,
'bin/teams/base/config/formations-dt'
,
args
.
port
,
'localhost'
,
'base_left'
,
False
)
'localhost'
,
'base_left'
,
False
)
if
args
.
seed
:
print
(
"Python randomization seed: {0:d}"
.
format
(
args
.
seed
))
for
episode
in
itertools
.
count
():
for
episode
in
itertools
.
count
():
status
=
hfo
.
IN_GAME
status
=
hfo
.
IN_GAME
while
status
==
hfo
.
IN_GAME
:
while
status
==
hfo
.
IN_GAME
:
...
@@ -59,8 +64,9 @@ def main():
...
@@ -59,8 +64,9 @@ def main():
status
=
hfo_env
.
step
()
status
=
hfo_env
.
step
()
# Check the outcome of the episode
# Check the outcome of the episode
end_status
=
hfo_env
.
statusToString
(
status
)
end_status
=
hfo_env
.
statusToString
(
status
)
print
(
"Episode {
} ended with {
}"
.
format
(
episode
,
end_status
))
print
(
"Episode {
0:n} ended with {1:s
}"
.
format
(
episode
,
end_status
))
# Quit if the server goes down
# Quit if the server goes down
if
status
==
hfo
.
SERVER_DOWN
:
if
status
==
hfo
.
SERVER_DOWN
:
...
...
example/python_agents_rpass_3v3.sh
0 → 100755
View file @
ac50eb1d
#!/bin/bash
./bin/HFO
--offense-agents
=
2
--defense-npcs
=
3
--offense-npcs
=
1
--trials
20
--headless
&
sleep
5
# -x is needed to skip first line - otherwise whatever default python version is will run
python2.7
-x
./example/high_level_custom_agent.py
--numTeammates
=
2
--numOpponents
=
3
--rand-pass
--port
6000 &> agent1.txt &
sleep
5
python3
-x
./example/high_level_custom_agent.py
--numTeammates
=
2
--numOpponents
=
3
--rand-pass
--port
6000 &> agent2.txt &
# The magic line
# $$ holds the PID for this script
# Negation means kill by process group id instead of PID
trap
"kill -TERM -
$$
"
SIGINT
wait
example/random_high_action_2v1.sh
0 → 100755
View file @
ac50eb1d
#!/bin/bash
./bin/HFO
--offense-agents
=
2
--defense-npcs
=
1
--trials
20
--headless
&
sleep
5
python2.7
-x
example/high_action_random_agent.py
--port
6000 &> agent1.txt &
sleep
5
python3
-x
example/high_action_random_agent.py
--port
6000 &> agent2.txt &
# The magic line
# $$ holds the PID for this script
# Negation means kill by process group id instead of PID
trap
"kill -TERM -
$$
"
SIGINT
wait
hfo/hfo.py
View file @
ac50eb1d
...
@@ -28,8 +28,8 @@ An enum of the possible HFO actions, including:
...
@@ -28,8 +28,8 @@ An enum of the possible HFO actions, including:
NOOP(): Do Nothing
NOOP(): Do Nothing
QUIT(): Quit the game
QUIT(): Quit the game
"""
"""
NUM_HFO_ACTIONS
=
19
NUM_HFO_ACTIONS
=
20
DASH
,
TURN
,
TACKLE
,
KICK
,
KICK_TO
,
MOVE_TO
,
DRIBBLE_TO
,
INTERCEPT
,
MOVE
,
SHOOT
,
PASS
,
DRIBBLE
,
CATCH
,
NOOP
,
QUIT
,
REDUCE_ANGLE_TO_GOAL
,
MARK_PLAYER
,
DEFEND_GOAL
,
GO_TO_BALL
=
list
(
range
(
NUM_HFO_ACTIONS
))
DASH
,
TURN
,
TACKLE
,
KICK
,
KICK_TO
,
MOVE_TO
,
DRIBBLE_TO
,
INTERCEPT
,
MOVE
,
SHOOT
,
PASS
,
DRIBBLE
,
CATCH
,
NOOP
,
QUIT
,
REDUCE_ANGLE_TO_GOAL
,
MARK_PLAYER
,
DEFEND_GOAL
,
GO_TO_BALL
,
REORIENT
=
list
(
range
(
NUM_HFO_ACTIONS
))
ACTION_STRINGS
=
{
DASH
:
"Dash"
,
ACTION_STRINGS
=
{
DASH
:
"Dash"
,
TURN
:
"Turn"
,
TURN
:
"Turn"
,
TACKLE
:
"Tackle"
,
TACKLE
:
"Tackle"
,
...
@@ -48,7 +48,8 @@ ACTION_STRINGS = {DASH: "Dash",
...
@@ -48,7 +48,8 @@ ACTION_STRINGS = {DASH: "Dash",
REDUCE_ANGLE_TO_GOAL
:
"Reduce_Angle_To_Goal"
,
REDUCE_ANGLE_TO_GOAL
:
"Reduce_Angle_To_Goal"
,
MARK_PLAYER
:
"Mark_Player"
,
MARK_PLAYER
:
"Mark_Player"
,
DEFEND_GOAL
:
"Defend_Goal"
,
DEFEND_GOAL
:
"Defend_Goal"
,
GO_TO_BALL
:
"Go_To_Ball"
}
GO_TO_BALL
:
"Go_To_Ball"
,
REORIENT
:
"Reorient"
}
"""
"""
Possible game statuses:
Possible game statuses:
...
@@ -132,7 +133,7 @@ class HFOEnvironment(object):
...
@@ -132,7 +133,7 @@ class HFOEnvironment(object):
play_goalie
=
False
,
play_goalie
=
False
,
record_dir
=
''
):
record_dir
=
''
):
"""
"""
Connect to the server on the specified port. The
Connect
s
to the server on the specified port. The
following information is provided by the ./bin/HFO
following information is provided by the ./bin/HFO
feature_set: High or low level state features
feature_set: High or low level state features
...
@@ -143,7 +144,14 @@ class HFOEnvironment(object):
...
@@ -143,7 +144,14 @@ class HFOEnvironment(object):
play_goalie: is this player the goalie
play_goalie: is this player the goalie
record_dir: record agent's states/actions/rewards to this directory
record_dir: record agent's states/actions/rewards to this directory
"""
"""
hfo_lib
.
connectToServer
(
self
.
obj
,
feature_set
,
config_dir
.
encode
(
'utf-8'
),
server_port
,
server_addr
.
encode
(
'utf-8'
),
team_name
.
encode
(
'utf-8'
),
play_goalie
,
record_dir
.
encode
(
'utf-8'
))
hfo_lib
.
connectToServer
(
self
.
obj
,
feature_set
,
config_dir
.
encode
(
'utf-8'
),
server_port
,
server_addr
.
encode
(
'utf-8'
),
team_name
.
encode
(
'utf-8'
),
play_goalie
,
record_dir
.
encode
(
'utf-8'
))
def
getStateSize
(
self
):
def
getStateSize
(
self
):
""" Returns the number of state features """
""" Returns the number of state features """
return
hfo_lib
.
getStateSize
(
self
.
obj
)
return
hfo_lib
.
getStateSize
(
self
.
obj
)
...
@@ -164,7 +172,7 @@ class HFOEnvironment(object):
...
@@ -164,7 +172,7 @@ class HFOEnvironment(object):
hfo_lib
.
act
(
self
.
obj
,
action_type
,
params
.
ctypes
.
data_as
(
POINTER
(
c_float
)))
hfo_lib
.
act
(
self
.
obj
,
action_type
,
params
.
ctypes
.
data_as
(
POINTER
(
c_float
)))
def
say
(
self
,
message
):
def
say
(
self
,
message
):
""" Transmit a message """
""" Transmit
s
a message """
hfo_lib
.
say
(
self
.
obj
,
message
.
encode
(
'utf-8'
))
hfo_lib
.
say
(
self
.
obj
,
message
.
encode
(
'utf-8'
))
def
hear
(
self
):
def
hear
(
self
):
...
@@ -188,7 +196,7 @@ class HFOEnvironment(object):
...
@@ -188,7 +196,7 @@ class HFOEnvironment(object):
return
STATUS_STRINGS
[
status
]
return
STATUS_STRINGS
[
status
]
def
getUnum
(
self
):
def
getUnum
(
self
):
""" Return the uniform number of the agent """
""" Return
s
the uniform number of the agent """
return
hfo_lib
.
getUnum
(
self
.
obj
)
return
hfo_lib
.
getUnum
(
self
.
obj
)
def
getNumTeammates
(
self
):
def
getNumTeammates
(
self
):
...
...
src/agent.cpp
View file @
ac50eb1d
...
@@ -358,6 +358,9 @@ void Agent::actionImpl() {
...
@@ -358,6 +358,9 @@ void Agent::actionImpl() {
case
GO_TO_BALL
:
case
GO_TO_BALL
:
addLastActionStatus
(
GO_TO_BALL
,
this
->
doGoToBall
());
addLastActionStatus
(
GO_TO_BALL
,
this
->
doGoToBall
());
break
;
break
;
case
REORIENT
:
addLastActionStatus
(
REORIENT
,
this
->
doReorient
());
break
;
default:
default:
std
::
cerr
<<
"ERROR: Unsupported Action: "
std
::
cerr
<<
"ERROR: Unsupported Action: "
<<
requested_action
<<
std
::
endl
;
<<
requested_action
<<
std
::
endl
;
...
@@ -737,6 +740,131 @@ Agent::doPreprocess()
...
@@ -737,6 +740,131 @@ Agent::doPreprocess()
return
false
;
return
false
;
}
}
/*-------------------------------------------------------------------*/
/*!
Alternative high-level action to always doing "Move"; usable by either side, although
probably more useful for offense. Variant of doPreprocess (above), which is called by doDribble.
*/
action_status_t
Agent
::
doReorient
()
{
// check tackle expires
// check self position accuracy
// ball search
// check queued intention
const
WorldModel
&
wm
=
this
->
world
();
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": (doPreProcessAsAction)"
);
//
// frozen by tackle effect
//
if
(
wm
.
self
().
isFrozen
()
)
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": tackle wait. expires= %d"
,
wm
.
self
().
tackleExpires
()
);
// face neck to ball
this
->
setViewAction
(
new
View_Tactical
()
);
this
->
setNeckAction
(
new
Neck_TurnToBallOrScan
()
);
return
ACTION_STATUS_MAYBE
;
}
//
// BeforeKickOff or AfterGoal. jump to the initial position
//
if
(
wm
.
gameMode
().
type
()
==
GameMode
::
BeforeKickOff
||
wm
.
gameMode
().
type
()
==
GameMode
::
AfterGoal_
)
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": before_kick_off"
);
Vector2D
move_point
=
Strategy
::
i
().
getPosition
(
wm
.
self
().
unum
()
);
Bhv_CustomBeforeKickOff
(
move_point
).
execute
(
this
);
this
->
setViewAction
(
new
View_Tactical
()
);
return
ACTION_STATUS_MAYBE
;
}
//
// self localization error
//
if
(
!
(
wm
.
self
().
posValid
()
&&
wm
.
self
().
velValid
()
)
)
{
if
(
!
wm
.
self
().
posValid
()
)
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": invalid my pos"
);
}
else
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": invalid my vel"
);
}
if
(
Bhv_Emergency
().
execute
(
this
))
{
// includes change view
return
ACTION_STATUS_MAYBE
;
}
else
{
return
ACTION_STATUS_UNKNOWN
;
}
}
//
// set default change view
//
this
->
setViewAction
(
new
View_Tactical
()
);
//
// ball localization error
//
const
int
count_thr
=
(
wm
.
self
().
goalie
()
?
10
:
5
);
if
(
wm
.
ball
().
posCount
()
>
count_thr
||
(
wm
.
gameMode
().
type
()
!=
GameMode
::
PlayOn
&&
wm
.
ball
().
seenPosCount
()
>
count_thr
+
10
)
)
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": search ball"
);
if
(
Bhv_NeckBodyToBall
().
execute
(
this
))
{
return
ACTION_STATUS_MAYBE
;
}
else
{
return
ACTION_STATUS_UNKNOWN
;
}
}
//
// check queued action
//
if
(
this
->
doIntention
()
)
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": do queued intention"
);
return
ACTION_STATUS_MAYBE
;
}
//
// check pass message
//
if
(
doHeardPassReceive
()
)
{
return
ACTION_STATUS_MAYBE
;
}
const
BallObject
&
ball
=
wm
.
ball
();
if
(
!
(
ball
.
rposValid
()
&&
ball
.
velValid
()
))
{
dlog
.
addText
(
Logger
::
TEAM
,
__FILE__
": search ball"
);
if
(
Bhv_NeckBodyToBall
().
execute
(
this
))
{
return
ACTION_STATUS_MAYBE
;
}
else
{
return
ACTION_STATUS_UNKNOWN
;
}
}
return
ACTION_STATUS_BAD
;
}
/*-------------------------------------------------------------------*/
/*-------------------------------------------------------------------*/
/*!
/*!
...
...
src/agent.h
View file @
ac50eb1d
...
@@ -85,6 +85,7 @@ protected:
...
@@ -85,6 +85,7 @@ protected:
private:
private:
bool
doPreprocess
();
bool
doPreprocess
();
hfo
::
action_status_t
doReorient
();
hfo
::
action_status_t
doSmartKick
();
hfo
::
action_status_t
doSmartKick
();
hfo
::
action_status_t
doShoot
();
hfo
::
action_status_t
doShoot
();
bool
doPass
();
bool
doPass
();
...
...
src/common.hpp
View file @
ac50eb1d
...
@@ -38,7 +38,8 @@ enum action_t
...
@@ -38,7 +38,8 @@ enum action_t
REDUCE_ANGLE_TO_GOAL
,
// [High-Level] Reduce_Angle_To_Goal : Reduces the shooting angle
REDUCE_ANGLE_TO_GOAL
,
// [High-Level] Reduce_Angle_To_Goal : Reduces the shooting angle
MARK_PLAYER
,
// [High-Level] Mark_Player(opponent_unum [0,11]) : Moves to the position in between the kicker and a given player
MARK_PLAYER
,
// [High-Level] Mark_Player(opponent_unum [0,11]) : Moves to the position in between the kicker and a given player
DEFEND_GOAL
,
DEFEND_GOAL
,
GO_TO_BALL
GO_TO_BALL
,
REORIENT
// [High-Level] Handle lost position of self/ball, misc other situations; variant of doPreprocess called in DRIBBLE
};
};
// Status of an HFO game
// Status of an HFO game
...
@@ -136,6 +137,8 @@ inline int NumParams(const action_t action) {
...
@@ -136,6 +137,8 @@ inline int NumParams(const action_t action) {
return
0
;
return
0
;
case
GO_TO_BALL
:
case
GO_TO_BALL
:
return
0
;
return
0
;
case
REORIENT
:
return
0
;
}
}
std
::
cerr
<<
"Unrecognized Action: "
<<
action
<<
std
::
endl
;
std
::
cerr
<<
"Unrecognized Action: "
<<
action
<<
std
::
endl
;
return
-
1
;
return
-
1
;
...
@@ -184,6 +187,8 @@ inline std::string ActionToString(action_t action) {
...
@@ -184,6 +187,8 @@ inline std::string ActionToString(action_t action) {
return
"Defend_Goal"
;
return
"Defend_Goal"
;
case
GO_TO_BALL
:
case
GO_TO_BALL
:
return
"Go_To_Ball"
;
return
"Go_To_Ball"
;
case
REORIENT
:
return
"Reorient"
;
default:
default:
return
"Unknown"
;
return
"Unknown"
;
}
}
...
...
tests/test_with_server.py
View file @
ac50eb1d
...
@@ -67,13 +67,11 @@ def test_with_server():
...
@@ -67,13 +67,11 @@ def test_with_server():
state
=
try_step
()
state
=
try_step
()
for
x
in
range
(
0
,
2
0
):
for
x
in
range
(
0
,
2
5
):
if
int
(
state
[
12
])
==
1
:
# can kick the ball
if
int
(
state
[
12
])
==
1
:
# can kick the ball
hfo_env
.
act
(
hfo
.
DRIBBLE
)
hfo_env
.
act
(
hfo
.
DRIBBLE
)
elif
(
x
%
2
)
!=
0
:
elif
(
state
[
50
]
<
0
)
or
(
state
[
0
]
<
0
)
or
(
state
[
1
]
<
0
)
or
(
state
[
54
]
<
0
):
hfo_env
.
act
(
hfo
.
MOVE
)
hfo_env
.
act
(
hfo
.
REORIENT
)
elif
int
(
state
[
50
])
==
1
:
# can see the ball
hfo_env
.
act
(
hfo
.
GO_TO_BALL
)
else
:
else
:
hfo_env
.
act
(
hfo
.
MOVE
)
hfo_env
.
act
(
hfo
.
MOVE
)
...
...
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