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
You need to sign in or sign up before continuing.
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
Hide 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