00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "spadesserver.h"
00023
00024 using namespace boost;
00025 using namespace zeitgeist;
00026 using namespace oxygen;
00027 using namespace spades;
00028 using namespace std;
00029
00030 #include <zeitgeist/corecontext.h>
00031 #include <zeitgeist/logserver/logserver.h>
00032 #include <zeitgeist/scriptserver/scriptserver.h>
00033 #include <oxygen/sceneserver/sceneserver.h>
00034 #include <oxygen/gamecontrolserver/gamecontrolserver.h>
00035 #include <oxygen/monitorserver/monitorserver.h>
00036 #include <oxygen/gamecontrolserver/actionobject.h>
00037 #include <spades/SimEngine.hpp>
00038 #include <spades/EndSimulationEvent.hpp>
00039 #include "spadescreatesenseevent.h"
00040 #include "spadesactevent.h"
00041
00042 SpadesServer::SpadesServer() :
00043 zeitgeist::Node(), spades::WorldModel(),
00044 mSimEngine(0), mSimulationModeChanged(false),
00045 mOffsetCreateSense(0),mNextInitialCreateSense(0)
00046 {
00047 }
00048
00049 SpadesServer::~SpadesServer()
00050 {
00051 }
00052
00053 bool
00054 SpadesServer::ConstructInternal()
00055 {
00056
00057 GetScript()->CreateVariable("Spades.TimePerStep", 0.01f);
00058 GetScript()->CreateVariable("Spades.MonitorInterval", 4);
00059 GetScript()->CreateVariable("Spades.RunIntegratedCommserver", false);
00060 GetScript()->CreateVariable("Spades.CommServersWanted", 1);
00061 GetScript()->CreateVariable("Spades.SendAgentThinkTimes", false);
00062
00063 return true;
00064 }
00065
00066 void
00067 SpadesServer::OnLink()
00068 {
00069 mMonitorServer = shared_dynamic_cast<MonitorServer>
00070 (GetCore()->Get("/sys/server/monitor"));
00071
00072 if (mMonitorServer.get() == 0)
00073 {
00074 GetLog()->Error() << "ERROR: (SpadesServer) MonitorServer not found.\n";
00075 }
00076
00077 mGameControlServer = shared_dynamic_cast<GameControlServer>
00078 (GetCore()->Get("/sys/server/gamecontrol"));
00079
00080 if (mGameControlServer.get() == 0)
00081 {
00082 GetLog()->Error() << "ERROR: (SpadesServer) GameControlServer not found.\n";
00083 }
00084
00085 mSceneServer = shared_dynamic_cast<SceneServer>
00086 (GetCore()->Get("/sys/server/scene"));
00087
00088 if (mSceneServer.get() == 0)
00089 {
00090 GetLog()->Error() << "ERROR: (SpadesServer) SceneServer not found.\n";
00091 }
00092
00093
00094 mTimePerStep = 0.01f;
00095 }
00096
00097 void
00098 SpadesServer::OnUnlink()
00099 {
00100 mMonitorServer.reset();
00101 mGameControlServer.reset();
00102 mSceneServer.reset();
00103 }
00104
00105 spades::SimEngine*
00106 SpadesServer::GetSimEngine()
00107 {
00108 return mSimEngine;
00109 }
00110
00111 float
00112 SpadesServer::GetTimePerStep() const
00113 {
00114 return mTimePerStep;
00115 }
00116
00117 int
00118 SpadesServer::GetCommServersWanted() const
00119 {
00120 int commServersWanted = 1;
00121 GetScript()->GetVariable("Spades.CommServersWanted",commServersWanted);
00122
00123 return std::max<int>(1,commServersWanted);
00124 }
00125
00126 bool
00127 SpadesServer::GetRunIntegratedCommserver() const
00128 {
00129 bool run_integrated_commserver = false;
00130 GetScript()->GetVariable("Spades.RunIntegratedCommserver",
00131 run_integrated_commserver);
00132
00133 return run_integrated_commserver;
00134 }
00135
00136 int
00137 SpadesServer::GetMonitorInterval() const
00138 {
00139 int monitor_interval = 10;
00140 GetScript()->GetVariable("Spades.MonitorInterval", monitor_interval);
00141
00142 return monitor_interval;
00143 }
00144
00145 bool
00146 SpadesServer::GetSendAgentThinkTimes() const
00147 {
00148 bool send_agent_think_times = false;
00149 GetScript()->GetVariable("Spades.SendAgentThinkTimes",
00150 send_agent_think_times);
00151
00152 return send_agent_think_times;
00153 }
00154
00155 boost::shared_ptr<GameControlServer>
00156 SpadesServer::GetGameControlServer() const
00157 {
00158 return mGameControlServer;
00159 }
00160
00161 void
00162 SpadesServer::StartAgents(const AgentItem& ai)
00163 {
00164 GetLog()->Debug() << "SpadesServer::StartAgents("
00165 << ai.mAgentType << ", " << ai.mNumber << ")\n";
00166
00167 if (!mSimEngine || mSimEngine->getNumCommServers () < 1)
00168 {
00169 GetLog()->Error() << "(SpadesServer) No simulation engine or comm server, "
00170 << "cannot start agents\n" << endl;
00171 return;
00172 }
00173
00174 AgentTypeDB::AgentTypeConstIterator
00175 at = mSimEngine->getAgentTypeDB()->getAgentType(ai.mAgentType);
00176
00177 if (at == mSimEngine->getAgentTypeDB()->nullIterator())
00178 {
00179 GetLog()->Error()
00180 << "ERROR: (SpadesServer) could not find agent type "
00181 << ai.mAgentType << endl;
00182 return;
00183 }
00184
00185 int num = std::max(ai.mNumber, 0);
00186
00187 while (num > 0)
00188 {
00189 if (mSimEngine->startNewAgent(at) == AGENTID_INVALID)
00190 {
00191 num = 0;
00192 GetLog()->Error()
00193 << "ERROR: (SpadesServer) starting agent of type " << ai.mAgentType
00194 << " failed" << endl;
00195 }
00196 --num;
00197 }
00198 }
00199
00200 void
00201 SpadesServer::Unpause()
00202 {
00203 mNewSimulationMode = SM_RunNormal;
00204 mSimulationModeChanged = true;
00205 }
00206
00207 void
00208 SpadesServer::QueueAgents(const std::string& agentType, int num)
00209 {
00210 mAgentQueue.push_back(AgentItem(agentType, num));
00211 }
00212
00213
00214
00215 EngineParam*
00216 SpadesServer::parseParameters(int argc, const char *const *argv)
00217 {
00218 mParamReader =
00219 shared_static_cast<ParamReader>(GetCore()->New("oxygen/ParamReader"));
00220
00221
00222
00223
00224 mParamReader->getOptions(argc, argv);
00225
00226
00227 mParamReader->setParam("run_integrated_commserver",
00228 GetRunIntegratedCommserver());
00229
00230
00231 mParamReader->setParam("monitor_interval", GetMonitorInterval());
00232
00233
00234 mParamReader->setParam("send_agent_think_times", GetSendAgentThinkTimes());
00235
00236 return mParamReader.get();
00237 }
00238
00239 bool
00240 SpadesServer::initialize(SimEngine* pSE)
00241 {
00242 mSimEngine = pSE;
00243 return true;
00244 }
00245
00246 bool
00247 SpadesServer::finalize()
00248 {
00249 return true;
00250 }
00251
00252 SimTime
00253 SpadesServer::simToTime(SimTime time_curr, SimTime time_desired)
00254 {
00255 int steps = time_desired - time_curr;
00256 if (steps <= 0)
00257 {
00258 GetLog()->Warning()
00259 << "WARNING: (SpadesServer) will not simulate <= 0 steps\n";
00260 return time_curr;
00261 }
00262
00263 if (
00264 (mSceneServer.get() == 0) ||
00265 (mGameControlServer.get() == 0)
00266 )
00267 {
00268 GetLog()->Warning()
00269 << "WARNING: (SpadesServer) SceneServer "
00270 << "and/or GameControlServer missing.\n";
00271 return time_curr;
00272 }
00273
00274 int i = steps;
00275
00276 while (i > 0)
00277 {
00278 mSceneServer->Update(mTimePerStep);
00279 mGameControlServer->Update(mTimePerStep);
00280 --i;
00281 }
00282
00283 static bool once = true;
00284 if (mGameControlServer->IsFinished() && once)
00285 {
00286 once = false;
00287
00288 mSimEngine->enqueueEvent(new EndSimulationEvent(time_desired+1));
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298 return time_desired - i;
00299 }
00300
00301 DataArray
00302 SpadesServer::getMonitorHeaderInfo()
00303 {
00304 if (mMonitorServer.get() == 0)
00305 {
00306 return DataArray();
00307 }
00308
00309 return DataArray(mMonitorServer->GetMonitorHeaderInfo());
00310 }
00311
00312 DataArray
00313 SpadesServer::getMonitorInfo(SimTime )
00314 {
00315 if (mMonitorServer.get() == 0)
00316 {
00317 return DataArray();
00318 }
00319
00320 return DataArray(mMonitorServer->GetMonitorInfo());
00321 }
00322
00323 void
00324 SpadesServer::parseMonitorMessage(const char* data, unsigned datalen)
00325 {
00326 if (mMonitorServer.get() == 0)
00327 {
00328 return;
00329 }
00330
00331 return mMonitorServer->ParseMonitorMessage(string(data,datalen));
00332 }
00333
00334 SimTime
00335 SpadesServer::getMinActionLatency() const
00336 {
00337 return 1;
00338 }
00339
00340 SimTime
00341 SpadesServer::getMinSenseLatency() const
00342 {
00343 return 1;
00344 }
00345
00346 ActEvent*
00347 SpadesServer::parseAct(SimTime act_received_time, AgentID a, const char* data, unsigned datalen) const
00348 {
00349 if (mGameControlServer.get() == 0)
00350 {
00351 return 0;
00352 }
00353
00354 shared_ptr<ActionObject::TList> actionList
00355 = mGameControlServer->Parse(a,std::string(data,datalen));
00356
00357 if (actionList.get() == 0)
00358 {
00359 return 0;
00360 }
00361
00362 float latency = mGameControlServer->GetActionLatency(a);
00363
00364
00365
00366
00367
00368 SimTime arrival = act_received_time + static_cast<int>(latency / GetTimePerStep());
00369
00370 return new SpadesActEvent(arrival, a, actionList);
00371 }
00372
00373 void
00374 SpadesServer::pauseModeCallback()
00375 {
00376
00377
00378
00379 if (mSimEngine->getSimulationMode() == SM_PausedInitial)
00380 {
00381 int numConnected = mSimEngine->getNumCommServers();
00382 GetLog()->Normal() << "(SpadesServer) waiting for a total of "
00383 << GetCommServersWanted()
00384 << " CommServers, " << numConnected
00385 << " already connected\n";
00386
00387 if (numConnected >= GetCommServersWanted())
00388 {
00389 Unpause();
00390 } else
00391 {
00392 return;
00393 }
00394 }
00395
00396 if (
00397 (mGameControlServer.get() != 0) &&
00398 (! mAgentQueue.empty())
00399 )
00400 {
00401 int agentCount = 0;
00402 for (
00403 TAgentQueue::iterator iter = mAgentQueue.begin();
00404 iter != mAgentQueue.end();
00405 ++iter
00406 )
00407 {
00408 agentCount += (*iter).mNumber;
00409 }
00410
00411
00412
00413 float deltaSense = 0.20;
00414 float offsetSec = deltaSense / agentCount;
00415
00416 mOffsetCreateSense = (offsetSec / GetTimePerStep());
00417 mNextInitialCreateSense = mSimEngine->getSimulationTime() + 1;
00418
00419 GetLog()->Debug() << "(SpadesServer) Starting "
00420 << agentCount << " agents (delta sense: " << deltaSense<< ")\n"
00421 << "with an CreateSenseEvent offset of "
00422 << mOffsetCreateSense << " (" << offsetSec << " seconds)\n"
00423 << "starting at simTime " << mNextInitialCreateSense << "\n";
00424
00425 while (! mAgentQueue.empty())
00426 {
00427 StartAgents(mAgentQueue.front());
00428 mAgentQueue.pop_front();
00429 }
00430 }
00431
00432 if (mSimulationModeChanged)
00433 {
00434 mSimEngine->changeSimulationMode(mNewSimulationMode);
00435 mSimulationModeChanged = false;
00436 }
00437 }
00438
00439 bool
00440 SpadesServer::agentConnect(AgentID agent, AgentTypeDB::AgentTypeConstIterator )
00441 {
00442
00443 shared_ptr<GameControlServer> gcs = GetGameControlServer();
00444
00445 if (
00446 (mGameControlServer.get() == 0) ||
00447 (! mGameControlServer->AgentConnect(static_cast<int>(agent)))
00448 )
00449 {
00450 GetLog()->Normal()
00451 << "(SpadesServer) ERROR: cannot register agent "
00452 << "to the GameControlServer\n";
00453 return false;
00454 }
00455
00456
00457 SimTime time = static_cast<SimTime>(mNextInitialCreateSense);
00458 SpadesCreateSenseEvent* event = new SpadesCreateSenseEvent
00459 (time,agent);
00460
00461 SimTime now = mSimEngine->getSimulationTime();
00462 GetLog()->Normal()
00463 << "(SpadesServer) agentConnect (id " << agent
00464 << ") at simlation time " << now << ".\n"
00465 << "Initial CreateSenseEvent scheduled at "
00466 << time << "\n";
00467
00468 mNextInitialCreateSense += mOffsetCreateSense;
00469 mSimEngine->enqueueEvent(event);
00470
00471 return true;
00472 }
00473
00474 bool
00475 SpadesServer::agentDisappear(AgentID agent, AgentLostReason )
00476 {
00477 if (mGameControlServer.get() == 0)
00478 {
00479 return false;
00480 }
00481
00482 return mGameControlServer->AgentDisappear(static_cast<int>(agent));
00483 }
00484
00485 void
00486 SpadesServer::notifyCommserverConnect(ServerID )
00487 {
00488 }
00489
00490 void
00491 SpadesServer::notifyCommserverDisconnect(ServerID )
00492 {
00493 }
00494
00495 void
00496 SpadesServer::UpdateCached()
00497 {
00498 GetScript()->GetVariable("Spades.TimePerStep", mTimePerStep);
00499 }