Skip to content

Commit

Permalink
Merge pull request #258 from matrx-software/254_log_sent_messages
Browse files Browse the repository at this point in the history
254 log sent messages
  • Loading branch information
thaije committed Feb 5, 2021
2 parents 072d25f + 7e8f1ac commit 35b7861
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 15 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ docs/source/sections/_generated_autodoc

*.gz

Results/*

# ignore any log data
Results/

32 changes: 18 additions & 14 deletions matrx/agents/agent_brain.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,20 +213,24 @@ def decide_on_action(self, state):
for learning agents.
"""

# Send a message to a random agent
agents = []
for obj_id, obj in state.items():

if obj_id is "World": # Skip the world properties
continue

classes = obj['class_inheritance']
if AgentBrain.__name__ in classes: # the object is an agent to which we can send our message
agents.append(obj)
selected_agent = self.rnd_gen.choice(agents)
message_content = f"Hello, my name is {self.agent_name}"
self.send_message(Message(content=message_content, from_id=self.agent_id, to_id=selected_agent['obj_id']))

# send a random message once in a while
if self.rnd_gen.random() < 0.1:
# Get all agents in our state.
# The codeline below can return three things:
# - None -> no agents found (impossible as we are in an agent right now)
# - an agent object -> only a single agent found
# - a list of agent objects -> multiple agents found
# Also see for state usage:
# https://github.com/matrx-software/matrx/blob/master/matrx/cases/bw4t/bw4t_agents.py
agents = state[{"isAgent": True}]

# If we found multiple agents, randomly select the ID of one of them or otherwise the ID of the only agent
to_id = self.rnd_gen.choice(agents)['obj_id'] if isinstance(agents, list) else agents['obj_id']

self.send_message(Message(content=f"Hello, my name is (agent) {self.agent_name} and I sent this message at "
f"tick {state['World']['nr_ticks']}",
from_id=self.agent_id,
to_id=to_id))
# Select a random action
if self.action_set:
action = self.rnd_gen.choice(self.action_set)
Expand Down
20 changes: 20 additions & 0 deletions matrx/agents/agent_types/human_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,26 @@ def decide_on_action(self, state, user_input):

action_kwargs = {}

# send a random message once in a while
if self.rnd_gen.random() < 0.1:
# Get all agents in our state.
# The codeline below can return three things:
# - None -> no agents found (impossible as we are in an agent right now)
# - an agent object -> only a single agent found
# - a list of agent objects -> multiple agents found
# Also see for state usage:
# https://github.com/matrx-software/matrx/blob/master/matrx/cases/bw4t/bw4t_agents.py
agents = state[{"isAgent": True}]

# If we found multiple agents, randomly select the ID of one of them or otherwise the ID of the only agent
to_id = self.rnd_gen.choice(agents)['obj_id'] if isinstance(agents, list) else agents['obj_id']

self.send_message(Message(content=f"Hello, my name is (human agent) {self.agent_name} and I sent this message at "
f"tick {state['World']['nr_ticks']}",
from_id=self.agent_id,
to_id=to_id))


# if no keys were pressed, do nothing
if user_input is None or user_input == []:
return None, {}
Expand Down
9 changes: 9 additions & 0 deletions matrx/cases/vis_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os

from matrx.agents import PatrollingAgentBrain, HumanAgentBrain
from matrx.logger.log_messages import MessageLogger
from matrx.world_builder import WorldBuilder
from matrx.actions import *
from datetime import datetime



def create_builder():
Expand Down Expand Up @@ -65,6 +68,12 @@ def create_builder():
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[2,1], is_traversable=True, visualize_colour="#e67e22", visualize_shape=1)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[2,2], is_traversable=True, visualize_colour="#2e4053", visualize_shape=0)

# create some folders for logging
timestamp = str(datetime.today().strftime("%d-%m-%Y_%H-%M"))
log_folder = os.path.join("Results", "logs_" + timestamp)

# add loggers
factory.add_logger(MessageLogger, save_path=log_folder, file_name_prefix="messages_")

return factory

Expand Down
80 changes: 80 additions & 0 deletions matrx/logger/log_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from matrx.logger.logger import GridWorldLogger
import copy
import json


class MessageLogger(GridWorldLogger):
""" Logs messages send and received by (all) agents """

def __init__(self, save_path="", file_name_prefix="", file_extension=".csv", delimeter=";"):
super().__init__(save_path=save_path, file_name=file_name_prefix, file_extension=file_extension,
delimiter=delimeter, log_strategy=1)
# IDs of the agents we want to log messages of
self.agent_ids = []
self.agent_ids_initialized = False
self.log_statement_template = {'correct_tick': 0}

def log(self, grid_world, agent_data):

# find the IDs of the agents we need to log and create a template log statement
if not self.agent_ids_initialized:
for agent_id in grid_world.registered_agents.keys():
self.agent_ids.append(agent_id)

# create a field for messages sent and messages received
self.log_statement_template[agent_id + "_sent"] = None
self.log_statement_template[agent_id + "_received"] = None
# field specific for logging the entire message as json
self.log_statement_template[agent_id + "_mssg_json"] = None

self.agent_ids_initialized = True

# create a copy of the log template for the messages of the tick we are now processing
log_statement = copy.copy(self.log_statement_template)

# we check the messages of the previous tick, as the messages of this tick haven't been processed yet
tick_to_check = grid_world.current_nr_ticks-1
log_statement['correct_tick'] = tick_to_check

if tick_to_check in grid_world.message_manager.preprocessed_messages.keys():
# loop through all messages of this tick
for message in grid_world.message_manager.preprocessed_messages[tick_to_check]:

# optional: filter only specific types of messages or specific agents here

# Log the message content for the sender and receiver
log_statement[message.from_id + "_sent"] = message.content
log_statement[message.to_id + "_received"] = message.content

# log the entire message to json as a dict
log_statement[message.from_id + "_mssg_json"] = json.dumps(message.__dict__)

return log_statement




























0 comments on commit 35b7861

Please sign in to comment.