00001
00002
00003
00004
00005 extern "C" {
00006 #include <assert.h>
00007 #include <fcntl.h>
00008 #include <math.h>
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <sys/time.h>
00013 #include <sys/types.h>
00014 #include <sys/uio.h>
00015 #include <unistd.h>
00016 #if !defined(sun) && !defined(__CYGWIN__)
00017 #include <err.h>
00018 #endif
00019 };
00020 #include "../../../rng.h"
00021
00022 #include "setdest.h"
00023
00024
00025
00026 #define SANITY_CHECKS
00027
00028
00029
00030 #define GOD_FORMAT "$ns_ at %.12f \"$god_ set-dist %d %d %d\"\n"
00031 #define GOD_FORMAT2 "$god_ set-dist %d %d %d\n"
00032 #define NODE_FORMAT "$ns_ at %.12f \"$node_(%d) setdest %.12f %.12f %.12f\"\n"
00033 #define NODE_FORMAT2 "$node_(%d) setdest %.12f %.12f %.12f\n"
00034 #define NODE_FORMAT3 "$node_(%d) set %c_ %.12f\n"
00035
00036 #define INFINITY 0x00ffffff
00037 #define min(x,y) ((x) < (y) ? (x) : (y))
00038 #define max(x,y) ((x) > (y) ? (x) : (y))
00039 #define ROUND_ERROR 1e-9
00040
00041 static int count = 0;
00042
00043
00044
00045
00046 void usage(char**);
00047 void init(void);
00048 double uniform(void);
00049
00050 void dumpall(void);
00051 void ComputeW(void);
00052 void floyd_warshall(void);
00053
00054 void show_diffs(void);
00055 void show_routes(void);
00056 void show_counters(void);
00057
00058
00059
00060
00061
00062 const double RANGE = 250.0;
00063 double TIME = 0.0;
00064 double MAXTIME = 0.0;
00065
00066 double MAXX = 0.0;
00067 double MAXY = 0.0;
00068 double MAXSPEED = 0.0;
00069 double PAUSE = 0.0;
00070 u_int32_t NODES = 0;
00071 u_int32_t RouteChangeCount = 0;
00072 u_int32_t LinkChangeCount = 0;
00073 u_int32_t DestUnreachableCount = 0;
00074
00075 Node *NodeList = 0;
00076 u_int32_t *D1 = 0;
00077 u_int32_t *D2 = 0;
00078
00079
00080
00081
00082
00083 #define M 2147483647L
00084 #define INVERSE_M ((double)4.656612875e-10)
00085
00086 char random_state[32];
00087 RNG *rng;
00088
00089 double
00090 uniform()
00091 {
00092 count++;
00093 return rng->uniform_double() ;
00094 }
00095
00096
00097
00098
00099
00100 void
00101 usage(char **argv)
00102 {
00103 fprintf(stderr,
00104 "\nusage: %s\t-n <nodes> -p <pause time> -s <max speed>\n",
00105 argv[0]);
00106 fprintf(stderr,
00107 "\t\t-t <simulation time> -x <max X> -y <max Y>\n\n");
00108 }
00109
00110 void
00111 init()
00112 {
00113
00114
00115
00116 "
00117 /*"
00118 * Allocate memory for globals
00119 */
00120 NodeList = new Node[NODES];
00121 if(NodeList == 0) {
00122 perror("new");
00123 exit(1);
00124 }
00125
00126 D1 = new u_int32_t[NODES * NODES];
00127 if(D1 == 0) {
00128 perror("new");
00129 exit(1);
00130 }
00131 memset(D1, '\xff', sizeof(u_int32_t) * NODES * NODES);
00132
00133 D2 = new u_int32_t[NODES * NODES];
00134 if(D2 == 0) {
00135 perror("new");
00136 exit(1);
00137 }
00138 memset(D2, '\xff', sizeof(u_int32_t) * NODES * NODES);
00139 }
00140
00141 extern "C" char *optarg;
00142
00143 int
00144 main(int argc, char **argv)
00145 {
00146 char ch;
00147
00148 while ((ch = getopt(argc, argv, "n:p:s:t:x:y:i:o:")) != EOF) {
00149
00150 switch (ch) {
00151
00152 case 'n':
00153 NODES = atoi(optarg);
00154 break;
00155
00156 case 'p':
00157 PAUSE = atof(optarg);
00158 break;
00159
00160 case 's':
00161 MAXSPEED = atof(optarg);
00162 break;
00163
00164 case 't':
00165 MAXTIME = atof(optarg);
00166 break;
00167
00168 case 'x':
00169 MAXX = atof(optarg);
00170 break;
00171
00172 case 'y':
00173 MAXY = atof(optarg);
00174 break;
00175
00176 default:
00177 usage(argv);
00178 exit(1);
00179 }
00180 }
00181
00182 if(MAXX == 0.0 || MAXY == 0.0 || NODES == 0 || MAXTIME == 0.0) {
00183 usage(argv);
00184 exit(1);
00185 }
00186
00187 fprintf(stdout, "#\n# nodes: %d, pause: %.2f, max speed: %.2f max x = %.2f, max y: %.2f\n#\n",
00188 NODES , PAUSE, MAXSPEED, MAXX, MAXY);
00189
00190
00191 rng = new RNG;
00192 rng->set_seed(RNG::HEURISTIC_SEED_SOURCE);
00193
00194 init();
00195
00196 while(TIME <= MAXTIME) {
00197 double nexttime = 0.0;
00198 u_int32_t i;
00199
00200 for(i = 0; i < NODES; i++) {
00201 NodeList[i].Update();
00202 }
00203
00204
00205
00206
00207
00208 for(i = 0; i < NODES; i++) {
00209 Node *n = &NodeList[i];
00210
00211 if(n->time_transition > 0.0) {
00212 if(nexttime == 0.0)
00213 nexttime = n->time_transition;
00214 else
00215 nexttime = min(nexttime, n->time_transition);
00216 }
00217
00218 if(n->time_arrival > 0.0) {
00219 if(nexttime == 0.0)
00220 nexttime = n->time_arrival;
00221 else
00222 nexttime = min(nexttime, n->time_arrival);
00223 }
00224 }
00225
00226
00227
00228 #ifdef DEBUG
00229 show_routes();
00230 #endif
00231
00232
00233
00234 #ifdef DEBUG
00235 dumpall();
00236 #endif
00237
00238 assert(nexttime > TIME + ROUND_ERROR);
00239 TIME = nexttime;
00240 }
00241
00242 show_counters();
00243
00244 int of;
00245 if ((of = open(".rand_state",O_WRONLY | O_TRUNC | O_CREAT, 0777)) < 0) {
00246 fprintf(stderr, "open rand state\n");
00247 exit(-1);
00248 }
00249 for (unsigned int i = 0; i < sizeof(random_state); i++)
00250 random_state[i] = 0xff & (int) (uniform() * 256);
00251 if (write(of,random_state, sizeof(random_state)) < 0) {
00252 fprintf(stderr, "writing rand state\n");
00253 exit(-1);
00254 }
00255 close(of);
00256 }
00257
00258
00259
00260
00261
00262 u_int32_t Node::NodeIndex = 0;
00263
00264 Node::Node()
00265 {
00266 u_int32_t i;
00267
00268 index = NodeIndex++;
00269
00270
00271
00272
00273 route_changes = 0;
00274 link_changes = 0;
00275
00276
00277
00278
00279
00280 time_arrival = TIME + PAUSE;
00281 time_update = TIME;
00282 time_transition = 0.0;
00283
00284 position.X = position.Y = position.Z = 0.0;
00285 destination.X = destination.Y = destination.Z = 0.0;
00286 direction.X = direction.Y = direction.Z = 0.0;
00287 speed = 0.0;
00288
00289 RandomPosition();
00290
00291 fprintf(stdout, NODE_FORMAT3, index, 'X', position.X);
00292 fprintf(stdout, NODE_FORMAT3, index, 'Y', position.Y);
00293 fprintf(stdout, NODE_FORMAT3, index, 'Z', position.Z);
00294
00295 neighbor = new Neighbor[NODES];
00296 if(neighbor == 0) {
00297 perror("new");
00298 exit(1);
00299 }
00300
00301 for(i = 0; i < NODES; i++) {
00302 neighbor[i].index = i;
00303 neighbor[i].reachable = (index == i) ? 1 : 0;
00304 neighbor[i].time_transition = 0.0;
00305 }
00306 }
00307
00308
00309
00310 void
00311 Node::RandomPosition()
00312 {
00313 position.X = uniform() * MAXX;
00314 position.Y = uniform() * MAXY;
00315 position.Z = 0.0;
00316 }
00317
00318
00319 void
00320 Node::RandomDestination()
00321 {
00322 destination.X = uniform() * MAXX;
00323 destination.Y = uniform() * MAXY;
00324 destination.Z = 0.0;
00325 assert(destination != position);
00326 }
00327
00328 void
00329 Node::RandomSpeed()
00330 {
00331 speed = uniform() * MAXSPEED;
00332
00333 assert(speed != 0.0);
00334 }
00335
00336
00337 void
00338 Node::Update()
00339 {
00340 position += (speed * (TIME - time_update)) * direction;
00341
00342 if(TIME == time_arrival) {
00343 vector v;
00344
00345 if(speed == 0.0 || PAUSE == 0.0) {
00346
00347 RandomDestination();
00348 RandomSpeed();
00349
00350 v = destination - position;
00351 direction = v / v.length();
00352 time_arrival = TIME + v.length() / speed;
00353 }
00354 else {
00355
00356 destination = position;
00357 speed = 0.0;
00358
00359 time_arrival = TIME + PAUSE;
00360 }
00361
00362 fprintf(stdout, NODE_FORMAT,
00363 TIME, index, destination.X, destination.Y, speed);
00364
00365 }
00366
00367 time_update = TIME;
00368 time_transition = 0.0;
00369 }
00370
00371
00372 void
00373 Node::UpdateNeighbors()
00374 {
00375 static Node *n2;
00376 static Neighbor *m1, *m2;
00377 static vector D, B, v1, v2;
00378 static double a, b, c, t1, t2, Q;
00379 static u_int32_t i, reachable;
00380
00381 v1 = speed * direction;
00382
00383
00384
00385
00386
00387 for(i = index+1; i < NODES; i++) {
00388
00389 m1 = &neighbor[i];
00390 n2 = &NodeList[i];
00391 m2 = &n2->neighbor[index];
00392
00393 assert(i == m1->index);
00394 assert(m1->index == n2->index);
00395 assert(index == m2->index);
00396 assert(m1->reachable == m2->reachable);
00397
00398 reachable = m1->reachable;
00399
00400
00401
00402
00403 { vector d = position - n2->position;
00404
00405 if(d.length() < RANGE) {
00406 #ifdef SANITY_CHECKS
00407 if(TIME > 0.0 && m1->reachable == 0)
00408 assert(RANGE - d.length() < ROUND_ERROR);
00409 #endif
00410 m1->reachable = m2->reachable = 1;
00411 }
00412
00413 else {
00414 #ifdef SANITY_CHECKS
00415 if(TIME > 0.0 && m1->reachable == 1)
00416 assert(d.length() - RANGE < ROUND_ERROR);
00417 #endif
00418 m1->reachable = m2->reachable = 0;
00419 }
00420 #ifdef DEBUG
00421 fprintf(stdout, "# %.6f (%d, %d) %.2fm\n",
00422 TIME, index, m1->index, d.length());
00423 #endif
00424 }
00425
00426
00427
00428
00429 v2 = n2->speed * n2->direction;
00430
00431 D = v2 - v1;
00432 B = n2->position - position;
00433
00434 a = (D.X * D.X) + (D.Y * D.Y) + (D.Z * D.Z);
00435 b = 2 * ((D.X * B.X) + (D.Y * B.Y) + (D.Z * B.Z));
00436 c = (B.X * B.X) + (B.Y * B.Y) + (B.Z * B.Z) - (RANGE * RANGE);
00437
00438 if(a == 0.0) {
00439
00440
00441
00442 m1->time_transition= 0.0;
00443 m2->time_transition= 0.0;
00444 goto next;
00445 }
00446
00447 Q = b * b - 4 * a * c;
00448 if(Q < 0.0) {
00449
00450
00451
00452 m1->time_transition = 0.0;
00453 m2->time_transition = 0.0;
00454 goto next;
00455 }
00456 Q = sqrt(Q);
00457
00458 t1 = (-b + Q) / (2 * a);
00459 t2 = (-b - Q) / (2 * a);
00460
00461
00462 if(t1 > 0.0 && t1 < ROUND_ERROR) t1 = 0.0;
00463 if(t1 < 0.0 && -t1 < ROUND_ERROR) t1 = 0.0;
00464 if(t2 > 0.0 && t2 < ROUND_ERROR) t2 = 0.0;
00465 if(t2 < 0.0 && -t2 < ROUND_ERROR) t2 = 0.0;
00466
00467 if(t1 < 0.0 && t2 < 0.0) {
00468
00469
00470
00471 m1->time_transition = 0.0;
00472 m2->time_transition = 0.0;
00473 goto next;
00474 }
00475
00476
00477
00478
00479 if((t1 == 0.0 && t2 > 0.0) || (t2 == 0.0 && t1 > 0.0)) {
00480 m1->reachable = m2->reachable = 1;
00481 m1->time_transition = m2->time_transition = TIME + max(t1, t2);
00482 }
00483 else if((t1 == 0.0 && t2 < 0.0) || (t2 == 0.0 && t1 < 0.0)) {
00484 m1->reachable = m2->reachable = 0;
00485 m1->time_transition = m2->time_transition = 0.0;
00486 }
00487
00488
00489
00490
00491 else if(t1 > 0.0 && t2 > 0.0) {
00492 m1->time_transition = TIME + min(t1, t2);
00493 m2->time_transition = TIME + min(t1, t2);
00494 }
00495 else if(t1 > 0.0) {
00496 m1->time_transition = TIME + t1;
00497 m2->time_transition = TIME + t1;
00498 }
00499 else {
00500 m1->time_transition = TIME + t2;
00501 m2->time_transition = TIME + t2;
00502 }
00503
00504
00505
00506
00507 if(time_transition == 0.0 || (m1->time_transition &&
00508 time_transition > m1->time_transition)) {
00509 time_transition = m1->time_transition;
00510 }
00511 if(n2->time_transition == 0.0 || (m2->time_transition &&
00512 n2->time_transition > m2->time_transition)) {
00513 n2->time_transition = m2->time_transition;
00514 }
00515 next:
00516 if(reachable != m1->reachable && TIME > 0.0) {
00517 LinkChangeCount++;
00518 link_changes++;
00519 n2->link_changes++;
00520 }
00521 }
00522 }
00523
00524 void
00525 Node::Dump()
00526 {
00527 Neighbor *m;
00528 u_int32_t i;
00529
00530 fprintf(stdout,
00531 "Node: %d\tpos: (%.2f, %.2f, %.2f) dst: (%.2f, %.2f, %.2f)\n",
00532 index, position.X, position.Y, position.Z,
00533 destination.X, destination.Y, destination.Z);
00534 fprintf(stdout, "\tdir: (%.2f, %.2f, %.2f) speed: %.2f\n",
00535 direction.X, direction.Y, direction.Z, speed);
00536 fprintf(stdout, "\tArrival: %.2f, Update: %.2f, Transition: %.2f\n",
00537 time_arrival, time_update, time_transition);
00538
00539 for(i = 0; i < NODES; i++) {
00540 m = &neighbor[i];
00541 fprintf(stdout, "\tNeighbor: %d (%x), Reachable: %d, Transition Time: %.2f\n",
00542 m->index, (int) m, m->reachable, m->time_transition);
00543 }
00544 }
00545
00546
00547
00548
00549
00550 void dumpall()
00551 {
00552 u_int32_t i;
00553
00554 fprintf(stdout, "\nTime: %.2f\n", TIME);
00555
00556 for(i = 0; i < NODES; i++) {
00557 NodeList[i].Dump();
00558 }
00559 }
00560
00561 void
00562 ComputeW()
00563 {
00564 u_int32_t i, j;
00565 u_int32_t *W = D2;
00566
00567 memset(W, '\xff', sizeof(int) * NODES * NODES);
00568
00569 for(i = 0; i < NODES; i++) {
00570 for(j = i; j < NODES; j++) {
00571 Neighbor *m = &NodeList[i].neighbor[j];
00572 if(i == j)
00573 W[i*NODES + j] = W[j*NODES + i] = 0;
00574 else
00575 W[i*NODES + j] = W[j*NODES + i] = m->reachable ? 1 : INFINITY;
00576 }
00577 }
00578 }
00579
00580 void
00581 floyd_warshall()
00582 {
00583 u_int32_t i, j, k;
00584
00585 ComputeW();
00586
00587 for(i = 0; i < NODES; i++) {
00588 for(j = 0; j < NODES; j++) {
00589 for(k = 0; k < NODES; k++) {
00590 D2[j*NODES + k] = min(D2[j*NODES + k], D2[j*NODES + i] + D2[i*NODES + k]);
00591 }
00592 }
00593 }
00594
00595 #ifdef SANITY_CHECKS
00596 for(i = 0; i < NODES; i++)
00597 for(j = 0; j < NODES; j++) {
00598 assert(D2[i*NODES + j] == D2[j*NODES + i]);
00599 assert(D2[i*NODES + j] <= INFINITY);
00600 }
00601 #endif
00602 }
00603
00604
00605
00606
00607
00608 void
00609 show_diffs()
00610 {
00611 u_int32_t i, j;
00612
00613 for(i = 0; i < NODES; i++) {
00614 for(j = i + 1; j < NODES; j++) {
00615 if(D1[i*NODES + j] != D2[i*NODES + j]) {
00616
00617 if(D2[i*NODES + j] == INFINITY)
00618 DestUnreachableCount++;
00619
00620 if(TIME > 0.0) {
00621 RouteChangeCount++;
00622 NodeList[i].route_changes++;
00623 NodeList[j].route_changes++;
00624 }
00625
00626 if(TIME == 0.0) {
00627 fprintf(stdout, GOD_FORMAT2,
00628 i, j, D2[i*NODES + j]);
00629 #ifdef SHOW_SYMMETRIC_PAIRS
00630 fprintf(stdout, GOD_FORMAT2,
00631 j, i, D2[j*NODES + i]);
00632 #endif
00633 }
00634 else {
00635 fprintf(stdout, GOD_FORMAT,
00636 TIME, i, j, D2[i*NODES + j]);
00637 #ifdef SHOW_SYMMETRIC_PAIRS
00638 fprintf(stdout, GOD_FORMAT,
00639 TIME, j, i, D2[j*NODES + i]);
00640 #endif
00641 }
00642 }
00643 }
00644 }
00645
00646 memcpy(D1, D2, sizeof(int) * NODES * NODES);
00647 }
00648
00649
00650 void
00651 show_routes()
00652 {
00653 u_int32_t i, j;
00654
00655 fprintf(stdout, "#\n# TIME: %.12f\n#\n", TIME);
00656 for(i = 0; i < NODES; i++) {
00657 fprintf(stdout, "# %2d) ", i);
00658 for(j = 0; j < NODES; j++)
00659 fprintf(stdout, "%3d ", D2[i*NODES + j] & 0xff);
00660 fprintf(stdout, "\n");
00661 }
00662 fprintf(stdout, "#\n");
00663 }
00664
00665 void
00666 show_counters()
00667 {
00668 u_int32_t i;
00669
00670 fprintf(stdout, "#\n# Destination Unreachables: %d\n#\n",
00671 DestUnreachableCount);
00672 fprintf(stdout, "# Route Changes: %d\n#\n", RouteChangeCount);
00673 fprintf(stdout, "# Link Changes: %d\n#\n", LinkChangeCount);
00674 fprintf(stdout, "# Node | Route Changes | Link Changes\n");
00675 for(i = 0; i < NODES; i++)
00676 fprintf(stdout, "# %4d | %4d | %4d\n",
00677 i, NodeList[i].route_changes,
00678 NodeList[i].link_changes);
00679 fprintf(stdout, "#\n");
00680 }
00681