root/vtcross/trunk/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp

Revision 545, 17.9 KB (checked in by bhilburn, 14 years ago)

Updated all cognitive engine examples to use new CBR structure.

Line 
1/*
2 Copyright 2009 Virginia Polytechnic Institute and State University 
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*! This file provides an implemention of a CBR-based CE that works with the
18 * provided test scripts and configuration filse.
19 */
20
21#include "DSA_CognitiveEngine.h"
22
23
24using namespace std;
25
26
27DSA_CE::DSA_CE()
28{
29    LOG("Creating Cognitive Engine.\n");
30    SML_present = false;
31    commandSocketFD = -1;
32    srand(time(NULL));
33}
34
35
36DSA_CE::~DSA_CE()
37{
38    delete myCBR;
39
40    delete [] pList;
41    delete [] oList;
42    delete [] uList;
43    delete [] radioInfo;
44}
45
46
47DSA_CE::DSA_CE(const char* serverName, const char* serverPort, \
48                const int32_t numFields, const bool SML) \
49        : CognitiveEngine(serverName, serverPort, numFields, SML)
50{
51    LOG("Creating Cognitive Engine.\n");
52    srand ( time(NULL) );
53
54    BuildCognitiveEngine();
55}
56
57
58void
59DSA_CE::RegisterServices()
60{
61    LOG("Cognitive Engine:: Registering services.\n");
62
63    SendMessage(commandSocketFD, "register_service");
64    SendMessage(commandSocketFD, "test_srv");
65
66    SendMessage(commandSocketFD, "register_service");
67    SendMessage(commandSocketFD, "test_srv1");
68
69    SendMessage(commandSocketFD, "register_service");
70    SendMessage(commandSocketFD, "test_srv2");
71
72    SendMessage(commandSocketFD, "register_service");
73    SendMessage(commandSocketFD, "test_srv3");
74
75}
76
77//Combined with deregister component since those two things must happen togeather
78void
79DSA_CE::DeregisterServices()
80{
81    LOG("Cognitive Engine:: Deregistering services.\n");
82
83    SendMessage(commandSocketFD, "deregister_service");
84    SendMessage(commandSocketFD, "test_srv");
85
86    SendMessage(commandSocketFD, "deregister_service");
87    SendMessage(commandSocketFD, "test_srv1");
88
89    SendMessage(commandSocketFD, "deregister_service");
90    SendMessage(commandSocketFD, "test_srv2");
91
92    SendMessage(commandSocketFD, "deregister_service");
93    SendMessage(commandSocketFD, "test_srv3");
94
95}
96
97/* The core of the CE is this function */
98Parameter*
99DSA_CE::GetSolution(Observable *observables, Parameter *currentParameters)
100{
101    LOG("Cognitive Engine:: Generating solution.\n");
102
103    /* Put together the CBR search array */
104
105    uint32_t channel = 0;
106    string searchNames[1];
107    string sumSearchName;
108    float searchVals[1];
109    float utilArray[(int)pList[0].max];
110    int searchOps[1];
111    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
112                             radioInfo->numObservables + 1;
113
114    float returnValues[numberColumns];
115    float sumRetVals[numberColumns];
116   
117    // Total sum of utilities in sumRetVals[0]
118
119    string channel_name = "channel";
120    string utility_name = "utility";
121
122    for(int32_t i = 0 ; i < pList[0].max ; i++ ) {
123        searchNames[0] = pList[0].name;
124        searchOps[0] = 0;
125        searchVals[0] = i+1;
126   
127        uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
128            1, returnValues);
129
130    if(rc == 31337) {
131        // No entry - must add
132       
133            string rowNames[numberColumns];
134            size_t rowIndex = 0;
135            for(size_t j = 0; j < radioInfo->numUtilities; j++) {
136                rowNames[rowIndex] = uList[j].name;
137                rowIndex++;
138            }
139            for(size_t j = 0; j < radioInfo->numParameters; j++) {
140                rowNames[rowIndex] = pList[j].name;
141            if(pList[j].name == "channel")
142                returnValues[rowIndex] = i+1;
143                rowIndex++;
144            }
145            for(size_t j = 0; j < radioInfo->numObservables; j++) {
146                rowNames[rowIndex] = oList[j].name;
147                rowIndex++;
148            }
149   
150            rowNames[rowIndex] = utility_name;
151        returnValues[rowIndex] = 500;
152
153                /* Add the new optimized set to the CBR database */
154
155            myCBR->AddRow(rowNames, returnValues, numberColumns);
156    }
157
158    utilArray[i] = returnValues[UTILITY];
159    }
160
161    printf("Current Channel Utility Scores\n");
162    printf("1: %f\t7: %f\t8: %f\t14: %f\n",utilArray[0],utilArray[1],utilArray[2],utilArray[3]);   
163    // Get sum of all the channel utilities.
164    sumSearchName = utility_name;
165    uint32_t rc = myCBR->SearchSum(sumSearchName, sumRetVals);
166
167    // Psuedo random channel selection based upon utility.
168    int k = rand() % (int)sumRetVals[0];
169    int cdf_total(0);
170
171    for ( int i = 0; i < pList[0].max; i++ ) {
172        cdf_total += utilArray[i];
173        if(k < cdf_total) {
174        channel = i + 1;
175        break;
176    }
177    }
178       
179    searchNames[0] = pList[0].name;
180    searchOps[0] = 0;
181    searchVals[0] = channel;
182 
183    rc = myCBR->Search(searchNames, searchOps, searchVals,
184        1, returnValues);
185
186
187    //returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min;
188    returnValues[CHANNEL] = channel;
189
190    printf("Cognitive Engine:: ..---===***### Channel %i has been selected ###***===---..\n",channel);
191    /* Package up the new set of parameters in order to add
192       the new entry into the CBR database.  */
193
194    size_t returnValueIndex = 0;
195    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
196        uList[i].value = returnValues[returnValueIndex];
197        returnValueIndex++;
198    }
199    for(size_t i = 0; i < radioInfo->numParameters; i++) {
200        pList[i].value = returnValues[returnValueIndex];
201        returnValueIndex++;
202    }
203    for(size_t i = 0; i < radioInfo->numObservables; i++) {
204        oList[i].value = returnValues[returnValueIndex];
205        returnValueIndex++;
206    }
207    //returnValues[returnValueIndex] = 0;
208
209    string allNames[numberColumns];
210    size_t allNameIndex = 0;
211    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
212        allNames[allNameIndex] = uList[i].name;
213        returnValues[allNameIndex] = uList[i].target;
214        allNameIndex++;
215    }
216    for(size_t i = 0; i < radioInfo->numParameters; i++) {
217        allNames[allNameIndex] = pList[i].name;
218        allNameIndex++;
219    }
220    for(size_t i = 0; i < radioInfo->numObservables; i++) {
221        allNames[allNameIndex] = oList[i].name;
222    //    returnValues[allNameIndex] = 0;
223        allNameIndex++;
224    }
225   
226    allNames[allNameIndex] = utility_name;
227
228    /* Add the new optimized set to the CBR database */
229    //myCBR->AddRow(allNames, returnValues, returnValueIndex+1);
230
231
232    /* Return the set of new parameter values.  */
233    return pList;
234}
235
236
237Parameter*
238DSA_CE::GetSolution(Observable *observables, \
239        Parameter *currentParameters, std::string service)
240{
241    LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str());
242
243    return pList;
244}
245
246
247void
248DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters)
249{
250   LOG("Cognitive Engine:: Receiving feedback.\n");
251   
252    uint32_t numberColumns =
253        radioInfo->numParameters;
254
255    uint32_t obsColumns = radioInfo->numObservables + 1;
256    uint32_t numberTotalColumns = radioInfo->numUtilities +
257                    radioInfo->numParameters +
258                    radioInfo->numObservables + 1;
259
260    float valList[numberColumns];
261    float obsVals[numberColumns];
262    string nameList[numberColumns];
263    string obsList[obsColumns];
264    string searchNames[1];
265    float searchVals[1];
266    int searchOps[1];
267    float returnValues[numberTotalColumns];
268
269    size_t columnObsIndex = 0;
270    for (size_t i = 0; i < radioInfo->numObservables; i++){
271        obsList[columnObsIndex] = observables[i].name;
272        columnObsIndex++;
273    } 
274    obsList[columnObsIndex] = "utility";
275
276    size_t columnIndex = 0;
277    for (size_t i = 0; i < radioInfo->numParameters; i++){
278        nameList[columnIndex] = parameters[i].name;
279        columnIndex++;
280    }   
281
282    size_t obsValueIndex = 0;
283    for(size_t i = 0; i < radioInfo->numObservables; i++) {
284        obsVals[obsValueIndex] = observables[i].value;
285        obsValueIndex++;
286    }
287
288    /* Make sure we do not return any entries for the current channel */
289    std::string channel_name = "channel";
290    searchNames[0] = channel_name;
291    searchOps[0] = 0;
292    searchVals[0] = parameters[0].value;
293
294    /* Execute CBR search and put output into returnValues */
295    myCBR->Search(searchNames, searchOps, searchVals,
296            1, returnValues);
297
298    /* Calculate Utility */
299    float oldUtilityValue = returnValues[UTILITY];
300   
301
302    //////////////////////////////////////////////
303    //
304    //  BEGIN CORE DSA ALGORITHM UTILITY FUNCTION
305    //
306    //////////////////////////////////////////////
307 
308    // Set DSA utility to take into account both the previously sensed
309    //  energy and the average communication time.
310
311    float newUtilityValue = oldUtilityValue + observables[COMMUNICATION_TIME].value;
312
313    // If communication time value is set, we know we need to change channels because of PU.
314    // So we should lower the utility for this channel.
315
316    int reward = 20;
317    int punishment = -100;
318    int Detection_Threshold = 10000000;
319
320    if((observables[COMMUNICATION_TIME].value != 0) || (observables[ENERGY].value > Detection_Threshold)) {
321    printf("Cognitive Engine:: Possible PU Detection - Decrementing Utility. %f %f",observables[COMMUNICATION_TIME].value,observables[ENERGY].value);
322    newUtilityValue = newUtilityValue + punishment;
323    } else {
324    printf("Cognitive Engine:: Scan Mode:: No PU detected - Incrementing Utility.");
325    newUtilityValue = newUtilityValue + reward;
326    }
327
328    if(newUtilityValue <= 100)
329    newUtilityValue = 100;
330
331    // Put limit on utility score to prevent a positive feedback loop
332    if(newUtilityValue >= 800)
333    newUtilityValue = 800;
334
335    obsVals[obsValueIndex] = newUtilityValue;
336
337    //////////////////////////////////////////////
338    //
339    //  END CORE DSA ALGORITHM UTILITY FUNCTION
340    //
341    //////////////////////////////////////////////
342
343
344    size_t returnValueIndex = 0;
345    for(size_t i = 0; i < radioInfo->numParameters; i++) {
346        valList[returnValueIndex] = parameters[i].value;
347        returnValueIndex++;
348    }
349
350    myCBR->Update(nameList, obsList, valList, obsVals,
351            numberColumns, obsColumns);
352}
353
354
355void
356DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \
357    std::string service)
358{
359    LOG("Cognitive Engine:: Receiving feedback.\n");
360}
361
362
363void
364DSA_CE::BuildCognitiveEngine()
365{
366    string filename = "ex1";
367    string tablename = "data";
368
369    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
370                             radioInfo->numObservables + 1;
371
372    string cols[numberColumns];
373
374    size_t columnIndex = 0;
375    for (size_t i = 0; i < radioInfo->numUtilities; i++){
376        cols[columnIndex] = uList[i].name;
377        columnIndex++;
378    }   
379
380    string paramCols[radioInfo->numParameters];
381    size_t paramColumnIndex = 0;
382    // Also need to make parameters the unique key
383    for (size_t i = 0; i < radioInfo->numParameters; i++){
384        cols[columnIndex] = pList[i].name;
385        paramCols[paramColumnIndex] = pList[i].name;
386        columnIndex++;
387        paramColumnIndex++;
388    } 
389
390    for (size_t i = 0; i < radioInfo->numObservables; i++){
391        cols[columnIndex] = oList[i].name;
392        columnIndex++;
393    }   
394   
395    std::string utility_name = "utility";
396    cols[columnIndex] = utility_name;
397
398    myCBR = new CBR(filename, tablename, cols, paramCols, numberColumns, radioInfo->numParameters);
399}
400
401
402void
403DSA_CE::PerformUpdatePerformance()
404{
405    /* Receive Set of current Parameters */
406    char buffer[256];
407    memset(buffer, 0, 256);
408    ReadMessage(commandSocketFD, buffer);
409    uint32_t numParameters = atoi(buffer);
410
411    Parameter *p = new Parameter[numParameters];
412
413    for(size_t i = 0; i < numParameters; i++) {
414        memset(buffer, 0, 256);
415        ReadMessage(commandSocketFD, buffer);
416        p[i].name = std::string(buffer);
417
418        memset(buffer, 0, 256);
419        ReadMessage(commandSocketFD, buffer);
420        p[i].value = atof(buffer);
421    }
422
423    /* Receive Set of Observables */
424    memset(buffer, 0, 256);
425    ReadMessage(commandSocketFD, buffer);
426    uint32_t numObservables = atoi(buffer);
427
428    Observable *o = new Observable[numObservables];
429
430    for(size_t i = 0; i < numObservables; i++) {
431        memset(buffer, 0, 256);
432        ReadMessage(commandSocketFD, buffer);
433        o[i].name = std::string(buffer);
434
435        memset(buffer, 0, 256);
436        ReadMessage(commandSocketFD, buffer);
437        o[i].value = atof(buffer);
438    } 
439
440    ReceiveFeedback(o,p);
441
442    delete [] o;
443    delete [] p;
444}
445
446
447void
448DSA_CE::PerformRequestOptimizationService()
449{
450    // THIS IS CURRENTLY IN DEMO MODE           
451
452
453    /* Receive Set of Observables */
454    LOG("\nCognitive Engine:: Receiving service name\n");
455
456    char buffer[256];
457    memset(buffer, 0, 256);
458    ReadMessage(commandSocketFD,buffer);
459    LOG("\nCognitive Engine:: Got service name, %s\n", buffer);
460
461    /* Receive Set of Observables */
462    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
463
464    memset(buffer, 0, 256);
465    ReadMessage(commandSocketFD,buffer);
466    uint32_t numObservables = atoi(buffer);
467
468    Observable *o = new Observable[numObservables];
469
470    for(size_t i = 0; i < numObservables; i++) {
471        memset(buffer, 0, 256);
472        ReadMessage(commandSocketFD, buffer);
473        o[i].name = std::string(buffer);
474
475        memset(buffer, 0, 256);
476        ReadMessage(commandSocketFD, buffer);
477        o[i].value = atof(buffer);
478    } 
479
480    /* Receive Set of current Parameters */
481    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
482
483    memset(buffer, 0, 256);
484    ReadMessage(commandSocketFD, buffer);
485    uint32_t numCurrentParameters = atoi(buffer);
486
487    Parameter *cp = new Parameter[numCurrentParameters];
488
489    for(size_t i = 0; i < numCurrentParameters; i++) {
490        memset(buffer, 0, 256);
491        ReadMessage(commandSocketFD, buffer);
492        cp[i].name = std::string(buffer);
493
494        memset(buffer, 0, 256);
495        ReadMessage(commandSocketFD, buffer);
496        cp[i].value = atof(buffer);
497    } 
498    LOG("Cognitive Engine:: Processing parameters....\n");
499
500    // TODO need to actually do something with the observables here
501   
502    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
503    char numParametersChar[10];
504    sprintf(numParametersChar, "%i", radioInfo->numParameters);
505    SendMessage(commandSocketFD, numParametersChar);
506    for(size_t i = 0; i < radioInfo->numParameters; i++) {
507        SendMessage(commandSocketFD, "test");
508        SendMessage(commandSocketFD, "00");
509    }
510
511    delete [] o;
512    delete [] cp;
513}
514
515
516void
517DSA_CE::PerformRequestOptimization()
518{
519        /* Receive Set of Observables */
520        LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
521
522    char buffer[256];
523        memset(buffer, 0, 256);
524        ReadMessage(commandSocketFD,buffer);
525        uint32_t numObservables = atoi(buffer);
526
527        Observable *o = new Observable[numObservables];
528
529        for(size_t i = 0; i < numObservables; i++) {
530                memset(buffer, 0, 256);
531                ReadMessage(commandSocketFD, buffer);
532                o[i].name = std::string(buffer);
533
534                memset(buffer, 0, 256);
535                ReadMessage(commandSocketFD, buffer);
536                o[i].value = atof(buffer);
537        } 
538
539        /* Receive Set of current Parameters */
540        LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
541
542        memset(buffer, 0, 256);
543        ReadMessage(commandSocketFD, buffer);
544        uint32_t numCurrentParameters = atoi(buffer);
545
546        Parameter *cp = new Parameter[numCurrentParameters];
547
548        for(size_t i = 0; i < numCurrentParameters; i++) {
549                memset(buffer, 0, 256);
550                ReadMessage(commandSocketFD, buffer);
551                cp[i].name = std::string(buffer);
552
553                memset(buffer, 0, 256);
554                ReadMessage(commandSocketFD, buffer);
555                cp[i].value = atof(buffer);
556        } 
557        LOG("Cognitive Engine:: Processing parameters....\n");
558
559        Parameter *solutionSet;
560       
561        solutionSet = GetSolution(o,cp);
562
563        // TODO need to actually do something with the observables here
564   
565        LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
566        char numParametersChar[10];
567        char solutionValue[50];
568        sprintf(numParametersChar, "%i", radioInfo->numParameters);
569        SendMessage(commandSocketFD, numParametersChar);
570        for(size_t i = 0; i < radioInfo->numParameters; i++) {
571                SendMessage(commandSocketFD, solutionSet[i].name.c_str());
572                memset(solutionValue, 0, 50);
573                sprintf(solutionValue, "%f", solutionSet[i].value);
574                SendMessage(commandSocketFD, solutionValue);
575        }
576
577        delete [] o;
578        delete [] cp;
579}
580
581
582void
583DSA_CE::PerformQueryComponentType()
584{
585        SendComponentType();
586}
587
588
589void
590DSA_CE::PerformConnectSML()
591{
592        /* This command implies that we are disconnecting from the shell and
593         * connecting to a SML component. */
594        char serverName[256];
595        char serverPort[256];
596        // TODO is this going to end up being too slow?
597        memset(serverName, 0, 256);
598        memset(serverPort, 0, 256);
599
600        ReadMessage(commandSocketFD, serverName);
601        ReadMessage(commandSocketFD, serverPort);
602
603        /* Only continue if we are currently connected to a shell. */
604        if(!SML_present) {
605                DeregisterComponent();
606
607                shutdown(commandSocketFD, 2);
608                close(commandSocketFD);
609
610                ConnectToRemoteComponent(serverName, serverPort, true);
611        }
612}
613
614
615void
616DSA_CE::PerformDisconnectSML()
617{
618        /* This command implies that we are disconnecting from the SML and
619         * connecting to a shell component. */
620        char serverName[256];
621        char serverPort[256];
622        // TODO is this going to end up being too slow?
623        memset(serverName, 0, 256);
624        memset(serverPort, 0, 256);
625
626        ReadMessage(commandSocketFD, serverName);
627        ReadMessage(commandSocketFD, serverPort);
628
629        /* We only want to do this if we are actually connected to an SML
630         * currently. */
631        if(SML_present) {
632                DeregisterServices();
633
634                shutdown(commandSocketFD, 2);
635                close(commandSocketFD);
636
637                ConnectToRemoteComponent(serverName, serverPort, false);
638        }
639}
640
641
642void
643DSA_CE::PerformResetEngineCognitive()
644{
645        Reset();
646}
647
648
649void
650DSA_CE::PerformShutdownEngineCognitive()
651{
652        Shutdown();
653}
654 
Note: See TracBrowser for help on using the browser.