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";
string team_name = "base_left";
bool goalie = false;
// We omit PASS & CATCH actions here
action_t HIGH_LEVEL_ACTIONS[3] = { MOVE, SHOOT, DRIBBLE };
// We omit PASS & CATCH & MOVE actions here
action_t HIGH_LEVEL_ACTIONS[2] = { SHOOT, DRIBBLE };
int main(int argc, char** argv) {
// Create the HFO environment
......@@ -34,7 +34,11 @@ int main(int argc, char** argv) {
// Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState();
// 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
status = hfo.step();
}
......
#!/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
./example/high_level_random_agent 6000 &
./example/high_level_random_agent 6000 &> agent1.txt &
sleep 5
./example/high_level_random_agent 6000 &
./example/high_level_random_agent 6000 &> agent2.txt &
# The magic line
# $$ holds the PID for this script
......
......@@ -60,11 +60,21 @@ void HFOEnvironment::connectToServer(feature_set_t feature_set,
act(NOOP);
while (agent->getState().empty()) {
if (!client->isServerAlive()) {
std::cerr << "Server Down!" << std::endl;
std::cerr << "[ConnectToServer] Server Down!" << std::endl;
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();
}
......@@ -111,12 +121,24 @@ Player HFOEnvironment::playerOnBall() {
status_t HFOEnvironment::step() {
assert(agent->currentTime().cycle() == current_cycle);
while (agent->statusUpdateTime() <= current_cycle) {
if (!client->isServerAlive()) {
assert(ready_for_action);
// 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;
}
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));
current_cycle = agent->currentTime().cycle();
return agent->getGameStatus();
......
......@@ -60,6 +60,7 @@ class HFOEnvironment {
rcsc::BasicClient* client;
Agent* agent;
long current_cycle;
bool ready_for_action;
};
} // namespace hfo
......
......@@ -311,14 +311,9 @@ void Agent::actionImpl() {
this->setNeckAction(new Neck_TurnToBallOrScan());
}
/*-------------------------------------------------------------------*/
/*!
*/
void
Agent::handleActionStart()
Agent::ProcessTrainerMessages()
{
// Process new trainer messages
if (audioSensor().trainerMessageTime().cycle() > lastTrainerMessageTime) {
const std::string& message = audioSensor().trainerMessage();
if (feature_extractor == NULL) {
......@@ -339,8 +334,11 @@ Agent::handleActionStart()
hfo::ParsePlayerOnBall(message, player_on_ball);
lastTrainerMessageTime = audioSensor().trainerMessageTime().cycle();
}
}
// Process new teammate message
void
Agent::ProcessTeammateMessages()
{
hear_msg.clear();
if (audioSensor().teammateMessageTime().cycle() > lastTeammateMessageTime) {
const std::list<HearMessage> teammateMessages = audioSensor().teammateMessages();
......@@ -353,11 +351,22 @@ Agent::handleActionStart()
}
lastTeammateMessageTime = audioSensor().teammateMessageTime().cycle();
}
}
// Update state features
void
Agent::UpdateFeatures()
{
if (feature_extractor != NULL) {
state = feature_extractor->ExtractFeatures(this->world());
}
}
void
Agent::handleActionStart()
{
ProcessTrainerMessages();
ProcessTeammateMessages();
UpdateFeatures();
// Optionally write to logfile
#ifdef ELOG
......
......@@ -24,6 +24,13 @@ public:
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:
// You can override this method. But you must call
// PlayerAgent::initImpl() in this method.
......
......@@ -263,6 +263,8 @@ inline bool ParseGameStatus(const std::string& message, status_t& status) {
status = OUT_OF_TIME;
} else if (message.find("IN_GAME") != std::string::npos){
status = IN_GAME;
} else if (message.find("HFO_FINISHED") != std::string::npos){
status = SERVER_DOWN;
} else {
return false;
}
......
......@@ -146,7 +146,7 @@ bool FeatureExtractor::valid(const rcsc::PlayerObject& player) {
pos.x < -ALLOWED_PITCH_FRAC * rcsc::ServerParam::i().pitchHalfLength()) {
return false;
}
return player.unum() > 0 && pos.isValid();
return pos.isValid();
}
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