MoBANCoordinator.cc

00001 /* -*- mode:c++ -*- ********************************************************
00002  * file:        MoBANCoordinator.cc
00003  *
00004  * author:      Majid Nabi <m.nabi@tue.nl>
00005  *
00006  *              http://www.es.ele.tue.nl/nes
00007  *
00008  * copyright:   (C) 2010 Electronic Systems group(ES),
00009  *              Eindhoven University of Technology (TU/e), the Netherlands.
00010  *
00011  *
00012  *              This program is free software; you can redistribute it
00013  *              and/or modify it under the terms of the GNU General Public
00014  *              License as published by the Free Software Foundation; either
00015  *              version 2 of the License, or (at your option) any later
00016  *              version.
00017  *              For further information see file COPYING
00018  *              in the top level directory
00019  ***************************************************************************
00020  * part of:    MoBAN (Mobility Model for wireless Body Area Networks)
00021  * description:     Implementation of the coordinator module of the MoBAN mobility model
00022  ***************************************************************************
00023  * Citation of the following publication is appreciated if you use MoBAN for
00024  * a publication of your own.
00025  *
00026  * M. Nabi, M. Geilen, T. Basten. MoBAN: A Configurable Mobility Model for Wireless Body Area Networks.
00027  * In Proc. of the 4th Int'l Conf. on Simulation Tools and Techniques, SIMUTools 2011, Barcelona, Spain, 2011.
00028  *
00029  * BibTeX:
00030  *    @inproceedings{MoBAN,
00031  *    author = "M. Nabi and M. Geilen and T. Basten.",
00032  *    title = "{MoBAN}: A Configurable Mobility Model for Wireless Body Area Networks.",
00033  *      booktitle = "Proceedings of the 4th Int'l Conf. on Simulation Tools and Techniques.",
00034  *      series = {SIMUTools '11},
00035  *      isbn = {978-963-9799-41-7},
00036  *      year = {2011},
00037  *      location = {Barcelona, Spain},
00038  *      publisher = {ICST} }
00039  *
00040  **************************************************************************/
00041 
00042 #include "MoBANCoordinator.h"
00043 #include <string>
00044 #include <stdio.h>
00045 #include <FWMath.h>
00046 #include <assert.h>
00047 
00048 Define_Module(MoBANCoordinator);
00049 
00050 void MoBANCoordinator::initialize(int stage) {
00051 
00052   if (stage == 0) {
00053     hasPar("debug") ? debug = par("debug").boolValue() : debug = false;
00054 
00055     useMobilityPattern = par("useMobilityPattern").boolValue();
00056     updateInterval = par("updateInterval").doubleValue();
00057     numNodes = par("numNodes").longValue();
00058 
00059     index = getIndex(); // Index of this WBAN
00060 
00061     // a pointer to world module
00062     world = FindModule<BaseWorldUtility*>::findGlobalModule();
00063     if (world == NULL)
00064       error("Could not find BaseWorldUtility module");
00065     network = getParentModule();
00066 
00067     //preparing output mobility pattern log file
00068     char log_file_name[70];
00069     sprintf(log_file_name, "MoBAN_Pattern_out%d.txt", index);
00070     logfile = fopen(log_file_name, "w");
00071 
00072     if (!readPostureSpecificationFile())
00073       error("MoBAN Coordinator: error in reading the posture specification file");
00074 
00075     if (!readConfigurationFile())
00076       error("MoBAN Coordinator: error in reading the input configuration file");
00077 
00078     if (useMobilityPattern)
00079       if (!readMobilityPatternFile())
00080         error("MoBAN Coordinator: error in reading the input mobility pattern file");
00081 
00082     cModule *gHost;
00083     nodeIndex = new int[numNodes];
00084 
00085     //Make the list of nodes belong to this WBAN.
00086     unsigned int tempNum = 0;
00087     unsigned int totalNumNodes = network->par("numNodes").longValue();
00088     for (int i = 0; i < static_cast<int>(totalNumNodes); ++i) {
00089       gHost = network->getSubmodule("node", i)->getSubmodule("mobility",0);
00090       if (gHost->hasPar("coordinatorIndex"))
00091         if (gHost->par("coordinatorIndex").longValue() == index) {
00092           ++tempNum;
00093           if (tempNum > numNodes)
00094             error(
00095                 "MoBAN Coordinator: wrong number of belonging nodes to the coordinator.");
00096           nodeIndex[tempNum - 1] = i;
00097         }
00098     }
00099     if (tempNum != numNodes)
00100       error(
00101           "MoBAN Coordinator: wrong number of belonging nodes to the coordinator.");
00102 
00103     mainProcess();
00104     publishToNodes();
00105 
00106     MoveMsg = new cMessage("Move");
00107     scheduleAt(simTime() + updateInterval, MoveMsg);
00108   }
00109 }
00110 
00114 void MoBANCoordinator::handleMessage(cMessage * msg) {
00115   if (msg == MoveMsg) {
00116     stepMove();
00117     scheduleAt(simTime() + updateInterval, msg);
00118   } else
00119     error("MoBAN Coordinator: unexpected message!");
00120 }
00121 
00128 void MoBANCoordinator::stepMove() {
00129   step++;
00130 
00131   if (currentPosture->isMobile()) {
00132     if (step == numSteps) { // reach the target
00133       logicalCenter = stepTarget;
00134       mainProcess();
00135     } else if (step < numSteps) {
00136       // step forward
00137       logicalCenter = stepTarget;
00138       stepTarget += stepSize;
00139     } else
00140       error("step should be less than numSteps");
00141   } else {
00142     if (step == numSteps)
00143       mainProcess();
00144   }
00145 
00149   if (currentPosture->isMobile() || step == 1)
00150     publishToNodes();
00151 }
00152 
00159 void MoBANCoordinator::mainProcess() {
00160   //select the new posture and set the variable currentPosture as well as the reference points of all nodes within the WBAN.
00161   if (useMobilityPattern) {
00162     currentPattern = (currentPattern + 1) % patternLength;
00163     int postureID = mobilityPattern[currentPattern].postureID;
00164     currentPosture = postureList[postureID];
00165   } else
00166     selectPosture();
00167 
00168   EV<<"New posture is selected:"<<currentPosture->getPostureName() << endl;
00169 
00170   if (currentPosture->isMobile())
00171   {
00172     double distance;
00173 
00174     if (useMobilityPattern) {
00175       targetPos = mobilityPattern[currentPattern].targetPos;
00176       speed = mobilityPattern[currentPattern].speed;
00177     }
00178     else {
00179       targetPos = selectDestination();
00180       speed = selectSpeed();
00181     }
00182 
00183     if (speed==0)
00184       error("The velocity in a mobile posture should not be zero!");
00185 
00186     distance = logicalCenter.distance(targetPos);
00187     duration = distance / speed;
00188 
00189     if (duration >= updateInterval)
00190       numSteps = FWMath::round(duration / updateInterval);
00191     else
00192       numSteps = 1; //The selected target position is quite close so that in less than one step, it will be reached with the given velocity.
00193 
00194     stepSize = targetPos - logicalCenter;
00195     stepSize = stepSize / numSteps;
00196     stepTarget = logicalCenter + stepSize;
00197   }
00198   else
00199   {
00200     if (useMobilityPattern)
00201       duration = mobilityPattern[currentPattern].duration;
00202     else
00203       duration = selectDuration();
00204 
00205     if (duration < updateInterval)
00206       error("The duration of a posture should be bigger than the updateInterval value!");
00207 
00208     numSteps = FWMath::round(duration / updateInterval) ;
00209   }
00210   step = 0;
00211 
00212     //show posture name in the graphical interface
00213   if(ev.isGUI()){
00214     char dis_str[100];
00215     sprintf(dis_str,"p=%f,50;i=block/wheelbarrow;is=vs;t=%s Duration:%f",world->getPgs()->getX()+10+(index*30),currentPosture->getPostureName(),duration.dbl());
00216     setDisplayString(dis_str);
00217   }
00218 
00219     // write the move step into the output log file
00220   if (currentPosture->isMobile())
00221     fprintf(logfile,"%s %d %f %f %f %f \n",currentPosture->getPostureName(),currentPosture->getPostureID(), targetPos.getX(),targetPos.getY(),targetPos.getZ(),speed);
00222   else
00223     fprintf(logfile,"%s %d %f \n",currentPosture->getPostureName(),currentPosture->getPostureID(), duration.dbl());
00224 
00225 
00226   EV << "New posture : " << currentPosture->getPostureName() << endl;
00227   EV << "Destination:" << targetPos.info() << " Total Time=" << duration << endl;
00228 }
00229 
00239 void MoBANCoordinator::selectPosture() {
00240   int postureID;
00241 
00242   if (postureSelStrategy == UNIFORM_RANDOM) {
00243     postureID = floor(uniform(0, numPostures)); // uniformly random posture selection
00244     currentPosture = postureList[postureID];
00245     return;
00246   }
00247 
00248   /* Here we check the area and the time to determine the corresponding posture transition matrix */
00249   markovMatrix = transitions->getMatrix(simTime(),logicalCenter);
00250 
00251   /* Using transition matrix to select the next posture */
00252   double randomValue = uniform(0, 1);
00253   double comp;
00254   int currentP = currentPosture->getPostureID(); // it determines the column in the matrix
00255 
00256   for (int i = 0; i < static_cast<int>(numPostures); ++i)
00257   {
00258     comp += markovMatrix[i][currentP];
00259     if (randomValue < comp)
00260     {
00261       postureID = i;
00262       break;
00263     }
00264   }
00265 
00266   currentPosture = postureList[postureID];
00267 }
00268 
00274 simtime_t MoBANCoordinator::selectDuration() {
00275   return uniform(minDuration, maxDuration);
00276 }
00277 
00283 Coord MoBANCoordinator::selectDestination() {
00284   Coord res;
00285   res = world->getRandomPosition();
00286   res.setZ(logicalCenter.getZ()); // the z value remain the same
00287 
00288   //check if it is okay using CoverRadius
00289   while (!isInsideWorld(res)) {
00290     res = world->getRandomPosition();
00291     res.setZ(logicalCenter.getZ());
00292   }
00293 
00294   return res;
00295 }
00296 
00302 double MoBANCoordinator::selectSpeed() {
00303   return (uniform(currentPosture->getMinSpeed(),
00304       currentPosture->getMaxSpeed()));
00305 }
00306 
00310 bool MoBANCoordinator::isInsideWorld(Coord tPos) {
00311   Coord absolutePosition;
00312 
00313   for (unsigned int i = 0; i < numNodes; ++i) {
00314     absolutePosition = tPos + currentPosture->getPs(i)
00315         + currentPosture->getRadius(i);
00316     if (!absolutePosition.isInBoundary(Coord(0, 0, 0), world->getPgs()))
00317       return false;
00318   }
00319 
00320   return true;
00321 }
00322 
00326 void MoBANCoordinator::finish() {
00327 
00328   cancelAndDelete(MoveMsg);
00329   fclose(logfile);
00330 
00331 }
00332 
00336 void MoBANCoordinator::publishToNodes() {
00337   BBMoBANMessage Refmove;
00338   for (unsigned int i = 0; i < numNodes; ++i) {
00339     EV<< "Publish data for node:" << nodeIndex[i] << endl;
00340 
00341     Refmove.position = currentPosture->getPs(i) + logicalCenter;
00342     Refmove.radius = currentPosture->getRadius(i);
00343     Refmove.speed = currentPosture->getSpeed(i);
00344 
00345     utility = FindModule<BaseUtility*>::findSubModule(network->getSubmodule("node",nodeIndex[i]));
00346       utility->publishBBItem(utility->getCategory(&Refmove), &Refmove, network->getSubmodule("node",nodeIndex[i])->getId());
00347 
00348     }
00349   }
00350 
00355 bool MoBANCoordinator::readMobilityPatternFile() {
00356   patternLength = 0;
00357   double x, y, z, s;
00358   int id;
00359   char file_name[70];
00360   char posture_name[50];
00361 
00362   sprintf(file_name, "%s", par("mobilityPatternFile").stringValue());
00363   FILE *fp = fopen(file_name, "r");
00364   if (fp == NULL)
00365     return false;
00366 
00367   //Count number of patterns (lines in the input file)
00368   int c;
00369   while ((c = fgetc(fp)) != EOF)
00370     if (c == '\n')
00371       patternLength++;
00372   fclose(fp);
00373 
00374   EV<< "Mobility Pattern Length:" << patternLength << endl;
00375 
00376   mobilityPattern = new Pattern[patternLength];
00377 
00378   fp = fopen(file_name,"r");
00379 
00380   int i=0;
00381   while (fscanf(fp,"%s %d",posture_name,&id)!= -1) {
00382     mobilityPattern[i].postureID = id;
00383     if (postureList[id]->isMobile())
00384     {
00385       assert( fscanf(fp,"%le %le %le %le",&x,&y,&z,&s)!=-1 );
00386       mobilityPattern[i].targetPos = Coord(x,y,z);
00387       mobilityPattern[i].speed = s;
00388     }
00389     else
00390     {
00391       assert ( fscanf(fp,"%le",&x)!=-1 );
00392       mobilityPattern[i].duration = x;
00393     }
00394     ++i;
00395   }
00396 
00397   fclose(fp);
00398 
00399   currentPattern = -1;
00400 
00401   return true;
00402 }
00403 
00411 bool MoBANCoordinator::readPostureSpecificationFile() {
00412 
00413   cXMLElement* xmlPosture = par("postureSpecFile").xmlValue();
00414   if (xmlPosture == 0)
00415     return false;
00416 
00417   const char* str;
00418 
00419   //read the specification of every posture from file and make a list of postures
00420   cXMLElementList postures;
00421 
00422   postures = xmlPosture->getElementsByTagName("posture");
00423 
00424   //Find the number of defined postures
00425   numPostures = postures.size();
00426   if (numPostures == 0)
00427     error("No posture is defined in the input posture specification file");
00428 
00429   unsigned int postureID;
00430 
00431   cXMLElementList::const_iterator posture;
00432   for (posture = postures.begin(); posture != postures.end(); posture++)
00433   {
00434     str = (*posture)->getAttribute("postureID");
00435     postureID = strtol(str, 0, 0);
00436     if ( postureID < 0 || postureID >= numPostures)
00437       error ("Posture ID in input posture specification file is out of the range.");
00438 
00439     postureList.push_back(new Posture(postureID, numNodes));
00440 
00441     str = (*posture)->getAttribute("name");
00442     postureList[postureID]->setPostureName(const_cast<char*> (str));
00443 
00444     str = (*posture)->getAttribute("minSpeed");
00445     double minS = strtod(str, 0);
00446     str = (*posture)->getAttribute("maxSpeed");
00447     double maxS = strtod(str, 0);
00448     postureList[postureID]->setPostureSpeed(minS, maxS);
00449 
00450     int i = 0;
00451     double x, y, z, s, r;
00452     cXMLElementList nodeParameters;
00453 
00454     nodeParameters = (*posture)->getElementsByTagName("nodeParameters");
00455     if (nodeParameters.size() != numNodes)
00456       error ("Some nodes may not have specified parameters in a posture in input posture specification file.");
00457 
00458     cXMLElementList::const_iterator param;
00459     for (param = nodeParameters.begin(); param!= nodeParameters.end(); param++)
00460     {
00461       str = (*param)->getAttribute("positionX");
00462       x = strtod(str, 0);
00463 
00464       str = (*param)->getAttribute("positionY");
00465       y = strtod(str, 0);
00466 
00467       str = (*param)->getAttribute("positionZ");
00468       z = strtod(str, 0);
00469 
00470       str = (*param)->getAttribute("radius");
00471       r = strtod(str, 0);
00472 
00473       str = (*param)->getAttribute("speed");
00474       s = strtod(str, 0);
00475 
00476       postureList[postureID]->setPs(i, Coord(x, y, z));
00477       postureList[postureID]->setRadius(i, r);
00478       postureList[postureID]->setSpeed(i, s);
00479 
00480       i++;
00481     }
00482   }
00483 
00484   /* Report the obtained specification of the postures. */
00485   for (unsigned int i = 0; i < numPostures; ++i) {
00486     EV<< "Information for the posture:"<<i<<" is"<<endl;
00487     for (unsigned int j=0;j<numNodes;++j)
00488     EV << "Node "<<j<< " position: "<<postureList[i]->getPs(j).info()<<
00489     " and radius:"<<postureList[i]->getRadius(j)<<" and speed:"<<postureList[i]->getSpeed(j)<<endl;
00490   }
00491 
00492   return true;
00493 
00494 }
00495 
00503 bool MoBANCoordinator::readConfigurationFile() {
00504   cXMLElement* xmlConfig = par("configFile").xmlValue();
00505   if (xmlConfig == 0)
00506     return false;
00507 
00508   cXMLElementList tagList;
00509   cXMLElement* tempTag;
00510   const char* str;
00511   std::string sstr; //for easier comparison
00512 
00513   /* Reading the initial posture if it is given*/
00514   int postureID;
00515   tagList = xmlConfig->getElementsByTagName("initialPosture");
00516 
00517   if (tagList.empty())
00518     postureID = 0; // no initial posture has been specified. The first one is selected!
00519   else {
00520     tempTag = tagList.front();
00521     str = tempTag->getAttribute("postureID");
00522     postureID = strtol(str, 0, 0);
00523   }
00524   currentPosture = postureList[postureID];
00525   EV<< "Initial Posture:"<< postureID <<endl;
00526 
00527 
00528   /* Reading the initial position of the logical center if it is given */
00529   tagList = xmlConfig->getElementsByTagName("initialLocation");
00530   if(tagList.empty())
00531     logicalCenter=Coord(10,10,5); // no initial location has been specified .
00532   else
00533   {
00534     double x,y,z;
00535     tempTag= tagList.front();
00536 
00537     str = tempTag->getAttribute("x"); x = strtod(str, 0);
00538     str = tempTag->getAttribute("y"); y = strtod(str, 0);
00539     str = tempTag->getAttribute("z"); z = strtod(str, 0);
00540     logicalCenter = Coord(x,y,z);
00541   }
00542   EV << "Initial position of the LC:"<< logicalCenter.info() <<endl;
00543 
00544   /* Reading the given range for duration of stable postures */
00545   tagList = xmlConfig->getElementsByTagName("durationRange");
00546   if(tagList.empty())
00547   {
00548     // no duration is specified. We assign a value!
00549     minDuration = updateInterval;
00550     maxDuration = 100;
00551   }
00552   else
00553   {
00554     double min,max;
00555     tempTag= tagList.front();
00556 
00557     str = tempTag->getAttribute("min"); min = strtod(str, 0);
00558     str = tempTag->getAttribute("max"); max = strtod(str, 0);
00559 
00560     minDuration = FWMath::max(updateInterval.dbl(),min); // the minimum should be bigger than the update interval.
00561     maxDuration = FWMath::max(min,max);
00562   }
00563   EV << "Posture duration range: ("<< minDuration << " , " << maxDuration << ")" << endl;
00564 
00565 
00566   transitions = new PostureTransition(numPostures);
00567 
00568 
00569   /* Reading the Markov transition matrices, if there are any. */
00570   tagList = xmlConfig->getElementsByTagName("markovMatrices");
00571 
00572   if(tagList.empty())
00573   {
00574     postureSelStrategy = UNIFORM_RANDOM; // no posture selection strategy is required. uniform random is applied
00575     EV << "Posture Selection strategy: UNIFORM_RANDOM "<< endl;
00576     return true;
00577   }
00578 
00579   tempTag = tagList.front();
00580 
00581   cXMLElementList matrixList;
00582   matrixList = tempTag->getElementsByTagName("MarkovMatrix");
00583 
00584   if(tagList.empty())
00585   {
00586     postureSelStrategy = UNIFORM_RANDOM; // no posture selection strategy is required. uniform random is applied
00587     EV << "Posture Selection strategy: UNIFORM_RANDOM "<< endl;
00588     return true;
00589   }
00590 
00591   postureSelStrategy = MARKOV_BASE;
00592 
00593   // make an empty matrix for the Markov Chain
00594     double** matrix = new double* [numPostures];
00595   for (unsigned int i=0;i<numPostures;++i)
00596     matrix[i] = new double [numPostures];
00597 
00598   bool setDefault=false; // variable to remember if the default matrix is defined.
00599   cXMLElementList::const_iterator matrixTag;
00600   for(matrixTag = matrixList.begin(); matrixTag != matrixList.end(); matrixTag++)
00601   {
00602 
00603     cXMLElementList rowList;
00604     cXMLElementList cellList;
00605     int i=0,j=0;
00606     bool thisDefault = false;
00607 
00608     if ( (*matrixTag)->getAttribute("type") != NULL)
00609     {
00610       sstr = (*matrixTag)->getAttribute("type");
00611       if ( sstr == "Default" || sstr == "default" )
00612       {
00613         if (setDefault)
00614           error ("There are more than one default matrix defined in the configuration file!");
00615         else
00616           {setDefault = true; thisDefault = true;}
00617       }
00618     }
00619 
00620 
00621     sstr = (*matrixTag)->getAttribute("name");
00622 
00623     rowList = (*matrixTag)->getElementsByTagName("row");
00624     if (rowList.size()!= numPostures && rowList.size()!= 1)
00625       error("Number of rows in  the Markov transition matrix should be equal to either the number"
00626           " of postures (full Markov matrix) or one (steady state vector).");
00627 
00628     if (rowList.size()!= numPostures && thisDefault )
00629       error("Dimension of the default Markov matrix should be equal to the number of postures in the configuration file.");
00630 
00631     if ( (rowList.size()== 1) && (!setDefault) )
00632       error("A default matrix is supposed to be defined before a steady state can be defined in the configuration file.");
00633 
00634     for(cXMLElementList::const_iterator row = rowList.begin(); row != rowList.end(); row++)
00635     {
00636       cellList = (*row)->getElementsByTagName("cell");
00637       if (cellList.size()!= numPostures)
00638         error("Number of columns in  the Markov transition matrix should be equal to the number of postures.");
00639 
00640       j=0;
00641       for(cXMLElementList::const_iterator cell = cellList.begin(); cell != cellList.end(); cell++)
00642       {
00643         str = (*cell)->getAttribute("value");
00644         matrix[i][j] = strtod(str, 0);
00645         j++;
00646       }
00647 
00648       ++i;
00649     }
00650 
00651     if (rowList.size() == 1)
00652       transitions->addSteadyState(sstr, matrix[0]); // steady state
00653     else
00654        transitions->addMatrix(sstr, matrix, thisDefault);     // A full Markovian matrix
00655 
00656     EV << "Markov transition matrix "<< sstr << " :" <<endl;
00657     for (int k=0;k < i ; ++k)
00658     {
00659       for (unsigned int f=0; f<numPostures ;++f)
00660         EV << matrix[k][f]<<" ";
00661       EV << endl;
00662     }
00663 
00664   }
00665 
00666   /* Reading the Area types, if there are any. */
00667   tagList = xmlConfig->getElementsByTagName("areaTypes");
00668 
00669   if( tagList.empty() )
00670     EV << "No area type is given. So there is no spatial correlation in posture selection." << endl;
00671   else{
00672 
00673       tempTag = tagList.front();
00674       cXMLElementList typeList = tempTag->getElementsByTagName("areaType");
00675 
00676       if( typeList.empty() )
00677         error ("No areaType has been defined in areaTypes!");
00678 
00679       for(cXMLElementList::const_iterator aType = typeList.begin(); aType != typeList.end(); aType++)
00680       {
00681         sstr = (*aType)->getAttribute("name");
00682 
00683         EV << "Area type " << sstr << " :" << endl;
00684 
00685         int typeID = transitions->addAreaType(sstr);
00686 
00687         cXMLElementList boundList = (*aType)->getElementsByTagName("boundary");
00688         if( boundList.empty() )
00689           error ("No boundary is given for a area type!");
00690 
00691         Coord minBound, maxBound;
00692         for(cXMLElementList::const_iterator aBound = boundList.begin(); aBound != boundList.end(); aBound++)
00693         {
00694           str = (*aBound)->getAttribute("xMin"); minBound.setX(strtod(str, 0));
00695           str = (*aBound)->getAttribute("yMin"); minBound.setY(strtod(str, 0));
00696           str = (*aBound)->getAttribute("zMin"); minBound.setZ(strtod(str, 0));
00697 
00698           str = (*aBound)->getAttribute("xMax"); maxBound.setX(strtod(str, 0));
00699           str = (*aBound)->getAttribute("yMax"); maxBound.setY(strtod(str, 0));
00700           str = (*aBound)->getAttribute("zMax"); maxBound.setZ(strtod(str, 0));
00701 
00702           transitions->setAreaBoundry(typeID,minBound,maxBound);
00703           EV << "Low bound: "<< minBound.info() << endl;
00704           EV << "High bound: "<< maxBound.info() << endl;
00705         }
00706       }
00707     }
00708 
00709   /* Reading the time domains, if there are any. */
00710   tagList = xmlConfig->getElementsByTagName("timeDomains");
00711 
00712   if( tagList.empty() )
00713     EV << "No time domain is given. So there is no temporal correlation in posture selection." << endl;
00714   else{
00715 
00716       tempTag = tagList.front();
00717       cXMLElementList typeList = tempTag->getElementsByTagName("timeDomain");
00718 
00719       if( typeList.empty() )
00720         error ("No timeDomain has been defined in timeDomains!");
00721 
00722       for(cXMLElementList::const_iterator aType = typeList.begin(); aType != typeList.end(); aType++)
00723       {
00724         sstr = (*aType)->getAttribute("name");
00725 
00726         EV << "Time domain " << sstr << " :" << endl;
00727 
00728         int typeID = transitions->addTimeDomain(sstr);
00729 
00730         cXMLElementList boundList = (*aType)->getElementsByTagName("boundary");
00731         if( boundList.empty() )
00732           error ("No boundary is given for a time domain!");
00733 
00734         simtime_t minTime,maxTime;
00735         for(cXMLElementList::const_iterator aBound = boundList.begin(); aBound != boundList.end(); aBound++)
00736         {
00737           str = (*aBound)->getAttribute("tMin"); minTime = strtod(str,0);
00738           str = (*aBound)->getAttribute("tMax"); maxTime = strtod(str,0);
00739 
00740           transitions->setTimeBoundry(typeID,minTime,maxTime);
00741           EV << "Low bound: ("<< minTime.dbl() << ", " << maxTime << ")" << endl;
00742         }
00743       }
00744   }
00745 
00746   /* Reading the combinations, if there are any. */
00747   tagList = xmlConfig->getElementsByTagName("combinations");
00748 
00749   if( tagList.empty() )
00750     EV << "No combination is given. The default Markov model is then used for the whole time and space!" << endl;
00751   else{
00752         tempTag = tagList.front();
00753       cXMLElementList combList = tempTag->getElementsByTagName("combination");
00754 
00755       if( combList.empty() )
00756         error ("No combination has been defined in combinations!");
00757 
00758       EV << "Combinations: " << endl;
00759 
00760       for(cXMLElementList::const_iterator aComb = combList.begin(); aComb != combList.end(); aComb++)
00761       {
00762         std::string areaName,timeName,matrixName;
00763 
00764         if ((*aComb)->getAttribute("areaType") != NULL)
00765           areaName = (*aComb)->getAttribute("areaType");
00766         else
00767           areaName.clear();
00768 
00769         if ( (*aComb)->getAttribute("timeDomain") != NULL )
00770           timeName = (*aComb)->getAttribute("timeDomain");
00771         else
00772           timeName.clear();
00773 
00774         if ( (*aComb)->getAttribute("matrix") != NULL )
00775           matrixName = (*aComb)->getAttribute("matrix");
00776         else
00777           error("No transition matrix is specified for a combination.");
00778 
00779         transitions->addCombination(areaName, timeName, matrixName);
00780 
00781         EV << "(" << areaName << ", " << timeName << ", " << matrixName << ")" << endl;
00782       }
00783     }
00784 
00785   return true;
00786 }