|
INET Framework for OMNeT++/OMNEST
|
00001 /* -*- mode:c++ -*- ******************************************************** 00002 * file: BasicMobility.cc 00003 * 00004 * author: Daniel Willkomm, Andras Varga 00005 * 00006 * copyright: (C) 2004 Telecommunication Networks Group (TKN) at 00007 * Technische Universitaet Berlin, Germany. 00008 * 00009 * (C) 2005 Andras Varga 00010 * 00011 * This program is free software; you can redistribute it 00012 * and/or modify it under the terms of the GNU General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2 of the License, or (at your option) any later 00015 * version. 00016 * For further information see file COPYING 00017 * in the top level directory 00018 *************************************************************************** 00019 * part of: framework implementation developed by tkn 00020 **************************************************************************/ 00021 00022 00023 #include "BasicMobility.h" 00024 #include "FWMath.h" 00025 00026 00027 #define coreEV (ev.isDisabled()||!coreDebug) ? (std::ostream&)ev : EV << logName() << "::BasicMobility: " 00028 00029 static int parseInt(const char *s, int defaultValue) 00030 { 00031 if (!s || !*s) 00032 return defaultValue; 00033 char *endptr; 00034 int value = strtol(s, &endptr, 10); 00035 return *endptr=='\0' ? value : defaultValue; 00036 } 00037 00038 00039 void BasicMobility::initialize(int stage) 00040 { 00041 BasicModule::initialize(stage); 00042 00043 EV << "initializing BasicMobility stage " << stage << endl; 00044 00045 if (stage == 0) 00046 { 00047 cc = ChannelControl::get(); 00048 00049 // get a pointer to the host 00050 hostPtr = findHost(); 00051 myHostRef = cc->registerHost(hostPtr, Coord()); 00052 } 00053 else if (stage == 1) 00054 { 00055 // playground size gets set up by ChannelControl in stage==0 (Andras) 00056 // read the playgroundsize from ChannelControl 00057 Coord pgs = cc->getPgs(); 00058 00059 // reading the coordinates from omnetpp.ini makes predefined scenarios a lot easier 00060 // -1 indicates start at display string position, or random position if it's not present 00061 pos.x = pos.y = -1; 00062 if (hasPar("x")) // not all mobility models have an "x" parameter 00063 pos.x = par("x"); 00064 if (pos.x == -1) 00065 pos.x = parseInt(hostPtr->getDisplayString().getTagArg("p",0), -1); 00066 if (pos.x == -1) 00067 pos.x = uniform(0, pgs.x); 00068 00069 if (hasPar("y")) // not all mobility models have an "y" parameter 00070 pos.y = par("y"); 00071 if (pos.y == -1) 00072 pos.y = parseInt(hostPtr->getDisplayString().getTagArg("p",1), -1); 00073 if (pos.y == -1) 00074 pos.y = uniform(0, pgs.y); 00075 00076 // check validity of position 00077 if (pos.x < 0 || pos.y < 0 || pos.x >= pgs.x || pos.y >= pgs.y) 00078 error("node position (%d,%d) is outside the playground", pos.x, pos.y); 00079 00080 // adjusting the display string is no longer needed (Andras) 00081 00082 // print new host position on the screen and update bb info 00083 updatePosition(); 00084 } 00085 } 00086 00087 void BasicMobility::handleMessage(cMessage * msg) 00088 { 00089 if (!msg->isSelfMessage()) 00090 error("mobility modules can only receive self messages"); 00091 00092 handleSelfMsg(msg); 00093 } 00094 00095 00096 void BasicMobility::updatePosition() 00097 { 00098 cc->updateHostPosition(myHostRef, pos); 00099 00100 if (ev.isGUI()) 00101 { 00102 double r = cc->getCommunicationRange(myHostRef); 00103 hostPtr->getDisplayString().setTagArg("p", 0, (long) pos.x); 00104 hostPtr->getDisplayString().setTagArg("p", 1, (long) pos.y); 00105 hostPtr->getDisplayString().setTagArg("r", 0, (long) r); 00106 } 00107 nb->fireChangeNotification(NF_HOSTPOSITION_UPDATED, &pos); 00108 } 00109 00110 00115 Coord BasicMobility::getRandomPosition() 00116 { 00117 Coord p; 00118 p.x = uniform(0, cc->getPgs()->x); 00119 p.y = uniform(0, cc->getPgs()->y); 00120 return p; 00121 } 00122 00123 void BasicMobility::reflectIfOutside(Coord& targetPos, Coord& step, double& angle) 00124 { 00125 if (pos.x < 0) 00126 { 00127 pos.x = -pos.x; 00128 targetPos.x = -targetPos.x; 00129 step.x = -step.x; 00130 angle = 180 - angle; 00131 } 00132 else if (pos.x >= getPlaygroundSizeX()) 00133 { 00134 pos.x = 2*getPlaygroundSizeX() - pos.x; 00135 targetPos.x = 2*getPlaygroundSizeX() - targetPos.x; 00136 step.x = -step.x; 00137 angle = 180 - angle; 00138 } 00139 if (pos.y < 0) 00140 { 00141 pos.y = -pos.y; 00142 targetPos.y = -targetPos.y; 00143 step.y = -step.y; 00144 angle = -angle; 00145 } 00146 else if (pos.y >= getPlaygroundSizeY()) 00147 { 00148 pos.y = 2*getPlaygroundSizeY() - pos.y; 00149 targetPos.y = 2*getPlaygroundSizeY() - targetPos.y; 00150 step.y = -step.y; 00151 angle = -angle; 00152 } 00153 } 00154 00155 void BasicMobility::wrapIfOutside(Coord& targetPos) 00156 { 00157 if (pos.x < 0) 00158 { 00159 pos.x += getPlaygroundSizeX(); 00160 targetPos.x += getPlaygroundSizeX(); 00161 } 00162 else if (pos.x >= getPlaygroundSizeX()) 00163 { 00164 pos.x -= getPlaygroundSizeX(); 00165 targetPos.x -= getPlaygroundSizeX(); 00166 } 00167 if (pos.y < 0) 00168 { 00169 pos.y += getPlaygroundSizeY(); 00170 targetPos.y += getPlaygroundSizeY(); 00171 } 00172 else if (pos.y >= getPlaygroundSizeY()) 00173 { 00174 pos.y -= getPlaygroundSizeY(); 00175 targetPos.y -= getPlaygroundSizeY(); 00176 } 00177 } 00178 00179 void BasicMobility::placeRandomlyIfOutside(Coord& targetPos) 00180 { 00181 if (pos.x<0 || pos.x>=getPlaygroundSizeX() || pos.y<0 || pos.y>=getPlaygroundSizeY()) 00182 { 00183 Coord newPos = getRandomPosition(); 00184 targetPos += newPos - pos; 00185 pos = newPos; 00186 } 00187 } 00188 00189 void BasicMobility::raiseErrorIfOutside() 00190 { 00191 if (pos.x<0 || pos.x>=getPlaygroundSizeX() || pos.y<0 || pos.y>=getPlaygroundSizeY()) 00192 { 00193 error("node moved outside the playground of size %gx%g (x=%g,y=%g)", 00194 getPlaygroundSizeX(), getPlaygroundSizeY(), pos.x, pos.y); 00195 } 00196 } 00197 00198 void BasicMobility::handleIfOutside(BorderPolicy policy, Coord& targetPos, Coord& step, double& angle) 00199 { 00200 switch (policy) 00201 { 00202 case REFLECT: reflectIfOutside(targetPos, step, angle); break; 00203 case WRAP: wrapIfOutside(targetPos); break; 00204 case PLACERANDOMLY: placeRandomlyIfOutside(targetPos); break; 00205 case RAISEERROR: raiseErrorIfOutside(); break; 00206 } 00207 }