3rd year group project. Electronic and Electrical Engineering. Heriot-Watt University. This is the code for the mbed for the Automatic Little Object Organiser (ALOO).
Dependencies: MCP23017 TCS3472_I2C WattBob_TextLCD mbed
commander.cpp
- Committer:
- dreamselec
- Date:
- 2015-12-17
- Revision:
- 32:9a4046224b11
- Parent:
- 30:c0bc92d009fe
File content as of revision 32:9a4046224b11:
// // commander.cpp // Created by Chandan Siyag on 14/11/2015. #include <iostream> #include <string> #include "commander.h" using namespace std; const int kCommandValueBufferSize = 80; const int kObjectBufferSize = 20; /// All objects that can recieve commands string CommandObjectValue [6] = { "mbed", "pc", "colour_sensor", "servos", "port", "break_beam" }; /// All object(fist column) and their possible commands(respective row). string CommandObjectCommandsValue [6][kMaxCommandCount] = { {"mbed", "haz-block", "read-current-block", "mode", "sort", "reading-count", "", "", "", ""}, {"pc", "connect", "disconnect", "", "", "", "", "", "reply-commands", "exit"}, {"colour_sensor", "i-time", "preview", "value", "block-value", "test", "", "", "", ""}, {"servos", "test", "reset", "toggle", "", "", "", "", "", ""}, {"port", "init", "b-rate", "parity", "", "", "", "", "", ""}, {"break_beam", "test", "", "", "", "", "", "", "", ""}, }; /// Creates new commander object Commander::Commander() { replyCommands = false; this->resetVariables(); } /// Desctructor Commander::~Commander() { } /// Recieves and decodes the command void Commander::decodeCommand(CommandTypeRaw type) { this->resetVariables(); this->typeRaw = type; this->typeChar = CommandTypeValue[type]; this->readCommandObject(); if (this->objectRaw == InvalidObject) { pc.printf("DEBUG:Invalid command object.\n"); return; } if (this->readCommand(this->objectRaw) == false) { pc.printf("DEBUG:Invalid command.\n"); return; } else if (connectedToPC == true || (this->typeRaw == Set && this->objectRaw == PC && this->commandIndex[0] == 1)) { this->executeCommand(); if (this->replyCommands == true) { pc.printf("VALUE:%s:VALUE\n", this->description().c_str()); } //TODO: Send request with response descriptor. // pc.("DEBUG:Finished executine command"); return; } pc.printf("INFO:Not connected to PC. %i\n", this->commandIndex[0]); return; } /// Get the information about the parsed command in a readable manner. //TODO: Fix format std::string Commander::description() { string str; str.append("Type:\t\t"); str.append(&this->typeChar); str.append("\nObject:\t\t" + this->object); for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->command[i] == "") { break; } str.append("\nCommand:\t" + this->command[i] + "\nValue:\t\t" + this->commandValue[i].c_str() + " \n"); } return str; } /// Reads and assignes the imminent commanding object. void Commander::readCommandObject() { char objectInitiator = '<'; char objectTerminator = '>'; char nextChar = '\0'; do { nextChar = pc.getc(); } while (nextChar != objectInitiator); char objectCharArray [kObjectBufferSize] = ""; int i = 0; while (i < kObjectBufferSize) { nextChar = pc.getc(); if (nextChar == '\n' || nextChar == '\r' || nextChar == ' ') { continue; } if (nextChar == objectTerminator) break; objectCharArray[i] = nextChar; i++; } string tempStr(objectCharArray); this->object = tempStr; for (int i = 0; i < (sizeof(CommandObjectValue)/sizeof(*CommandObjectValue)); i++) { if (CommandObjectValue[i] == this->object) { this->objectRaw = static_cast<CommandObjectRaw>(i); return; } } this->objectRaw = InvalidObject; return; } /// Reads the command for the previouly read object. /// Return true if is a possible command, false otherwise. bool Commander::readCommand(CommandObjectRaw objectRaw) { char nextChar = '\0'; char commandCharArray [kMaxCommandCount - 1][kCommandValueBufferSize] = { '\0' }; char commandValueArray [kMaxCommandCount -1][kCommandValueBufferSize] = { '\0' }; int charIndex = 0; int valueCharIndex = 0; int commandValueIndex = 0; bool commandComplete = false; while (charIndex < kCommandValueBufferSize - 1 && valueCharIndex < kCommandValueBufferSize - 1) { nextChar = pc.getc(); if (nextChar == '\n' || nextChar == '\r' || nextChar == ' ') { continue; } else if (nextChar == kCommandTerminator) { break; } else if (nextChar == '=') { commandComplete = true; } else if (nextChar == ',') { commandComplete = false; commandValueIndex++; charIndex = 0; valueCharIndex = 0; } if (commandComplete == false && nextChar != ',') { commandCharArray[commandValueIndex][charIndex] = nextChar; charIndex++; } else if (commandComplete == true && nextChar != '=') { commandValueArray[commandValueIndex][valueCharIndex] = nextChar; valueCharIndex++; } } for (int i = 0; i < kMaxCommandCount - 1; i++) { // pc.printf("i: %i\n", i); if (commandCharArray[i][0] == '\0') { break; } string tempCommandStr(commandCharArray[i]); string tempValueStr(commandValueArray[i]); int row = this->objectRaw; int column = 1; for (; column < kMaxCommandCount - 1; column++) { if (CommandObjectCommandsValue[row][column] == tempCommandStr) { this->command[i] = tempCommandStr; this->commandIndex[i] = column; this->commandValue[i] = tempValueStr; break; } } if (this->commandIndex[i] == -1) { return false; } } return true; } /// Executes the previously read command with the object. void Commander::executeCommand() { switch (this->objectRaw) { case MBED: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { if (this->typeRaw == Set) { if (this->commandValue[i] == "start") { hazBlock(this->typeRaw); } else if (this->commandValue[i] == "pause") { pc.printf("DEBUG: Exited set new haz block mode.\n"); setNewHazBlock = false; } } else if (this->typeRaw == Query) { hazBlock(this->typeRaw); } } else if (this->commandIndex[i] == 2) { getCurrentBlock(this->typeRaw); } else if (this->commandIndex[i] == 3) { if (this->commandValue[i] == "maintanence") { currentMode = Maintanence; pc.printf("INFO:Running in maintanence mode.\n"); } else if (this->commandValue[i] == "normal") { currentMode = Normal; pc.printf("INFO:Running in nomal mode.\n"); } else if (this->commandValue[i] == "none") { currentMode = None; pc.printf("INFo:Running in none mode.\n"); } } else if (this->commandIndex[i] == 4 && currentMode == Normal) { if (this->commandValue[i] == "start") { currentState = Start; pc.printf("INFO:Starting sorting.\n"); } else if (this->commandValue[i] == "pause") { currentState = Pause; pc.printf("INFO:Pausing sorting.\n"); } } else if (this->commandIndex[i] == 5) { int readingCount = 0; sscanf(this->commandValue[i].c_str(), "%i", readingCount); hazReadingCount = readingCount; } } break; case PC: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { connectToPC(this->typeRaw); } else if (this->commandIndex[i] == 2) { disconnectToPC(this->typeRaw); } else if (this->commandIndex[i] == 8) { if (this->commandValue[i] == "ON") { this->replyCommands = true; } else if (this->commandValue[i] == "OFF") { this->replyCommands = false; } } } break; case ColourSensor: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { float integrationTime; sscanf(this->commandValue[i].c_str(), "%f", &integrationTime); if (integrationTime < 2.4 || integrationTime > 600) { pc.printf("ERROR:Integration Time invalid: %.3f\n", integrationTime); continue; } setIntegrationTimeTo(integrationTime); } else if (this->commandIndex[i] == 2) { if (this->commandValue[i] == "ON") { previewOnPC(true); } else if (this->commandValue[i] == "OFF") { previewOnPC(false); } } else if (this->commandIndex[i] == 3 && runColourSensorTest == true && getColourSensorValue == false) { getColourSensorValue = true; } else if (this->commandIndex[i] == 4 && runColourSensorTest == true && getBlockColourValue == false) { getBlockColourValue = true; } else if (this->commandIndex[i] == 5) { if (this->commandValue[i] == "start") { testColourSensor(Start); } else if (this->commandValue[i] == "pause") { testColourSensor(Pause); } } } break; case Servos: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { if (this->commandValue[i] == "start") { testServos(Start); } else if (this->commandValue[i] == "pause") { testServos(Pause); } } else if (this->commandIndex[i] == 2) { resetServos(); } else if (this->commandIndex[i] == 3) { if (this->commandValue[i] == "1") { pc.printf("INFO: Moving top servo.\n"); gToggleServoNumber = 1; } else if (this->commandValue[i] == "2") { pc.printf("INFO: Moving bottom servo.\n"); gToggleServoNumber = 2; } else if (this->commandValue[i] == "3") { pc.printf("INFO: Moving both servos.\n"); gToggleServoNumber = 3; } } } break; case Port: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { getPortInfo(); } else if (this->commandIndex[i] == 2) { int baudRate; sscanf(this->commandValue[i].c_str(), "%i", &baudRate); setPortBaudRate(baudRate); } else if (this->commandIndex[i] == 3) { int parity = 0; sscanf(this->commandValue[i].c_str(), "%i", &parity); setPortParity(parity); } } break; case BreakBeam: for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i++) { if (this->commandIndex[i] == -1 || this->commandIndex[i] == 0) { break; } if (this->commandIndex[i] == 1) { if (this->commandValue[i] == "start") { testBreakBeams(Start); } else if (this->commandValue[i] == "pause") { testBreakBeams(Pause); } } } default: break; } return; } // Cleans all the properties, ready to recieved next command. void Commander::resetVariables() { this->object = ""; this->objectRaw = InvalidObject; for (int i = 0; i < sizeof(this->command)/sizeof(*this->command); i ++) { this->command[i].clear(); this->commandValue[i].clear(); this->commandIndex[i] = -1; } this->typeRaw = InvalidType; this->typeChar = '\0'; }