Emanuel Kuflik / Mbed OS smat_controller

Dependencies:   MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Road.cpp Source File

Road.cpp

00001 #include "Road.h"
00002 #include "mbed.h"
00003 
00004 #define ROADLENGTH 100
00005 #define ROAD_TAG "[ROAD] "
00006 //#define ROAD_DEBUG 
00007 
00008 Serial road_pc (USBTX, USBRX);
00009 
00010 Road::Road(int id, mqtt* mqtt_singleton) 
00011 {    
00012     this->road_id = id;
00013     this->singleton = mqtt_singleton;
00014     this->active_cars = 0;
00015     this->active_car_bits = 0x00;
00016     this->road_clock = 0;
00017     // clear out our pointer table
00018     for (int i = 0; i < MAX_CARS_ON_ROAD; ++i)
00019     {
00020         this->car_table[i] = NULL;
00021     }
00022 }
00023  
00024 void Road::add_acc_car(AccCar* car) {
00025     
00026     // make sure all is well on the road
00027     assert( active_cars < MAX_CARS_ON_ROAD );
00028     
00029     car_table[active_cars] = car; 
00030        
00031     // no need to lock as main thread is only callee
00032     active_car_bits = active_car_bits | car->flag;
00033     active_cars++;
00034 }
00035  
00036 void Road::let_cars_update() {
00037     go_flags.set(active_car_bits);
00038     road_clock++;
00039 }
00040  
00041 void Road::wait_for_car_update() {
00042     done_flags.wait_all(active_car_bits);
00043 }
00044 
00045 bool Road::can_car_enter(int speed)
00046 {
00047     // if no cars on the road enter
00048     if(active_cars == 0)
00049         return true;
00050     
00051     // else make sure you have not exceed the max amount of cars and make sure you can safely enter
00052     // safely being that you maintain your safety gap with your speed
00053     AccCar* caboose = car_table[active_cars-1];
00054     assert( caboose != NULL);    
00055     if(active_cars < MAX_CARS_ON_ROAD && speed <= caboose->position - 2 ) // 2 is safety gap
00056     {
00057         return true;    
00058     }
00059     return false;
00060 }
00061 
00062 // whats the id of next car
00063 // used to set bit flags really
00064 int Road::get_new_car_id()
00065 {
00066     return active_cars;   
00067 }
00068 
00069 // how many active cars are there
00070 int Road::get_active_cars()
00071 {
00072     return active_cars;   
00073 }
00074 
00075 // get a car pointer based off some id
00076 AccCar* Road::get_car(int id)
00077 {
00078     assert(id < MAX_CARS_ON_ROAD);
00079     return car_table[id];    
00080 }
00081 
00082 // 0 is the lead car 
00083 // 1 is the second car and so on
00084 AccCar* Road::get_forward_car(int id)
00085 {
00086     // make sure we don't go out of bounds
00087     assert( id >= 0 && id <= MAX_CARS_ON_ROAD );
00088     if( id > 0 )
00089         return car_table[id-1];
00090     else
00091         return NULL;  // return null means there is no forward car 
00092 }  
00093 
00094 // manages any clean up
00095 void Road::DESTROY_ALL_CARS()
00096 {
00097     for( int i = 0; i < active_cars; i++)
00098     {
00099         AccCar* car = car_table[i];
00100         car->stop();
00101         delete car;
00102     }   
00103 }
00104 
00105 // dumb function to end simulation only returns true when we have 
00106 // 5 cars and the last car is passed 100 or road length
00107 bool Road::simulating()
00108 {
00109     if(active_cars != MAX_CARS_ON_ROAD )
00110         return 1;
00111     
00112     else
00113     {
00114         AccCar* car = car_table[active_cars-1];
00115         assert( car != NULL );
00116         if(car->position > ROADLENGTH) // TODO use macro 
00117             return 0; 
00118     }
00119     return 1;
00120 }
00121 
00122 // typical getter functions
00123 int Road::get_road_id()
00124 {
00125     return road_id;   
00126 }
00127 
00128 int Road::get_road_clock()
00129 {
00130     return road_clock;
00131 }
00132 
00133 AccCar* Road::get_last_car()
00134 {
00135     return car_table[active_cars-1];    
00136 }
00137 
00138 int Road::synchronize(int simulating)
00139 {
00140 //#ifdef ROAD_DEBUG
00141 //            road_pc.printf(ROAD_TAG "synchronizing  cycle %d complete=%d ..."DELIM, road_clock,simulating);
00142 //#endif 
00143         road_msg_t* msg = new road_msg_t;
00144         msg->road_id = road_id;
00145         msg->simulating = simulating;
00146         msg->road_clock = road_clock;
00147         this->singleton->add_to_road_to_network_queue(msg);     
00148 
00149    
00150         //
00151         road_msg_t* rmsg = this->singleton->get_network_to_road_msg();
00152         int rc = rmsg->simulating;
00153         
00154 #ifdef ROAD_DEBUG
00155             road_pc.printf(ROAD_TAG "my id %d rcvd id %d"DELIM, road_clock, rmsg->road_clock);
00156 #endif 
00157             assert(rmsg->road_clock == road_clock);
00158         
00159     delete rmsg;
00160     return rc;
00161 }
00162 void Road::free_msg()
00163 {  
00164     // wait for any last emssages then clean up for next iter
00165     ThisThread::sleep_for(1000);
00166     this->singleton->clear_queues(); 
00167     return;   
00168 }