Emanuel Kuflik / Mbed OS smat_controller

Dependencies:   MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers simulator.cpp Source File

simulator.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  */
00005 
00006 #include "mbed.h"
00007 #include <cctype>
00008 #include "AccCar.h"
00009 #include "Road.h"
00010 #include "mqtt.h"
00011 
00012 #define MAGIC_NUMBER 2
00013 
00014 //#define SIM_DEBUG
00015 #define SIM_TAG "[SIM] "
00016 
00017 Serial pc(USBTX, USBRX);
00018 
00019 // prints statistics
00020 static void print_wait_time(Road* road)
00021 {
00022     int active_cars = road->get_active_cars();
00023     for( int i = 0; i < active_cars; i++)
00024     {
00025             AccCar* car = road->get_car(i);
00026             assert(car != NULL);
00027             pc.printf(SIM_TAG "Car %d Road %d wait_time %d"DELIM, i,road->get_road_id(), car->wait_time); 
00028     }
00029 }
00030 
00031 // handles adding a new car safely to the intersection
00032 static void add_new_car(Road* road,int* cycles,mqtt* mqtt_singleton)
00033 {
00034         // get rand speed
00035         int temp_speed = rand() %11;
00036         temp_speed += 5;
00037             
00038         // 
00039         assert( temp_speed >=5 && temp_speed <= 15);
00040         
00041         if(road->can_car_enter( temp_speed ))
00042         {
00043             *cycles = 0; // we added a car reset our timer
00044             
00045             int id = road->get_new_car_id();
00046             
00047             AccCar* car = new AccCar(id, road, (1 << id),mqtt_singleton );
00048             assert(car != NULL);
00049             
00050 #ifdef SIM_DEBUG
00051             pc.printf(SIM_TAG "adding new car to road %d car %d"DELIM,road->get_road_id(),id);
00052 #endif
00053 
00054             road->add_acc_car(car);
00055             
00056             AccCar* forward_car = road->get_forward_car(id);
00057             
00058             // lead car will get a null pointer
00059             car->set_forward_car( forward_car ); 
00060             
00061             // this needs to be a rand number [0,15]
00062             car->reset(temp_speed);
00063             
00064         }
00065 }
00066 
00067 void print_positions(Road* road)
00068 {
00069 //#ifdef SIM_DEBUG
00070             pc.printf(SIM_TAG " -------------- "DELIM);
00071 //#endif  
00072     int active_cars = road->get_active_cars();
00073     for( int i = 0; i < active_cars; i++)
00074     {
00075             AccCar* car = road->get_car(i);
00076             assert(car != NULL);
00077             pc.printf(SIM_TAG "Car %d Road %d position %d speed %d target %d cycles %d car_cycles %d "DELIM, i,road->get_road_id(), car->position,car->speed,car->get_target_speed(),road->get_road_clock(), car->get_cycles()); 
00078     }
00079 //#ifdef SIM_DEBUG
00080             pc.printf(SIM_TAG " -------------- "DELIM);
00081 //#endif 
00082 }
00083 
00084 
00085 int start_simulation(mqtt* mqtt_singleton)
00086 {   
00087     // ------------------------------------------------------------------------------
00088     // The following three variables are used for timing statistics, do not modify them
00089     Timer stopwatch;    // A timer to keep track of how long the updates take, for statistics purposes
00090     int numberCycles = 0;
00091     int totalUpdateTime = 0;
00092     
00093     // every 3 cycles we need to add a new car
00094     int new_car_cycles = 0;
00095 
00096     // ------------------------------------------------------------------------------
00097     // seed rand number generator
00098     //srand(mqtt_singleton->mqtt_id);
00099     
00100     // make new road based off of ID
00101     Road* road = new Road(mqtt_singleton->mqtt_id, mqtt_singleton);
00102         
00103     // add first cars to the road to kick everything off
00104     add_new_car(road,&new_car_cycles,mqtt_singleton);
00105     
00106     stopwatch.start();
00107     
00108     stopwatch.reset();
00109     
00110     int other_simulating;
00111     int simulating; 
00112     
00113     // 
00114     //road->synchronize(simulating);
00115     
00116     do {
00117         
00118         // if we get a random number thats right OR if we hit our max of 3
00119         // then add a new car
00120         if( (rand() %3) == MAGIC_NUMBER || new_car_cycles >= 3)
00121         {
00122             // add new car to road and then set the forward car to it
00123             add_new_car(road,&new_car_cycles,mqtt_singleton);  
00124         }
00125         
00126         //
00127         road->let_cars_update();
00128         
00129         //
00130         road->wait_for_car_update();
00131     
00132         // are we still simulating? true if yes
00133         simulating = road->simulating();
00134 
00135 #ifndef PUBLISH_ONLY
00136         // is the other road still simulating? true if yes
00137         other_simulating = road->synchronize(simulating);
00138 #endif           
00139 
00140         // ------------------------------------------------------------------
00141         // Timing statistics logic, do not modify
00142         totalUpdateTime += stopwatch.read_ms();
00143         numberCycles++;
00144         new_car_cycles++;
00145         stopwatch.reset();
00146         // ------------------------------------------------------------------
00147         
00148         print_positions(road);
00149 
00150 #ifndef PUBLISH_ONLY
00151     // TODO figure out how to end simulation like they want
00152     } while (other_simulating || simulating); 
00153 #else
00154     } while (simulating);
00155 #endif
00156     // ----------------------------------------------------------------------
00157     // Timing statistics printout, do not modify
00158     pc.printf(SIM_TAG "Average update cycle took: %fms "DELIM, (totalUpdateTime*1.0)/(numberCycles*1.0));
00159     totalUpdateTime = 0;
00160     numberCycles = 0;
00161     
00162     // print wait times
00163     print_wait_time(road);
00164     
00165     // ----------------------------------------------------------------------
00166     road->DESTROY_ALL_CARS();
00167     road->free_msg();
00168     delete road;
00169     return 0;
00170 }
00171