Component Test's Software to work with "Universal Controller Box" - Software is an interpreter or "compiler" for programs to be done with a .txt file and read off of the SD Card

Dependencies:   BridgeDriver FrontPanelButtons MCP23017 SDFileSystem TextLCD mbed

main.cpp

Committer:
mehatfie
Date:
2014-09-23
Revision:
6:d1594fd2ec5a
Parent:
5:e36e0538a903
Child:
7:cca801103b86

File content as of revision 6:d1594fd2ec5a:


#include "mbed.h"
#include "LocalPinNames.h"
#include "BridgeDriver.h"
#include "FrontPanelButtons.h"
#include "TextLCD.h"
#include "SDFileSystem.h"
#include "Initialization.hpp"
#include "TextFile.h"
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <vector>
using std::string;

FrontPanelButtons buttons(&i2c);

//extern "C" void mbed_reset(); //enable software reset of code



int interpretCommand(FILE *, LineData &);
int loopCommand(FILE *, LineData &);

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/***************************                        <FUNCTION: resetLineData>                            **************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
void resetLineData(LineData &lineData){
    
    //lineData.fullLine.clear();
    lineData.lineNumber = 0;
    lineData.numWords = 0;
    lineData.lineAddress = 0;
}

    

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/************************                        <FUNCTION: cyclePrograms>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
   
int cyclePrograms(vector<string> files, int SIZE, int currIndex, int direction){
    
    int nextIndex = 0;
    switch(direction){
        case 0: //Cycle Back one File
            if ((currIndex - 1) < 0)
                nextIndex = SIZE - 1;
            else
                nextIndex = currIndex - 1;
            break;
        case 1: //Cycle Forward one File
            if ((currIndex + 1) >= SIZE)
                nextIndex = 0; 
            else
                nextIndex = currIndex + 1;
            break;
        case -1: //set the selectedFile to the currIndex (used for initialization)
            nextIndex = currIndex;
            break;
    }

    //Output file on Display 
    lcd.setAddress(0,3);
    lcd.printf("                   "); // Clear the Line using Spaces (Emptyness) - Note one line is 20 Characters
    wait(.2);
    lcd.setAddress(0,3);
    lcd.printf("%s", files[nextIndex]);
    
    return nextIndex; // Return the file index in the Array         
}
            
    
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/**************************                        <FUNCTION: conditionCommand>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

//Create an enum map of the positble conditions
enum  ConditionType{xAND, AND, xOR, OR, NONE};                              
//static const enum ConditionType Condition_Map[] = {xAND, AND, xOR, OR};    

struct ConditionOp{
    
    int value;          //returned value of the interpret function: 1 = meets criteria, 0 = criteria not met, -1 = failed to interpret
    ConditionType op; //operator that follows the given parameter: x val 2 AND y val 3, if this ConditionOp is for x, then the value will be AND
};

int conditionCommand(FILE *selectedFile, LineData &lineData){
        
    //Get the number of condition parameters 
    string numConditionVals = lineData.word[1];
    int numConditionValues = 0;
    sscanf(numConditionVals.c_str(), "%d", &numConditionValues);
    
    //LineData tempLineData;
    LineData param[15];
    //vector<LineData> param;
    vector<ConditionOp> paramCondition;
 
    
    //Fill the param Vector with Line structs of each individual device, this way we can send the Line struct to the appropriate interpret function without modification within the function itself
    int i = 2, numParam = 0, paramNumWords = 0;
    for (i = 2; i < lineData.numWords; i++){
                       
        // if the word is not an AND or an OR, it must mean it's for the specific function
        // set the current parameter's next word to be equal to the current word we're checking
        // increase number of words that the parameter has
        if (lineData.word[i] != "AND" && lineData.word[i] != "xAND" && lineData.word[i] != "OR" && lineData.word[i] != "xOR"){

            //tempLineData.word[paramNumWords] = lineData.word[i];
            param[numParam].word[paramNumWords] = lineData.word[i];
            paramNumWords++;
            
            //if this is the last word in the line....
            if(i == (lineData.numWords - 1)){
                param[numParam].numWords = paramNumWords;
                 paramCondition[numParam].op = NONE;
                numParam++;
            }
            
        }
            
        // if the word is an AND or an OR, it must mean the last function has been completely identified
        // set the parameters number of Words value to the calculated value
        // increase the number of Parameters (the current parameter function we're filling)
        else if (lineData.word[i].compare("AND") == 0 || lineData.word[i].compare("xAND") == 0 || lineData.word[i].compare("OR") == 0 || lineData.word[i].compare("xOR") == 0){
            
            //tempLineData.numWords = paramNumWords;
            param[numParam].numWords = paramNumWords;
            
            paramCondition.push_back(ConditionOp());
            if (lineData.word[i].compare("AND") == 0)
                paramCondition[numParam].op = AND;
            else if (lineData.word[i].compare("xAND") == 0)
                paramCondition[numParam].op = xAND;
            else if (lineData.word[i].compare("OR") == 0)
                paramCondition[numParam].op = OR;
            else if (lineData.word[i].compare("xOR") == 0)
                paramCondition[numParam].op = xOR;

            //param.push_back(LineData()); 
            //param[numParam] = tempLineData;
            //param.push_back(tempLineData); //add it to the vector list of parameters
            //tempLineData = LineData(); //reset
            numParam++; // increase the index of param
            paramNumWords = 0; // reset the number of words
        }    
    }
    

    vector<ConditionOp> combinedCondition;
    ConditionOp tempCombinedCondition;
    int j = 0, k = 0;
    for (j = 0; j < numParam; j++){
        paramCondition[j].value = interpretCommand(selectedFile, param[j]);
    }

    //create the combined Condition vector (take care of this xAND and xOR statements and combine them into one so that the whole vector is just AND's and OR's)
    //this should make the xAND's / xOR's into a single member of the combinedCondition vector
    enum ConditionType prevCondition = NONE; 
    int first = 1, last = 0;
    for (k = 0; k < numParam; k++){

        if (k == numParam - 1)
            last = 1;
            
       if (!last && (prevCondition != AND || prevCondition != OR)){
            if (paramCondition[k].op != xAND && paramCondition[k].op != xOR && paramCondition[k + 1].op != xAND && paramCondition[k + 1].op != xOR){
                lcd.setAddress(0,3);
                lcd.printf("Test 0.1     ");
                wait(1);
                
                //AND
                if (paramCondition[k].op == AND){
                     lcd.setAddress(0,3);
                    lcd.printf("Test 1.1     ");
                    wait(1);
                    if (!first && prevCondition != xAND && prevCondition != xOR){
                    lcd.setAddress(0,3);
                    lcd.printf("Test 1.11     ");
                    wait(1);
                        combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value;
                        }
                    else if (first || prevCondition == xAND || prevCondition == xOR){
                        lcd.setAddress(0,3);
                    lcd.printf("Test 1.12     ");
                    wait(1);
                        tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; 
                        combinedCondition.push_back(tempCombinedCondition);
                        first = 0;
                    }    
                    prevCondition = AND;
                }
                
                //OR
                else if (paramCondition[k].op == OR){
                    lcd.setAddress(0,3);
                    lcd.printf("Test 1.2     ");
                    wait(1);
                    if (!first && prevCondition != xAND && prevCondition != xOR){
                        lcd.setAddress(0,3);
                    lcd.printf("Test 1.3     ");
                    wait(1);
                        combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value;
                        }
                    else if (first || prevCondition == xAND || prevCondition == xOR){
                        lcd.setAddress(0,3);
                    lcd.printf("Test 1.4     ");
                    wait(1);
                        tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; 
                        combinedCondition.push_back(tempCombinedCondition);
                        first = 0;
                    }    
                    prevCondition = OR;
                }
            }
            
            // first value is something, not exclusive, but next values are exclusive
            else if (first && (paramCondition[k].op == AND || paramCondition[k].op == OR) && (paramCondition[k + 1].op == xAND || paramCondition[k + 1].op == xOR)){
                lcd.setAddress(0,3);
                lcd.printf("Test 1     ");
                wait(1);
                tempCombinedCondition.value = paramCondition[k].value;
                tempCombinedCondition.op = paramCondition[k].op;
                combinedCondition.push_back(tempCombinedCondition);
                prevCondition = paramCondition[k].op;
                first = 0;
                lcd.setAddress(0,3);
                lcd.printf("1cCval: %d   ", combinedCondition.back().value);
                wait(1);
            }
            
            else{   
                /*lcd.setAddress(0,3);
                lcd.printf("Test 0.2     ");
                wait(1);*/
                //xAND
                if (paramCondition[k].op == xAND && prevCondition == xAND){
                        lcd.setAddress(0,3);
                    lcd.printf("Test 2.1     ");
                    wait(1);
                    combinedCondition.back().value = combinedCondition.back().value && paramCondition[k + 1].value;
                    prevCondition = xAND;
                }
                else if (paramCondition[k].op == xAND && prevCondition != xAND){
                     lcd.setAddress(0,3);
                    lcd.printf("Test 2.2    ");
                    wait(1);
                    tempCombinedCondition.value = paramCondition[k].value && paramCondition[k + 1].value; 
                    combinedCondition.push_back(tempCombinedCondition);
                    prevCondition = xAND;
                }
                
                //xOR
                else if (paramCondition[k].op == xOR && prevCondition == xOR){
                     lcd.setAddress(0,3);
                    lcd.printf("Test 2.3     ");
                    wait(1);
                    combinedCondition.back().value = combinedCondition.back().value || paramCondition[k + 1].value;
                    prevCondition = xOR;
                    lcd.setAddress(0,3);
                    lcd.printf("2.3cCval: %d   ", combinedCondition.back().value);
                    wait(1);
                }
                else if (paramCondition[k].op == xOR && prevCondition != xOR){
                     lcd.setAddress(0,3);
                    lcd.printf("Test 2.4     ");
                    wait(1);
                    tempCombinedCondition.value = paramCondition[k].value || paramCondition[k + 1].value; 
                    combinedCondition.push_back(tempCombinedCondition);
                    prevCondition = xOR;
                    lcd.setAddress(0,3);
                    lcd.printf("2.4cCval: %d   ", combinedCondition.back().value);
                    wait(1);
                }
                
                // Since the k + 1 value is included in the xAND or xOR exclusively, skip checking that value, and add the appropriate AND / OR as the
                // operator of this exclusive xAND / xOR set
                if ((paramCondition[k + 1].op == AND || paramCondition[k + 1].op == OR) && (prevCondition == xAND || prevCondition == xOR)){
                    combinedCondition.back().op = paramCondition[k + 1].op;
                    k++;
                }
                
            }
       }
        
        //else if (last && (prevCondition != AND || prevCondition != OR)){
            
        
        //the last value was not included in any combination, since directly before the last value was an xAND / xOR set that
        // included the very last AND / OR as the set's operator
        else if (last && (prevCondition != AND || prevCondition != OR)){
            tempCombinedCondition.value = paramCondition[k].value;
            tempCombinedCondition.op = NONE; 
            combinedCondition.push_back(tempCombinedCondition);
        }
        
        //reset the tempCombinedCondition variable
        tempCombinedCondition = ConditionOp();
    }
        
        
        lcd.setAddress(0,3);
                lcd.printf("cCsize: %d   ", combinedCondition.size());
                wait(1);
                
    // run through all values in the combined Condition vector, AND'ing / OR'ing as appropriate
    // in the end, the last value in the array should be the final condition of the Condition statement... whether it was successful or failed
    for (i = 0; i < (combinedCondition.size() - 1); i++){
        if (combinedCondition[i].op == AND)
            combinedCondition[i + 1].value = combinedCondition[i].value && combinedCondition[i + 1].value;
        else if (combinedCondition[i].op == OR)
            combinedCondition[i + 1].value = combinedCondition[i].value || combinedCondition[i + 1].value;
    }

    int conditionSuccess = combinedCondition.back().value; //value is the success(1) or failure(0) of the condition statement

    int checkEnd = 0;
    if (!conditionSuccess){

        while (checkEnd != 4){
            
            getNextLine(selectedFile, lineData);
            
            // check if the first word is an end command (avoids interpreting functions that perform actions)
            if (lineData.word[0].compare("end") == 0)   
                checkEnd = interpretCommand(selectedFile, lineData);
        
            if (checkEnd == 4) // custom return value for this function
                return 0;
        }
    }
    
    // Return success as the function either met the condition and will continue from the next line, or
    // failed to meet the condition and ran through the lines inside the condition until "end condition" was found, therefore
    // the program will proceed from the line after the "end condition" line
    return 1;
}      
   

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/**************************                        <FUNCTION: loopCommand>                            *****************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int loopCommand(FILE *selectedFile, LineData &lineData){
        
    //Get the Condition value for number of times to loop
    string loopCondition = lineData.word[1];
    int loopConditionValue = 0;
    sscanf(loopCondition.c_str(), "%d", &loopConditionValue);
    
    int loopStartAddress = 0, loopLineNumber = 0, firstLineOfLoop = 1;
        
    lcd.setAddress(0,0);
    lcd.printf("Cycle 1 of %d", loopConditionValue);
        
    Timer cycleTimer;
    float totalLoopTime = 0;
    cycleTimer.reset();
    cycleTimer.start();
       
    int counter = 1, checkEnd = 0;
    while (counter <= loopConditionValue){
        
        getNextLine(selectedFile, lineData); 
        
        //Must get the address before entering the interpret command
        // if a Condition command is immediately after, and the condition fails, then
        // the interpret command will return the line at the "end condition" line, and therefore
        // set the loop's first line to be the "end condition" line, if interpretCommand is called BEFORE setting the first loop line address
        if (firstLineOfLoop){
            loopStartAddress = lineData.lineAddress; //Save the Line Address
            loopLineNumber = lineData.lineNumber;    //Save the Line Number
            firstLineOfLoop = 0;
        }
           
        checkEnd = interpretCommand(selectedFile, lineData);

        //Increase the loop counter and go back to the beginning of the loop
        if (checkEnd == 3){
            /*cycleTimer.stop();
            lcd.setAddress(0,0);
            lcd.printf("tLT: %d, tR", cycleTimer.read());
            wait(2);*/
            
            //Output the Avg Cycle Time
            cycleTimer.stop(); 
            totalLoopTime += cycleTimer.read();
            
           /* lcd.setAddress(0,0);
            lcd.printf("tLT: %d, tR", cycleTimer.read());
            wait(2);*/
            
            lcd.setAddress(0,1);
            lcd.printf("Avg t(sec): %1.3f", (totalLoopTime / counter));
            
            //Output Cycle Number
            counter++;
            lcd.setAddress(0,0);
            lcd.printf("Cycle %d of %d", counter, loopConditionValue);
            
            fseek(selectedFile, loopStartAddress, SEEK_SET);
            lineData.lineNumber = loopLineNumber - 2;
            checkEnd = 0;
            
            //Restart the timer for the next loop
            cycleTimer.reset();
            cycleTimer.start();
        }
    }
                
    return 1;
 }   

/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/*************************                        <FUNCTION: interpretCommand>                            *************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int interpretCommand(FILE *selectedFile, LineData &lineData){
        
    if (lineData.word[0].compare("device") == 0){

        int i = 0, deviceFound = -1;
        for (i = 0; i < numDevices; i++){
            if (lineData.word[2].compare(DeviceNames[i]) == 0){
                deviceFound = i;
            }
        }
        
        //if the device type does not match any known type, error out
        if (deviceFound == -1){
            //Error Out since the device Name was not matched with anything *************************   
        }
        
        //Add device to the array of devices and initialize it
        else{
            devices.push_back(Device::newDevice(deviceFound, lineData.word[1], lineData));
            devices.back()->name = lineData.word[1];             
        }
    }
    
    else if (lineData.word[0].compare("delay") == 0){
        string duration = lineData.word[1];
        int durationValue = 0;
        sscanf(duration.c_str(), "%d", &durationValue);
        
        if (durationValue){
            timer.reset();
            timer.start();
            while (timer.read_ms() < durationValue); //Do Nothing while the timer has not reached the duration
            timer.stop(); //Stop the Timer
        }
        else{
            //Error Out
            return -1;
        }
    }
    
    else if (lineData.word[0].compare("loop") == 0){
        int checkLoopEnd = loopCommand(selectedFile, lineData);
        if (checkLoopEnd == 1)
            return 1;
    }
       
    else if (lineData.word[0].compare("condition") == 0){
        int checkLoopEnd = conditionCommand(selectedFile, lineData);
        if (checkLoopEnd == 1)
            return 2;
    }     
    // end with custom return value for specific function
    else if (lineData.word[0].compare("end") == 0){
        if (lineData.word[1].compare("program") == 0){
            return 2;
        }
        else if (lineData.word[1].compare("loop") == 0){
            return 3;
        }
        else if (lineData.word[1].compare("condition") == 0){
            return 4;
        }
    }
    
    //not a keyword so check if it's a localName for a device
    else{
    
        int i = 0, deviceFound = -1;
        for (i = 0; i < devices.size(); i++){
            if (lineData.word[0].compare(devices[i]->name) == 0)
                deviceFound = i;
        }
                
        //no device was found that matched the local name, and this is also the last error check, meaning it can match no other potential keywords
        if (deviceFound == -1){
            lcd.setAddress(0,3);
            lcd.printf("Final ERROR!");
            wait(10);
        }
        
        //Local Name matches a device, send line to that device in order to process the functionality
        else{
            //addDevice(deviceFound);
            return devices[deviceFound]->interpret(lineData);
        }
    }  
    
    return -1;
}


/**********************************************************************************************************************************/
/**********************************************************************************************************************************/
/******************************                        <FUNCTION: main>                            ********************************/
/**********************************************************************************************************************************/
/**********************************************************************************************************************************/

int main() {
    
    fullInit(); //Initialize anything that's required to run the code (LCD)
    
    LineData lineData;
    resetLineData(lineData);

        /******************************************************************************/
        /***                 <Get all the Potential Programs>                       ***/
        /******************************************************************************/
        int numTextFiles = 0;
        vector<string> textFiles; //Assuming Maximum of 25 txt files will be on the SD Card        
        vector<string> filenames = readFileNames("/sd");    
        numTextFiles = getFileNamesWithoutExt(textFiles, filenames);
            
    
        /******************************************************************************/
        /***                   <Select the Program txt File>                        ***/
        /******************************************************************************/
        int fileSelected = 0, selectedFileIndex = 0;
    
        lcd.cls(); //clear the display
        lcd.setAddress(0,1);
        lcd.printf("Select Your Program");
        lcd.setAddress(0,2);
        lcd.printf("Num Programs = %d", numTextFiles);
        
        uint8_t lastButState = 0;
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
    
        selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, -1); //Initialize the first file to the screen
        while(!fileSelected) {
            
            uint8_t curButState = buttons.readBus();
            if(curButState != lastButState){
                lastButState = curButState;
                if(buttons.readRight())
                    selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 1);
                else if(buttons.readLeft())
                    selectedFileIndex = cyclePrograms(textFiles, numTextFiles, selectedFileIndex, 0);
                else if(buttons.readSel())
                    fileSelected = 1;
            }
        }
               
        char selectedFileName[50];
        strcpy(selectedFileName, textFiles[selectedFileIndex].c_str());
        
        /******************************************************************************/
        /***                    <Open the Program txt File>                         ***/
        /******************************************************************************/
        
        //Create the string of the full directory and path to the program txt file
        char selectedFileFullName[100] = "/sd/";    //Assuming that no directory and file name will be longer than 100 characters
        strcat(selectedFileFullName, selectedFileName);
        strcat(selectedFileFullName, ".txt");
        
        FILE *selectedFile = fopen(selectedFileFullName, "r");

        lcd.cls(); //clear the display 

        if(selectedFile == NULL) {
            lcd.setAddress(0,0);
            lcd.printf("Invalid");
            wait(10);
        }
    
        
    while(1){  
            
        resetLineData(lineData);
        
        lcd.cls(); //clear the display   
        lcd.setAddress(0,0);
        //lcd.printf("Program: %s", selectedFileName);

        
        /******************************************************************************/
        /***          <Start Running through the Program txt File Lines>            ***/
        /******************************************************************************/
  
        int endOfFile = 0;
        
        while (!endOfFile){
        
            getNextLine(selectedFile, lineData);
            int checkEnd = interpretCommand(selectedFile, lineData);   
                    
            if (checkEnd == 0)
                endOfFile = 1;
        }
        
        
        lcd.cls(); //clear the display   
        lcd.setAddress(0,0);
        lcd.printf("END OF PROGRAM");
        lcd.setAddress(0,2);
        lcd.printf("To Restart...");
        lcd.setAddress(0,3);
        lcd.printf("Press BACK");
       
        while(!buttons.readBack());
        
        lcd.setAddress(0,1);
        //rewind(selectedFile);
    }

 } 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   
    /***** Cycle through txt lines and remember last lines ******/
    /*
    int running = 0, selectedFile = 0;
    int locCount = 0, tempSpot = 0;
    int loc[4];
    char line[32];
    uint8_t lastButState;
    
    
    while(1){
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
        while(!running) {
            uint8_t curButState = buttons.readBus();
    
            if(curButState != lastButState){
                switch(lastButState = curButState){
                    case 0x1F: //right
                    
                        loc[locCount] = ftell(fp);
                        
                        if (locCount >= 3)
                            locCount = 0;
                        else
                            locCount++;
                        
                        //tempSpot = ftell(fp);
                        fgets(line, 32, fp);
                        
                        lcd.setAddress(0,1);
                        lcd.printf("L: %s", line);
                        wait(0.2);
                        break;
                    case 0x2F: //left
                    
                        if (locCount == 0) {
                            locCount = 3;
                            fseek(fp, loc[locCount], SEEK_SET);
                        }
                        else {
                            fseek(fp, loc[locCount - 1], SEEK_SET);
                            locCount--;
                        }
                        fgets(line, 32, fp);
                        lcd.setAddress(0,1);
                        lcd.printf("L: %s", line);
                        wait(0.2);
                        break;
                }
            }
        } 
    } 
        */   
  
    
    
    /******* Select the Program txt File ***********/
    /*
    int numTextFiles = 0;
    string tempTextFiles[25]; //Assuming Maximum of 25 txt files will be on the SD Card
    lcd.cls(); //clear the display
    readFileNames("/sd");
    numTextFiles = getFileNamesWithoutExt(tempTextFiles);
    
    string *textFiles = resize_StringArr(tempTextFiles, numTextFiles); //Resize Array
    //delete [] tempTextFiles; //free previous array
    

    int running = 0, selectedFile = 0;

    lcd.cls(); //clear the display
    lcd.setAddress(0,1);
    lcd.printf("Select Your Program");
    lcd.setAddress(0,2);
    lcd.printf("Num Programs = %d", numTextFiles);
    
    uint8_t lastButState;
    while(1){
        lcd.setCursor(TextLCD::CurOn_BlkOn); //turn blinking cursor on
        while(!running) {
            uint8_t curButState = buttons.readBus();
    
            if(curButState != lastButState){
                switch(lastButState = curButState){
                    case 0x1F: //right
                        selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 1);
                        break;
                    case 0x2F: //left
                        selectedFile = cyclePrograms(textFiles, numTextFiles, selectedFile, 0);
                        break;
                }
            }
        }
    }
    
    */

    /*float speed = 0.5;
    while(1){
        bridges.drive(1, -1*speed);
        wait(2);
        bridges.drive(1, speed);
        wait(2);
    }*/
    
//BridgeDriver::MOTOR_A