541 smart traffic controller

Dependencies:   MQTT

Files at this revision

API Documentation at this revision

Comitter:
micallef25
Date:
Thu Dec 12 17:25:27 2019 +0000
Parent:
6:6cb13ac483e0
Commit message:
stable, passed 1000 simulation regression

Changed in this revision

AccCar.cpp Show annotated file Show diff for this revision Revisions of this file
AccCar.h Show annotated file Show diff for this revision Revisions of this file
Road.cpp Show annotated file Show diff for this revision Revisions of this file
Road.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mqtt.cpp Show annotated file Show diff for this revision Revisions of this file
mqtt.h Show annotated file Show diff for this revision Revisions of this file
simulator.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/AccCar.cpp	Wed Dec 11 20:12:21 2019 +0000
+++ b/AccCar.cpp	Thu Dec 12 17:25:27 2019 +0000
@@ -11,7 +11,7 @@
 
 //#define DEBUG_ACC
 #define ACC_TAG "[ACC] "
-
+#define ERROR_TAG "[ERROR] "
 // speed for a legal stop
 #define STOPPED_SPEED 0
 
@@ -68,7 +68,11 @@
             int diff = forward_car->position - position;
             int maxSafeSpeed = diff - SAFETY_GAP;
             speed = std::min(maxSafeSpeed, target_speed);
+            //if(speed < 0)
+           // {
+             //   printf(ERROR_TAG"f_pos %d pos %d id %d"DELIM,forward_car->position,position,car_id);
             assert(speed >= 0);
+            //}
         }   else {
             speed = target_speed;
         }
@@ -89,6 +93,24 @@
     this->target_speed = temp_speed;
 }
 
+/*
+* assuming the car has some way to see a stop sign
+* will kick in until a position message with the right ID comes
+* which is not implemented
+*/
+int AccCar::enter_safety_mode()
+{
+    int old_position = position;
+    // using previous speed
+    int next_position = position + speed;
+    if( old_position < 54 && next_position >= 54 ) 
+    {
+        // return new speed 0 or 
+        return 54 - position;
+    }
+    return speed;  
+}
+
 // update FSM 
 void AccCar::update()
 {
@@ -105,25 +127,28 @@
             if(c_msg == NULL)
             {
                 // test if we actually have a large delay
-                assert(c_msg != NULL);
-                //speed = enter_safety_mode();
+               assert(c_msg != NULL);
+               speed = enter_safety_mode();
             }
             else{
             //
             // do something with the control message
                 assert(c_msg->car_id == car_id );
-                speed = c_msg->speed;
-            
-                //
-                if(speed == 0)
-                {
-                    state = STOPPED_STATE;    
+                if(c_msg->speed > speed){
+                    printf(ERROR_TAG" msg speed %d , speed %d car %d"DELIM,c_msg->speed,speed, car_id);
                 }
-                else
-                {
-                    state = NORMAL_STATE;   
+                
+                else{
+                    // add wait time if we got 0 or something less than our sent speed
+                    if(speed == 0 || c_msg->speed < speed)
+                    {
+                        wait_time++;
+                        printf(ACC_TAG"car %d has waited %d"DELIM,car_id,wait_time);
+                    }
+                    speed = c_msg->speed;
                 }
                 
+                
                 //  
                 delete c_msg;
             }
@@ -132,9 +157,13 @@
 
         position = position + speed;
         
-        // ensure correctness 
-        assert(position <= this->forward_car->position - 2);
-        
+        // ensure correctness
+        if(!lead){
+            //if(position >= this->forward_car->position - 2){
+              //  printf(ERROR_TAG"position %d forward pos %d id %d speed %d"DELIM,position,this->forward_car->position, car_id,speed);
+                assert(position <= this->forward_car->position - 2);    
+           // }
+        }
         
         if( (cycles % 5) == 0)
         {
@@ -146,10 +175,6 @@
         {
             drive_normal();
         }
-        else if( state == STOPPED_STATE )
-        {
-            wait_time++;    
-        }
         else
         {   
             // case should not happen
@@ -170,20 +195,6 @@
         // stuff a message in the queue
         this->singleton->add_to_position_queue(msg);
         
-//#ifndef PUBLISH_ONLY       
-//        //
-//        // get_control message may need to malloc the message or something
-//        control_msg_t* c_msg = this->singleton->get_control_msg(this->car_id);
-//        
-//        //
-//        // do something with the control message
-//        assert(c_msg->car_id == car_id );
-//        speed = c_msg->speed;
-//    
-//        //
-//        // delete the control message
-//        delete c_msg;
-//#endif
         // set flag for completion of cycle
         road->done_flags.set(this->flag);
     }
@@ -221,7 +232,7 @@
 // and stop or update speed accordingly
 void AccCar::drive_normal()
 {
-    assert( state == NORMAL_STATE );
+    //assert( state == NORMAL_STATE );
     // first update our speed
     if( !lead ) 
     {
@@ -241,3 +252,8 @@
 {
     return cycles;
 }
+
+int AccCar::get_target_speed()
+{
+    return target_speed;
+}
--- a/AccCar.h	Wed Dec 11 20:12:21 2019 +0000
+++ b/AccCar.h	Thu Dec 12 17:25:27 2019 +0000
@@ -38,6 +38,7 @@
     
     int get_cycles();
     
+    int get_target_speed();
 protected:
     int car_id;
     int target_speed;
@@ -66,6 +67,8 @@
     
     //
     void make_position_msg(position_msg_t* msg);
+    
+    int enter_safety_mode();
 
 };
 #endif
--- a/Road.cpp	Wed Dec 11 20:12:21 2019 +0000
+++ b/Road.cpp	Thu Dec 12 17:25:27 2019 +0000
@@ -14,7 +14,6 @@
     this->active_cars = 0;
     this->active_car_bits = 0x00;
     this->road_clock = 0;
-    this->msg = new road_msg;
     // clear out our pointer table
     for (int i = 0; i < MAX_CARS_ON_ROAD; ++i)
     {
@@ -108,16 +107,16 @@
 bool Road::simulating()
 {
     if(active_cars != MAX_CARS_ON_ROAD )
-        return true;
+        return 1;
     
     else
     {
         AccCar* car = car_table[active_cars-1];
         assert( car != NULL );
         if(car->position > ROADLENGTH) // TODO use macro 
-            return false; 
+            return 0; 
     }
-    return true;
+    return 1;
 }
 
 // typical getter functions
@@ -136,26 +135,34 @@
     return car_table[active_cars-1];    
 }
 
-bool Road::synchronize(bool simulating)
+int Road::synchronize(int simulating)
 {
-#ifdef ROAD_DEBUG
-            road_pc.printf(ROAD_TAG "synchronizing  cycle %d complete=%d ..."DELIM, road_clock,simulating);
-#endif 
+//#ifdef ROAD_DEBUG
+//            road_pc.printf(ROAD_TAG "synchronizing  cycle %d complete=%d ..."DELIM, road_clock,simulating);
+//#endif 
+        road_msg_t* msg = new road_msg_t;
+        msg->road_id = road_id;
+        msg->simulating = simulating;
+        msg->road_clock = road_clock;
+        this->singleton->add_to_road_to_network_queue(msg);     
 
-        this->msg->road_id = road_id;
-        this->msg->simulating = simulating;
-        this->msg->road_clock = road_clock;
-        this->singleton->add_to_road_to_network_queue(this->msg);     
-    
+   
         //
         road_msg_t* rmsg = this->singleton->get_network_to_road_msg();
-        bool rc = rmsg->simulating;
-        assert(rmsg->road_clock == road_clock);
+        int rc = rmsg->simulating;
         
 #ifdef ROAD_DEBUG
-            road_pc.printf(ROAD_TAG "clock %d id %d sync complete rc=%d"DELIM,rmsg->road_clock,rmsg->road_id,rmsg->simulating);
+            road_pc.printf(ROAD_TAG "my id %d rcvd id %d"DELIM, road_clock, rmsg->road_clock);
 #endif 
+            assert(rmsg->road_clock == road_clock);
+        
     delete rmsg;
     return rc;
 }
-
+void Road::free_msg()
+{  
+    // wait for any last emssages then clean up for next iter
+    ThisThread::sleep_for(1000);
+    this->singleton->clear_queues(); 
+    return;   
+}
--- a/Road.h	Wed Dec 11 20:12:21 2019 +0000
+++ b/Road.h	Thu Dec 12 17:25:27 2019 +0000
@@ -44,9 +44,9 @@
         
     AccCar* get_last_car();
     
-    bool synchronize(bool simulating);
+    int synchronize(int simulating);
     
-    road_msg_t* msg;
+    void free_msg();
     
 private: 
     // for sharing intersections
@@ -65,5 +65,8 @@
     
     //
     int road_clock;
+    
+    //
+    road_msg_t* msg;
 };
 #endif
--- a/main.cpp	Wed Dec 11 20:12:21 2019 +0000
+++ b/main.cpp	Thu Dec 12 17:25:27 2019 +0000
@@ -15,7 +15,11 @@
     
     // setup callbacks and mqtt and wifi connection
     mqtt::instance()->setup_network();
-
+    
+    // wait for partner 
+    ThisThread::sleep_for(2000);
+    
+    
 for(int i = 0; i < REGRESSIONS; i++)
 {
     printf("starting simulation... %d\r\n",i);
--- a/mqtt.cpp	Wed Dec 11 20:12:21 2019 +0000
+++ b/mqtt.cpp	Thu Dec 12 17:25:27 2019 +0000
@@ -146,7 +146,7 @@
     if( msg->road_id != mqtt::instance()->mqtt_id )
     {
 #ifdef DEBUG_MQTT  
-    mqtt_pc.printf(MQTT_TAG"rcvd road %d "DELIM,msg->road_id);
+    mqtt_pc.printf(MQTT_TAG"rcvd road %d "DELIM,msg->road_clock);
 #endif
         // add our message to the queue no fucking clue what happens internally to
         // the message memory thanks mbed os 5 documentation
@@ -169,19 +169,17 @@
 {
     assert(msg != NULL && client != NULL);
     
-//    MQTT::Message message;
-    
 #ifdef DEBUG_MQTT
     mqtt_pc.printf(MQTT_TAG"sending position msg %d "DELIM,msg->road_id);
 #endif
+    
+    MQTT::Message tmessage;
 
-    // might be safest to memcopy this? but well if shit breaks then well fix
-//    memcpy(message.payload,msg,sizeof(position_msg_t));
-    message.payload = (void*)msg;
-    message.payloadlen = sizeof(position_msg_t); 
-    message.qos = MQTT::QOS1;
+    tmessage.payload = (void*)msg;
+    tmessage.payloadlen = sizeof(position_msg_t); 
+    tmessage.qos = MQTT::QOS1;
 
-    int rc = client->publish(POSITION_TOPIC,message);
+    int rc = client->publish(POSITION_TOPIC,tmessage);
     assert(rc == 0);  
 
     return 0;
@@ -191,19 +189,16 @@
 {
     assert(msg != NULL && client != NULL);
     
-//    MQTT::Message message;
-    
 #ifdef DEBUG_MQTT
-    mqtt_pc.printf(MQTT_TAG"sending road msg %d "DELIM,msg->road_id);
+    mqtt_pc.printf(MQTT_TAG"sending road msg %d "DELIM,msg->road_clock);
 #endif
+    MQTT::Message tmessage;
 
-    // might be safest to memcopy thius seems to work
-    //memcpy(message.payload,msg,sizeof(position_msg_t));
-    message.payload = (void*)msg;
-    message.payloadlen = sizeof(road_msg_t); 
-    message.qos = MQTT::QOS1;
+    tmessage.payload = (void*)msg;
+    tmessage.payloadlen = sizeof(road_msg_t); 
+    tmessage.qos = MQTT::QOS1;
 
-    int rc = client->publish(ROAD_TOPIC,message);
+    int rc = client->publish(ROAD_TOPIC,tmessage);
     assert(rc == 0);  
     
     return 0;
@@ -234,7 +229,7 @@
     
     // make a road based of mqtt id
     mqtt_id = 0;
-    if(strcmp(wifi->get_mac_address(),"2c:3a:e8:0b:75:06") == 0){
+    if(strcmp(wifi->get_mac_address(),"2c:3a:e8:0b:8e:77") == 0){
         mqtt_id = 0;
     }
     else{
@@ -280,6 +275,7 @@
             road_msg_t *road_msg = (road_msg_t*)revt.value.p;
             assert(road_msg != NULL);
             send_road_msg(mqtt_message,road_msg);
+            delete road_msg;
         }
 
       client->yield(10);
@@ -317,4 +313,48 @@
     assert(thread != NULL);
     thread->start( callback(this,&mqtt::manage_network) );
     
+}
+
+// before the next run make sure
+// that everything is cleaned up properly
+// the control queue may have one entry due to 
+// the last iteration ending
+void mqtt::clear_queues()
+{
+    while(!position_queue.empty())
+    {
+        osEvent revt = position_queue.get();
+        assert(revt.status == osEventMessage);
+        //printf("cleaned up queue\n");
+            //
+        position_msg_t *msg = (position_msg_t*)revt.value.p;
+        delete msg;     
+    }
+    for(int i = 0; i < 5; i++)
+    {
+        while(!control_queue[i].empty())
+        {
+            osEvent revt = control_queue[i].get();
+            assert(revt.status == osEventMessage);
+            //printf("cleaned up control queue\n");
+            //
+            control_msg_t *msg = (control_msg_t*)revt.value.p;
+            delete msg;     
+        }  
+    }
+       
+    while(!network_to_road_queue.empty())
+    {
+        osEvent evt = network_to_road_queue.get();
+        assert(evt.status == osEventMessage);
+        road_msg_t *message = (road_msg_t*)evt.value.p;
+        delete message;     
+    }  
+    while(!road_to_network_queue.empty())
+    {
+        osEvent evt = road_to_network_queue.get();
+        assert(evt.status == osEventMessage);
+        road_msg_t *message = (road_msg_t*)evt.value.p;
+        delete message;     
+    }  
 }
\ No newline at end of file
--- a/mqtt.h	Wed Dec 11 20:12:21 2019 +0000
+++ b/mqtt.h	Thu Dec 12 17:25:27 2019 +0000
@@ -17,8 +17,8 @@
 #define DELIM "\n"
 #endif
 
-#define PUBLISH_ONLY
-
+//#define PUBLISH_ONLY
+//#define SAFE_CRITICAL
 enum drive_state_t{
  NORMAL_STATE = 0,
  STOPPED_STATE,
@@ -37,7 +37,7 @@
 typedef struct road_msg{
     int road_id;
     int road_clock;
-    bool simulating;
+    int simulating;
 }road_msg_t;
 
 typedef struct control_msg{
@@ -71,16 +71,16 @@
     Thread* thread;
     
     // queue for sending position msessages
-    Queue<position_msg_t, 5> position_queue;
+    Queue<position_msg_t, 15> position_queue;
     
     // queue for sending road msessages
-    Queue<road_msg_t, 1> road_to_network_queue;
+    Queue<road_msg_t, 3> road_to_network_queue;
     
     // queue for sending road msessages
-    Queue<road_msg_t, 1> network_to_road_queue;
+    Queue<road_msg_t, 3> network_to_road_queue;
     
     // queue for control message passsing between mqtt and car threads
-    Queue<control_msg_t, 1> control_queue[MAX_CARS_ON_ROAD];
+    Queue<control_msg_t, 3> control_queue[MAX_CARS_ON_ROAD];
 
     
 public:
@@ -98,7 +98,7 @@
     // setup and tear down API's
     void setup_network();
     void shutdown_network();
-
+    void clear_queues();
     
     static mqtt *instance()
     {
@@ -110,37 +110,39 @@
     // adding to a queue to be sent on mqtt network
     inline void add_to_position_queue(position_msg_t* msg)
     {
-        position_queue.put(msg);
+        position_queue.put(msg,osWaitForever);
     }
     
     // adding to road queue to be sent on mqtt network
     inline void add_to_road_to_network_queue(road_msg_t* msg)
     {
-        road_to_network_queue.put(msg);
+        road_to_network_queue.put(msg,osWaitForever);
     }
     
     // adding to road queue to be sent on mqtt network
     inline void add_to_network_to_road_queue(road_msg_t* msg)
     {
-        network_to_road_queue.put(msg);
+        network_to_road_queue.put(msg,osWaitForever);
     }
     
 
     // adding to a queue to be sent on mqtt network
     inline void add_to_control_queue(int car_id,control_msg_t* msg)
     {
-        control_queue[car_id].put(msg);
+        control_queue[car_id].put(msg,osWaitForever);
     }
     
     // adding to a queue to be sent on mqtt network
     inline control_msg_t* get_control_msg(int car_id)
     {
         // handle the case if no message was received in time
+#ifdef SAFETY_CRITICAL
         if(control_queue[car_id].empty())
         {
             return NULL;   
         }
-        osEvent evt = control_queue[car_id].get();
+#endif
+        osEvent evt = control_queue[car_id].get(osWaitForever);
         assert(evt.status == osEventMessage);
         control_msg_t *message = (control_msg_t*)evt.value.p;
         return message;
@@ -151,7 +153,7 @@
     inline road_msg_t* get_network_to_road_msg()
     {
         // get message from queue
-        osEvent evt = network_to_road_queue.get();
+        osEvent evt = network_to_road_queue.get(osWaitForever);
         assert(evt.status == osEventMessage);
         road_msg_t *message = (road_msg_t*)evt.value.p;
         // we handle ignoring messages in callback
--- a/simulator.cpp	Wed Dec 11 20:12:21 2019 +0000
+++ b/simulator.cpp	Thu Dec 12 17:25:27 2019 +0000
@@ -11,7 +11,7 @@
 
 #define MAGIC_NUMBER 2
 
-#define SIM_DEBUG
+//#define SIM_DEBUG
 #define SIM_TAG "[SIM] "
 
 Serial pc(USBTX, USBRX);
@@ -74,7 +74,7 @@
     {
             AccCar* car = road->get_car(i);
             assert(car != NULL);
-            pc.printf(SIM_TAG "Car %d Road %d position %d : speed %d cycles: %d car_cycles %d "DELIM, i,road->get_road_id(), car->position,car->speed, road->get_road_clock(), car->get_cycles()); 
+            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()); 
     }
 //#ifdef SIM_DEBUG
             pc.printf(SIM_TAG " -------------- "DELIM);
@@ -95,7 +95,7 @@
 
     // ------------------------------------------------------------------------------
     // seed rand number generator
-    srand(mqtt_singleton->mqtt_id);
+    //srand(mqtt_singleton->mqtt_id);
     
     // make new road based off of ID
     Road* road = new Road(mqtt_singleton->mqtt_id, mqtt_singleton);
@@ -107,8 +107,8 @@
     
     stopwatch.reset();
     
-    bool other_simulating=false;
-    bool simulating = true; 
+    int other_simulating;
+    int simulating; 
     
     // 
     //road->synchronize(simulating);
@@ -164,7 +164,7 @@
     
     // ----------------------------------------------------------------------
     road->DESTROY_ALL_CARS();
-    delete road->msg;
+    road->free_msg();
     delete road;
     return 0;
 }