#include <TurtleMobility.h>
Inheritance diagram for TurtleMobility:

Protected Member Functions | |
| virtual void | initialize (int) |
| Initializes mobility model parameters. | |
| virtual void | setTargetPosition () |
| Overridden from LineSegmentsMobilityBase. Invokes resumeScript(). | |
| virtual void | fixIfHostGetsOutside () |
| Overridden from LineSegmentsMobilityBase. | |
| void | resumeScript () |
| Process next statements from script. | |
| void | executeStatement (cXMLElement *nextStatement) |
| Execute the given statement. | |
| double | getValue (const char *s) |
| Parse attrs in the script -- accepts things like "uniform(10,50) as well. | |
| void | gotoNextStatement () |
| Advance nextStatement pointer. | |
Protected Attributes | |
| cXMLElement * | turtleScript |
| cXMLElement * | nextStatement |
| double | speed |
| double | angle |
| BorderPolicy | borderPolicy |
| std::stack< long > | loopVars |
|
|
Execute the given statement.
00094 {
00095 const char *tag = stmt->getTagName();
00096
00097 EV << "doing <" << tag << ">\n";
00098
00099 if (!strcmp(tag,"repeat"))
00100 {
00101 const char *nAttr = stmt->getAttribute("n");
00102 long n = -1; // infinity -- that's the default
00103 if (nAttr)
00104 {
00105 n = (long) getValue(nAttr);
00106 if (n<0)
00107 error("<repeat>: negative repeat count at %s", stmt->getSourceLocation());
00108 }
00109 loopVars.push(n);
00110 }
00111 else if (!strcmp(tag,"set"))
00112 {
00113 const char *speedAttr = stmt->getAttribute("speed");
00114 const char *angleAttr = stmt->getAttribute("angle");
00115 const char *xAttr = stmt->getAttribute("x");
00116 const char *yAttr = stmt->getAttribute("y");
00117 const char *bpAttr = stmt->getAttribute("borderPolicy");
00118 if (speedAttr)
00119 speed = getValue(speedAttr);
00120 if (angleAttr)
00121 angle = getValue(angleAttr);
00122 if (xAttr)
00123 targetPos.x = pos.x = getValue(xAttr);
00124 if (yAttr)
00125 targetPos.y = pos.y = getValue(yAttr);
00126 if (speed<=0)
00127 error("<set>: speed is negative or zero at %s", stmt->getSourceLocation());
00128 if (bpAttr)
00129 {
00130 if (!strcmp(bpAttr,"reflect"))
00131 borderPolicy = REFLECT;
00132 else if (!strcmp(bpAttr,"wrap"))
00133 borderPolicy = WRAP;
00134 else if (!strcmp(bpAttr,"placerandomly"))
00135 borderPolicy = PLACERANDOMLY;
00136 else if (!strcmp(bpAttr,"error"))
00137 borderPolicy = RAISEERROR;
00138 else
00139 error("<set>: value for attribute borderPolicy is invalid, should be "
00140 "'reflect', 'wrap', 'placerandomly' or 'error' at %s",
00141 stmt->getSourceLocation());
00142 }
00143 }
00144 else if (!strcmp(tag,"forward"))
00145 {
00146 const char *dAttr = stmt->getAttribute("d");
00147 const char *tAttr = stmt->getAttribute("t");
00148 if (!dAttr && !tAttr)
00149 error("<forward>: must have at least attribute 't' or 'd' (or both) at %s", stmt->getSourceLocation());
00150 double d, t;
00151 if (tAttr && dAttr)
00152 {
00153 // cover distance d in time t (current speed is ignored)
00154 d = getValue(dAttr);
00155 t = getValue(tAttr);
00156 }
00157 else if (dAttr)
00158 {
00159 // travel distance d at current speed
00160 d = getValue(dAttr);
00161 t = d / speed;
00162 }
00163 else // tAttr only
00164 {
00165 // travel for time t at current speed
00166 t = getValue(tAttr);
00167 d = speed * t;
00168 }
00169 if (t<0)
00170 error("<forward>: time (attribute t) is negative at %s", stmt->getSourceLocation());
00171 if (d<0)
00172 error("<forward>: distance (attribute d) is negative at %s", stmt->getSourceLocation());
00173 // FIXME handle zeros properly...
00174 targetPos.x += d * cos(PI * angle / 180);
00175 targetPos.y += d * sin(PI * angle / 180);
00176 targetTime += t;
00177 }
00178 else if (!strcmp(tag,"turn"))
00179 {
00180 const char *angleAttr = stmt->getAttribute("angle");
00181 if (!angleAttr)
00182 error("<turn>: required attribute 'angle' missing at %s", stmt->getSourceLocation());
00183 angle += getValue(angleAttr);
00184 }
00185 else if (!strcmp(tag,"wait"))
00186 {
00187 const char *tAttr = stmt->getAttribute("t");
00188 if (!tAttr)
00189 error("<wait>: required attribute 't' missing at %s", stmt->getSourceLocation());
00190 double t = getValue(tAttr);
00191 if (t<0)
00192 error("<wait>: time (attribute t) is negative (%g) at %s", t, stmt->getSourceLocation());
00193 targetTime += t; // targetPos is unchanged
00194 }
00195 else if (!strcmp(tag,"moveto"))
00196 {
00197 const char *xAttr = stmt->getAttribute("x");
00198 const char *yAttr = stmt->getAttribute("y");
00199 const char *tAttr = stmt->getAttribute("t");
00200 if (xAttr)
00201 targetPos.x = getValue(xAttr);
00202 if (yAttr)
00203 targetPos.y = getValue(yAttr);
00204 // travel to targetPos at current speed, or get there in time t (ignoring current speed then)
00205 double t = tAttr ? getValue(tAttr) : pos.distance(targetPos)/speed;
00206 if (t<0)
00207 error("<wait>: time (attribute t) is negative at %s", stmt->getSourceLocation());
00208 targetTime += t;
00209 }
00210 else if (!strcmp(tag,"moveby"))
00211 {
00212 const char *xAttr = stmt->getAttribute("x");
00213 const char *yAttr = stmt->getAttribute("y");
00214 const char *tAttr = stmt->getAttribute("t");
00215 if (xAttr)
00216 targetPos.x += getValue(xAttr);
00217 if (yAttr)
00218 targetPos.y += getValue(yAttr);
00219 // travel to targetPos at current speed, or get there in time t (ignoring current speed then)
00220 double t = tAttr ? getValue(tAttr) : pos.distance(targetPos)/speed;
00221 if (t<0)
00222 error("<wait>: time (attribute t) is negative at %s", stmt->getSourceLocation());
00223 targetTime += t;
00224 }
00225 }
|
|
|
Overridden from LineSegmentsMobilityBase.
Implements LineSegmentsMobilityBase. 00068 {
00069 handleIfOutside(borderPolicy, targetPos, step, angle);
00070 }
|
|
|
Parse attrs in the script -- accepts things like "uniform(10,50) as well.
00228 {
00229 // first, textually replace $MAXX and $MAXY with their actual values
00230 std::string str;
00231 if (strchr(s,'$'))
00232 {
00233 char strMaxX[32], strMaxY[32];
00234 sprintf(strMaxX, "%g", playgroundSizeX()-1);
00235 sprintf(strMaxY, "%g", playgroundSizeY()-1);
00236
00237 str = s;
00238 std::string::size_type pos;
00239 while ((pos = str.find("$MAXX")) != std::string::npos)
00240 str.replace(pos, sizeof("$MAXX")-1, strMaxX);
00241 while ((pos = str.find("$MAXY")) != std::string::npos)
00242 str.replace(pos, sizeof("$MAXY")-1, strMaxY);
00243 s = str.c_str();
00244 }
00245
00246 // then use cPar to evaluate the string
00247 cPar tmp;
00248 if (!tmp.setFromText(s,'?'))
00249 error("wrong value '%s' around %s", s, nextStatement->getSourceLocation());
00250 return tmp.doubleValue();
00251 }
|
|
|
Advance nextStatement pointer.
00254 {
00255 // "statement either doesn't have a child, or it's a <repeat> and loop count is already pushed on the stack"
00256 ASSERT(!nextStatement->getFirstChild() || (!strcmp(nextStatement->getTagName(),"repeat") && !loopVars.empty()));
00257
00258 if (nextStatement->getFirstChild() && (loopVars.top()!=0 || (loopVars.pop(),false))) // !=0: positive or -1
00259 {
00260 // statement must be a <repeat> if it has children; repeat count>0 must be
00261 // on the stack; let's start doing the body.
00262 nextStatement = nextStatement->getFirstChild();
00263 }
00264 else if (!nextStatement->getNextSibling())
00265 {
00266 // no sibling -- either end of <repeat> body, or end of script
00267 ASSERT(nextStatement->getParentNode()==turtleScript ? loopVars.empty() : !loopVars.empty());
00268 if (!loopVars.empty())
00269 {
00270 // decrement and check loop counter
00271 if (loopVars.top()!=-1) // -1 means infinity
00272 loopVars.top()--;
00273 if (loopVars.top()!=0) // positive or -1
00274 {
00275 // go to beginning of <repeat> block again
00276 nextStatement = nextStatement->getParentNode()->getFirstChild();
00277 }
00278 else
00279 {
00280 // end of loop -- locate next statement after the <repeat>
00281 nextStatement = nextStatement->getParentNode();
00282 gotoNextStatement();
00283 }
00284 }
00285 else
00286 {
00287 // end of script
00288 nextStatement = NULL;
00289 }
00290 }
00291 else
00292 {
00293 // go to next statement (must exist -- see "if" above)
00294 nextStatement = nextStatement->getNextSibling();
00295 }
00296 }
|
|
|
Initializes mobility model parameters. Reads the parameters. If the host is not stationary it calculates a random position and schedules a timer to trigger the first movement Reimplemented from LineSegmentsMobilityBase. 00032 {
00033 LineSegmentsMobilityBase::initialize(stage);
00034
00035 EV << "initializing TurtleMobility stage " << stage << endl;
00036
00037 if (stage == 1)
00038 {
00039 turtleScript = par("turtleScript");
00040 nextStatement = turtleScript->getFirstChild();
00041
00042 speed = 1;
00043 angle = 0;
00044 borderPolicy = REFLECT;
00045
00046 // a dirty trick to extract starting position out of the script
00047 // (start doing it, but then rewind to the beginning)
00048 resumeScript();
00049 targetPos = pos;
00050 targetTime = simTime();
00051 nextStatement = turtleScript->getFirstChild();
00052 while (!loopVars.empty()) loopVars.pop();
00053
00054 updatePosition();
00055
00056 WATCH(speed);
00057 WATCH(angle);
00058 //WATCH(borderPolicy);
00059 }
00060 }
|
|
|
Process next statements from script. Will set a new targetTime and targetPos 00076 {
00077 if (!nextStatement)
00078 {
00079 stationary = true;
00080 return;
00081 }
00082
00083 simtime_t now = targetTime;
00084
00085 // interpret statement
00086 while (nextStatement && targetTime==now)
00087 {
00088 executeStatement(nextStatement);
00089 gotoNextStatement();
00090 }
00091 }
|
|
|
Overridden from LineSegmentsMobilityBase. Invokes resumeScript().
Implements LineSegmentsMobilityBase. 00063 {
00064 resumeScript();
00065 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.4.1