1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package nl.tudelft.goal.unreal.environment;
21
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import nl.tudelft.goal.unreal.messages.BotParameters;
26 import nl.tudelft.goal.unreal.messages.Configuration;
27 import nl.tudelft.goal.unreal.messages.MapOfParameters;
28 import nl.tudelft.goal.unreal.translators.AgentIdTranslator;
29 import nl.tudelft.goal.unreal.translators.BotParametersKeyTranslator;
30 import nl.tudelft.goal.unreal.translators.BotParametersListTranslator;
31 import nl.tudelft.goal.unreal.translators.BotParametersTranslator;
32 import nl.tudelft.goal.unreal.translators.ConfigurationKeyTranslator;
33 import nl.tudelft.goal.unreal.translators.ConfigurationTranslator;
34 import nl.tudelft.goal.unreal.translators.LevelTranslator;
35 import nl.tudelft.goal.unreal.translators.LocationTranslator;
36 import nl.tudelft.goal.unreal.translators.ParameterMapTranslator;
37 import nl.tudelft.goal.unreal.translators.RotationTranslator;
38 import nl.tudelft.goal.unreal.translators.SkinTranslator;
39 import nl.tudelft.goal.unreal.translators.TeamTranslator;
40 import nl.tudelft.goal.unreal.translators.URITranslator;
41 import nl.tudelft.goal.unreal.translators.VelocityTranslator;
42 import nl.tudelft.goal.unreal.util.EnvironmentUtil;
43 import nl.tudelft.goal.unreal.util.vecmathcheck.VecmathCheck;
44 import cz.cuni.amis.pogamut.base.agent.IAgent;
45 import cz.cuni.amis.pogamut.base.agent.IAgentId;
46 import cz.cuni.amis.pogamut.base.agent.exceptions.AgentException;
47 import cz.cuni.amis.pogamut.base.agent.impl.AgentId;
48 import cz.cuni.amis.pogamut.base.agent.state.level0.IAgentState;
49 import cz.cuni.amis.pogamut.base.agent.state.level1.IAgentStateDown;
50 import cz.cuni.amis.pogamut.base.communication.command.IAct;
51 import cz.cuni.amis.pogamut.base.component.IComponent;
52 import cz.cuni.amis.pogamut.base.utils.Pogamut;
53 import cz.cuni.amis.pogamut.base.utils.logging.AgentLogger;
54 import cz.cuni.amis.pogamut.base.utils.logging.IAgentLogger;
55 import cz.cuni.amis.pogamut.base.utils.logging.LogCategory;
56 import cz.cuni.amis.pogamut.base3d.worldview.IVisionWorldView;
57 import cz.cuni.amis.pogamut.ut2004.agent.params.UT2004AgentParameters;
58 import cz.cuni.amis.pogamut.ut2004.bot.IUT2004Bot;
59 import cz.cuni.amis.pogamut.ut2004.bot.IUT2004BotController;
60 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004Bot;
61 import cz.cuni.amis.pogamut.ut2004.bot.impl.UT2004BotController;
62 import cz.cuni.amis.pogamut.ut2004.bot.params.UT2004BotParameters;
63 import cz.cuni.amis.pogamut.ut2004.communication.messages.gbcommands.Pause;
64 import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ServerFactory;
65 import cz.cuni.amis.pogamut.ut2004.factory.guice.remoteagent.UT2004ServerModule;
66 import cz.cuni.amis.pogamut.ut2004.server.IUT2004Server;
67 import cz.cuni.amis.pogamut.ut2004.utils.UT2004BotRunner;
68 import cz.cuni.amis.pogamut.ut2004.utils.UT2004ServerRunner;
69 import cz.cuni.amis.pogamut.ut2004.utils.UTBotRunner;
70 import cz.cuni.amis.utils.exception.PogamutException;
71 import cz.cuni.amis.utils.flag.FlagListener;
72 import eis.eis2java.environment.AbstractEnvironment;
73 import eis.eis2java.exception.TranslationException;
74 import eis.eis2java.handlers.ActionHandler;
75 import eis.eis2java.handlers.DefaultActionHandler;
76 import eis.eis2java.handlers.DefaultPerceptHandler;
77 import eis.eis2java.handlers.PerceptHandler;
78 import eis.eis2java.translation.Translator;
79 import eis.exceptions.EntityException;
80 import eis.exceptions.ManagementException;
81 import eis.exceptions.RelationException;
82 import eis.iilang.Action;
83 import eis.iilang.EnvironmentState;
84 import eis.iilang.Parameter;
85
86 @SuppressWarnings("rawtypes")
87 public abstract class AbstractUnrealEnvironment extends
88 SimpleTransitioningEnvironment implements IComponent {
89
90
91
92
93 private static final long serialVersionUID = 6786623950045095814L;
94 protected final IAgentId id;
95
96
97 protected final IAgentLogger environmentLogger;
98
99 protected final LogCategory log;
100
101
102 private final Map<String, AgentDownListener> agentDownListeners;
103
104
105 protected Configuration configuration;
106
107
108 private IUT2004Server utServer;
109
110
111
112
113
114
115 public AbstractUnrealEnvironment() {
116 id = new AgentId(getName());
117 agentDownListeners = new HashMap<String, AgentDownListener>();
118 environmentLogger = new AgentLogger(id);
119 environmentLogger.addDefaultConsoleHandler();
120 log = environmentLogger.getCategory(this);
121 log.info("Environment has been created.");
122 log.addConsoleHandler();
123
124
125 Translator translator = Translator.getInstance();
126 translator.registerParameter2JavaTranslator(new AgentIdTranslator());
127
128 translator
129 .registerParameter2JavaTranslator(new BotParametersKeyTranslator());
130 translator
131 .registerParameter2JavaTranslator(new BotParametersListTranslator());
132 translator
133 .registerParameter2JavaTranslator(new BotParametersTranslator());
134
135 translator
136 .registerParameter2JavaTranslator(new ConfigurationKeyTranslator());
137 translator
138 .registerParameter2JavaTranslator(new ConfigurationTranslator());
139
140 translator.registerParameter2JavaTranslator(new LevelTranslator());
141 translator.registerParameter2JavaTranslator(new LocationTranslator());
142
143 translator
144 .registerParameter2JavaTranslator(new ParameterMapTranslator());
145
146 translator.registerParameter2JavaTranslator(new RotationTranslator());
147
148 translator.registerParameter2JavaTranslator(new SkinTranslator());
149 translator.registerParameter2JavaTranslator(new TeamTranslator());
150
151 translator.registerParameter2JavaTranslator(new URITranslator());
152
153 translator.registerParameter2JavaTranslator(new VelocityTranslator());
154
155
156 registerTranslators();
157 }
158
159 protected abstract void registerTranslators();
160
161
162
163
164
165 @Override
166 public IAgentId getComponentId() {
167 return id;
168 }
169
170
171
172
173
174
175
176 @Override
177 public String toString() {
178 return EnvironmentUtil.simplefyID(getComponentId());
179 }
180
181 public String getName() {
182 return "Unreal Environment for EIS" + requiredVersion();
183 }
184
185 protected synchronized void initializeEnvironment(
186 Map<String, Parameter> parameters) throws ManagementException {
187
188
189 if (!VecmathCheck.check()) {
190 throw new ManagementException(VecmathCheck.getErrorMessage());
191 }
192
193
194 try {
195
196 Parameter parameterMap = new MapOfParameters(parameters);
197 configuration = Translator.getInstance().translate2Java(
198 parameterMap, Configuration.class);
199 configuration.assignDefaults(Configuration.getDefaults());
200 } catch (TranslationException e) {
201 throw new ManagementException("Invalid parameters", e);
202 }
203
204
205 log.setLevel(configuration.getLogLevel());
206 }
207
208 protected synchronized void connectEnvironment() throws ManagementException {
209 assert configuration != null;
210
211
212 if (configuration.getControlServer() != null)
213 startServer();
214
215 }
216
217 @Override
218 protected void connectAgents() throws ManagementException {
219
220 for (BotParameters bot : configuration.getBots()) {
221 startAgent(bot);
222 }
223
224 }
225
226 protected void startServer() throws ManagementException {
227
228 try {
229
230 UT2004ServerRunner<? extends IUT2004Server, ? extends UT2004AgentParameters> serverRunner = createServerRunner();
231 utServer = serverRunner.startAgent();
232 } catch (PogamutException e) {
233 throw new ManagementException(
234
235
236 "Pogmut was unable to start the server. Cause: "
237 + e.toString());
238 }
239 String simpleID = EnvironmentUtil.simplefyID(utServer.getComponentId());
240
241 try {
242 registerEntity(simpleID, "server", utServer,
243 createServerActionHandler(utServer),
244 createServerPerceptHandler(utServer));
245 } catch (EntityException e) {
246 utServer.stop();
247 throw new ManagementException("Unable to register entity", e);
248 }
249
250
251 agentDownListeners.put(simpleID, new AgentDownListener(simpleID,
252 utServer));
253
254
255
256 }
257
258 protected ActionHandler createServerActionHandler(IUT2004Server entity)
259 throws EntityException {
260 return new DefaultActionHandler(entity);
261 }
262
263 protected PerceptHandler createServerPerceptHandler(IUT2004Server entity)
264 throws EntityException {
265 return new DefaultPerceptHandler(entity);
266 }
267
268 protected UT2004ServerRunner<? extends IUT2004Server, ? extends UT2004AgentParameters> createServerRunner() {
269 UT2004ServerModule<UT2004AgentParameters> serverModule = new UT2004ServerModule<UT2004AgentParameters>();
270 UT2004ServerFactory<IUT2004Server, UT2004AgentParameters> serverFactory = new UT2004ServerFactory<IUT2004Server, UT2004AgentParameters>(
271 serverModule);
272 UT2004ServerRunner<IUT2004Server, UT2004AgentParameters> serverRunner = new UT2004ServerRunner<IUT2004Server, UT2004AgentParameters>(
273 serverFactory, "UTServer",
274 configuration.getControlServerHost(),
275 configuration.getControlServerPort());
276 return serverRunner;
277 }
278
279 protected synchronized void startAgent(BotParameters parameters)
280 throws ManagementException {
281
282
283 if (getState() == EnvironmentState.KILLED) {
284 return;
285 }
286
287
288 utServer.getAct().act(new Pause(false, false));
289
290
291 parameters.assignDefaults(BotParameters.getDefaults());
292
293 UTBotRunner<UT2004Bot<IVisionWorldView, IAct, UT2004BotController>, UT2004BotParameters> runner = getBotRunner(configuration);
294
295 runner.setLogLevel(parameters.getLogLevel());
296
297
298
299 UT2004Bot<IVisionWorldView, IAct, UT2004BotController> agent;
300 try {
301 agent = runner.startAgents(parameters).get(0);
302 } catch (PogamutException e) {
303 throw new ManagementException(
304
305
306 "Pogmut was unable to start an agents. Cause: "
307 + e.toString());
308 }
309
310
311 String simpleID = EnvironmentUtil.simplefyID(agent.getComponentId());
312 UT2004BotController controller = agent.getController();
313 try {
314 registerEntity(simpleID, "bot", controller,
315 createActionHandler(controller),
316 createPerceptHandler(controller));
317 } catch (EntityException e) {
318 agent.stop();
319
320 throw new ManagementException("Unable to register entity", e);
321 }
322
323
324 agentDownListeners
325 .put(simpleID, new AgentDownListener(simpleID, agent));
326
327
328 if (agent.inState(IAgentStateDown.class)) {
329 agentDownListeners.get(simpleID).removeListener();
330 synchronizedDeleteEntity(simpleID);
331
332 }
333
334
335 }
336
337 protected abstract UTBotRunner<UT2004Bot<IVisionWorldView, IAct, UT2004BotController>, UT2004BotParameters> getBotRunner(
338 Configuration configuration);
339
340 protected abstract Class<? extends IUT2004BotController> getControlerClass();
341
342 protected abstract PerceptHandler createPerceptHandler(
343 UT2004BotController controller) throws EntityException;
344
345 protected abstract ActionHandler createActionHandler(
346 UT2004BotController controller) throws EntityException;
347
348 protected void startEnvironment() throws ManagementException {
349 utServer.getAct().act(new Pause(false, false));
350 }
351
352 protected void pauseEvironment() {
353 utServer.getAct().act(new Pause(true, false));
354 }
355
356 protected synchronized void killEnvironment() {
357
358 if (utServer != null)
359 utServer.getAct().act(new Pause(false, false));
360
361
362 try {
363 Thread.sleep(1000);
364 } catch (InterruptedException e1) {
365
366 }
367
368
369 for (String id : getEntities()) {
370
371
372
373 Object entity = getEntity(id);
374 IAgent bot;
375 if (entity instanceof UT2004BotController<?>) {
376 @SuppressWarnings("unchecked")
377 UT2004BotController<UT2004Bot> controller = ((UT2004BotController<UT2004Bot>) getEntity(id));
378 bot = controller.getBot();
379 } else {
380 bot = (IAgent) entity;
381 }
382
383 try {
384 agentDownListeners.get(id).removeListener();
385 bot.stop();
386 log.info(bot.getName() + " has been stopped");
387 } catch (AgentException e) {
388
389 log.info(bot.getName() + " has been killed", e);
390 }
391 }
392
393
394 if (utServer != null)
395 utServer.stop();
396 utServer = null;
397
398
399 configuration = null;
400
401
402 Pogamut.getPlatform().close();
403 }
404
405
406
407
408
409
410
411
412 protected synchronized void synchronizedDeleteEntity(String name) {
413 try {
414 deleteEntity(name);
415 } catch (RelationException e) {
416
417 log.severe("Could not delete entity " + name);
418 } catch (EntityException e) {
419
420
421 log.severe("Could not delete entity " + name
422 + ", it was already deleted.");
423 }
424 }
425
426
427
428
429
430
431
432
433 private class AgentDownListener implements FlagListener<IAgentState> {
434
435 private final String key;
436 private final IAgent agent;
437
438 public AgentDownListener(String key, IAgent agent) {
439 this.key = key;
440 this.agent = agent;
441 this.agent.getState().addStrongListener(this);
442 }
443
444 @Override
445 public void flagChanged(IAgentState state) {
446 if (state instanceof IAgentStateDown) {
447 removeListener();
448 synchronizedDeleteEntity(key);
449 }
450 }
451
452 public void removeListener() {
453 agent.getState().removeListener(this);
454 agentDownListeners.remove(key);
455 }
456 }
457
458 @Override
459 protected boolean isSupportedByEnvironment(Action arg0) {
460 return true;
461 }
462
463 @Override
464 protected boolean isSupportedByType(Action arg0, String arg1) {
465 return true;
466 }
467
468 }