/* Simulation of the VANET for CPSC 601.08 Assignment 2 */ /* */ /* Written by Carey Williamson, University of Calgary */ /* */ /* Usage: gcc -o hiway hiway.c -lm */ /* ./hiway */ #include #include #include /* use man 3 log for the math functions */ #define NUM_CARS 1000 /* Number of cars to simulate */ #define LAMBDA 0.1 /* Arrival rate of new cars per second */ #define VELOCITY_MIN 60.0 /* Lowest speed permitted (km/hr) */ #define VELOCITY_MAX 100.0 /* Highest speed permitted (km/hr) */ #define VELOCITY_RANGE (VELOCITY_MAX - VELOCITY_MIN) #define DISTANCE 100.0 /* Length of highway (km) */ #define ACCELERATION 1.0 /* Velocity change permitted (km/hr) */ #define SAFETY_MARGIN 0.05 /* Safety gap between cars (km) */ /* Simulation parameters */ #define TIME_STEP 1.0 /* Granularity for time-stepped model (sec) */ #define END_TIME 7200.0 /* Simulation duration in seconds */ /* Debugging output */ /* #define DEBUG 1 */ #define FLAG 1 /* Flag the tailgaters in the output stream */ /* #define REPORT 1 /* Report inter-car gaps in column 2 for analysis */ /***********************************************************************/ /* RANDOM NUMBER GENERATION STUFF */ /***********************************************************************/ /* Parameters for random number generation. */ #define MAX_INT 2147483647 /* Maximum positive integer 2^31 - 1 */ /* Generate a random floating point value uniformly distributed in [0,1] */ float Uniform01() { float randnum; /* get a random positive integer from random() */ randnum = (float) 1.0 * random(); /* divide by max int to get something in 0..1 */ randnum = (float) randnum / (1.0 * MAX_INT); return( randnum ); } /* Generate a random floating point number from an exponential */ /* distribution with mean mu. */ float Exponential(mu) float mu; { float randnum, ans; randnum = Uniform01(); ans = -(mu) * log(randnum); return( ans ); } /***********************************************************************/ /* MAIN PROGRAM */ /***********************************************************************/ int main() { int i, arrivals, departures, active; float now, nextarrival; float speed, time, distance, gap; float atimes[NUM_CARS], velocity[NUM_CARS], location[NUM_CARS]; /* Initialization */ arrivals = 0; departures = 0; active = 0; now = 0.0; srandom(12753); nextarrival = now + Exponential(1.0 / LAMBDA); while( now < END_TIME ) { /* check for car arrivals in the next interval */ while( nextarrival <= now + TIME_STEP ) { #ifdef DEBUG printf("Car %d arrives at time %8.6f\n", arrivals, nextarrival); #endif atimes[arrivals] = nextarrival; location[arrivals] = 0.0; velocity[arrivals] = VELOCITY_MIN; velocity[arrivals] += Uniform01() * VELOCITY_RANGE; #ifdef DEBUG printf("Car %d has velocity %4.1f km/hr\n", arrivals, velocity[arrivals]); #endif arrivals++; active++; /* schedule next car arrival */ nextarrival += Exponential(1.0 / LAMBDA); /* safety check */ if( arrivals >= NUM_CARS ) { printf("Too many cars to handle!\n"); return; } } /* advance simulation time forward */ now += TIME_STEP; #ifdef DEBUG printf("Advancing simulation time to %8.6f\n", now); #endif /* update locations of all the active cars */ for( i = 0; i < arrivals; i++ ) { if( location[i] > DISTANCE ) continue; speed = velocity[i]; if( now - atimes[i] < TIME_STEP ) time = now - atimes[i]; else time = TIME_STEP; distance = speed * time / 3600.0; location[i] += distance; #ifdef DEBUG printf("Car %d moved %8.6f km to location %8.6f\n", i, distance, location[i]); #endif if( location[i] > DISTANCE ) { departures++; active--; #ifdef DEBUG printf("Car %d is all done now\n", i); #endif } else { /* adjust velocity for next interval */ if( Uniform01() < 0.5 ) { /* speed up a bit */ velocity[i] += Uniform01() * ACCELERATION; #ifdef DEBUG2 printf("Possible accel of car %d to %4.1f km/hr\n", i, velocity[i]); #endif } else { /* slow down a bit */ velocity[i] -= Uniform01() * ACCELERATION; #ifdef DEBUG2 printf("Possible decel of car %d to %4.1f km/hr\n", i, velocity[i]); #endif } if( velocity[i] < VELOCITY_MIN ) velocity[i] = VELOCITY_MIN; if( velocity[i] > VELOCITY_MAX ) velocity[i] = VELOCITY_MAX; #ifdef DEBUG printf("Adjusting velocity of car %d to %4.1f km/hr\n", i, velocity[i]); #endif /* safety check for gap between cars */ if( i > 0 ) { gap = location[i-1] - location[i]; if( gap < SAFETY_MARGIN ) { #ifdef DEBUG printf("*** Car %d is within %8.6f of car %d\n", i, gap, i-1); #endif if( velocity[i] > velocity[i-1] ) { velocity[i] = velocity[i-1]; #ifdef DEBUG printf("Slowing velocity of car %d to %4.1f km/hr\n", i, velocity[i]); #endif } } } } } } printf("\n"); printf("Highway Simulation: D %4.1f LAMBDA %3.1f V_MIN %4.1f V_MAX %4.1f\n", DISTANCE, LAMBDA, VELOCITY_MIN, VELOCITY_MAX); printf("Number of cars: %d\n", NUM_CARS); printf("Time: %8.6f Arrivals: %d Departures: %d In system: %d\n", now, arrivals, departures, active); /* report positions of cars */ printf("\nRelative Locations of %d active cars:\n", active); for( i = arrivals - 1; i >= 0; i-- ) { if( location[i] < DISTANCE ) { printf("%8.6f ", location[i]); /* flag the bumper to bumper cases visually */ if( i > 0 ) { gap = location[i-1] - location[i]; #ifdef REPORT printf("%8.6f\n", gap); #endif #ifdef FLAG if( gap < SAFETY_MARGIN ) { printf("%8.6f *\n", gap); } else printf("%8.6f\n", gap); #endif } } } printf("\n"); }