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