Commit ff0550d2cec4bd5ac5cc6b41291825d750f6cef8

Authored by Etienne Pallier
1 parent a7887020
Exists in dev

Multi-agents : AgentA et AgentX s'envoient des commandes (en //)

- AgentA et AgentX ont chacun leur propre scenario
- GROSSE OPTIMISATION : plus besoin du script "start_agent.py" !!!
- pyros.py lance directement "cd src/agent/ ; python AgentX.py"
- Mode opératoire pour lancer un agent:
		- pour démarrer agentX : ./pyros.py start agentX [-c configfile]
		(ou encore: activer l'environnement virtuel, puis lancer "./AgentX.py
configfile")
		- pour démarrer agentA : ouvrir un autre terminal et taper "./pyros.py
start agentA"
		- pour utiliser thread ou processus : il suffit de mettre la constante
RUN_IN_THREAD de AgentX (ou AgentA) à False ou True
README.md
... ... @@ -74,12 +74,13 @@ Author: E. Pallier
74 74 VERSION: 0.20.19
75 75  
76 76 Comment:
77   - GROSSE OPTIMISATION : plus besoin du script intermédiaire "start_agent.py" !!!
  77 + Multi-agents : AgentA et AgentX s'envoient mutuellement des commandes (en //)
78 78  
  79 + - AgentA et AgentX ont chacun leur propre scenario
  80 + - GROSSE OPTIMISATION : plus besoin du script intermédiaire "start_agent.py" !!!
79 81 - pyros.py lance directement "cd src/agent/ ; python AgentX.py"
80   - - Multi-agents : AgentA et AgentX fonctionnent en parallèle
81 82 - Mode opératoire pour lancer un agent:
82   - - ./pyros.py start agentX [-c configfile]
  83 + - pour démarrer agentX : ./pyros.py start agentX [-c configfile]
83 84 (ou encore: activer l'environnement virtuel, puis lancer "./AgentX.py configfile")
84 85 - pour démarrer agentA : ouvrir un autre terminal et taper "./pyros.py start agentA"
85 86 - pour utiliser thread ou processus : il suffit de mettre la constante RUN_IN_THREAD de AgentX (ou AgentA) à False ou True
... ...
pyros.py
... ... @@ -24,6 +24,7 @@ INIT_FIXTURE = "initial_fixture.json"
24 24  
25 25 AGENTS = {
26 26 #"agentX" : "agent",
  27 + "agent" : "Agent",
27 28 "agentX" : "AgentX",
28 29 "agentA" : "AgentA",
29 30 "webserver" : "webserver",
... ... @@ -366,7 +367,7 @@ def start(agent:str, configfile:str):
366 367 ##agentX.run(FOR_REAL=True)
367 368 os.chdir("src/agent/")
368 369 #cmd = "-m AgentX"
369   - cmd = f" Agent{agent_name[5:]}.py " + configfile
  370 + cmd = f" Agent{agent_name[5:]}.py {configfile}"
370 371  
371 372 if not test_mode(): execProcessFromVenv(cmd)
372 373 # self._change_dir("..")
... ...
src/agent/Agent.py
... ... @@ -103,61 +103,6 @@ DEBUG_FILE = False
103 103  
104 104 log = L.setupLogger("AgentLogger", "Agent")
105 105  
106   -# FOR TEST ONLY
107   -# Run this agent in simulator mode
108   -SIMULATOR_MODE = True
109   -SIMULATOR_WITH_TEST = True
110   -SIMULATOR_COMMANDS = iter([
111   - "go_active",
112   - "go_idle",
113   -
114   - # specific0 not_executed_because_idle
115   - "specific0",
116   -
117   - "go_active",
118   -
119   - # specific1 executed_because_not_idle, should complete ok
120   - "specific1",
121   -
122   - # specific2 will be executed only when specific1 is finished,
123   - # and should be aborted before end of execution,
124   - # because of the 1st coming "abort" command below
125   - "specific2",
126   -
127   - # specific3 should be executed only when specific2 is finished (in fact, aborted),
128   - # and should be aborted before end of execution,
129   - # because of the 2nd coming "abort" command below
130   - "specific3",
131   -
132   - # These commands should not have the time to be processed
133   - # because the "exit" command below should be executed before
134   - "specific4",
135   - "specific5",
136   - "specific6",
137   - "specific7",
138   - "specific8",
139   -
140   - # Should abort the current running command (which should normally be specific2)
141   - # even if commands above (specific3, ..., specific8) are already pending
142   - "abort",
143   -
144   - # These commands (except abort) won't be executed
145   - # because too many commands are already pending (above)
146   - "specific9",
147   - "abort",
148   - "go_active",
149   - "go_idle",
150   -
151   - # Should stop the agent even before the previous pending commands are executed
152   - "exit",
153   -
154   - # Because of the previous "exit" command,
155   - # these following commands should not be executed,
156   - # and not even be added to the database command table
157   - "go_active",
158   - "specific10"
159   -])
160   -
161 106  
162 107  
163 108  
... ... @@ -198,6 +143,67 @@ class StoppableThreadEvenWhenSleeping(threading.Thread):
198 143  
199 144 class Agent:
200 145  
  146 + # FOR TEST ONLY
  147 + # Run this agent in simulator mode
  148 + SIMULATOR_MODE = True
  149 + # Run the assertion tests at the end
  150 + SIMULATOR_WITH_TEST = True
  151 + # Who should I send commands to ?
  152 + SIMULATOR_COMMANDS_DEST = "myself"
  153 + # Default scenario to be executed
  154 + #SIMULATOR_COMMANDS = iter([
  155 + SIMULATOR_COMMANDS = [
  156 + "go_active",
  157 + "go_idle",
  158 +
  159 + # specific0 not_executed_because_idle
  160 + "specific0",
  161 +
  162 + "go_active",
  163 +
  164 + # specific1 executed_because_not_idle, should complete ok
  165 + "specific1",
  166 +
  167 + # specific2 will be executed only when specific1 is finished,
  168 + # and should be aborted before end of execution,
  169 + # because of the 1st coming "abort" command below
  170 + "specific2",
  171 +
  172 + # specific3 should be executed only when specific2 is finished (in fact, aborted),
  173 + # and should be aborted before end of execution,
  174 + # because of the 2nd coming "abort" command below
  175 + "specific3",
  176 +
  177 + # These commands should not have the time to be processed
  178 + # because the "exit" command below should be executed before
  179 + "specific4",
  180 + "specific5",
  181 + "specific6",
  182 + "specific7",
  183 + "specific8",
  184 +
  185 + # Should abort the current running command (which should normally be specific2)
  186 + # even if commands above (specific3, ..., specific8) are already pending
  187 + "abort",
  188 +
  189 + # These commands (except abort) won't be executed
  190 + # because too many commands are already pending (above)
  191 + "specific9",
  192 + "abort",
  193 + "go_active",
  194 + "go_idle",
  195 +
  196 + # Should stop the agent even before the previous pending commands are executed
  197 + "exit",
  198 +
  199 + # Because of the previous "exit" command,
  200 + # these following commands should not be executed,
  201 + # and not even be added to the database command table
  202 + "go_active",
  203 + "specific10"
  204 + ]
  205 +
  206 +
201 207 """
202 208 How to run this agent exec_specific_cmd() method ?
203 209 - True = inside a Thread (cannot be killed, must be asked to stop, and inadequate for computation)
... ... @@ -267,6 +273,7 @@ class Agent:
267 273  
268 274 def __init__(self, name:str="Agent", config_filename:str=None, RUN_IN_THREAD=True):
269 275 self.name = name
  276 + self.SIMULATOR_COMMANDS = iter(self.SIMULATOR_COMMANDS)
270 277 self.RUN_IN_THREAD = RUN_IN_THREAD
271 278 self.set_status(self.STATUS_LAUNCH)
272 279 self.set_mode(self.MODE_IDLE)
... ... @@ -366,7 +373,7 @@ class Agent:
366 373  
367 374 self.update_survey()
368 375  
369   - if SIMULATOR_MODE: self.simulator_send_command_to_myself()
  376 + if self.SIMULATOR_MODE: self.simulator_send_next_command()
370 377  
371 378 # generic cmd in json format
372 379 print("------START COMMMAND PROCESSING------")
... ... @@ -575,12 +582,14 @@ class Agent:
575 582 self._agent_survey.save()
576 583  
577 584  
578   - def simulator_send_command_to_myself(self):
  585 + def simulator_send_next_command(self):
579 586 #self._current_test_cmd = "go_idle" if self._current_test_cmd=="go_active" else "go_active"
580 587 #if self._nb_test_cmds == 4: self._current_test_cmd = "exit"
581   - cmd_name = next(SIMULATOR_COMMANDS, None)
  588 + cmd_name = next(self.SIMULATOR_COMMANDS, None)
582 589 if not cmd_name: return
583   - Command.objects.create(sender=self.name, receiver=self.name, name=cmd_name)
  590 + #Command.objects.create(sender=self.name, receiver=self.name, name=cmd_name)
  591 + receiver_agent = self.name if self.SIMULATOR_COMMANDS_DEST=="myself" else self.SIMULATOR_COMMANDS_DEST
  592 + Command.objects.create(sender=self.name, receiver=receiver_agent, name=cmd_name)
584 593 #time.sleep(1)
585 594 #self._simulator_current_cmd_idx += 1
586 595 #self._nb_test_cmds += 1
... ... @@ -689,7 +698,7 @@ class Agent:
689 698 print("(before exiting) Here are the current (still) pending commands (time ordered) :")
690 699 commands = Command.get_pending_commands_for_agent(self.name)
691 700 Command.show_commands(commands)
692   - if SIMULATOR_MODE and SIMULATOR_WITH_TEST: self.simulator_test_results()
  701 + if self.SIMULATOR_MODE and self.SIMULATOR_WITH_TEST: self.simulator_test_results()
693 702 exit(0)
694 703 # Command is executed, so return None
695 704 return None
... ...
src/agent/AgentA.py
... ... @@ -14,6 +14,25 @@ from Agent import Agent
14 14  
15 15 class AgentA(Agent):
16 16  
  17 + # FOR TEST ONLY
  18 + # Run this agent in simulator mode
  19 + SIMULATOR_MODE = True
  20 + # Run the assertion tests at the end
  21 + SIMULATOR_WITH_TEST = False
  22 + # Who should I send commands to ?
  23 + #SIMULATOR_COMMANDS_DEST = "myself"
  24 + SIMULATOR_COMMANDS_DEST = "AgentX"
  25 + # Scenario to be executed
  26 + SIMULATOR_COMMANDS = [
  27 + "go_active",
  28 + "go_idle",
  29 + "go_active",
  30 + "go_idle",
  31 + "go_active",
  32 + "go_idle",
  33 + "exit",
  34 + ]
  35 +
17 36 """
18 37 How to run this agent thread_exec_specific_cmd() method ?
19 38 - True = inside a Thread (cannot be killed, must be asked to stop, and inadequate for computation)
... ...
src/agent/AgentX.py
... ... @@ -19,6 +19,26 @@ from Agent import Agent
19 19  
20 20 class AgentX(Agent):
21 21  
  22 +
  23 + # FOR TEST ONLY
  24 + # Run this agent in simulator mode
  25 + SIMULATOR_MODE = True
  26 + # Run the assertion tests at the end
  27 + SIMULATOR_WITH_TEST = False
  28 + # Who should I send commands to ?
  29 + #SIMULATOR_COMMANDS_DEST = "myself"
  30 + SIMULATOR_COMMANDS_DEST = "AgentA"
  31 + # Scenario to be executed
  32 + SIMULATOR_COMMANDS = [
  33 + "go_active",
  34 + "go_idle",
  35 + "go_active",
  36 + "go_idle",
  37 + "go_active",
  38 + "go_idle",
  39 + "exit",
  40 + ]
  41 +
22 42 """
23 43 =================================================================
24 44 FUNCTIONS RUN INSIDE MAIN THREAD
... ...
src/common/models.py
... ... @@ -358,6 +358,7 @@ class Command(models.Model):
358 358  
359 359 @classmethod
360 360 def show_commands(cls, commands:models.query):
  361 + if not commands.exists(): print("<No command>")
361 362 for cmd in commands: print("-", cmd)
362 363  
363 364  
... ...