/* Copyright 2009 Virginia Polytechnic Institute and State University Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /*! This file provides a default implementation for a case-based-reasoning based * cognitive engine. */ #include "CBR_CE.h" using namespace std; CBR_CE::CBR_CE(const char* serverName, const char* serverPort, \ const int32_t numFields, const bool SML) \ : CognitiveEngine(serverName, serverPort, numFields, SML) { BuildCognitiveEngine(); } void CBR_CE::RegisterServices() { LOG("Cognitive Engine:: Registering services.\n"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv1"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv2"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv3"); } void CBR_CE::DeregisterServices() { LOG("Cognitive Engine:: Deregistering services.\n"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv1"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv2"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv3"); } Parameter* CBR_CE::GetSolution(Observable *observables, Parameter *currentParameters) { LOG("Cognitive Engine:: Generating solution.\n"); string searchNames[radioInfo->numUtilities]; for(size_t i = 0; i < radioInfo->numUtilities; i++) { searchNames[i] = observables[i].name; } float searchVals[radioInfo->numUtilities]; for(size_t i = 0; i < radioInfo->numUtilities; i++) { searchVals[i] = uList[i].target; } uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters \ + radioInfo->numObservables + 1; float returnValues[numberColumns]; int searchOps[radioInfo->numUtilities]; for(size_t i = 0; i < radioInfo->numUtilities; i++) { /* If the goal is to maximum, set the search operation to * return values greater than the target. * * If the goal is to minimize, set the search operation to * return values less than the target. * * NOTE: the values '2' and '4' here are from some old preprocesser * definitions, which I will copy here until I can figure out just what * exactly they were for: 42 #define EQ 0 // equals 43 #define NE 1 // not equals 44 #define GT 2 // greater than 45 #define GE 3 // greater than or equal to 46 #define LT 4 // less than 47 #define LE 5 // less than or equal to */ if(strcmp(uList[i].goal.c_str(), "max") == 0) { searchOps[i] = 2; } else if(strcmp(uList[i].goal.c_str(), "min") == 0) { searchOps[i] = 4; } } /* CBR specific call */ uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals, radioInfo->numUtilities, returnValues); if(rc == 0){ /* Adapt the returned parameters to meet the objective */ LOG("Cognitive Engine:: Found\n"); /* Should do a random adaptation.. */ if(returnValues[numberColumns-1] < 0) { returnValues[2] = returnValues[2] - 15; returnValues[3] = returnValues[3] - 2; } else { returnValues[2] = returnValues[2] + 15; returnValues[3] = returnValues[3] + 2; } } else if(rc == 31337) { LOG("Cognitive Engine:: Not Found.\n"); /* No rows in the CBR, pick default parameters */ /* Currently this is hard coded and implementation specific! */ returnValues[2] = currentParameters[0].value + 5; returnValues[3] = currentParameters[1].value + 10; } else { LOG("Cognitive Engine:: Search return an invalid value.\n"); } size_t returnValueIndex = 0; for(size_t i = 0; i < radioInfo->numUtilities; i++) { uList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } for(size_t i = 0; i < radioInfo->numParameters; i++) { pList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } for(size_t i = 0; i < radioInfo->numObservables; i++) { oList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } returnValues[returnValueIndex] = 0; string allNames[numberColumns]; size_t allNameIndex = 0; for(size_t i = 0; i < radioInfo->numUtilities; i++) { allNames[allNameIndex] = uList[i].name; returnValues[allNameIndex] = uList[i].target; allNameIndex++; } for(size_t i = 0; i < radioInfo->numParameters; i++) { allNames[allNameIndex] = pList[i].name; allNameIndex++; } for(size_t i = 0; i < radioInfo->numObservables; i++) { allNames[allNameIndex] = oList[i].name; returnValues[allNameIndex] = 0; allNameIndex++; } allNames[allNameIndex] = "utility"; // Add row to CBR. myCBR->AddRow(allNames, returnValues, returnValueIndex + 1); return pList; } Parameter* CBR_CE::GetSolution(Observable *observables, \ Parameter *currentParameters, std::string service) { LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str()); return pList; } void CBR_CE::ReceiveFeedback(Observable *observables, Parameter *parameters) { LOG("Cognitive Engine:: Receiving feedback.\n"); uint32_t numberColumns = radioInfo->numParameters + radioInfo->numUtilities; uint32_t obsColumns = radioInfo->numObservables + 1; float valList[numberColumns]; float obsVals[numberColumns]; string nameList[numberColumns]; string obsList[obsColumns]; size_t columnObsIndex = 0; for (size_t i = 0; i < radioInfo->numObservables; i++){ obsList[columnObsIndex] = observables[i].name; columnObsIndex++; } obsList[columnObsIndex] = "utility"; size_t columnIndex = 0; for (size_t i = 0; i < radioInfo->numParameters; i++){ nameList[columnIndex] = parameters[i].name; columnIndex++; } for (size_t i = 0; i < radioInfo->numUtilities; i++){ nameList[columnIndex] = uList[i].name; columnIndex++; } size_t obsValueIndex = 0; for(size_t i = 0; i < radioInfo->numObservables; i++) { obsVals[obsValueIndex] = observables[i].value; obsValueIndex++; } /* Calculate Utility */ float newUtilityValue = 0; for(size_t i = 0; i < radioInfo->numUtilities; i++) { newUtilityValue = newUtilityValue + (uList[i].target - observables[i].value); } obsVals[obsValueIndex] = newUtilityValue; size_t returnValueIndex = 0; for(size_t i = 0; i < radioInfo->numParameters; i++) { valList[returnValueIndex] = parameters[i].value; returnValueIndex++; } for(size_t i = 0; i < radioInfo->numUtilities; i++) { valList[returnValueIndex] = uList[i].target; returnValueIndex++; } } void CBR_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \ std::string service) { LOG("Cognitive Engine:: Receiving feedback.\n"); } void CBR_CE::BuildCognitiveEngine() { string filename = "ex1"; string tablename = "data"; uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters \ + radioInfo->numObservables + 1; string cols[numberColumns]; size_t columnIndex = 0; for (size_t i = 0; i < radioInfo->numUtilities; i++){ cols[columnIndex] = uList[i].name; columnIndex++; } for (size_t i = 0; i < radioInfo->numParameters; i++){ cols[columnIndex] = pList[i].name; columnIndex++; } for (size_t i = 0; i < radioInfo->numObservables; i++){ cols[columnIndex] = oList[i].name; columnIndex++; } cols[columnIndex] = "utility"; myCBR = new CBR(filename, tablename, cols, numberColumns); } void CBR_CE::PerformUpdatePerformance() { /* Receive Set of current Parameters */ char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numParameters = atoi(buffer); Parameter *p = new Parameter[numParameters]; for(size_t i = 0; i < numParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); p[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); p[i].value = atof(buffer); } /* Receive Set of Observables */ memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } ReceiveFeedback(o, p); delete [] o; delete [] p; } void CBR_CE::PerformRequestOptimizationService() { // THIS IS CURRENTLY IN DEMO MODE /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving service name\n"); char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); LOG("\nCognitive Engine:: Got service name, %s\n", buffer); /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving Observable Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } /* Receive Set of current Parameters */ LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numCurrentParameters = atoi(buffer); Parameter *cp = new Parameter[numCurrentParameters]; for(size_t i = 0; i < numCurrentParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].value = atof(buffer); } LOG("Cognitive Engine:: Processing parameters....\n"); //Parameter *solutionSet; //solutionSet = GetSolution(o,cp); // TODO need to actually do something with the observables here LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n"); char numParametersChar[10]; //char solutionValue[50]; sprintf(numParametersChar, "%i", radioInfo->numParameters); SendMessage(commandSocketFD, numParametersChar); for(size_t i = 0; i < radioInfo->numParameters; i++) { // TODO What's with all the commented-out code? //SendMessage(commandSocketFD, solutionSet[i].name.c_str()); SendMessage(commandSocketFD, "test"); //memset(solutionValue, 0, 50); //sprintf(solutionValue, "%f", solutionSet[i].value); //SendMessage(commandSocketFD, solutionValue); SendMessage(commandSocketFD, "00"); } delete [] o; delete [] cp; } void CBR_CE::PerformRequestOptimization() { /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving Observable Parameters\n"); char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } /* Receive Set of current Parameters */ LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numCurrentParameters = atoi(buffer); Parameter *cp = new Parameter[numCurrentParameters]; for(size_t i = 0; i < numCurrentParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].value = atof(buffer); } LOG("Cognitive Engine:: Processing parameters....\n"); Parameter *solutionSet; solutionSet = GetSolution(o,cp); // TODO need to actually do something with the observables here LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n"); char numParametersChar[10]; char solutionValue[50]; sprintf(numParametersChar, "%i", radioInfo->numParameters); SendMessage(commandSocketFD, numParametersChar); for(size_t i = 0; i < radioInfo->numParameters; i++) { SendMessage(commandSocketFD, solutionSet[i].name.c_str()); memset(solutionValue, 0, 50); sprintf(solutionValue, "%f", solutionSet[i].value); SendMessage(commandSocketFD, solutionValue); } delete [] o; delete [] cp; } void CBR_CE::PerformQueryComponentType() { SendComponentType(); } void CBR_CE::PerformConnectSML() { /* This command implies that we are disconnecting from the shell and * connecting to a SML component. */ char serverName[256]; char serverPort[256]; // TODO is this going to end up being too slow? memset(serverName, 0, 256); memset(serverPort, 0, 256); ReadMessage(commandSocketFD, serverName); ReadMessage(commandSocketFD, serverPort); /* Only continue if we are currently connected to a shell. */ if(!SML_present) { DeregisterComponent(); shutdown(commandSocketFD, 2); close(commandSocketFD); ConnectToRemoteComponent(serverName, serverPort, true); } } void CBR_CE::PerformDisconnectSML() { /* This command implies that we are disconnecting from the SML and * connecting to a shell component. */ char serverName[256]; char serverPort[256]; // TODO is this going to end up being too slow? memset(serverName, 0, 256); memset(serverPort, 0, 256); ReadMessage(commandSocketFD, serverName); ReadMessage(commandSocketFD, serverPort); /* We only want to do this if we are actually connected to an SML * currently. */ if(SML_present) { DeregisterServices(); shutdown(commandSocketFD, 2); close(commandSocketFD); ConnectToRemoteComponent(serverName, serverPort, false); } } void CBR_CE::PerformResetEngineCognitive() { Reset(); } void CBR_CE::PerformShutdownEngineCognitive() { Shutdown(); }