Commit 734cd0e0 authored by Matthew Hausknecht's avatar Matthew Hausknecht Committed by GitHub

Merge pull request #30 from drallensmith/master

Documentation update; fullstate test program; hand_coded_defense_agent bug
parents 5f99d8fe 5c8d683f
......@@ -5,6 +5,7 @@ __pycache__/
# C extensions
*.so
*.a
*.o
# Distribution / packaging
.Python
......
......@@ -153,6 +153,10 @@ add_executable(high_level_random_agent ${CMAKE_CURRENT_SOURCE_DIR}/example/high_
set_target_properties(high_level_random_agent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/example)
target_link_libraries(high_level_random_agent hfo-lib)
add_executable(hand_coded_defense_agent ${CMAKE_CURRENT_SOURCE_DIR}/example/hand_coded_defense_agent.cpp)
set_target_properties(hand_coded_defense_agent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/example)
target_link_libraries(hand_coded_defense_agent hfo-lib)
add_executable(mid_level_move_agent ${CMAKE_CURRENT_SOURCE_DIR}/example/mid_level_move_agent.cpp)
set_target_properties(mid_level_move_agent PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/example)
target_link_libraries(mid_level_move_agent hfo-lib)
......
No preview for this file type
......@@ -438,6 +438,16 @@ player's body 3) the magnitude of the player's velocity and 4) the
global angle of the player's velocity. Eight floating point numbers
are used to encode each player feature.
\subsubsection{Uniform Number Features}
In the low-level feature space, unknown uniform numbers, or \textit{unums},
are encoded as -1, while known ones are encoded as $\frac{unum}{100}$, thus
remaining well within the $[-1, 1]$ range. (Note that roundoff error may need
to be allowed for when converting these back to integers, such as for use in
high-level actions; e.g., 0.0799 will need to be converted back to 8.)
Uniform number features, a later addition to the low-level feature space,
are positioned after all other features to hopefully ensure compatibility
with older programs.
\subsubsection{Other Features}
Some features, such as the agent's stamina, do not fall into any of
the above categories. These features are referred to as \textit{other
......@@ -445,7 +455,7 @@ the above categories. These features are referred to as \textit{other
\subsubsection{Low Level State Feature List}
Let $T$ denote the number of teammates and $O$ denote the number of
opponents in the HFO game. Then there are a total of $58 + 8T + 8O$
opponents in the HFO game. Then there are a total of $58 + 9T + 9O$
low-level features:
\begin{enumerate}[noitemsep]
......@@ -493,6 +503,8 @@ low-level features:
\itemrange{1}{\textbf{Ball Vel Ang} [Angle] Global angle of ball velocity.}
\item [$8T$] {\textbf{Teammate Features} [Player] One teammate feature set (8 features) for each teammate active in HFO, sorted by proximity to the agent.}
\item [$8O$] {\textbf{Opponent Features} [Player] One opponent feature set (8 features) for each opponent present, sorted by proximity to the player.}
\item [$T$] {\textbf{Teammate Uniform Nums} [Unum] One uniform number for each teammate active in HFO, sorted by proximity to the agent.}
\item [$O$] {\textbf{Opponent Uniform Nums} [Unum] One uniform number for each opponent present, sorted by proximity to the player.}
\end{enumerate}
\section{Action Space}
......
......@@ -104,7 +104,7 @@ action_with_params get_defense_action(const std::vector<float>& state_vec, doubl
//std:: cout << "In open Area" << "\n";
if (is_kickable(ball_pos_x, ball_pos_y, opp1_pos_x, opp1_pos_y) &&
get_dist_normalized(ball_pos_x, ball_pos_y, opp1_pos_x, opp1_pos_y) <
get_dist_normalized(ball_pos_x, ball_pos_y, opp1_pos_x, opp1_pos_y)) {
get_dist_normalized(ball_pos_x, ball_pos_y, opp2_pos_x, opp2_pos_y)) {
return {MARK_PLAYER, opp2_unum};
// return {REDUCE_ANGLE_TO_GOAL, 1};
......
"""A few tests using a server (and --fullstate so that know will 'see' uniform numbers)"""
from __future__ import print_function
import os
import subprocess
import sys
import time
import hfo
hfo_env = hfo.HFOEnvironment()
def try_step(): # if a game ends within ~5 frames, something is wrong...
status = hfo_env.step()
assert (status ==
hfo.IN_GAME), ("Status is {!s} ({!r}), not IN_GAME".
format(hfo_env.statusToString(status),status))
return hfo_env.getState()
def test_with_server():
test_dir = os.path.dirname(os.path.abspath(os.path.realpath(__file__)))
binary_dir = os.path.normpath(test_dir + "/../bin")
conf_dir = os.path.join(binary_dir, 'teams/base/config/formations-dt')
bin_HFO = os.path.join(binary_dir, "HFO")
popen_list = [sys.executable, "-x", bin_HFO,
"--offense-agents=1", "--defense-npcs=2",
"--offense-npcs=2", "--trials=1", "--headless",
"--fullstate"]
HFO_process = subprocess.Popen(popen_list)
time.sleep(0.2)
assert (HFO_process.poll() is
None), "Failed to start HFO with command '{}'".format(" ".join(popen_list))
time.sleep(3)
try:
hfo_env.connectToServer(config_dir=conf_dir) # using defaults otherwise
min_state_size = 58+(9*4)
state_size = hfo_env.getStateSize()
assert (state_size >=
min_state_size), "State size is {!s}, not {!s}+".format(state_size,min_state_size)
print("State size is {!s}".format(state_size))
my_unum = hfo_env.getUnum()
assert ((my_unum > 0) and (my_unum <= 11)), "Wrong self uniform number ({!r})".format(my_unum)
print("My unum is {!s}".format(my_unum))
had_ok_unum = False
had_ok_unum_set_my_side = set()
had_ok_unum_set_their_side = set();
hfo_env.act(hfo.NOOP)
state = try_step()
for x in range(0,5):
if int(state[12]) == 1: # can kick the ball
hfo_env.act(hfo.DRIBBLE)
else:
hfo_env.act(hfo.MOVE)
state = try_step()
for n in range((state_size-4), state_size):
their_unum = state[n]
if ((their_unum > 0) and (their_unum <= 0.11)):
print("{!s}: OK uniform number ({!r}) for {!s}".format(x,their_unum,n))
had_ok_unum = True
if n > (state_size-3):
had_ok_unum_set_their_side.add(their_unum)
else:
had_ok_unum_set_my_side.add(their_unum)
elif x > 3:
print("{!s}: Wrong other uniform number ({!r}) for {!s}".format(x,their_unum,n))
if (len(had_ok_unum_set_my_side) > 1) and (len(had_ok_unum_set_their_side) > 1):
break
assert had_ok_unum, "Never saw OK other uniform number"
try:
hfo_env.act(hfo.MOVE_TO)
except AssertionError:
pass
else:
raise AssertionError("Should have got AssertionError")
HFO_process.terminate()
hfo_env.act(hfo.QUIT)
time.sleep(1.2)
status = hfo_env.step()
assert (status ==
hfo.SERVER_DOWN), ("Status is {!s} ({!r}), not SERVER_DOWN".
format(hfo_env.statusToString(status), status))
finally:
if HFO_process.poll() is None:
HFO_process.terminate()
os.system("killall -9 rcssserver")
if __name__ == '__main__':
test_with_server()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment