Skip to content
Snippets Groups Projects
Commit 50ed9322 authored by Olivier Bertrand's avatar Olivier Bertrand
Browse files

Change agent to use a brain instead of renderer

parent a7c5beeb
No related branches found
No related tags found
No related merge requests found
"""
Every agent comes with a battery of a brain processing the about of \
senses or sensors for biological or technical agent, respectively.
The senses of agents in navipy are limited
to:
* 4d vision (brighness + depth)
The 4d vision sense is controlled by rendering module, either an \
online rendering or loaded from a database containing pre-rendered images.
For example to use pre-rendered images from a database:
.. literalinclude:: example/processing/apcv.py
:lines: 10-11
Then the senses can be updated at a new position orientation:
.. literalinclude:: example/processing/apcv.py
:lines: 15
Renderer
--------
.. automodule:: navipy.sensors.renderer
"""
from database import DataBaseLoad
class Bunch:
def __init__(self, **kwds):
self.__dict__.update(kwds)
class Brain():
def __init__(self,
renderer=None):
self.vision = Bunch(scene=None,
viewing_directions=None,
channels=None)
self.renderer = renderer
if self.renderer is not None:
self.vision.scene = None
self.vision.viewing_directions = renderer.viewing_directions
self.vision.channels = renderer.channels
def velocity(self):
raise NotImplementedError("Subclasses should implement this")
def update(self, posorient):
if self.renderer is not None:
self.vision.scene = self.renderer.scene(posorient)
@property
def posorients(self):
if isinstance(self.renderer, DataBaseLoad):
return self.renderer.posorients
else:
raise NotImplementedError("Subclasses should implement this, "+
"when renderer is not DataBaseLoad")
...@@ -37,8 +37,7 @@ class DefaultSensors(): ...@@ -37,8 +37,7 @@ class DefaultSensors():
class AbstractAgent(): class AbstractAgent():
def __init__(self): def __init__(self):
self._sensors = DefaultSensors() self._brian = DefaultSensors()
self._motion = defaultcallback
self._motion_param = None self._motion_param = None
self._alter_posorientvel = defaultcallback self._alter_posorientvel = defaultcallback
self._posorient_col = ['x', 'y', 'z', self._posorient_col = ['x', 'y', 'z',
...@@ -81,37 +80,20 @@ class AbstractAgent(): ...@@ -81,37 +80,20 @@ class AbstractAgent():
velocity.loc[self._velocity_col] velocity.loc[self._velocity_col]
@property @property
def motion(self): def brain(self):
return inspect.getsourcelines(self._motion) return inspect.getsourcelines(self._brain)
@property @brain.setter
def motion_param(self): def brain(self, brain):
return self._motion_param.copy() self._brain = brain
@motion_param.setter
def motion_param(self, param):
if isinstance(param, dict):
self._motion_param = param
else:
raise TypeError('motion param should be a dictionary')
@property
def sensors(self):
return inspect.getsourcelines(self._sensors)
@property @property
def alter_posorientvel(self): def alter_posorientvel(self):
return inspect.getsourcelines(self._alter_posorientvel) return inspect.getsourcelines(self._alter_posorientvel)
def move(self): def move(self):
self._sensors.update(self.posorient) self._brain.update(self.posorient)
if self._motion_param is None: self.velocity = self._brian.velocity()
self.velocity = self._motion(self._posorient_vel,
self._sensors)
else:
self.velocity = self._motion(self._posorient_vel,
self._sensors,
**self._motion_param)
alteredpos = self._alter_posorientvel(self._posorient_vel) alteredpos = self._alter_posorientvel(self._posorient_vel)
self.posorient = alteredpos self.posorient = alteredpos
self.velocity = alteredpos self.velocity = alteredpos
...@@ -142,20 +124,12 @@ CyberBeeAgent is a close loop agent and need to be run within blender \ ...@@ -142,20 +124,12 @@ CyberBeeAgent is a close loop agent and need to be run within blender \
bla bla
""" """
def __init__(self, renderer): def __init__(self, brain):
AbstractAgent.__init__(self) AbstractAgent.__init__(self)
AbstractAgent._alter_posorientvel = \ AbstractAgent._alter_posorientvel = \
lambda motion_vec: navimomath.next_pos(motion_vec, lambda motion_vec: navimomath.next_pos(motion_vec,
move_mode='free_run') move_mode='free_run')
self.sensors = renderer self.brain = brain
@AbstractAgent.sensors.setter
def sensors(self, renderer):
self._sensors = Senses(renderer)
@AbstractAgent.motion.setter
def motion(self, motion):
self._motion = motion
class GridAgent(AbstractAgent, Process): class GridAgent(AbstractAgent, Process):
...@@ -173,25 +147,15 @@ GridAgent is a close loop agent here its position is snap to a grid. ...@@ -173,25 +147,15 @@ GridAgent is a close loop agent here its position is snap to a grid.
library. Thus, several GridAgents can safely be run in parallel. library. Thus, several GridAgents can safely be run in parallel.
""" """
def __init__(self, database_filename, def __init__(self, brain,
posorients_queue=None, posorients_queue=None,
results_queue=None): results_queue=None):
if (posorients_queue is not None) and (results_queue is not None): if (posorients_queue is not None) and (results_queue is not None):
multiprocessing.Process.__init__(self) multiprocessing.Process.__init__(self)
AbstractAgent.__init__(self) AbstractAgent.__init__(self)
self._alter_posorientvel = self.snap_to_grid self._alter_posorientvel = self.snap_to_grid
self.sensors = database_filename self.brain = brain
@AbstractAgent.sensors.setter
def sensors(self, database_filename):
self.db = DataBaseLoad(database_filename)
self._posorients = self.db.posorients
self._sensors = Senses(renderer=self.db)
@AbstractAgent.motion.setter
def motion(self, motion):
self._motion = motion
@property @property
def mode_of_motion(self): def mode_of_motion(self):
""" """
...@@ -284,11 +248,11 @@ the agent motion, or ...@@ -284,11 +248,11 @@ the agent motion, or
2. pre-computed agent-motion 2. pre-computed agent-motion
""" """
def __init__(self, database_filename): def __init__(self, brian):
self.db = DataBaseLoad(database_filename) self._brain = copy.deepcopy(brain)
# Init the graph # Init the graph
self._graph = nx.DiGraph() self._graph = nx.DiGraph()
for row_id, posor in self.db.posorients.iterrows(): for row_id, posor in self._brain.posorients.iterrows():
posor.name = row_id posor.name = row_id
self._graph.add_node(row_id, self._graph.add_node(row_id,
posorient=posor) posorient=posor)
...@@ -320,7 +284,7 @@ the agent motion, or ...@@ -320,7 +284,7 @@ the agent motion, or
# Start ndatabase loader # Start ndatabase loader
num_agents = ncpu num_agents = ncpu
agents = [GridAgent(self.dbname, agents = [GridAgent(copy.deepcopy(self._brain),
posorients_queue=posorients_queue, posorients_queue=posorients_queue,
results_queue=results_queue) results_queue=results_queue)
for _ in range(num_agents)] for _ in range(num_agents)]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment