EventManager.cpp 10.9 KB
Newer Older
1
#include "EventManager.h"
2 3 4

using namespace std;

5 6 7 8
/*******************
 Konstruktoren
 ******************/

Ulrich Kemloh's avatar
Ulrich Kemloh committed
9 10 11
#define UPDATE_FREQUENCY 1 // in seconds


12
EventManager::EventManager(Building *_b){
13
    _event_times=vector<double>();
14 15 16
    _event_types=vector<string>();
    _event_states=vector<string>();
    _event_ids=vector<int>();
17
    _projectFilename = "";
18
    _building = _b;
19 20
    _eventCounter=0;
    _dynamic=false;
21
    _file = fopen("../events/events.txt","r");
Ulrich Kemloh's avatar
Ulrich Kemloh committed
22
    _lastUpdateTime=0;
23
    _deltaT=0;
24
    if(!_file){
25
        Log->Write("INFO:\tDatei events.txt nicht gefunden. Dynamisches Eventhandling nicht moeglich.");
26 27
    }
    else{
28
        Log->Write("INFO:\tDatei events.txt gefunden. Dynamisches Eventhandling moeglich.");
29 30
        _dynamic=true;
    }
31
}
32

33 34 35 36 37 38
/*******************
 Dateien einlesen
 ******************/
void EventManager::SetProjectFilename(const std::string &filename){
    _projectFilename=filename;
}
39

40 41 42 43 44
void EventManager::SetProjectRootDir(const std::string &filename){
    _projectRootDir= filename;
}

void EventManager::readEventsXml(){
Ulrich Kemloh's avatar
Ulrich Kemloh committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
     Log->Write("INFO: \tLooking for events");
     //get the geometry filename from the project file
     TiXmlDocument doc(_projectFilename);
     if (!doc.LoadFile()){
          Log->Write("ERROR: \t%s", doc.ErrorDesc());
          Log->Write("ERROR: \t could not parse the project file.");
          exit(EXIT_FAILURE);
     }

     TiXmlElement* xMainNode = doc.RootElement();
     string eventfile="";
     if(xMainNode->FirstChild("events")){
          eventfile=_projectRootDir+xMainNode->FirstChild("events")->FirstChild()->Value();
          Log->Write("INFO: \tevents <"+eventfile+">");
     }
     else
     {
          Log->Write("INFO: \tNo events found");
          return;
     }

     Log->Write("INFO: \tParsing the event file");
     TiXmlDocument docEvent(eventfile);
     if(!docEvent.LoadFile()){
          Log->Write("ERROR: \t%s",docEvent.ErrorDesc());
          Log->Write("ERROR: \t could not parse the event file.");
          return;
     }

     TiXmlElement* xRootNode = docEvent.RootElement();
     if(!xRootNode){
          Log->Write("ERROR:\tRoot element does not exist.");
          exit(EXIT_FAILURE);
     }

     if( xRootNode->ValueStr () != "JPScore" ) {
          Log->Write("ERROR:\tRoot element value is not 'JPScore'.");
          exit(EXIT_FAILURE);
     }

     TiXmlNode* xEvents = xRootNode->FirstChild("events");
     if(!xEvents){
          Log->Write("ERROR:\tNo events found.");
          exit(EXIT_FAILURE);
     }

     for(TiXmlElement* e = xEvents->FirstChildElement("event"); e; e= e->NextSiblingElement("event")){
          _event_times.push_back(atoi(e->Attribute("time")));
          _event_types.push_back(e->Attribute("type"));
          _event_states.push_back(e->Attribute("state"));
          _event_ids.push_back(atoi(e->Attribute("id")));
     }
     Log->Write("INFO: \tEvents were read\n");
98 99 100
}

void EventManager::listEvents(){
101
    if(_event_times.size()==0){
102
        Log->Write("INFO: \tNo events in the events.xml");
103 104
    }
    else{
105
        char buf[10],buf2[10];
106
        for(unsigned int i=0;i<_event_times.size();i++){
107 108 109
            sprintf(buf,"%f",_event_times[i]);
            sprintf(buf2,"%d",_event_ids[i]);
            Log->Write("INFO: \tAfter "+string(buf)+" sec: "+_event_types[i]+" "+string(buf2)+" "+_event_states[i]);
110 111 112 113 114
        }
    }

}

115
void EventManager::readEventsTxt(double time){
116
    rewind(_file);
117 118
    char cstring[256];
    int lines=0;
119
    do{
120 121 122 123 124
        if(fgets(cstring,30,_file)==NULL)
        {
            Log->Write("WARNING: \tCould not read the event file");
            return;
        }
125 126 127 128 129 130 131
        if(cstring[0]!='#'){// keine Kommentarzeile
            lines++;
            if(lines>_eventCounter){
                Log->Write("INFO:\tEvent: after %f sec: ",time);
                getTheEvent(cstring);
                _eventCounter++;
            }
132
        }
133
     }while (feof(_file)==0);
134 135
}

136 137 138 139
/***********
 Update
 **********/

140
void EventManager::Update_Events(double time, double d){
Ulrich Kemloh's avatar
Ulrich Kemloh committed
141 142 143 144 145 146 147
     //1. pruefen ob in _event_times der zeitstempel time zu finden ist. Wenn ja zu 2. sonst zu 3.
     //2. Event aus _event_times und _event_values verarbeiten (Tuere schliessen/oeffnen, neues Routing)
     //   Dann pruefen, ob eine neue Zeile in der .txt Datei steht
     //3. .txt Datei auf neue Zeilen pruefen. Wenn es neue gibt diese Events verarbeiten ( Tuere schliessen/oeffnen,
     //   neues Routing) ansonsten fertig

     _deltaT=d;
Ulrich Kemloh's avatar
Ulrich Kemloh committed
148
     const vector<Pedestrian*>& _allPeds=_building->GetAllPedestrians();
Ulrich Kemloh's avatar
Ulrich Kemloh committed
149 150 151

     //zuerst muss geprueft werden, ob die Peds, die die neuen Infos schon haben sie an andere Peds weiter-
     //leiten muessen (wenn diese sich in der naechsten Umgebung befinden)
152
     int currentTime = _allPeds[0]->GetGlobalTime();
Ulrich Kemloh's avatar
Ulrich Kemloh committed
153 154
     if(currentTime!=_lastUpdateTime)
          if((currentTime%UPDATE_FREQUENCY)==0) {
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

               for(unsigned int p1=0;p1<_allPeds.size();p1++)
               {
                    Pedestrian* ped1 = _allPeds[p1];
                    if(ped1->GetNewEventFlag()){
                         int rID = ped1->GetRoomID();
                         int srID = ped1->GetSubRoomID();

                         for(unsigned int p2=0;p2<_allPeds.size();p2++)
                         {
                              Pedestrian* ped2 = _allPeds[p2];
                              //same room and subroom
                              if(rID==ped2->GetRoomID() && srID==ped2->GetSubRoomID())
                              {
                                   if(!ped2->GetNewEventFlag()&&ped2->GetReroutingTime()>2.0){
                                        //wenn der Pedestrian die neuen Infos noch nicht hat und eine Reroutingtime von > 2 Sekunden hat, pruefen ob er nah genug ist
                                        Point pos1 = ped1->GetPos();
                                        Point pos2 = ped2->GetPos();
                                        double distX = pos1.GetX()-pos2.GetX();
                                        double distY = pos1.GetY()-pos2.GetY();
                                        double dist = sqrt(distX*distX+distY*distY);
                                        if(dist<=J_EPS_INFO_DIST){// wenn er nah genug (weniger als 2m) ist, Info weitergeben (Reroutetime auf 2 Sek)
                                             //ped->RerouteIn(2.0);
                                             ped2->RerouteIn(0.0);
                                        }
Ulrich Kemloh's avatar
Ulrich Kemloh committed
180 181 182
                                   }
                              }
                         }
183
                    }
Ulrich Kemloh's avatar
Ulrich Kemloh committed
184 185 186 187 188 189
               }
               _lastUpdateTime=currentTime;
               //cout<<"updating..."<<currentTime<<endl<<endl;
          }

     //dann muss die Reroutingzeit der Peds, die die neuen Infos noch nicht haben, aktualisiert werden:
190 191 192 193 194 195 196 197
     for(unsigned int p1=0;p1<_allPeds.size();p1++)
     {
          Pedestrian* ped1 = _allPeds[p1];
          ped1->UpdateReroutingTime();
          if(ped1->IsReadyForRerouting()){
               ped1->ClearMentalMap();
               ped1->ResetRerouting();
               ped1->SetNewEventFlag(true);
Ulrich Kemloh's avatar
Ulrich Kemloh committed
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
          }
     }

     //Events finden
     for(unsigned int i=0;i<_event_times.size();i++){
          if(fabs(_event_times[i]-time)<J_EPS_EVENT){
               //Event findet statt
               Log->Write("INFO:\tEvent: after %f sec: ",time);
               if(_event_states[i].compare("close")==0){
                    closeDoor(_event_ids[i]);
               }
               else{
                    openDoor(_event_ids[i]);
               }
          }
     }
     if(_dynamic)
          readEventsTxt(time);
216 217 218 219 220 221 222 223 224 225
}

/***************
 Eventhandling
 **************/
void EventManager::closeDoor(int id){
    //pruefen ob entsprechende Tuer schon zu ist, wenn nicht dann schliessen und neues Routing berechnen
    Transition *t=_building->GetTransition(id);
    if(t->IsOpen()){
        t->Close();
226
        Log->Write("\tDoor %d closed.",id);
227
        changeRouting(id,"close");
228
    }
229
    else{
230
        Log->Write("Door %d is already close yet.", id);
231
    }
232 233 234 235 236 237 238 239

}

void EventManager::openDoor(int id){
    //pruefen ob entsprechende Tuer schon offen ist, wenn nicht dann oeffnen und neues Routing berechnen
    Transition *t=_building->GetTransition(id);
    if(!t->IsOpen()){
        t->Open();
240
        Log->Write("\tDoor %d opened.",id);
241 242 243
        changeRouting(id,"open");
    }
    else{
244
        Log->Write("Door %d is already open yet.", id);
245 246 247
    }
}

248 249 250
void EventManager::changeRouting(int id, string state){
    RoutingEngine* routingEngine= _building->GetRoutingEngine();
    routingEngine->Init(_building);
251
    //_building->InitPhiAllPeds(_deltaT);
Ulrich Kemloh's avatar
Ulrich Kemloh committed
252
    const vector<Pedestrian*>& _allPedestrians=_building->GetAllPedestrians();
253
    unsigned int nSize = _allPedestrians.size();
254

255 256
    //Pedestrians sollen, damit es realitaetsnaeher wird, je nachdem wo sie stehen erst spaeter(abh. von der
    //Entfernung zur Tuer) merken, dass sich Tueren aendern. Oder sie bekommen die Info von anderen Pedestrians
257
    Transition *t = _building->GetTransition(id);
258
    //Abstand der aktuellen Position des Pedestrians zur entsprechenden Tuer: Tuer als Linie sehen und mit
259
    //DistTo(ped.GetPos()) den Abstand messen. Reroutezeit dann aus Entfernung und Geschwindigkeit berechnen.
260
    Line* l = new Line(t->GetPoint1(),t->GetPoint2());
261
    for (unsigned int p = 0; p < nSize; ++p) {
262
        //if(_allPedestrians[p]->GetExitIndex()==t->GetUniqueID()){
263
        _allPedestrians[p]->SetNewEventFlag(false);
264
        double dist = l->DistTo(_allPedestrians[p]->GetPos());
265 266
        Point v = _allPedestrians[p]->GetV();
        double norm =sqrt((v.GetX()*v.GetX())+(v.GetY()*v.GetY()));
267
        if(norm==0.0){
268
            norm=0.01;
269
        }
270 271 272 273
        double time = dist/norm;
        if(time<1.0){
            _allPedestrians[p]->ClearMentalMap();
            _allPedestrians[p]->ResetRerouting();
274
            _allPedestrians[p]->SetNewEventFlag(true);
275 276
        }
        else{
277
            _allPedestrians[p]->RerouteIn(time);
278
        }
279 280 281 282 283 284 285 286 287
        //if(dist>0.0&&dist<0.5){
          // _allPedestrians[p]->ClearMentalMap();
        //}
        //else if(dist>=0.5&&dist<3.0){
          // _allPedestrians[p]->RerouteIn(1.0);
        //}
        //else{
          // _allPedestrians[p]->RerouteIn(2.0);
        //}
288 289 290 291
        //}
        //else{
          //  _allPedestrians[p]->ClearMentalMap();
        //}
292 293 294 295 296 297 298 299 300
    }
}

void EventManager::getTheEvent(char* c){
    int split = 0;
    string type = "";
    string id = "";
    string state = "";
    for(int i=0;i<20;i++){
301
        if(!c[i]){
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
            break;
        }
        else if(c[i]==' '){
            split++;
        }
        else if(c[i]=='\n'){

        }
        else{
            if(split==0){
                type+=c[i];
            }
            else if(split==1){
                id+=c[i];
            }
            else if(split==2){
                state+=c[i];
            }
        }

    }
    if(state.compare("close")==0){
        closeDoor(atoi(id.c_str()));
    }
    else{
        openDoor(atoi(id.c_str()));
328
    }
329
}