Browse Source

molecules evaporation

Bastien Sevajol 9 years ago
parent
commit
e595fc5914

+ 1 - 1
TODO View File

1
 * Fourmis (map.tmx) pas en mode nurse (-> algo de choix d'activité plus tard)
1
 * Fourmis (map.tmx) pas en mode nurse (-> algo de choix d'activité plus tard)
2
 * Ant: MOVE_MODE_HOME && rien à faire (pas de truc à stocker, switch to mode EXPLO)
2
 * Ant: MOVE_MODE_HOME && rien à faire (pas de truc à stocker, switch to mode EXPLO)
3
 * Nourriture posé: Comme oeufs, plus de debug. Implique algo pour pas remplir couloirs. Implique ne plus travailler a xplo de nourriture si plus de place ? etc ...
3
 * Nourriture posé: Comme oeufs, plus de debug. Implique algo pour pas remplir couloirs. Implique ne plus travailler a xplo de nourriture si plus de place ? etc ...
4
-* ! Les molecules d'odeur (oeuf et bouffe) ne disparaissent pas. Ce que l'on peut faire: Ces odeurs ont tjrs une intensité de 1. En même temps que l'on lance la SmellAction on lance (juste avant) l'Action d'évaporation. Les odeurs seront ainsi nettoyé.
4
+* ! Les molecules d'odeur (oeuf et bouffe) ne disparaissent pas. Ce que l'on peut faire: Ces odeurs ont tjrs une intensité de 1. En même temps que l'on lance la SmellAction on lance (juste avant) l'Action d'évaporation. Les odeurs seront ainsi nettoyé. EDIT c'est censcé être dans le cycle_pre_run de l'action !

+ 9 - 1
config.py View File

28
             'mainprocess': True,
28
             'mainprocess': True,
29
             'cycles': -1,
29
             'cycles': -1,
30
             'seed': 42
30
             'seed': 42
31
-        }
31
+        },
32
+        'clean_each_cycle': 100
32
     },
33
     },
33
     'simulations': simulations,
34
     'simulations': simulations,
34
     'connections': [Pygame],
35
     'connections': [Pygame],
60
         'put': {
61
         'put': {
61
             'max_objects_at_same_position': 5
62
             'max_objects_at_same_position': 5
62
         }
63
         }
64
+    },
65
+    'stigmergy': {
66
+        'molecule': {
67
+            'evaporate_decrement': 5,
68
+            'evaporate_min_age': 100,
69
+            'evaporate_each_cycle': 100
70
+        }
63
     }
71
     }
64
 }
72
 }

+ 2 - 2
intelligine/cst.py View File

35
 TYPE_ANT = IncrementedNamedInt.get('intelligine.object.type.ant')
35
 TYPE_ANT = IncrementedNamedInt.get('intelligine.object.type.ant')
36
 
36
 
37
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
37
 PHEROMON_POSITIONS = IncrementedNamedInt.get('intelligine.phero.positions')
38
-MOLECULES_INFOS = IncrementedNamedInt.get('intelligine.phero.infos')
39
-MOLECULES_DIRECTION = IncrementedNamedInt.get('intelligine.phero.direction')
38
+MOLECULES_INFOS = IncrementedNamedInt.get('intelligine.mol.infos')
39
+MOLECULES_DIRECTION = IncrementedNamedInt.get('intelligine.mol.direction')
40
 PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
40
 PHEROMON_DIR_NONE = IncrementedNamedInt.get('intelligine.phero.direction.none')
41
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
41
 PHEROMON_DIR_EXPLO = IncrementedNamedInt.get('intelligine.phero.direction.explo')
42
 EXPLORATION_VECTOR = IncrementedNamedInt.get('intelligine.exploration_vector')
42
 EXPLORATION_VECTOR = IncrementedNamedInt.get('intelligine.exploration_vector')

+ 1 - 1
intelligine/display/pygame/config.py View File

1
 from intelligine.synergy.Colony import Colony
1
 from intelligine.synergy.Colony import Colony
2
 from intelligine.synergy.Environment import Environment
2
 from intelligine.synergy.Environment import Environment
3
+from intelligine.synergy.Simulation import Simulation
3
 from intelligine.synergy.object.StockedFood import StockedFood
4
 from intelligine.synergy.object.StockedFood import StockedFood
4
-from synergine.synergy.Simulation import Simulation
5
 from intelligine.synergy.object.Food import Food
5
 from intelligine.synergy.object.Food import Food
6
 from intelligine.synergy.object.Rock import Rock
6
 from intelligine.synergy.object.Rock import Rock
7
 from intelligine.synergy.object.ant.Ant import Ant
7
 from intelligine.synergy.object.ant.Ant import Ant

+ 1 - 1
intelligine/simulation/molecule/DirectionMolecule.py View File

11
 
11
 
12
     @classmethod
12
     @classmethod
13
     def appose(cls, context, point, molecule):
13
     def appose(cls, context, point, molecule):
14
-        context.molecules().increment_with_molecule(point, molecule)
14
+        context.molecules().increment_with_molecule(point, molecule, context.get_cycle())
15
         context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
15
         context.metas.list.add(MOLECULES, MOLECULES, point, assert_not_in=False)
16
 
16
 
17
     @classmethod
17
     @classmethod

+ 35 - 0
intelligine/simulation/molecule/Evaporation.py View File

1
+from intelligine.cst import MOLECULES, MOLECULES_DIRECTION
2
+from intelligine.synergy.stigmergy.MoleculesManager import MoleculesManager
3
+
4
+
5
+class Evaporation:
6
+
7
+    def __init__(self, context, intensity_decrement, molecules_exclude_types, molecule_minimum_age):
8
+        self._context = context
9
+        self._intensity_decrement = intensity_decrement
10
+        self._molecules_manager = MoleculesManager(context)
11
+        self._molecules_exclude_types = molecules_exclude_types
12
+        self._molecule_minimum_age = molecule_minimum_age
13
+
14
+    def evaporate(self):
15
+        for position, flavour in self._get_flavours():
16
+            self._decrease_flavour(flavour)
17
+            self._molecules_manager.set_flavour(position, flavour)
18
+
19
+    def _get_flavours(self):
20
+        molecules_points = self._context.metas.list.get(MOLECULES, MOLECULES)
21
+        for molecule_point in molecules_points:
22
+            yield molecule_point, self._molecules_manager.get_flavour(molecule_point)
23
+
24
+    def _decrease_flavour(self, flavour):
25
+        for direction_molecule in flavour.get_molecules(MOLECULES_DIRECTION):
26
+            if not self._is_recent_molecule(direction_molecule) \
27
+               and not self._is_excluded_molecule_type(direction_molecule):
28
+                direction_molecule.increment_intensity(-self._intensity_decrement)
29
+                flavour.set_molecule(direction_molecule)
30
+
31
+    def _is_recent_molecule(self, molecule):
32
+        return (self._context.get_cycle() - molecule.get_cycle_age()) < self._molecule_minimum_age
33
+
34
+    def _is_excluded_molecule_type(self, molecule):
35
+        return molecule.get_type() in self._molecules_exclude_types

+ 5 - 1
intelligine/simulation/molecule/Molecule.py View File

1
 class Molecule():
1
 class Molecule():
2
 
2
 
3
-    def __init__(self, category, type, distance=None, intensity=0):
3
+    def __init__(self, category, type, distance=None, intensity=0, cycle_age=None):
4
         self._category = category
4
         self._category = category
5
         self._type = type
5
         self._type = type
6
         self._distance = distance
6
         self._distance = distance
7
         self._intensity = intensity
7
         self._intensity = intensity
8
+        self._cycle_age = cycle_age
8
 
9
 
9
     def get_category(self):
10
     def get_category(self):
10
         return self._category
11
         return self._category
21
     def get_intensity(self):
22
     def get_intensity(self):
22
         return self._intensity
23
         return self._intensity
23
 
24
 
25
+    def get_cycle_age(self):
26
+        return self._cycle_age
27
+
24
     def increment_intensity(self, increment_value):
28
     def increment_intensity(self, increment_value):
25
         self._intensity += increment_value
29
         self._intensity += increment_value

+ 13 - 4
intelligine/simulation/molecule/MoleculeFlavour.py View File

10
         for category in raw_data:
10
         for category in raw_data:
11
             molecules_by_category = raw_data[category]
11
             molecules_by_category = raw_data[category]
12
             for type in molecules_by_category:
12
             for type in molecules_by_category:
13
-                distance, intensity = molecules_by_category[type]
13
+                distance, intensity, cycle_age = molecules_by_category[type]
14
                 if category not in flavour:
14
                 if category not in flavour:
15
                     flavour[category] = {}
15
                     flavour[category] = {}
16
-                flavour[category][type] = Molecule(category, type, distance, intensity)
16
+                flavour[category][type] = Molecule(category, type, distance, intensity, cycle_age)
17
         return cls(flavour)
17
         return cls(flavour)
18
 
18
 
19
     def get_raw_data(self):
19
     def get_raw_data(self):
24
                 molecule = molecules_by_category[type]
24
                 molecule = molecules_by_category[type]
25
                 if category not in raw_data:
25
                 if category not in raw_data:
26
                     raw_data[category] = {}
26
                     raw_data[category] = {}
27
-                raw_data[category][type] = (molecule.get_distance(), molecule.get_intensity())
27
+                if molecule.get_intensity() >= 0:
28
+                    raw_data[category][type] = (molecule.get_distance(),
29
+                                                molecule.get_intensity(),
30
+                                                molecule.get_cycle_age())
28
         return raw_data
31
         return raw_data
29
 
32
 
30
     def __init__(self, flavour):
33
     def __init__(self, flavour):
43
         :return: Molecules dict or empty dict of no molecules
46
         :return: Molecules dict or empty dict of no molecules
44
         """
47
         """
45
         try:
48
         try:
46
-            return self.get_types(category)
49
+            return self.get_types(category).values()
50
+        except NoCategoryInMolecule:
51
+            return {}
52
+
53
+    def get_molecules_types(self, category):
54
+        try:
55
+            return self.get_types(category).keys()
47
         except NoCategoryInMolecule:
56
         except NoCategoryInMolecule:
48
             return {}
57
             return {}
49
 
58
 

+ 2 - 2
intelligine/simulation/object/brain/part/move/AntMoveBrainPart.py View File

117
     def _on_home_smell(cls, context, object_id):
117
     def _on_home_smell(cls, context, object_id):
118
         current_position = context.metas.value.get(POSITION, object_id)
118
         current_position = context.metas.value.get(POSITION, object_id)
119
         flavour = context.molecules().get_flavour(current_position)
119
         flavour = context.molecules().get_flavour(current_position)
120
-        molecules = flavour.get_molecules(MOLECULES_DIRECTION)
120
+        molecules = flavour.get_molecules_types(MOLECULES_DIRECTION)
121
 
121
 
122
         if not molecules:
122
         if not molecules:
123
             return False
123
             return False
140
             self._update_exploration_vector()
140
             self._update_exploration_vector()
141
 
141
 
142
     def _start_new_exploration(self):
142
     def _start_new_exploration(self):
143
-        self._reinit_exploration_vector()
143
+        self._init_exploration_vector()
144
         self._host_brain.switch_to_mode(MODE_EXPLO)
144
         self._host_brain.switch_to_mode(MODE_EXPLO)
145
 
145
 
146
     def _init_exploration_vector(self):
146
     def _init_exploration_vector(self):

+ 1 - 1
intelligine/simulation/object/brain/part/transport/AntTakeBrainPart.py View File

1
 from intelligine.simulation.object.brain.part.transport.TakeBrainPart import TakeBrainPart
1
 from intelligine.simulation.object.brain.part.transport.TakeBrainPart import TakeBrainPart
2
 from intelligine.synergy.object.ressource.Ressource import Resource
2
 from intelligine.synergy.object.ressource.Ressource import Resource
3
 from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, \
3
 from intelligine.cst import MODE_EXPLO, TYPE_RESOURCE_EXPLOITABLE, \
4
-    MODE_GOHOME, MODE_NURSE, TYPE_NURSERY
4
+    MODE_GOHOME, MODE_NURSE, TYPE_NURSERY, MODE_HOME
5
 
5
 
6
 
6
 
7
 class AntTakeBrainPart(TakeBrainPart):
7
 class AntTakeBrainPart(TakeBrainPart):

+ 29 - 1
intelligine/synergy/Simulation.py View File

1
+from intelligine.simulation.molecule.Evaporation import Evaporation
2
+from synergine.core.Core import Core
1
 from synergine.synergy.Simulation import Simulation as BaseSimulation
3
 from synergine.synergy.Simulation import Simulation as BaseSimulation
2
 from synergine_xyz.cst import POSITIONS
4
 from synergine_xyz.cst import POSITIONS
3
 
5
 
4
 
6
 
5
 class Simulation(BaseSimulation):
7
 class Simulation(BaseSimulation):
6
 
8
 
9
+    _smells = []
10
+
11
+    @classmethod
12
+    def add_smell(cls, smell):
13
+        if smell not in cls._smells:
14
+            cls._smells.append(smell)
15
+
16
+    @classmethod
17
+    def get_smells(cls):
18
+        return cls._smells
19
+
7
     def end_cycle(self, context):
20
     def end_cycle(self, context):
8
-        if context.get_cycle() % 100 is 0:
21
+        clean_each_cycle = Core.get_configuration_manager().get('engine.clean_each_cycle', 100)
22
+        evaporate_each_cycle = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_each_cycle', 100)
23
+
24
+        if context.get_cycle() % clean_each_cycle is 0:
9
             context.metas.list.clean(POSITIONS)
25
             context.metas.list.clean(POSITIONS)
26
+
27
+        if context.get_cycle() % evaporate_each_cycle is 0:
28
+            self._evaporate(context)
29
+
30
+    def _evaporate(self, context):
31
+        evaporation_increment = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_decrement', 5)
32
+        evaporation_min_age = Core.get_configuration_manager().get('stigmergy.molecule.evaporate_min_age', 100)
33
+        evaporation = Evaporation(context,
34
+                                  evaporation_increment,
35
+                                  molecules_exclude_types=self.get_smells(),
36
+                                  molecule_minimum_age=evaporation_min_age)
37
+        evaporation.evaporate()

+ 1 - 1
intelligine/synergy/event/smell/SmellAction.py View File

35
             try:
35
             try:
36
                 DirectionMolecule.appose(context, smell_point, molecule)
36
                 DirectionMolecule.appose(context, smell_point, molecule)
37
             except BestMoleculeHere:
37
             except BestMoleculeHere:
38
-                pass  #
38
+                pass  # TODO: Pas l'inverse ? A voir apres avoir fix la disparition.
39
 
39
 
40
             #
40
             #
41
             # current_point_smell = points_distances[smell_point]
41
             # current_point_smell = points_distances[smell_point]

+ 2 - 0
intelligine/synergy/object/SynergyObject.py View File

1
 from intelligine.cst import OBJ_SMELL, INSTANCE_CLASS
1
 from intelligine.cst import OBJ_SMELL, INSTANCE_CLASS
2
+from intelligine.synergy.Simulation import Simulation
2
 from synergine_xyz.SynergyObject import SynergyObject as XyzSynergyObject
3
 from synergine_xyz.SynergyObject import SynergyObject as XyzSynergyObject
3
 
4
 
4
 
5
 
12
     def _set_smell(self, smell_type):
13
     def _set_smell(self, smell_type):
13
         self._smell = smell_type
14
         self._smell = smell_type
14
         self._context.metas.value.set(OBJ_SMELL, self.get_id(), smell_type)
15
         self._context.metas.value.set(OBJ_SMELL, self.get_id(), smell_type)
16
+        Simulation.add_smell(smell_type)
15
 
17
 
16
     def get_smell(self):
18
     def get_smell(self):
17
         if not self._smell:
19
         if not self._smell:

+ 3 - 2
intelligine/synergy/stigmergy/MoleculesManager.py View File

28
                 return Molecule()
28
                 return Molecule()
29
             raise
29
             raise
30
 
30
 
31
-    def increment_with_molecule(self, position, apposed_molecule):
31
+    def increment_with_molecule(self, position, apposed_molecule, cycle_age):
32
         flavour = self.get_flavour(position)
32
         flavour = self.get_flavour(position)
33
         try:
33
         try:
34
             position_molecule = flavour.get_molecule(apposed_molecule.get_category(), apposed_molecule.get_type())
34
             position_molecule = flavour.get_molecule(apposed_molecule.get_category(), apposed_molecule.get_type())
35
         except NoMolecule:
35
         except NoMolecule:
36
             position_molecule = Molecule(apposed_molecule.get_category(),
36
             position_molecule = Molecule(apposed_molecule.get_category(),
37
                                          apposed_molecule.get_type(),
37
                                          apposed_molecule.get_type(),
38
-                                         distance=apposed_molecule.get_distance())
38
+                                         distance=apposed_molecule.get_distance(),
39
+                                         cycle_age=cycle_age)
39
 
40
 
40
         position_molecule.increment_intensity(apposed_molecule.get_intensity())
41
         position_molecule.increment_intensity(apposed_molecule.get_intensity())
41
 
42