Commit abc00c38 authored by Matthew Hausknecht's avatar Matthew Hausknecht

Refactored agent-environment interaction.

parent e0d61860
...@@ -31,9 +31,10 @@ int main(int argc, char** argv) { ...@@ -31,9 +31,10 @@ int main(int argc, char** argv) {
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
int unum = hfo.getUnum(); int unum = hfo.getUnum();
for (int episode=0; episode<10; episode++) { status_t status = IN_GAME;
for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
int agent_on_ball = 7; int agent_on_ball = 7;
status_t status = IN_GAME;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState(); const vector<float>& feature_vec = hfo.getState();
...@@ -70,7 +71,7 @@ int main(int argc, char** argv) { ...@@ -70,7 +71,7 @@ int main(int argc, char** argv) {
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -24,9 +24,9 @@ int main() { ...@@ -24,9 +24,9 @@ int main() {
// manual for more information on feature sets. // manual for more information on feature sets.
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
// Play 5 episodes status_t status = IN_GAME;
for (int episode=0; episode<5; episode++) { for (int episode = 0; status != SERVER_DOWN; episode++) {
status_t status = IN_GAME; status = IN_GAME;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
const std::vector<float>& feature_vec = hfo.getState(); const std::vector<float>& feature_vec = hfo.getState();
...@@ -37,7 +37,7 @@ int main() { ...@@ -37,7 +37,7 @@ int main() {
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -17,11 +17,8 @@ string server_addr = "localhost"; ...@@ -17,11 +17,8 @@ string server_addr = "localhost";
string team_name = "base_left"; string team_name = "base_left";
bool goalie = false; bool goalie = false;
// Returns a random high-level action // We omit PASS & CATCH actions here
action_t get_random_high_lv_action() { action_t HIGH_LEVEL_ACTIONS[3] = { MOVE, SHOOT, DRIBBLE };
action_t action_indx = (action_t) ((rand() % 5) + MOVE);
return action_indx;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
// Create the HFO environment // Create the HFO environment
...@@ -29,20 +26,21 @@ int main(int argc, char** argv) { ...@@ -29,20 +26,21 @@ int main(int argc, char** argv) {
// Connect to the server and request high-level feature set. See // Connect to the server and request high-level feature set. See
// manual for more information on feature sets. // manual for more information on feature sets.
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
for (int episode=0; episode<10; episode++) { status_t status = IN_GAME;
status_t status = IN_GAME; for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState(); const vector<float>& feature_vec = hfo.getState();
// Perform the action // Perform the action
hfo.act(get_random_high_lv_action()); hfo.act(HIGH_LEVEL_ACTIONS[rand() % 3]);
// Advance the environment and get the game status // Advance the environment and get the game status
status = hfo.step(); status = hfo.step();
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl; << StatusToString(status) << endl;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -52,9 +52,10 @@ int main(int argc, char** argv) { ...@@ -52,9 +52,10 @@ int main(int argc, char** argv) {
// Connect to the server and request low-level feature set. See // Connect to the server and request low-level feature set. See
// manual for more information on feature sets. // manual for more information on feature sets.
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
for (int episode=0; episode<10; episode++) { status_t status = IN_GAME;
status_t status = IN_GAME; for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState(); const vector<float>& feature_vec = hfo.getState();
...@@ -64,7 +65,7 @@ int main(int argc, char** argv) { ...@@ -64,7 +65,7 @@ int main(int argc, char** argv) {
status = hfo.step(); status = hfo.step();
} }
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -28,8 +28,9 @@ int main(int argc, char** argv) { ...@@ -28,8 +28,9 @@ int main(int argc, char** argv) {
// manual for more information on feature sets. // manual for more information on feature sets.
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
for (int episode=0; episode<10; episode++) { status_t status = IN_GAME;
status_t status = IN_GAME; for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
int step = 0; int step = 0;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
...@@ -44,7 +45,7 @@ int main(int argc, char** argv) { ...@@ -44,7 +45,7 @@ int main(int argc, char** argv) {
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -26,8 +26,9 @@ int main(int argc, char** argv) { ...@@ -26,8 +26,9 @@ int main(int argc, char** argv) {
// manual for more information on feature sets. // manual for more information on feature sets.
hfo.connectToServer(features, config_dir, port, server_addr, hfo.connectToServer(features, config_dir, port, server_addr,
team_name, goalie); team_name, goalie);
for (int episode=0; episode < 10; episode++) { status_t status = IN_GAME;
status_t status = IN_GAME; for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
while (status == IN_GAME) { while (status == IN_GAME) {
// Get the vector of state features for the current state // Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState(); const vector<float>& feature_vec = hfo.getState();
...@@ -53,7 +54,7 @@ int main(int argc, char** argv) { ...@@ -53,7 +54,7 @@ int main(int argc, char** argv) {
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
...@@ -27,8 +27,9 @@ int main(int argc, char** argv) { ...@@ -27,8 +27,9 @@ int main(int argc, char** argv) {
team_name, goalie); team_name, goalie);
float target_x = .82; float target_x = .82;
float target_y = .9; float target_y = .9;
for (int episode = 0; episode < 10; episode++) { status_t status = IN_GAME;
status_t status = IN_GAME; for (int episode = 0; status != SERVER_DOWN; episode++) {
status = IN_GAME;
if (episode % 2 != 0) { if (episode % 2 != 0) {
target_x *= -1; target_x *= -1;
} else { } else {
...@@ -45,7 +46,7 @@ int main(int argc, char** argv) { ...@@ -45,7 +46,7 @@ int main(int argc, char** argv) {
} }
// Check what the outcome of the episode was // Check what the outcome of the episode was
cout << "Episode " << episode << " ended with status: " cout << "Episode " << episode << " ended with status: "
<< StatusToString(status) << std::endl;; << StatusToString(status) << endl;;
} }
hfo.act(QUIT); hfo.act(QUIT);
}; };
#!/bin/bash
./bin/HFO --offense-agents=2 --defense-npcs=1 --trials 100 --headless &
sleep 5
./example/high_level_random_agent 6000 &
sleep 5
./example/high_level_random_agent 6000 &
# The magic line
# $$ holds the PID for this script
# Negation means kill by process group id instead of PID
trap "kill -TERM -$$" SIGINT
wait
...@@ -56,15 +56,16 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set, ...@@ -56,15 +56,16 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set,
std::cerr << "Unable to start agent" << std::endl; std::cerr << "Unable to start agent" << std::endl;
exit(1); exit(1);
} }
assert(client->isServerAlive() == true);
// Do nothing until the agent begins getting state features // Do nothing until the agent begins getting state features
act(NOOP);
while (agent->getState().empty()) { while (agent->getState().empty()) {
act(NOOP); if (!client->isServerAlive()) {
agent->executeAction(); std::cerr << "Server Down!" << std::endl;
do { exit(1);
client->runStep(agent); }
} while (agent->lastPreActionTime() < agent->currentTime()); client->runStep(agent);
} }
current_cycle = agent->currentTime().cycle();
} }
const std::vector<float>& HFOEnvironment::getState() { const std::vector<float>& HFOEnvironment::getState() {
...@@ -109,36 +110,14 @@ Player HFOEnvironment::playerOnBall() { ...@@ -109,36 +110,14 @@ Player HFOEnvironment::playerOnBall() {
} }
status_t HFOEnvironment::step() { status_t HFOEnvironment::step() {
// Agent sends action to server assert(agent->currentTime().cycle() == current_cycle);
agent->executeAction(); while (agent->statusUpdateTime() <= current_cycle) {
// Wait until server replies with new game state
long start_cycle = agent->currentTime().cycle();
bool cycle_advanced = false;
bool end_of_trial = agent->getGameStatus() != IN_GAME;
bool still_eot = false;
int steps = 0;
do {
client->runStep(agent);
if (steps++ > MAX_STEPS) {
break;
}
if (!client->isServerAlive()) { if (!client->isServerAlive()) {
return SERVER_DOWN; return SERVER_DOWN;
} }
cycle_advanced = agent->currentTime().cycle() > start_cycle; client->runStep(agent);
} while (!cycle_advanced || agent->lastPreActionTime() < agent->currentTime());
// If the trial is over, wait until the next episode starts
if (end_of_trial) {
while (agent->getGameStatus() != IN_GAME) {
act(NOOP);
agent->executeAction();
do {
client->runStep(agent);
if (!client->isServerAlive()) {
return SERVER_DOWN;
}
} while (agent->lastPreActionTime() < agent->currentTime());
}
} }
assert(agent->currentTime().cycle() == (current_cycle + 1));
current_cycle = agent->currentTime().cycle();
return agent->getGameStatus(); return agent->getGameStatus();
} }
...@@ -59,6 +59,7 @@ class HFOEnvironment { ...@@ -59,6 +59,7 @@ class HFOEnvironment {
private: private:
rcsc::BasicClient* client; rcsc::BasicClient* client;
Agent* agent; Agent* agent;
long current_cycle;
}; };
} // namespace hfo } // namespace hfo
......
...@@ -99,6 +99,7 @@ Agent::Agent() ...@@ -99,6 +99,7 @@ Agent::Agent()
feature_extractor(NULL), feature_extractor(NULL),
lastTrainerMessageTime(-1), lastTrainerMessageTime(-1),
lastTeammateMessageTime(-1), lastTeammateMessageTime(-1),
lastStatusUpdateTime(-1),
game_status(IN_GAME), game_status(IN_GAME),
requested_action(NOOP) requested_action(NOOP)
{ {
...@@ -227,13 +228,6 @@ FeatureExtractor* Agent::getFeatureExtractor(feature_set_t feature_set_indx, ...@@ -227,13 +228,6 @@ FeatureExtractor* Agent::getFeatureExtractor(feature_set_t feature_set_indx,
} }
} }
// Instead of calling PlayerAgent::action() we instead call preAction
// which does everything up to actionImpl(). actionImpl() is then
// called in hfo::step(), PlayerAgent::executeAction().
void Agent::action() {
preAction();
}
/*! /*!
main decision main decision
virtual method in super class virtual method in super class
...@@ -312,9 +306,6 @@ void Agent::actionImpl() { ...@@ -312,9 +306,6 @@ void Agent::actionImpl() {
<< requested_action << std::endl; << requested_action << std::endl;
exit(1); exit(1);
} }
// Clear the action
requested_action = (hfo::action_t) -1;
params.clear();
// For now let's not worry about turning the neck or setting the vision. // For now let's not worry about turning the neck or setting the vision.
this->setViewAction(new View_Tactical()); this->setViewAction(new View_Tactical());
this->setNeckAction(new Neck_TurnToBallOrScan()); this->setNeckAction(new Neck_TurnToBallOrScan());
...@@ -342,7 +333,9 @@ Agent::handleActionStart() ...@@ -342,7 +333,9 @@ Agent::handleActionStart()
feature_set, num_teammates, num_opponents, playing_offense); feature_set, num_teammates, num_opponents, playing_offense);
} }
} }
hfo::ParseGameStatus(message, game_status); if (hfo::ParseGameStatus(message, game_status)) {
lastStatusUpdateTime = audioSensor().trainerMessageTime().cycle();
}
hfo::ParsePlayerOnBall(message, player_on_ball); hfo::ParsePlayerOnBall(message, player_on_ball);
lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle(); lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle();
} }
......
...@@ -22,14 +22,13 @@ public: ...@@ -22,14 +22,13 @@ public:
int num_opponents, int num_opponents,
bool playing_offense); bool playing_offense);
inline long statusUpdateTime() { return lastStatusUpdateTime; }
protected: protected:
// You can override this method. But you must call // You can override this method. But you must call
// PlayerAgent::initImpl() in this method. // PlayerAgent::initImpl() in this method.
virtual bool initImpl(rcsc::CmdLineParser& cmd_parser); virtual bool initImpl(rcsc::CmdLineParser& cmd_parser);
// We override PlayerAgent's Action function
virtual void action();
// main decision // main decision
virtual void actionImpl(); virtual void actionImpl();
...@@ -48,6 +47,7 @@ protected: ...@@ -48,6 +47,7 @@ protected:
FeatureExtractor* feature_extractor; // Extracts the features FeatureExtractor* feature_extractor; // Extracts the features
long lastTrainerMessageTime; // Last time the trainer sent a message long lastTrainerMessageTime; // Last time the trainer sent a message
long lastTeammateMessageTime; // Last time a teammate sent a message long lastTeammateMessageTime; // Last time a teammate sent a message
long lastStatusUpdateTime; // Last time we got a status update
hfo::status_t game_status; // Current status of the game hfo::status_t game_status; // Current status of the game
hfo::Player player_on_ball; // Player in posession of the ball hfo::Player player_on_ball; // Player in posession of the ball
std::vector<float> state; // Vector of current state features std::vector<float> state; // Vector of current state features
......
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