diff --git a/navipy/comparing/__init__.py b/navipy/comparing/__init__.py index a918ca387d40c6c41f68e1dffcf351a2c8e328c6..0899ac287f5d6eb547eb53aff1ccc07d49006404 100644 --- a/navipy/comparing/__init__.py +++ b/navipy/comparing/__init__.py @@ -80,6 +80,9 @@ the current and memorised place code. should be image based') check_scene(current) check_scene(memory) + # ridf is a NxM matrix, + # because one value per azimuth (N) and n values per channel + # (M) ridf = np.zeros((current.shape[1], current.shape[2])) for azimuth_i in range(0, current.shape[1]): rot_im = np.roll(current, azimuth_i, axis=1) diff --git a/navipy/models/hafner_2000.py b/navipy/models/hafner_2000.py index 3c94b921d17c379fc4430e082c89fd6b27524b1c..d2c3c921653083c346920fd1037d0f374fb0ddbf 100644 --- a/navipy/models/hafner_2000.py +++ b/navipy/models/hafner_2000.py @@ -18,12 +18,12 @@ def processing(scene, viewing_directions, channel): * Müller et al. 2018 * Basten and Mallot 2010 refer as COMANV in : - * Hafter 2000, + * Hafner 2000, * Bertrand 2015 center of mass of average nearness vector """ # Invert distance to nearness - scene[..., 3, :] = 1/scene[..., 3, :] + scene[..., 3, :] = 1 / scene[..., 3, :] # Calculate the skyline scene = skyline(scene) # skyline viewing direction @@ -38,7 +38,7 @@ def comparing(current, memory): homing vector = current vector - memory vector """ - return current-memory + return current - memory class ASVBrain(Brain): diff --git a/navipy/models/irdf_2003.py b/navipy/models/irdf_2003.py new file mode 100644 index 0000000000000000000000000000000000000000..a7c0918beac06a87b01650d9fd519b4caba47e37 --- /dev/null +++ b/navipy/models/irdf_2003.py @@ -0,0 +1,79 @@ +from navipy import Brain +from navipy.comparing import rot_imagediff +import pandas as pd +import numpy as np +from navipy.scene import __spherical_indeces__ +from navipy.maths.coordinates import spherical_to_cartesian +# 0) Define a class heriting from Brain + + +def processing(scene, channel): + """ Return the image difference + + * inverse of distance (i.e. distance -> nearness) + """ + # Invert distance to nearness + scene[..., 3, :] = 1 / scene[..., 3, :] + return scene[..., channel, :] + + +def comparing(current, memory, viewing_directions): + """ Calculate homing vector with irdf + + irdf: Image rotation difference function + The image difference is root mean square + + Used in: + * Zeil, J., Hofmann, M., & Chahl, J. (2003). \ + Catchment Areas of Panoramic Snapshots in Outdoor Scenes. + * Baddeley, B., Graham, P., Husbands, P., & Philippides, A. (2012).\ + A Model of Ant Route Navigation Driven by Scene Familiarity. + * Ardin, P., Peng, F., Mangan, M., Lagogiannis, K., & Webb, B. (2016).\ + Using an Insect Mushroom Body Circuit to Encode Route \ + Memory in Complex Natural Environments. + """ + if (current.shape[2] != 1) or (memory.shape[2] != 1): + msg = 'Current view {} and the memory {} \n' + msg += 'should be a NxMx1x1 matrix' + msg = msg.format(current.shape, memory.shape) + raise NameError(msg) + irdf = rot_imagediff(current, memory) + # [..., 0] because processing + # select one channel, and therefore + # irdf should is only a Nx1 matrix + idx = np.argmin(irdf[..., 0]) + minval = np.min(irdf[..., 0]) + direction = viewing_directions[idx, + __spherical_indeces__['azimuth']] + homing_vect = spherical_to_cartesian(elevation=0, + azimuth=direction, + radius=minval) + return homing_vect + + +class IRDFBrain(Brain): + def __init__(self, + memory, + renderer=None, + channel=0): + Brain.__init__(self, renderer=renderer) + # Init memory + self.channel = channel + self.memory = memory + + def velocity(self): + index = self.posorient.index + convention = index.levels[0][-1] + current = processing(self.vision.scene, + self.channel) + homing_vector = comparing(current, + self.memory, + self.vision.viewing_directions, + ) + homing_vector = np.squeeze(homing_vector) + indeces = [('location', 'dx'), ('location', 'dy'), + ('location', 'dz'), (convention, 'dalpha_0'), + (convention, 'dalpha_1'), (convention, 'dalpha_2')] + velocity = pd.Series(data=0, index=pd.MultiIndex.from_tuples(indeces)) + velocity.loc['location'] = homing_vector + return velocity