Commit ab0990d6 authored by Matthew Hausknecht's avatar Matthew Hausknecht

More work on the agent-environment interface.

parent a625a971
...@@ -17,8 +17,8 @@ string server_addr = "localhost"; ...@@ -17,8 +17,8 @@ string server_addr = "localhost";
string team_name = "base_left"; string team_name = "base_left";
bool goalie = false; bool goalie = false;
// We omit PASS & CATCH actions here // We omit PASS & CATCH & MOVE actions here
action_t HIGH_LEVEL_ACTIONS[3] = { MOVE, SHOOT, DRIBBLE }; action_t HIGH_LEVEL_ACTIONS[2] = { SHOOT, DRIBBLE };
int main(int argc, char** argv) { int main(int argc, char** argv) {
// Create the HFO environment // Create the HFO environment
...@@ -34,7 +34,11 @@ int main(int argc, char** argv) { ...@@ -34,7 +34,11 @@ int main(int argc, char** argv) {
// 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(HIGH_LEVEL_ACTIONS[rand() % 3]); if (feature_vec[5] == 1) { // Feature 5 is 1 when the player can kick the ball
hfo.act(HIGH_LEVEL_ACTIONS[rand() % 2]);
} else {
hfo.act(MOVE);
}
// Advance the environment and get the game status // Advance the environment and get the game status
status = hfo.step(); status = hfo.step();
} }
......
#!/bin/bash #!/bin/bash
./bin/HFO --offense-agents=2 --defense-npcs=1 --trials 100 --headless & ./bin/HFO --offense-agents=2 --defense-npcs=1 --trials 20 --headless &
sleep 5 sleep 5
./example/high_level_random_agent 6000 & ./example/high_level_random_agent 6000 &> agent1.txt &
sleep 5 sleep 5
./example/high_level_random_agent 6000 & ./example/high_level_random_agent 6000 &> agent2.txt &
# The magic line # The magic line
# $$ holds the PID for this script # $$ holds the PID for this script
......
...@@ -60,11 +60,21 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set, ...@@ -60,11 +60,21 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set,
act(NOOP); act(NOOP);
while (agent->getState().empty()) { while (agent->getState().empty()) {
if (!client->isServerAlive()) { if (!client->isServerAlive()) {
std::cerr << "Server Down!" << std::endl; std::cerr << "[ConnectToServer] Server Down!" << std::endl;
exit(1); exit(1);
} }
client->runStep(agent); ready_for_action = client->runStep(agent);
if (ready_for_action) {
agent->action();
}
} }
// Step until it is time to act
do {
ready_for_action = client->runStep(agent);
} while (!ready_for_action);
agent->ProcessTrainerMessages();
agent->ProcessTeammateMessages();
agent->UpdateFeatures();
current_cycle = agent->currentTime().cycle(); current_cycle = agent->currentTime().cycle();
} }
...@@ -111,12 +121,24 @@ Player HFOEnvironment::playerOnBall() { ...@@ -111,12 +121,24 @@ Player HFOEnvironment::playerOnBall() {
status_t HFOEnvironment::step() { status_t HFOEnvironment::step() {
assert(agent->currentTime().cycle() == current_cycle); assert(agent->currentTime().cycle() == current_cycle);
while (agent->statusUpdateTime() <= current_cycle) { assert(ready_for_action);
if (!client->isServerAlive()) {
// Execute the action
agent->action();
// Advance the environment by one step
do {
ready_for_action = client->runStep(agent);
if (!client->isServerAlive() || agent->getGameStatus() == SERVER_DOWN) {
return SERVER_DOWN; return SERVER_DOWN;
} }
client->runStep(agent); agent->ProcessTrainerMessages();
} } while (agent->statusUpdateTime() <= current_cycle || !ready_for_action);
// Update the state features
agent->ProcessTeammateMessages();
agent->UpdateFeatures();
assert(agent->currentTime().cycle() == (current_cycle + 1)); assert(agent->currentTime().cycle() == (current_cycle + 1));
current_cycle = agent->currentTime().cycle(); current_cycle = agent->currentTime().cycle();
return agent->getGameStatus(); return agent->getGameStatus();
......
...@@ -60,6 +60,7 @@ class HFOEnvironment { ...@@ -60,6 +60,7 @@ class HFOEnvironment {
rcsc::BasicClient* client; rcsc::BasicClient* client;
Agent* agent; Agent* agent;
long current_cycle; long current_cycle;
bool ready_for_action;
}; };
} // namespace hfo } // namespace hfo
......
...@@ -311,14 +311,9 @@ void Agent::actionImpl() { ...@@ -311,14 +311,9 @@ void Agent::actionImpl() {
this->setNeckAction(new Neck_TurnToBallOrScan()); this->setNeckAction(new Neck_TurnToBallOrScan());
} }
/*-------------------------------------------------------------------*/
/*!
*/
void void
Agent::handleActionStart() Agent::ProcessTrainerMessages()
{ {
// Process new trainer messages
if (audioSensor().trainerMessageTime().cycle() > lastTrainerMessageTime) { if (audioSensor().trainerMessageTime().cycle() > lastTrainerMessageTime) {
const std::string& message = audioSensor().trainerMessage(); const std::string& message = audioSensor().trainerMessage();
if (feature_extractor == NULL) { if (feature_extractor == NULL) {
...@@ -339,8 +334,11 @@ Agent::handleActionStart() ...@@ -339,8 +334,11 @@ Agent::handleActionStart()
hfo::ParsePlayerOnBall(message, player_on_ball); hfo::ParsePlayerOnBall(message, player_on_ball);
lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle(); lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle();
} }
}
// Process new teammate message void
Agent::ProcessTeammateMessages()
{
hear_msg.clear(); hear_msg.clear();
if (audioSensor().teammateMessageTime().cycle() > lastTeammateMessageTime) { if (audioSensor().teammateMessageTime().cycle() > lastTeammateMessageTime) {
const std::list<HearMessage> teammateMessages = audioSensor().teammateMessages(); const std::list<HearMessage> teammateMessages = audioSensor().teammateMessages();
...@@ -353,11 +351,22 @@ Agent::handleActionStart() ...@@ -353,11 +351,22 @@ Agent::handleActionStart()
} }
lastTeammateMessageTime = audioSensor().teammateMessageTime().cycle(); lastTeammateMessageTime = audioSensor().teammateMessageTime().cycle();
} }
}
// Update state features void
Agent::UpdateFeatures()
{
if (feature_extractor != NULL) { if (feature_extractor != NULL) {
state = feature_extractor->ExtractFeatures(this->world()); state = feature_extractor->ExtractFeatures(this->world());
} }
}
void
Agent::handleActionStart()
{
ProcessTrainerMessages();
ProcessTeammateMessages();
UpdateFeatures();
// Optionally write to logfile // Optionally write to logfile
#ifdef ELOG #ifdef ELOG
......
...@@ -24,6 +24,13 @@ public: ...@@ -24,6 +24,13 @@ public:
inline long statusUpdateTime() { return lastStatusUpdateTime; } inline long statusUpdateTime() { return lastStatusUpdateTime; }
// Process incoming trainer messages. Used to update the game status.
void ProcessTrainerMessages();
// Process incoming teammate messages.
void ProcessTeammateMessages();
// Update the state features from the world model.
void UpdateFeatures();
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.
......
...@@ -263,6 +263,8 @@ inline bool ParseGameStatus(const std::string& message, status_t& status) { ...@@ -263,6 +263,8 @@ inline bool ParseGameStatus(const std::string& message, status_t& status) {
status = OUT_OF_TIME; status = OUT_OF_TIME;
} else if (message.find("IN_GAME") != std::string::npos){ } else if (message.find("IN_GAME") != std::string::npos){
status = IN_GAME; status = IN_GAME;
} else if (message.find("HFO_FINISHED") != std::string::npos){
status = SERVER_DOWN;
} else { } else {
return false; return false;
} }
......
...@@ -146,7 +146,7 @@ bool FeatureExtractor::valid(const rcsc::PlayerObject& player) { ...@@ -146,7 +146,7 @@ bool FeatureExtractor::valid(const rcsc::PlayerObject& player) {
pos.x < -ALLOWED_PITCH_FRAC * rcsc::ServerParam::i().pitchHalfLength()) { pos.x < -ALLOWED_PITCH_FRAC * rcsc::ServerParam::i().pitchHalfLength()) {
return false; return false;
} }
return player.unum() > 0 && pos.isValid(); return pos.isValid();
} }
float FeatureExtractor::angleToPoint(const rcsc::Vector2D &self, float FeatureExtractor::angleToPoint(const rcsc::Vector2D &self,
......
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