00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
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();
00060
00061
00062 world = FindModule<BaseWorldUtility*>::findGlobalModule();
00063 if (world == NULL)
00064 error("Could not find BaseWorldUtility module");
00065 network = getParentModule();
00066
00067
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
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) {
00133 logicalCenter = stepTarget;
00134 mainProcess();
00135 } else if (step < numSteps) {
00136
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
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;
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
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
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));
00244 currentPosture = postureList[postureID];
00245 return;
00246 }
00247
00248
00249 markovMatrix = transitions->getMatrix(simTime(),logicalCenter);
00250
00251
00252 double randomValue = uniform(0, 1);
00253 double comp;
00254 int currentP = currentPosture->getPostureID();
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());
00287
00288
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
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
00420 cXMLElementList postures;
00421
00422 postures = xmlPosture->getElementsByTagName("posture");
00423
00424
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
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;
00512
00513
00514 int postureID;
00515 tagList = xmlConfig->getElementsByTagName("initialPosture");
00516
00517 if (tagList.empty())
00518 postureID = 0;
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
00529 tagList = xmlConfig->getElementsByTagName("initialLocation");
00530 if(tagList.empty())
00531 logicalCenter=Coord(10,10,5);
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
00545 tagList = xmlConfig->getElementsByTagName("durationRange");
00546 if(tagList.empty())
00547 {
00548
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);
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
00570 tagList = xmlConfig->getElementsByTagName("markovMatrices");
00571
00572 if(tagList.empty())
00573 {
00574 postureSelStrategy = UNIFORM_RANDOM;
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;
00587 EV << "Posture Selection strategy: UNIFORM_RANDOM "<< endl;
00588 return true;
00589 }
00590
00591 postureSelStrategy = MARKOV_BASE;
00592
00593
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;
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]);
00653 else
00654 transitions->addMatrix(sstr, matrix, thisDefault);
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
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
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
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 }