Skip to content

Commit

Permalink
Merge branch 'continuous_bug_fixing' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jwaa committed May 1, 2021
2 parents 1b5de43 + deb6a26 commit eb2bdec
Show file tree
Hide file tree
Showing 16 changed files with 128 additions and 152 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Ignore pycharm project folder
.idea/
.vscode/

# Ignore build related folders and files
build/
Expand Down
Binary file removed dist/matrx-2.0.3-py3-none-any.whl
Binary file not shown.
Binary file removed dist/matrx-2.0.3.tar.gz
Binary file not shown.
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
from matrx import cases

if __name__ == "__main__":
cases.run_vis_test()
# cases.run_vis_test()
# cases.run_test()
# cases.run_simple_case()
# cases.run_test_navigators()
# cases.run_bw4t()
cases.run_bw4t()
2 changes: 1 addition & 1 deletion matrx/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
__url__ = 'https://matrx-software.com'
__doc_url__ = 'http://docs.matrx-software.com/en/latest/'
__source_url__ = 'https://github.com/matrx-software/matrx'
__version__ = '2.0.6'
__version__ = '2.0.8'
__author__ = 'MATRX Team at TNO.nl'
__author_email__ = 'info@matrx.com'
__license__ = 'MIT License'
Expand Down
2 changes: 1 addition & 1 deletion matrx/agents/agent_types/human_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def decide_on_action(self, state, user_input):
actual performed and the agent can perform a new action (a value
of 0 is no wait, 1 means to wait 1 tick, etc.).
"""

action = None
action_kwargs = {}

# send a random message once in a while
Expand Down
11 changes: 3 additions & 8 deletions matrx/agents/agent_utils/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,10 @@ def locate(id_obj_pair):
return obj
return None

# try to locate it in the regular dict as an object id, this allows us to use this method also to quickly locate
# objects based on their object ID.
try:
return self.__state_dict[prop_value]
# if the prop value was not a key in the dict (or simply None), find all objects with that property and value if
# Find all objects with that property and value if
# given. This uses Python's map function to bring our search to C.
except KeyError:
located = map(locate, self.__state_dict.items())
return [l for l in located if l is not None] # only return the found objects
located = map(locate, self.__state_dict.items())
return [l for l in located if l is not None] # only return the found objects

@staticmethod
def __is_iterable(arg):
Expand Down
26 changes: 13 additions & 13 deletions matrx/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

# variables to be read (only!) by MATRX and set (only!) through api calls
_userinput = {}
_matrx_paused = False
matrx_paused = False
_matrx_done = False


Expand All @@ -63,7 +63,7 @@ def get_info():
MATRX world object, containing general information on the world and scenario.
-------
"""
_MATRX_info['matrx_paused'] = _matrx_paused
_MATRX_info['matrx_paused'] = matrx_paused
_MATRX_info['matrx_version'] = _matrx_version
return jsonify(_MATRX_info)

Expand Down Expand Up @@ -137,7 +137,7 @@ def get_latest_state_and_messages():
states_ = __fetch_states(_current_tick, agent_id)
chatrooms, messages = __get_messages(agent_id, chat_offsets)

return jsonify({"matrx_paused": _matrx_paused, "states": states_, "chatrooms": chatrooms, "messages": messages})
return jsonify({"matrx_paused": matrx_paused, "states": states_, "chatrooms": chatrooms, "messages": messages})


#########################################################################
Expand Down Expand Up @@ -577,9 +577,9 @@ def pause_MATRX():
True if paused, False if already paused
-------
"""
global _matrx_paused
if not _matrx_paused:
_matrx_paused = True
global matrx_paused
if not matrx_paused:
matrx_paused = True
return jsonify(True)
else:
return jsonify(False)
Expand All @@ -597,9 +597,9 @@ def start_MATRX():
-------
"""
global _matrx_paused
if _matrx_paused:
_matrx_paused = False
global matrx_paused
if matrx_paused:
matrx_paused = False
return jsonify(True)
else:
return jsonify(False)
Expand Down Expand Up @@ -776,7 +776,7 @@ def __check_states_API_request(tick=None, ids=None, ids_required=False):
return False, error_message

# Don't throw an error if MATRX is paused the first tick, and thus still has no states
# if _current_tick is 0 and _matrx_paused:
# if _current_tick is 0 and matrx_paused:
# return True, None

# if this api call requires ids, check this variable on validity as well
Expand Down Expand Up @@ -1005,7 +1005,7 @@ def _add_state(agent_id, state, agent_inheritence_chain, world_settings):
if 'World' not in state:
state['World'] = world_settings

# state['World']['matrx_paused'] = _matrx_paused
# state['World']['matrx_paused'] = matrx_paused

# reorder and save the new state along with some meta information
_temp_state[agent_id] = {'state': __reorder_state(state), 'agent_inheritence_chain': agent_inheritence_chain}
Expand Down Expand Up @@ -1051,12 +1051,12 @@ def _pop_userinput(agent_id):

def _reset_api():
""" Reset the MATRX api variables """
global _temp_state, _userinput, _matrx_paused, _matrx_done, __states, _current_tick, tick_duration, _grid_size, \
global _temp_state, _userinput, matrx_paused, _matrx_done, __states, _current_tick, tick_duration, _grid_size, \
_nr_states_to_store
global _MATRX_info, _next_tick_info, _received_messages, __current_world_ID
_temp_state = {}
_userinput = {}
_matrx_paused = False
matrx_paused = False
_matrx_done = False
__states = {}
_current_tick = 0
Expand Down
3 changes: 1 addition & 2 deletions matrx/cases/bw4t/bw4t_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@

class CollectBlock(EnvObject):

def __init__(self, location, visualize_colour):
name = "Collect block"
def __init__(self, location, visualize_colour, name="Collect block"):
super().__init__(location, name, class_callable=SignalBlock, is_traversable=True, is_movable=True,
visualize_shape=0, visualize_colour=visualize_colour)

Expand Down
75 changes: 11 additions & 64 deletions matrx/cases/vis_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,22 @@
from matrx.world_builder import WorldBuilder
from matrx.actions import *
from datetime import datetime


from matrx.objects import Door, SquareBlock, AreaTile, SmokeTile, CollectionDropOffTile
from matrx.agents import HumanAgentBrain

def create_builder():
tick_dur = 0.1
factory = WorldBuilder(random_seed=1, shape=[14, 20], tick_duration=tick_dur, verbose=False, run_matrx_api=True,
run_matrx_visualizer=True, visualization_bg_clr="#f0f0f0", simulation_goal=100000,
visualization_bg_img='/static/images/restaurant_bg.png')

factory.add_room(top_left_location=[0, 0], width=14, height=20, name="world_bounds")

n_agent = 5

is_even = True
is_reverse = True
for x in range(1, n_agent + 1):
if is_even:
is_even = False
if is_reverse:
start = (x, 12)
waypoints = [(x, 1), (x, 11)]
else:
start = (x, 1)
waypoints = [(x, 11), (x, 1)]
else:
is_even = True
is_reverse = False
if is_reverse:
start = (1, x)
waypoints = [(11, x), (1, x)]
else:
start = (12, x)
waypoints = [(1, x), (11, x)]

navigating_agent = PatrollingAgentBrain(waypoints, move_speed=10)
factory.add_agent(start, navigating_agent, name="navigate " + str(x), visualization_shape=2, has_menu=True,
is_traversable=False, visualize_when_busy=True)

# add human agent
key_action_map = {
'w': MoveNorth.__name__,
'd': MoveEast.__name__,
's': MoveSouth.__name__,
'a': MoveWest.__name__,
'r': RemoveObject.__name__
}
factory.add_human_agent([5, 5], HumanAgentBrain(), name="human",
key_action_map=key_action_map, img_name="/static/images/transparent.png")

factory.add_human_agent([6, 6], HumanAgentBrain(), name="human2",
key_action_map=key_action_map, img_name="/static/images/agent.gif", visualize_when_busy=True)

# add a number of blocks to showcase the subtile functionality
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[0,0], is_traversable=True, visualize_colour="#c0392b", visualize_shape=2)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[0,1], is_traversable=True, visualize_colour="#9b59b6", visualize_shape=1)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[0,2], is_traversable=True, visualize_colour="#2980b9", visualize_shape=0)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[1,0], is_traversable=True, visualize_colour="#1abc9c", visualize_shape=2, visualize_size=0.75)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[1,1], is_traversable=True, img_name="/static/images/fire.gif")
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[1,2], is_traversable=True, visualize_colour="#27ae60", visualize_shape=0)
factory.add_object([6,7], "block", subtiles=[3,3], subtile_loc=[2,0], is_traversable=True, visualize_colour="#f1c40f", visualize_shape=2, visualize_size=0.5)
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)
factory = WorldBuilder(random_seed=1, shape=[9, 10], tick_duration=1, verbose=False, run_matrx_api=True,
run_matrx_visualizer=True, visualization_bg_clr="#f0f0f0", simulation_goal=100000)

# create some folders for logging
timestamp = str(datetime.today().strftime("%d-%m-%Y_%H-%M"))
log_folder = os.path.join("Results", "logs_" + timestamp)
factory.add_room(top_left_location=[0, 0], width=9, height=10, name='Wall_Border', wall_visualize_opacity=0.5)
factory.add_object(location=[3,3], name="door", callable_class=Door, visualize_opacity=0.5, is_open=False)
factory.add_object(location=[3,4], name="block", callable_class=SquareBlock, visualize_opacity=0.5)
factory.add_object(location=[3,5], name="tile1", callable_class=AreaTile, visualize_opacity=0.5)
factory.add_object(location=[3,6], name="tile2", callable_class=SmokeTile, visualize_opacity=0.5)
factory.add_object(location=[4,6], name="CollectionDropOffTile", callable_class=CollectionDropOffTile, visualize_opacity=0.5)

# add loggers
factory.add_logger(MessageLogger, save_path=log_folder, file_name_prefix="messages_")
factory.add_human_agent(location=[5,6], agent=HumanAgentBrain(), visualize_opacity=0.5)

return factory

Expand Down
15 changes: 8 additions & 7 deletions matrx/grid_world.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def initialize(self, api_info):
}

# start paused
api._matrx_paused = True if '_matrx_paused' not in api_info else api_info['_matrx_paused']
api.matrx_paused = True if 'matrx_paused' not in api_info else api_info['matrx_paused']

# fetch the initial state of every agent to display
self._fetch_initial_states()
Expand Down Expand Up @@ -235,7 +235,7 @@ def run(self, api_info):
is_done = False
while not is_done:

if self.__run_matrx_api and api._matrx_paused:
if self.__run_matrx_api and api.matrx_paused:
print("MATRX paused through api")
gevent.sleep(1)
else:
Expand Down Expand Up @@ -937,14 +937,15 @@ def __perform_action(self, agent_id, action_name, action_kwargs):
# Apply world mutation
result = action.mutate(self, agent_id, **action_kwargs)

# Get agent's send_result function
set_action_result = self.__registered_agents[agent_id].set_action_result_func
# Send result of mutation to agent
set_action_result(result)

# Update the grid
self.__update_agent_location(agent_id)

# Get agent's send_result function
set_action_result = self.__registered_agents[agent_id].set_action_result_func

# Send result of mutation to agent
set_action_result(result)

# Whether the action succeeded or not, we return the result
return result

Expand Down
6 changes: 6 additions & 0 deletions matrx/logger/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ def __init__(self, log_strategy=1, save_path="/logs", file_name="", file_extensi
self.__columns = [] # place holder for the columns in our data file
self.__prev_goal_status = {} # to track if a goal was accomplished since last call


@property
def file_name(self):
""" Make the logger filename publicly available """
return self.__file_name

def log(self, grid_world, agent_data):
""" The main method to be overwritten by your own logger class.
Expand Down
30 changes: 17 additions & 13 deletions matrx/objects/env_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def __init__(self, location, name, class_callable, customizable_properties=None,
# remove double spaces
tmp_obj_name = " ".join(name.split())
# append a object ID to the end of the object name
self.obj_id = f"{tmp_obj_name}_{_next_obj_id()}".replace(" ", "_")
self.obj_id = _ensure_unique_obj_ID(f"{tmp_obj_name}".replace(" ", "_"))

# prevent breaking of the frontend
if "#" in self.obj_id:
Expand Down Expand Up @@ -319,22 +319,26 @@ def properties(self, property_dictionary: dict):
pass


object_counter = 0

# keep track of all obj IDs added so far
added_obj_ids = []

def _next_obj_id():
""" Increments the object counter used to generate unique object IDs.
def _ensure_unique_obj_ID(obj_id):
""" Make sure every obj ID is unique by adding an increasing count to objects with duplicate names.
Example: three objects named "drone". The object IDs will then become "drone", "drone_1", "drone_2", etc."""
if obj_id in added_obj_ids:

Returns
-------
int
The increment object counter.
# found the next obj ID based on the obj name + count
i = 1
while f"{obj_id}_{i}" in added_obj_ids:
i += 1

"""
global object_counter
res = object_counter
object_counter += 1
return res
# warnings.warn(f"There already exists an object with name {obj_id}, new object ID is: {obj_id}_{i}")
obj_id = f"{obj_id}_{i}"

# keep track of all object IDs we added
added_obj_ids.append(obj_id)
return obj_id


def _get_inheritence_path(callable_class):
Expand Down

0 comments on commit eb2bdec

Please sign in to comment.