Denver / Mbed 2 deprecated denver_train_proj

Dependencies:   mbed TextLCD

Revision:
60:a1b987ad45fb
Parent:
57:ee5da8a011e0
Child:
61:ecd2fc4a1a81
--- a/main.cpp	Thu Jun 21 15:39:05 2018 +0000
+++ b/main.cpp	Mon Jun 25 10:33:48 2018 +0000
@@ -4,9 +4,13 @@
 #include <string>
 #include <iostream>
 #include <vector>
+#include <fstream>
+#include <sstream>
 
 using namespace std;
 
+
+LocalFileSystem local("local");
  
 /******PINS AND DECLARATIONS*******/
 
@@ -99,6 +103,7 @@
 #define R_MEDIUM 5
 
 
+
 /**
 *
 *Position class.
@@ -383,6 +388,10 @@
 };
 
 
+
+
+
+
 //Creation of all the positions. One for every sensor on the table - Position name(mapping)
 Position d0(D0);
 Position d1(D1);
@@ -447,19 +456,131 @@
 *Using boolean constructor because position initialization will be done after initializing all position vectors.
 *DR_train = Dark Red train - LR_train = Light Red Train
 **/
-Train DR_train(DCCaddressDR,MEDIUM);
+Train DR_train(DCCaddressDR,FAST);
 Train LR_train(DCCaddressLR,MEDIUM);
 
 //possibility of an array having {dr_train, lr_train}? for reuse and modularity of functions
 
 
+//****** SYSTEM LOGGER FUNCTIONS ******//
+
 /**
-*Booleans that will determine if the train should be moving or not. 
-*Booleans will switch to false to stop any of the trains and avoid collisions.
-*DR_run - Boolean for DR_train / LR_run - Boolean for LR_train
+*
+*
+*
+**/
+string train_dir_toString(Train* train){
+ 
+    string dir_string;
+    
+    if(train->goes_cw()){
+        
+        dir_string = "cw";
+    }else{
+        
+        dir_string = "ccw";
+    }
+    return dir_string;
+}
+
+/**
+*
+*
+*
+**/
+string train_pos_toString(Train* train){
+    
+    int i = train->get_position_number();
+    std::string tr_pos;
+    std::stringstream ss;
+    
+    ss << i;    
+    tr_pos = ss.str();
+    
+    return tr_pos;
+}
+
+
+/**
+*
+*
+*
+**/
+void logger_add(string s){
+    
+    FILE *fp = fopen("/local/sys_log.txt", "a"); 
+    fprintf(fp, "%s \n", s); 
+    fclose(fp);
+    
+}
+
+
+/**
+*
+*
+*
 **/
-bool DR_run = true;
-bool LR_run = true;
+void init_logger(){
+    
+    FILE *fp = fopen("/local/sys_log.txt", "w"); 
+    
+    fprintf(fp, "Log for the main train program: \n"); 
+    fprintf(fp, "------------------------------- \n \n"); 
+    
+    fclose(fp);
+
+}
+
+/**
+*
+*
+*
+**/
+void train_pos0_log(){
+    
+    FILE *fp = fopen("/local/sys_log.txt", "a"); 
+    
+    fprintf(fp, "DR_train START: D%s sensor, %s direction. \n", train_pos_toString(&DR_train), train_dir_toString(&DR_train)); 
+    fprintf(fp, "LR_train START: D%s sensor, %s direction. \n \n", train_pos_toString(&LR_train), train_dir_toString(&LR_train)); 
+    
+    fprintf(fp, "..............Program Start................ \n");
+        
+    fclose(fp);
+
+}
+
+void print_next_sensors(Train* train){
+     
+    FILE *fp = fopen("/local/sys_log.txt", "a"); 
+
+    for(int i=0; i<train->get_next_sensors().size(); i++){ 
+           
+        fprintf(fp, "%d" ,train->get_next_sensors()[i]);
+    }
+    
+    fprintf(fp, "\n");
+    fclose(fp);  
+
+}
+
+void trains_posn_log(int sensor){
+ 
+    FILE *fp = fopen("/local/sys_log.txt", "a"); 
+    
+    fprintf(fp, "SIGNAL FROM SENSOR D%d \n", sensor);
+    fprintf(fp, "DR_train: D%s sensor, %s direction. // Next positions:  ", train_pos_toString(&DR_train), train_dir_toString(&DR_train)); 
+    print_next_sensors(&DR_train);
+       
+    fprintf(fp, "LR_train: D%s sensor, %s direction. // Next positions: ", train_pos_toString(&LR_train), train_dir_toString(&LR_train)); 
+    print_next_sensors(&LR_train);
+    fprintf(fp, "\n");
+
+    fclose(fp);  
+}
+
+
+
+
 
 
 
@@ -612,7 +733,61 @@
     return sensor;
 }
 
+/**
+*
+*Method to flip the switches
+*
+*@switchId - (1-4)The ID of the switch we want to flip
+*@times - The number of times we want to send the command
+*@activate - True if the switch is going to be activated. False if it needs to go back to rest position.
+*
+**/
+void flip_switch(int switchId, int times, bool activate=true){
+    
+    unsigned int SWBflip = SWBidle; //IDLE - Flip last activated SW.
+    
+    switch(switchId){
+        
+        case 1:
+            SWBflip = SWBflip_1;     //FLIP SW1
+            break;
+            
+        case 2:
+            SWBflip = SWBflip_2;     //FLIP SW2
+            break;
+            
+        case 3:
+            SWBflip = SWBflip_3;     //FLIP SW3
+            break;
+            
+        case 4:
+            SWBflip = SWBflip_4;     //FLIP SW4
+            break;
+            
+        default:
+            break;    
+    }          
 
+    //Security measure not to burn the switch.
+    if(times <=5){ 
+    
+        DCC_send_command(SWBaddress,SWBflip,times); //Activating switch
+        if(!activate){
+              
+              DCC_send_command(SWBaddress,SWBidle,times);  //Sending IDLE to flip back.
+        }
+     }
+}
+
+/**
+* Action to do when NAC is detected 
+* Booster is disabled and the buzz is activated
+* 
+*/
+void NAC_action(){
+    enable = 0;
+    doBuzz();
+}
 
 
 
@@ -650,20 +825,36 @@
     return NAC;     
 }
 
-/*
-void AFC_action(int switch_n, int sensor, Train *stop_train, Train * cont_train ){
+/**
+* Switch_n switch that needs to switch
+´* cont_sensor sensor that when activated the stopped train continues
+* switch_sensor sensor where the switch should be activated
+*/
+void AFC_action(int switch_n, int cont_sensor, int switch_sensor, Train *stop_train, Train * cont_train ){
+    bool send_pack_switch = false;
     
-    flip_switch(switch_n,5); //Activate switch 5
+    //flip_switch(switch_n,5);
     
-    while(cont_train->get_position_number() != sensor){
-        DR_run = false; //DR has to stop
-        LR_run = true; //LR continues
-        send_command();
+    while(cont_train->get_position_number() != cont_sensor){
+        if(cont_train->get_position_number() == switch_sensor){
+            send_pack_switch = true;          
+        }
+        stop_train->set_speed(STOP);
+        stop_train->run(); //Stopping train on sensor D4 or D10
+        cont_train->run();
+        
+        if(send_pack_switch){
+            lcd.cls();
+            lcd.printf("Switching SW%d",switch_n);
+            flip_switch(switch_n,5);
+        }
     }
-    DR_run = true;
-    LR_run = true; //Both trains start to run again
+    
+    flip_switch(5,5); //Send IDLE command
+    
 }
-*/
+
+
 
 /**
 *
@@ -673,51 +864,73 @@
 *Train in area A(ccw) and train in D4(cw)
 *Train in area A(cw) and train in D10(ccw)
 *Train in area B(cw) and train in D4(ccw)
-*Train in area B(ccw) and train in D10(ccw) 
+*Train in area B(ccw) and train in D10(ccw)
+*
+*stop_train is the train that is going to stop in sensors D4 or D10 until the other train passes
+*cont_train is the train that won't stop and will do the switch 
 *
 **/
-bool check_AFC(bool DR_in_A, bool DR_in_B,bool LR_in_A,bool LR_in_B){   //TODO - Add same for LR train
-    
-    if( DR_train.get_position_number() == D4){  
+bool check_AFC(Train *stop_train, Train *cont_train){   //TODO - Add same for LR train
+    bool detected_AFC = false;
+    if( stop_train->get_position_number() == D4){  
              
-            if(DR_train.goes_cw()){
+            if(stop_train->goes_cw()){
                 
-                if(LR_in_A && !LR_train.goes_cw()){
+                if(cont_train->is_in_A() && !cont_train->goes_cw()){
+                    
+                    lcd.cls();
+                    lcd.printf("AFC!!! STOP D4 SW2 CONT D3");
                     
-                //Activate switch2
-                //DR_train has to stop
-                //When LR is at D3 DR continues
+                    AFC_action(2,D3,D2,stop_train,cont_train); 
+                    //Activate switch2
+                    //When cont_train is at D3 stop_train continues
+                
+                detected_AFC = true;
                 }
             }else{ //DR goes ccw
             
-                if(LR_in_B && LR_train.goes_cw()){
+                if(cont_train->is_in_B() && cont_train->goes_cw()){
                     
+                    lcd.cls();
+                    lcd.printf("AFC!!! STOP D4 SW3 CONT D5");
+                    
+                    AFC_action(3,D5,D6,stop_train,cont_train); 
                     //DR_train stops
                     //Activate switch3
                     //When LR is at D5 DR continues
+                    detected_AFC = true;
                 }
             }
             
-    }else if(DR_train.get_position_number() == D10){
+    }else if(stop_train->get_position_number() == D10){
         
-        if(DR_train.goes_cw()){
+        if(stop_train->goes_cw()){
             
-            if(LR_in_B && !LR_train.goes_cw()){
+            if(cont_train->is_in_B() && !cont_train->goes_cw()){
+                lcd.cls();
+                lcd.printf("AFC!!! STOP D10 SW4 CONT D9");
                 
+                AFC_action(4,D9,D8,stop_train,cont_train); 
                 //DR train stops
                 //Activate switch4
                 //When LR is at D9 DR continues
+                detected_AFC = true;
             }
         }else{
             
-            if(LR_in_A && LR_train.goes_cw()){
-                
+            if(cont_train->is_in_A() && cont_train->goes_cw()){
+                lcd.cls();
+                lcd.printf("AFC!!! STOP D10 SW1 CONT D11");
+                AFC_action(1,D11,D12,stop_train,cont_train); 
                 //DR train stops
                 //Activate switch1
-                //When LR is at D9 DR continues
+                //When LR is at D11 DR continues
+                detected_AFC = true;
             }
         }
     }
+    
+    return detected_AFC;
 }
 
 
@@ -732,7 +945,12 @@
     if(check_NAC()){
         lcd.cls();
         lcd.printf("NAC!!!");
-    }      
+        NAC_action();
+    }
+    check_AFC(&DR_train,&LR_train);       
+        
+    check_AFC(&LR_train,&DR_train);
+            
     
 }
 
@@ -771,6 +989,8 @@
         led2 = 0;        
     }else{
         
+        //trains_posn_log(sensor);
+        
         lcd.cls();
         lcd.printf("S:D%d DR%d(",sensor,DR_train.get_position_number());
         
@@ -788,7 +1008,8 @@
         }
         
         lcd.printf(")%s",LR_dir);
-    
+        
+
         //Checking next sensors for DR train
         for(int i=0; i<DR_train.get_next_sensors().size(); i++){         
             
@@ -916,51 +1137,7 @@
 
 
 
-/**
-*
-*Method to flip the switches
-*
-*@switchId - (1-4)The ID of the switch we want to flip
-*@times - The number of times we want to send the command
-*@activate - True if the switch is going to be activated. False if it needs to go back to rest position.
-*
-**/
-void flip_switch(int switchId, int times, bool activate=true){
-    
-    unsigned int SWBflip = SWBidle; //IDLE - Flip last activated SW.
-    
-    switch(switchId){
-        
-        case 1:
-            SWBflip = SWBflip_1;     //FLIP SW1
-            break;
-            
-        case 2:
-            SWBflip = SWBflip_2;     //FLIP SW2
-            break;
-            
-        case 3:
-            SWBflip = SWBflip_3;     //FLIP SW3
-            break;
-            
-        case 4:
-            SWBflip = SWBflip_4;     //FLIP SW4
-            break;
-            
-        default:
-            break;    
-    }          
 
-    //Security measure not to burn the switch.
-    if(times <=5){ 
-    
-        DCC_send_command(SWBaddress,SWBflip,times); //Activating switch
-        if(!activate){
-              
-              DCC_send_command(SWBaddress,SWBidle,times);  //Sending IDLE to flip back.
-        }
-     }
-}
 
 
 /**
@@ -1168,8 +1345,22 @@
     lcd.printf("Ready to start");
     wait(1);
     
+    //init_logger();
+    //train_pos0_log();
+    //logger_add("There we go lads this is the start of the program");
+    
     enable = 1;
     
+    flip_switch(5,5);//Send IDLE command at the beginning
+    flip_switch(1,5);
+    flip_switch(5,5);
+    flip_switch(2,5);
+    flip_switch(5,5);
+    flip_switch(3,5);
+    flip_switch(5,5);
+    flip_switch(4,5);
+    flip_switch(5,5);
+    
     //Demo for stopping at the station
     while(1) {