Commit d061c331 authored by sanmit's avatar sanmit

Implemented communication

parent a1022b8d
......@@ -119,6 +119,7 @@ class Trainer(object):
agent_cmd += ' -g'
if self._record:
agent_cmd += ' --record'
# Comment next two lines to show output from agent.cpp and the server
kwargs = {'stdout':open('/dev/null', 'w'),
'stderr':open('/dev/null', 'w')}
p = subprocess.Popen(agent_cmd.split(' '), shell = False, **kwargs)
......
......@@ -2,13 +2,16 @@
#include <vector>
#include <HFO.hpp>
#include <cstdlib>
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
using namespace hfo;
// Before running this program, first Start HFO server:
// $./bin/HFO --offense-agents 1
#define PI 3.14159265
int main(int argc, char** argv) {
int port = 6000;
if (argc > 1) {
......@@ -21,19 +24,24 @@ int main(int argc, char** argv) {
hfo.connectToAgentServer(port, HIGH_LEVEL_FEATURE_SET);
// Play 5 episodes
for (int episode=0; ; episode++) {
int step = 0;
status_t status = IN_GAME;
while (status == IN_GAME) {
// Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState();
// Get any incoming communication
std::string msg = hfo.hear();
// TODO: [Sanmit] Do something with incoming communication
// Perform the action
hfo.act(DASH, 0, 0);
// TODO: [Sanmit] Do something with outgoing communication
// Do something with incoming communication
cout << "HEARD: " << msg.c_str() << endl;
float target_x = sin((step % 360) * PI/180);
float target_y = cos((step % 360) * PI/180);
hfo.act(DRIBBLE_TO, target_x, target_y);
// Do something with outgoing communication
hfo.say("Message");
// Advance the environment and get the game status
status = hfo.step();
step+=2;
}
}
hfo.act(QUIT);
......
#!/usr/bin/env python
# encoding: utf-8
import sys
# First Start the server: $> bin/start.py
if __name__ == '__main__':
port = 6000
if len(sys.argv) > 1:
port = int(sys.argv[1])
try:
from hfo import *
except:
print 'Failed to import hfo. To install hfo, in the HFO directory'\
' run: \"pip install .\"'
exit()
# Create the HFO Environment
hfo_env = hfo.HFOEnvironment()
# Connect to the agent server on port 6000 with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo_env.connectToAgentServer(port, HFO_Features.HIGH_LEVEL_FEATURE_SET)
# Play 5 episodes
for episode in xrange(5):
status = HFO_Status.IN_GAME
while status == HFO_Status.IN_GAME:
# Grab the state features from the environment
features = hfo_env.getState()
# Get any incoming communication
msg = hfo_env.hear()
# Do something with incoming communication
print 'Heard: ', msg
# Take an action and get the current game status
hfo_env.act(HFO_Actions.DASH, 20.0, 0)
# Do something with outgoing communication
hfo_env.say('Message')
status = hfo_env.step()
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
print 'goal'
elif status == HFO_Status.CAPTURED_BY_DEFENSE:
print 'captured by defense'
elif status == HFO_Status.OUT_OF_BOUNDS:
print 'out of bounds'
elif status == HFO_Status.OUT_OF_TIME:
print 'out of time'
else:
print 'Unknown status', status
exit()
# Cleanup when finished
hfo_env.cleanup()
#!/usr/bin/env python
# encoding: utf-8
import sys
# First Start the server: $> bin/start.py
if __name__ == '__main__':
port = 6000
if len(sys.argv) > 1:
port = int(sys.argv[1])
try:
from hfo import *
except:
......@@ -14,7 +21,7 @@ if __name__ == '__main__':
hfo = hfo.HFOEnvironment()
# Connect to the agent server on port 6000 with the specified
# feature set. See feature sets in hfo.py/hfo.hpp.
hfo.connectToAgentServer(6000, HFO_Features.HIGH_LEVEL_FEATURE_SET)
hfo.connectToAgentServer(port, HFO_Features.HIGH_LEVEL_FEATURE_SET)
# Play 5 episodes
for episode in xrange(5):
status = HFO_Status.IN_GAME
......@@ -22,7 +29,10 @@ if __name__ == '__main__':
# Grab the state features from the environment
features = hfo.getState()
# Take an action and get the current game status
status = hfo.act(HFO_Actions.DASH, 20.0, 0)
hfo.act(HFO_Actions.DASH, 20.0, 0)
hfo.step()
print 'Episode', episode, 'ended with',
# Check what the outcome of the episode was
if status == HFO_Status.GOAL:
......
......@@ -31,12 +31,15 @@ int main(int argc, char** argv) {
}
std::cout << "target (x,y) = " << target_x << ", " << target_y << std::endl;
while (status == IN_GAME) {
// Get the vector of state features for the current state
const vector<float>& feature_vec = hfo.getState();
// Perform the action
hfo.act(MOVE_TO, target_x, target_y);
// Advance the environment and get the game status
status = hfo.step();
std::cout << "Status: " << status << " (IN_GAME = " << IN_GAME << ")\n";
}
}
hfo.act(QUIT);
......
......@@ -45,8 +45,8 @@ class HFOEnvironment(object):
self.numFeatures = None # Given by the server in handshake
self.features = None # The state features
self.requested_action = None # Action to execute and parameters
self.say_msg = None # Outgoing message to say
self.hear_msg = None # Incoming heard message
self.say_msg = '' # Outgoing message to say
self.hear_msg = '' # Incoming heard message
def NumParams(self, action_type):
''' Returns the number of required parameters for each action type. '''
......@@ -94,6 +94,12 @@ class HFOEnvironment(object):
self.cleanup()
exit(1)
self.features = struct.unpack('f'*self.numFeatures, state_data)
# Get first hear message
hearMsgLengthData = self.socket.recv(struct.calcsize('I'))
hearMsgLength = struct.unpack('I', hearMsgLengthData)[0]
if hearMsgLength > 0:
hearMsgData = self.socket.recv(struct.calcsize('c')*hearMsgLength)
self.hear_msg = struct.unpack(str(hearMsgLength)+'s', hearMsgData)[0]
def handshakeAgentServer(self, feature_set):
'''Handshake with the agent's server. '''
......@@ -144,11 +150,16 @@ class HFOEnvironment(object):
# Send action and parameters
self.socket.send(struct.pack('i'+'f'*(len(self.requested_action)-1),
*self.requested_action))
# TODO: [Sanmit] Send self.say_msg
# [Sanmit] Send self.say_msg
self.socket.send(struct.pack('I', len(self.say_msg)))
if len(self.say_msg) > 0:
self.socket.send(struct.pack(str(len(self.say_msg))+'s', self.say_msg))
self.say_msg = ''
# Get the current game status
data = self.socket.recv(struct.calcsize("i"))
status = struct.unpack("i", data)[0]
# Get the next state features
state_data = self.socket.recv(struct.calcsize('f')*self.numFeatures)
if not state_data:
......@@ -157,7 +168,13 @@ class HFOEnvironment(object):
exit(1)
self.features = struct.unpack('f'*self.numFeatures, state_data)
self.hear_msg = ''
# TODO: [Sanmit] Receive self.hear_msg
# [Sanmit] Receive self.hear_msg
hearMsgLengthData = self.socket.recv(struct.calcsize('I'))
hearMsgLength = struct.unpack('I', hearMsgLengthData)[0]
if hearMsgLength > 0:
hearMsgData = self.socket.recv(struct.calcsize('c')*hearMsgLength)
self.hear_msg = struct.unpack(str(hearMsgLength)+'s', hearMsgData)[0]
return status
def cleanup(self):
......
......@@ -188,6 +188,28 @@ void HFOEnvironment::connectToAgentServer(int server_port,
close(sockfd);
exit(1);
}
// Get first hear message
// Message length
uint32_t msgLength;
if (recv(sockfd, &msgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Client] ERROR recieving hear message length from socket");
close(sockfd);
exit(1);
}
// Message
if (msgLength > 0){
std::vector<char> hearMsgBuffer;
hearMsgBuffer.resize(msgLength);
if (recv(sockfd, &hearMsgBuffer[0], msgLength, 0) < 0){
perror("[Agent Client] ERROR recieving hear message from socket");
close(sockfd);
exit(1);
}
hear_msg.assign(&(hearMsgBuffer[0]), hearMsgBuffer.size());
}
}
void HFOEnvironment::handshakeAgentServer(feature_set_t feature_set) {
......@@ -288,7 +310,24 @@ status_t HFOEnvironment::step() {
exit(1);
}
}
// TODO: [Sanmit] Send say_msg
// [Sanmit] Send say_msg
// Send message length
uint32_t sendMsgLength = say_msg.size();
if (send(sockfd, &sendMsgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Client] ERROR sending from socket");
close(sockfd);
exit(1);
}
// Send message
if (sendMsgLength > 0){
if (send(sockfd, say_msg.c_str(), say_msg.size(), 0) < 0){
perror("[Agent Client] ERROR sending from socket");
close(sockfd);
exit(1);
}
}
// Clear say message buffer
say_msg.clear();
// Get the game status
......@@ -298,13 +337,34 @@ status_t HFOEnvironment::step() {
exit(1);
}
// Get the next game state
if (recv(sockfd, &(feature_vec.front()), numFeatures*sizeof(float), 0) < 0) {
if (recv(sockfd, &(feature_vec.front()), numFeatures * sizeof(float), 0) < 0) {
perror("[Agent Client] ERROR recieving state features from socket");
close(sockfd);
exit(1);
}
// [Sanmit] Receive comm_msg
// Clear last message
hear_msg.clear();
// TODO: [Sanmit] Receive comm_msg
// Message length
uint32_t msgLength;
if (recv(sockfd, &msgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Client] ERROR recieving hear message length from socket");
close(sockfd);
exit(1);
}
// Message
if (msgLength > 0){
std::vector<char> hearMsgBuffer;
hearMsgBuffer.resize(msgLength);
if (recv(sockfd, &hearMsgBuffer[0], msgLength, 0) < 0){
perror("[Agent Client] ERROR recieving hear message from socket");
close(sockfd);
exit(1);
}
hear_msg.assign(&(hearMsgBuffer[0]), hearMsgBuffer.size());
}
return game_status;
}
......@@ -29,6 +29,7 @@
#endif
#include "agent.h"
#include "custom_message.h"
#include "strategy.h"
#include "field_analyzer.h"
......@@ -100,6 +101,7 @@
#include <rcsc/param/cmd_line_parser.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib>
......@@ -120,8 +122,10 @@ Agent::Agent()
M_field_evaluator(createFieldEvaluator()),
M_action_generator(createActionGenerator()),
lastTrainerMessageTime(-1),
lastTeammateMessageTime(-1),
server_port(6008),
client_connected(false),
num_teammates(-1),
num_opponents(-1),
playing_offense(false)
......@@ -422,9 +426,39 @@ void Agent::actionImpl() {
if (send(newsockfd, &(features.front()),
features.size() * sizeof(float), 0) < 0) {
perror("[Agent Server] ERROR sending state features from socket");
close(sockfd);
exit(1);
}
// TODO: [Sanmit] Send the communication heard by the agent
// [Sanmit] Send the communication heard by the agent
// Hear for teammate messages and send them via socket to the HFO interface.
std::string teammateMessage = "";
// Received a new message
if (audioSensor().teammateMessageTime().cycle() > lastTeammateMessageTime){
// Receive all teammate messages
std::list<HearMessage> teammateMessages = audioSensor().teammateMessages();
for (std::list<HearMessage>::iterator msgIterator = teammateMessages.begin(); msgIterator != teammateMessages.end(); msgIterator++){
if ((*msgIterator).unum_ != world().self().unum()){
teammateMessage = (*msgIterator).str_;
break; // For now we just take one. Remove this and concatenate messages if desired -- though technically, agents should only be able to hear one message.
}
}
}
// Send message size
uint32_t hearMsgLength = teammateMessage.size();
if (send(newsockfd, &hearMsgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Server] ERROR sending hear message length from socket");
close(sockfd);
exit(1);
}
// Send message
if (hearMsgLength > 0){
if (send(newsockfd, teammateMessage.c_str(), teammateMessage.size(), 0) < 0){
perror("[Agent Server] ERROR sending hear message from socket");
close(sockfd);
exit(1);
}
}
// Get the action type
action_t action;
......@@ -443,8 +477,44 @@ void Agent::actionImpl() {
exit(1);
}
}
// TODO: [Sanmit] Receive the outgoing communication
// TODO: [Sanmit] "Say" in the actual game
// [Sanmit] Receive the outgoing communication
// Receive message length
uint32_t sayMsgLength;
if (recv(newsockfd, &sayMsgLength, sizeof(uint32_t), 0) < 0){
perror("[Agent Server] ERROR recv size of say message from socket");
close(sockfd);
exit(1);
}
std::cout << "[AGENT.CPP] Say message length " << sayMsgLength << std::endl;
// Receive message
std::vector<char> sayMsgBuffer;
sayMsgBuffer.resize(sayMsgLength);
std::string msgString = "";
// Check message size
if (sayMsgLength > ServerParam::i().playerSayMsgSize()){
perror("[Agent Server] ERROR message size too large. Increase size by starting bin/HFO with larger --messageSize argument");
close(sockfd);
exit(1);
}
if (sayMsgLength > 0) {
if (recv(newsockfd, &sayMsgBuffer[0], sayMsgLength, 0) < 0){
perror("[Agent Server] ERROR recv say message from socket");
close(sockfd);
exit(1);
}
msgString.assign(&(sayMsgBuffer[0]),sayMsgBuffer.size());
// [Sanmit] "Say" in the actual game
addSayMessage(new CustomMessage(msgString));
std::cout << "\n\n[AGENT SERVER] " << msgString << std::endl;
}
if (action == SHOOT) {
const ShootGenerator::Container & cont =
......@@ -704,7 +774,8 @@ Agent::communicationImpl()
{
if ( M_communication )
{
M_communication->execute( this );
// [Sanmit]: Turning this off since it adds default communication messages which can conflict with our comm messages.
// M_communication->execute( this );
}
}
......
......@@ -79,6 +79,7 @@ protected:
protected:
FeatureExtractor* feature_extractor;
long lastTrainerMessageTime; // Last time the trainer sent a message
long lastTeammateMessageTime; // Last time a teammate sent a message
int server_port; // Port to start the server on
bool client_connected; // Has the client connected and handshake?
int sockfd, newsockfd; // Server sockets
......
#ifndef CUSTOM_MESSAGE_H
#define CUSTOM_MESSAGE_H
#include <rcsc/player/say_message_builder.h>
class CustomMessage : public rcsc::SayMessage {
private:
std::string msg;
public:
CustomMessage(std::string m) : msg(m) {}
char header() const { return 'm'; } // Should be one (unique) character
int length() const {return msg.length(); }
bool toStr(std::string & to) const {to+=msg; return true;}
std::ostream & printDebug( std::ostream & os ) const { os << "[MYMSG]"; return os;} // TODO [SANMIT]
};
#endif
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