Exemple #1
0
def test_directional_sensors():
    a = Animat()
    lx, ly = 0.5, 0.5  # obj position
    o = Obj(lx, ly, 'default')
    a.add_obj(o)

    res = np.linspace(0, 1, 50)
    mesh = np.meshgrid(res, res)

    def f(coords):
        a.x = coords[0]
        a.y = coords[1]
        a.update_sensors()
        return a.sensors['default'][Sides.LEFT]

    zs = np.apply_along_axis(f, 0, mesh)

    imshow(zs, extent=[0, 1, 0, 1], origin='lower')

    plot(lx, ly, 'wo', label='object')

    xlabel('animat position')

    ylabel('animat position')

    title('Animat is facing to the right')

    legend()

    show()
Exemple #2
0
 def __init__(self, genome, parent=None, gen=0):
     self.parent = parent
     self.animat = Animat(genome)
     self.gen = gen
     # Mark whether the animat's phenotype needs updating.
     self._dirty_phenotype = True
Exemple #3
0
class Individual:
    def __init__(self, genome, parent=None, gen=0):
        self.parent = parent
        self.animat = Animat(genome)
        self.gen = gen
        # Mark whether the animat's phenotype needs updating.
        self._dirty_phenotype = True

    def __eq__(self, other):
        return self.genome == other.genome and self.parent == other.parent

    @property
    def genome(self):
        """The animat's genome."""
        return self.animat.genome

    @property
    def gen(self):
        """The generation the animat was born."""
        return self.animat.gen

    @gen.setter
    def gen(self, value):
        self.animat.gen = value

    @property
    def edges(self):
        """The animat's edge list."""
        self._update_phenotype()
        return self.animat.edges

    @property
    def cm(self):
        """The animat's connectivity matrix."""
        cm = np.zeros((params.NUM_NODES, params.NUM_NODES), int)
        cm[list(zip(*self.edges))] = 1
        return cm

    @property
    def tpm(self):
        """The animats's TPM."""
        self._update_phenotype()
        return np.array(self.animat.tpm).astype(float)

    @property
    def correct(self):
        """The number of correct catches/avoidances in the game."""
        return self.animat.correct

    @property
    def incorrect(self):
        """The number of incorrect catches/avoidances in the game."""
        return self.animat.incorrect

    def _update_phenotype(self):
        """Update the animat's phenotype if necessary. Returns whether an
        update was performed."""
        if self._dirty_phenotype:
            self.animat.update_phenotype()
            self._dirty_phenotype = False
            return True
        return False

    def __deepcopy__(self, memo):
        # Don't copy the animat or the parent.
        copy = Individual(genome=self.animat.genome, parent=self.parent)
        for key, val in self.__dict__.items():
            if key not in ('animat', 'parent'):
                copy.__dict__[key] = deepcopy(val, memo)
        return copy

    def mutate(self):
        """Mutate the animat's genome in-place."""
        self.animat.mutate(params.MUTATION_PROB, params.DUPLICATION_PROB,
                           params.DELETION_PROB, params.MIN_GENOME_LENGTH,
                           params.MAX_GENOME_LENGTH)
        self._dirty_phenotype = True

    def play_game(self):
        """Return the list of state transitions the animat goes through when
        playing the game."""
        self._update_phenotype()
        transitions = self.animat.play_game(
            params.HIT_MULTIPLIERS,
            params.BLOCK_PATTERNS,
            scramble_world=params.SCRAMBLE_WORLD)
        # TODO remove this assertion at some point for speed
        # Check that everything adds up.
        assert self.animat.correct + self.animat.incorrect == params.NUM_TRIALS
        return transitions

    def lineage(self):
        """Return a generator for the lineage of this individual."""
        yield self.animat
        ancestor = self.parent
        while ancestor is not None:
            yield ancestor.animat
            ancestor = ancestor.parent
Exemple #4
0
def simulate_trial(controller, trial_index, generating_animation=False):
    # seed for environment for this generation
    np.random.seed(generation_index * 10 + trial_index)

    current_t = 0.0
    score = 0.0

    animat = Animat()
    animat.x = 0.0
    animat.y = 0.0
    animat.a = 0.0

    controller.trial_data = {}

    foods = []
    waters = []
    traps = []

    n = {ObjTypes.FOOD: 2, ObjTypes.WATER: 2, ObjTypes.TRAP: 2}
    for obj_type in ObjTypes:
        for _ in range(n[obj_type]):
            x, y = random_obj_position(animat)
            obj = Obj(x, y, obj_type)
            animat.add_obj(obj)

            if obj_type == ObjTypes.FOOD:
                foods.append(obj)
            if obj_type == ObjTypes.WATER:
                waters.append(obj)
            if obj_type == ObjTypes.TRAP:
                traps.append(obj)

    food_bat = 1.0
    water_bat = 1.0

    controller.trial_data['sample_times'] = []
    controller.trial_data['water_battery_h'] = []
    controller.trial_data['food_battery_h'] = []
    controller.trial_data['score_h'] = []
    controller.trial_data['eaten_FOOD_positions'] = []
    controller.trial_data['eaten_WATER_positions'] = []
    controller.trial_data['eaten_TRAP_positions'] = []
    controller.trial_data['FOOD_positions'] = []
    controller.trial_data['WATER_positions'] = []
    controller.trial_data['TRAP_positions'] = []

    for iteration in range(N_STEPS):
        # battery states for plotting
        controller.trial_data['sample_times'].append(current_t)
        controller.trial_data['water_battery_h'].append(water_bat)
        controller.trial_data['food_battery_h'].append(food_bat)
        controller.trial_data['score_h'].append(score)

        if generating_animation:
            # used in animation
            controller.trial_data['FOOD_positions'].append([(l.x, l.y)
                                                            for l in foods])
            controller.trial_data['WATER_positions'].append([(l.x, l.y)
                                                             for l in waters])
            controller.trial_data['TRAP_positions'].append([(l.x, l.y)
                                                            for l in traps])

        current_t += DT

        # drain battery states
        DRAIN_RATE = 0.2
        water_bat = water_bat - DT * DRAIN_RATE
        food_bat = food_bat - DT * DRAIN_RATE

        # if going faster drains more battery
        # water_b -= (animat.lm**2) * DT * 0.01
        # food_b  -= (animat.rm**2) * DT * 0.01

        score += (water_bat * food_bat) * DT

        # pass sensor states to controller
        for obj_type in ObjTypes:
            controller.set_sensor_states(obj_type, animat.sensors[obj_type])
        # set animat motor states with controller calculations
        animat.lm, animat.rm = controller.get_motor_output(
            (food_bat, water_bat))

        animat.calculate_derivative()  # calculate changes
        animat.euler_update(DT=DT)  # apply changes

        # check for FOOD collisions
        for food in animat.objs[ObjTypes.FOOD]:
            if (animat.x - food.x)**2 + (animat.y - food.y)**2 < Obj.RADIUS**2:
                food_bat += 20.0 * DT
                controller.trial_data['eaten_FOOD_positions'].append(
                    (food.x, food.y))
                food.x, food.y = random_obj_position(animat)  # relocate entity

        # check for WATER collisions
        for water in animat.objs[ObjTypes.WATER]:
            if (animat.x - water.x)**2 + (animat.y -
                                          water.y)**2 < Obj.RADIUS**2:
                water_bat += 20.0 * DT
                controller.trial_data['eaten_WATER_positions'].append(
                    (water.x, water.y))
                water.x, water.y = random_obj_position(
                    animat)  # relocate entity

        # check for TRAP collisions
        for trap in animat.objs[ObjTypes.TRAP]:
            if (animat.x - trap.x)**2 + (animat.y - trap.y)**2 < Obj.RADIUS**2:
                food_bat -= 50.0 * DT
                water_bat -= 50.0 * DT
                score = 0.0
                controller.trial_data['eaten_TRAP_positions'].append(
                    (trap.x, trap.y))
                trap.x, trap.y = random_obj_position(animat)  # relocate entity

        # DEATH -- if either of the batteries reaches 0, the trial is over
        if food_bat < 0.0 or water_bat < 0.0:
            food_bat = water_bat = 0.0
            break

    # position of entities still not eaten at end of trial (used for plotting)
    controller.trial_data['uneaten_FOOD_positions'] = [
        (l.x, l.y) for l in animat.objs[ObjTypes.FOOD]
    ]
    controller.trial_data['uneaten_WATER_positions'] = [
        (l.x, l.y) for l in animat.objs[ObjTypes.WATER]
    ]
    controller.trial_data['uneaten_TRAP_positions'] = [
        (l.x, l.y) for l in animat.objs[ObjTypes.TRAP]
    ]
    controller.trial_data['animat'] = animat

    if TEST_GA:
        # simple GA test -- maximise genome
        score = np.mean(controller.genome)

    return score
Exemple #5
0
def test_animat_no_controller():
    for n_animats in range(10):
        duration = 50.0
        DT = 0.02
        iterations = int(np.round(duration / DT))

        animat = Animat()
        animat.x = np.random.randn()
        animat.y = np.random.randn()
        animat.a = np.random.rand() * np.pi * 2.0
        obj = Obj(0, 0, 'default')
        animat.add_obj(obj)

        for iteration in range(iterations):
            animat.calculate_derivative()
            animat.euler_update(DT=DT)

            left_sensor = animat.sensors['default'][Sides.LEFT]
            right_sensor = animat.sensors['default'][Sides.RIGHT]

            # print(f'l:{left_sensor}\t r:{right_sensor}')

            # animat.lm = 0.4
            # animat.rm = 0.5

            animat.lm = left_sensor * 5
            animat.rm = right_sensor * 5

        plot(animat.x_h, animat.y_h, ',')
        plot(animat.x_h[-1], animat.y_h[-1], 'ko', ms=3)

    plot(-999, -999, 'k.', label='Aniamt Final Position')
    plot(0, 0, ',', label='Animat Trajectory')
    plot(0, 0, 'rx', label='Object Position')
    xlim(-3, 3)
    ylim(-3, 3)
    legend()
    gca().set_aspect('equal')
    show()
Exemple #6
0
 def __init__(self, genome, parent=None, gen=0):
     self.parent = parent
     self.animat = Animat(genome)
     self.gen = gen
     # Mark whether the animat's phenotype needs updating.
     self._dirty_phenotype = True
Exemple #7
0
class Individual:

    def __init__(self, genome, parent=None, gen=0):
        self.parent = parent
        self.animat = Animat(genome)
        self.gen = gen
        # Mark whether the animat's phenotype needs updating.
        self._dirty_phenotype = True

    def __eq__(self, other):
        return self.genome == other.genome and self.parent == other.parent

    @property
    def genome(self):
        """The animat's genome."""
        return self.animat.genome

    @property
    def gen(self):
        """The generation the animat was born."""
        return self.animat.gen

    @gen.setter
    def gen(self, value):
        self.animat.gen = value

    @property
    def edges(self):
        """The animat's edge list."""
        self._update_phenotype()
        return self.animat.edges

    @property
    def cm(self):
        """The animat's connectivity matrix."""
        cm = np.zeros((params.NUM_NODES, params.NUM_NODES), int)
        cm[list(zip(*self.edges))] = 1
        return cm

    @property
    def tpm(self):
        """The animats's TPM."""
        self._update_phenotype()
        return np.array(self.animat.tpm).astype(float)

    @property
    def correct(self):
        """The number of correct catches/avoidances in the game."""
        return self.animat.correct

    @property
    def incorrect(self):
        """The number of incorrect catches/avoidances in the game."""
        return self.animat.incorrect

    def _update_phenotype(self):
        """Update the animat's phenotype if necessary. Returns whether an
        update was performed."""
        if self._dirty_phenotype:
            self.animat.update_phenotype()
            self._dirty_phenotype = False
            return True
        return False

    def __deepcopy__(self, memo):
        # Don't copy the animat or the parent.
        copy = Individual(genome=self.animat.genome, parent=self.parent)
        for key, val in self.__dict__.items():
            if key not in ('animat', 'parent'):
                copy.__dict__[key] = deepcopy(val, memo)
        return copy

    def mutate(self):
        """Mutate the animat's genome in-place."""
        self.animat.mutate(params.MUTATION_PROB, params.DUPLICATION_PROB,
                           params.DELETION_PROB, params.MIN_GENOME_LENGTH,
                           params.MAX_GENOME_LENGTH)
        self._dirty_phenotype = True

    def play_game(self):
        """Return the list of state transitions the animat goes through when
        playing the game."""
        self._update_phenotype()
        transitions = self.animat.play_game(
            params.HIT_MULTIPLIERS,
            params.BLOCK_PATTERNS,
            scramble_world=params.SCRAMBLE_WORLD)
        # TODO remove this assertion at some point for speed
        # Check that everything adds up.
        assert self.animat.correct + self.animat.incorrect == params.NUM_TRIALS
        return transitions

    def lineage(self):
        """Return a generator for the lineage of this individual."""
        yield self.animat
        ancestor = self.parent
        while ancestor is not None:
            yield ancestor.animat
            ancestor = ancestor.parent