Source code for evolearn.controllers.controller_simple


#######################################################
#   ____  _      ___   _     ____   __    ___   _     #
#  | |_  \ \  / / / \ | |   | |_   / /\  | |_) | |\ | #
#  |_|__  \_\/  \_\_/ |_|__ |_|__ /_/--\ |_| \ |_| \| #
#                                                     #
#                  Chad Carlson - 2017                #
#######################################################


import itertools
import numpy as np


[docs]class SimpleAgent: """ Simple agent object for interacting with Simple Wrapping Environments. """ def __init__(self, world_size): # -------------------- REFERENCE -------------------- self.world_size = world_size # -------------------- ORIENTATION -------------------- # Start the agent in the center of the world self.location = [self.world_size / 2, self.world_size / 2] # Start the agent facing upwards self.heading = 0 # -------------------- FIELD OF VIEW -------------------- # Rows in agent FOV self.levels_fov = 1 # Shape of agent FOV self.conical_fov = False # not currently used
[docs] def cyclical_heading(self, heading): """ Heading conversion. Prevents requests for heading indices that do not exist ( range(4) possible ). :param heading: original agent.heading :return: converted (cyclical) agent.heading """ if heading < 0: heading = 3 elif heading > 3: heading = 0 return heading
[docs] def define_fov(self, world): """ Defines the agent's field-of-vision. :param world: current environment :return: observation """ rows = range(self.location[0] - self.levels_fov, self.location[0] + self.levels_fov + 1) cols = range(self.location[1] - self.levels_fov, self.location[1] + self.levels_fov + 1) fov = list(itertools.product(rows, cols)) fov = [(self.enforce_wrapping(i), self.enforce_wrapping(j)) for i, j in fov] fov_heading = self.define_fov_heading() final_fov = [fov[i] for i in fov_heading] observation = np.array([world[point[0], point[1]] for point in final_fov]) return observation
[docs] def define_fov_heading(self): """ Defines the structure of an agent's field-of-vision :return: FOV_heading """ fov_heading = [] r = 2 * self.levels_fov + 1 th = self.levels_fov * r t = r ** 2 for l in range(1, self.levels_fov + 1): fov_heading += self.heading_row_calc(r, th, t, l) return fov_heading
[docs] def enforce_wrapping(self, position): """ Location conversion. Prevents requests for locations that are not accessible in the current environment. :param position: world positionX or world positionY :return: new world positionX or world positionY """ if position >= self.world_size: wrapped_position = 0 elif position < 0: wrapped_position = self.world_size - 1 else: wrapped_position = position return wrapped_position
[docs] def heading_row_calc(self, r, th, t, l): """ Calculates location indices for individual cells in a row of an agent's field-of-view. Todo: * Flush out input parameters definitions. * Rename input parameters to more readable ones. :return output: """ if not self.heading: output = range((self.levels_fov - l) * r, (self.levels_fov - l + 1) * r, 1) elif self.heading == 1: output = range(r - (self.levels_fov - l + 1), t, r) elif self.heading == 2: output = range((r - (self.levels_fov - l)) * r - 1, (self.levels_fov + l) * r - 1, -1) elif self.heading == 3: output = range(2 * th + (self.levels_fov - l), self.levels_fov - l - 1, -1 * r) return output
[docs] def reset(self): """ Reset agent location and heading in environment to initial values. """ # Restart the agent in the center of the world self.location = [self.world_size / 2, self.world_size / 2] # Restart the agent facing upwards self.heading = 0