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

Revision 533, 21.3 KB (checked in by bhilburn, 14 years ago)

Converted the DSA_CE to use the new class tree.

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 <cstdlib>
22#include <cstring>
23#include <stdint.h>
24#include <cmath>
25#include <string>
26
27#include "vtcross/cbr.h"
28#include "vtcross/cognitive_engine.h"
29#include "vtcross/common.h"
30#include "vtcross/components.h"
31#include "vtcross/containers.h"
32#include "vtcross/debug.h"
33#include "vtcross/error.h"
34#include "vtcross/socketcomm.h"
35
36
37#define INTERFERENCE 0
38
39#define CHANNEL 1
40
41#define ENERGY 0
42#define COMMUNICATION_TIME 1
43
44#define UTILITY 4
45
46class DSA_CE : public CognitiveEngine
47{
48    public:
49        /*! Default constructor. */
50        DSA_CE();
51
52        /*! Default destructor. */
53        ~DSA_CE();
54
55        /*! \brief Preferred constructor.
56         *
57         * Overloaded constructor that creates a cognitive engine object and
58         * connects it to either the shell or an SML, depening on the SML bool.
59         *
60         * The 'numFields' parameter sets how large the parameter, observable,
61         * and utility arrays should be upon instantiation.
62         */
63        DSA_CE(const char* serverName, const char* serverPort, \
64                const int32_t numFields, const bool SML);
65
66        void RegisterServices();
67        void DeregisterServices();
68
69        /*! \brief Request that the CE optimize a set of parameters.
70         *
71         * Find the most optimal set of transmission parameters given certain
72         * observables and possibly a service if the SML component is present
73         * and active. */
74        Parameter *GetSolution(Observable *observables, \
75                Parameter *currentParameters);
76        Parameter *GetSolution(Observable *observables, \
77                Parameter *currentParameters, std::string service);
78
79        /*! \brief Receive feedback from the radio
80         *
81         * Receive a feedback from the radio regarding the performance of a
82         * certain set of parameters, possibly associated with a service.
83         *
84         * Feedback is a single set of performance statistics that is achieved
85         * corresponding to a specific set of transmission parameters.  Feedback
86         * helps a Cognitive Engine make better future decisions based upon
87         * more accurate performance statistics.
88         */
89        void ReceiveFeedback(Observable *observables,Parameter *parameters);
90        void ReceiveFeedback(Observable *observables, Parameter *parameters, \
91                std::string service);
92
93
94        /*! \brief Initialize the CE and prepare it for operation.
95         *
96         * BuildCognitiveEngine performs the CE implementation specific work
97         * that defines the internals of a CE.  For example, a CBR CE engine
98         * would build the case-base reasoner or create the database, a neural
99         * network based CE may perform the initial training, a GA based CE
100         * may build the chromosome structure.
101         */
102        void BuildCognitiveEngine();
103
104        /*! \brief Each of these functions responds to a specific command.
105         *
106         * These functions are left principally un-implemented. It is the duty
107         * of child classes to implement these functions, as they define the
108         * cognitive engine's functionality.
109         */
110        void PerformUpdatePerformance();
111        void PerformRequestOptimizationService();
112        void PerformRequestOptimization();
113        void PerformQueryComponentType();
114        void PerformConnectSML();
115        void PerformDisconnectSML();
116        void PerformResetEngineCognitive();
117        void PerformShutdownEngineCognitive();
118
119        CBR *myCBR;
120};
121
122DSA_CE::DSA_CE()
123{
124    LOG("Creating Cognitive Engine.\n");
125    SML_present = false;
126    commandSocketFD = -1;
127    srand(time(NULL));
128}
129
130
131DSA_CE::~DSA_CE()
132{
133    delete myCBR;
134
135    delete [] pList;
136    delete [] oList;
137    delete [] uList;
138    delete [] radioInfo;
139}
140
141
142DSA_CE::DSA_CE(const char* serverName, const char* serverPort, \
143                const int32_t numFields, const bool SML) \
144        : CognitiveEngine(serverName, serverPort, numFields, SML)
145{
146    LOG("Creating Cognitive Engine.\n");
147    srand ( time(NULL) );
148}
149
150
151void
152DSA_CE::RegisterServices()
153{
154    LOG("Cognitive Engine:: Registering services.\n");
155
156    SendMessage(commandSocketFD, "register_service");
157    SendMessage(commandSocketFD, "test_srv");
158
159    SendMessage(commandSocketFD, "register_service");
160    SendMessage(commandSocketFD, "test_srv1");
161
162    SendMessage(commandSocketFD, "register_service");
163    SendMessage(commandSocketFD, "test_srv2");
164
165    SendMessage(commandSocketFD, "register_service");
166    SendMessage(commandSocketFD, "test_srv3");
167
168}
169
170//Combined with deregister component since those two things must happen togeather
171void
172DSA_CE::DeregisterServices()
173{
174    LOG("Cognitive Engine:: Deregistering services.\n");
175
176    SendMessage(commandSocketFD, "deregister_service");
177    SendMessage(commandSocketFD, "test_srv");
178
179    SendMessage(commandSocketFD, "deregister_service");
180    SendMessage(commandSocketFD, "test_srv1");
181
182    SendMessage(commandSocketFD, "deregister_service");
183    SendMessage(commandSocketFD, "test_srv2");
184
185    SendMessage(commandSocketFD, "deregister_service");
186    SendMessage(commandSocketFD, "test_srv3");
187
188}
189
190/* The core of the CE is this function */
191Parameter*
192DSA_CE::GetSolution(Observable *observables, Parameter *currentParameters)
193{
194    LOG("Cognitive Engine:: Generating solution.\n");
195
196    /* Put together the CBR search array */
197
198    uint32_t channel = 0;
199    string searchNames[1];
200    string sumSearchName;
201    float searchVals[1];
202    float utilArray[(int)pList[0].max];
203    int searchOps[1];
204    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
205                             radioInfo->numObservables + 1;
206
207    float returnValues[numberColumns];
208    float sumRetVals[numberColumns];
209   
210    // Total sum of utilities in sumRetVals[0]
211
212    string channel_name = "channel";
213    string utility_name = "utility";
214
215    for(int32_t i = 0 ; i < pList[0].max ; i++ ) {
216        searchNames[0] = pList[0].name;
217        searchOps[0] = 0;
218        searchVals[0] = i+1;
219   
220        uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
221            1, returnValues);
222
223    if(rc == 31337) {
224        // No entry - must add
225       
226            string rowNames[numberColumns];
227            size_t rowIndex = 0;
228            for(size_t j = 0; j < radioInfo->numUtilities; j++) {
229                rowNames[rowIndex] = uList[j].name;
230                rowIndex++;
231            }
232            for(size_t j = 0; j < radioInfo->numParameters; j++) {
233                rowNames[rowIndex] = pList[j].name;
234            if(pList[j].name == "channel")
235                returnValues[rowIndex] = i+1;
236                rowIndex++;
237            }
238            for(size_t j = 0; j < radioInfo->numObservables; j++) {
239                rowNames[rowIndex] = oList[j].name;
240                rowIndex++;
241            }
242   
243            rowNames[rowIndex] = utility_name;
244        returnValues[rowIndex] = 500;
245
246                /* Add the new optimized set to the CBR database */
247
248            myCBR->AddRow(rowNames, returnValues, numberColumns);
249    }
250
251    utilArray[i] = returnValues[UTILITY];
252    }
253
254    printf("Current Channel Utility Scores\n");
255    printf("1: %f\t7: %f\t8: %f\t14: %f\n",utilArray[0],utilArray[1],utilArray[2],utilArray[3]);   
256    // Get sum of all the channel utilities.
257    sumSearchName = utility_name;
258    uint32_t rc = myCBR->SearchSum(sumSearchName, sumRetVals);
259
260    // Psuedo random channel selection based upon utility.
261    int k = rand() % (int)sumRetVals[0];
262    int cdf_total(0);
263
264    for ( int i = 0; i < pList[0].max; i++ ) {
265        cdf_total += utilArray[i];
266        if(k < cdf_total) {
267        channel = i + 1;
268        break;
269    }
270    }
271       
272    searchNames[0] = pList[0].name;
273    searchOps[0] = 0;
274    searchVals[0] = channel;
275 
276    rc = myCBR->Search(searchNames, searchOps, searchVals,
277        1, returnValues);
278
279
280    //returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min;
281    returnValues[CHANNEL] = channel;
282
283    printf("Cognitive Engine:: ..---===***### Channel %i has been selected ###***===---..\n",channel);
284    /* Package up the new set of parameters in order to add
285       the new entry into the CBR database.  */
286
287    size_t returnValueIndex = 0;
288    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
289        uList[i].value = returnValues[returnValueIndex];
290        returnValueIndex++;
291    }
292    for(size_t i = 0; i < radioInfo->numParameters; i++) {
293        pList[i].value = returnValues[returnValueIndex];
294        returnValueIndex++;
295    }
296    for(size_t i = 0; i < radioInfo->numObservables; i++) {
297        oList[i].value = returnValues[returnValueIndex];
298        returnValueIndex++;
299    }
300    //returnValues[returnValueIndex] = 0;
301
302    string allNames[numberColumns];
303    size_t allNameIndex = 0;
304    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
305        allNames[allNameIndex] = uList[i].name;
306        returnValues[allNameIndex] = uList[i].target;
307        allNameIndex++;
308    }
309    for(size_t i = 0; i < radioInfo->numParameters; i++) {
310        allNames[allNameIndex] = pList[i].name;
311        allNameIndex++;
312    }
313    for(size_t i = 0; i < radioInfo->numObservables; i++) {
314        allNames[allNameIndex] = oList[i].name;
315    //    returnValues[allNameIndex] = 0;
316        allNameIndex++;
317    }
318   
319    allNames[allNameIndex] = utility_name;
320
321    /* Add the new optimized set to the CBR database */
322    //myCBR->AddRow(allNames, returnValues, returnValueIndex+1);
323
324
325    /* Return the set of new parameter values.  */
326    return pList;
327}
328
329
330Parameter*
331DSA_CE::GetSolution(Observable *observables, \
332        Parameter *currentParameters, std::string service)
333{
334    LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str());
335
336    return pList;
337}
338
339
340void
341DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters)
342{
343   LOG("Cognitive Engine:: Receiving feedback.\n");
344   
345    uint32_t numberColumns =
346        radioInfo->numParameters;
347
348    uint32_t obsColumns = radioInfo->numObservables + 1;
349    uint32_t numberTotalColumns = radioInfo->numUtilities +
350                    radioInfo->numParameters +
351                    radioInfo->numObservables + 1;
352
353    float valList[numberColumns];
354    float obsVals[numberColumns];
355    string nameList[numberColumns];
356    string obsList[obsColumns];
357    string searchNames[1];
358    float searchVals[1];
359    int searchOps[1];
360    float returnValues[numberTotalColumns];
361
362    size_t columnObsIndex = 0;
363    for (size_t i = 0; i < radioInfo->numObservables; i++){
364        obsList[columnObsIndex] = observables[i].name;
365        columnObsIndex++;
366    } 
367    obsList[columnObsIndex] = "utility";
368
369    size_t columnIndex = 0;
370    for (size_t i = 0; i < radioInfo->numParameters; i++){
371        nameList[columnIndex] = parameters[i].name;
372        columnIndex++;
373    }   
374
375    size_t obsValueIndex = 0;
376    for(size_t i = 0; i < radioInfo->numObservables; i++) {
377        obsVals[obsValueIndex] = observables[i].value;
378        obsValueIndex++;
379    }
380
381    /* Make sure we do not return any entries for the current channel */
382    std::string channel_name = "channel";
383    searchNames[0] = channel_name;
384    searchOps[0] = 0;
385    searchVals[0] = parameters[0].value;
386
387    /* Execute CBR search and put output into returnValues */
388    myCBR->Search(searchNames, searchOps, searchVals,
389            1, returnValues);
390
391    /* Calculate Utility */
392    float oldUtilityValue = returnValues[UTILITY];
393   
394
395    //////////////////////////////////////////////
396    //
397    //  BEGIN CORE DSA ALGORITHM UTILITY FUNCTION
398    //
399    //////////////////////////////////////////////
400 
401    // Set DSA utility to take into account both the previously sensed
402    //  energy and the average communication time.
403
404    float newUtilityValue = oldUtilityValue + observables[COMMUNICATION_TIME].value;
405
406    // If communication time value is set, we know we need to change channels because of PU.
407    // So we should lower the utility for this channel.
408
409    int reward = 20;
410    int punishment = -100;
411    int Detection_Threshold = 10000000;
412
413    if((observables[COMMUNICATION_TIME].value != 0) || (observables[ENERGY].value > Detection_Threshold)) {
414    printf("Cognitive Engine:: Possible PU Detection - Decrementing Utility. %f %f",observables[COMMUNICATION_TIME].value,observables[ENERGY].value);
415    newUtilityValue = newUtilityValue + punishment;
416    } else {
417    printf("Cognitive Engine:: Scan Mode:: No PU detected - Incrementing Utility.");
418    newUtilityValue = newUtilityValue + reward;
419    }
420
421    if(newUtilityValue <= 100)
422    newUtilityValue = 100;
423
424    // Put limit on utility score to prevent a positive feedback loop
425    if(newUtilityValue >= 800)
426    newUtilityValue = 800;
427
428    obsVals[obsValueIndex] = newUtilityValue;
429
430    //////////////////////////////////////////////
431    //
432    //  END CORE DSA ALGORITHM UTILITY FUNCTION
433    //
434    //////////////////////////////////////////////
435
436
437    size_t returnValueIndex = 0;
438    for(size_t i = 0; i < radioInfo->numParameters; i++) {
439        valList[returnValueIndex] = parameters[i].value;
440        returnValueIndex++;
441    }
442
443    myCBR->Update(nameList, obsList, valList, obsVals,
444            numberColumns, obsColumns);
445}
446
447
448void
449DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \
450    std::string service)
451{
452    LOG("Cognitive Engine:: Receiving feedback.\n");
453}
454
455
456void
457DSA_CE::BuildCognitiveEngine()
458{
459    string filename = "ex1";
460    string tablename = "data";
461
462    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \
463                             radioInfo->numObservables + 1;
464
465    string cols[numberColumns];
466
467    size_t columnIndex = 0;
468    for (size_t i = 0; i < radioInfo->numUtilities; i++){
469        cols[columnIndex] = uList[i].name;
470        columnIndex++;
471    }   
472
473    string paramCols[radioInfo->numParameters];
474    size_t paramColumnIndex = 0;
475    // Also need to make parameters the unique key
476    for (size_t i = 0; i < radioInfo->numParameters; i++){
477        cols[columnIndex] = pList[i].name;
478        paramCols[paramColumnIndex] = pList[i].name;
479        columnIndex++;
480        paramColumnIndex++;
481    } 
482
483    for (size_t i = 0; i < radioInfo->numObservables; i++){
484        cols[columnIndex] = oList[i].name;
485        columnIndex++;
486    }   
487   
488    std::string utility_name = "utility";
489    cols[columnIndex] = utility_name;
490
491    myCBR = new CBR(filename, tablename, cols, paramCols, numberColumns, radioInfo->numParameters);
492}
493
494
495void
496DSA_CE::PerformUpdatePerformance()
497{
498    /* Receive Set of current Parameters */
499    char buffer[256];
500    memset(buffer, 0, 256);
501    ReadMessage(commandSocketFD, buffer);
502    uint32_t numParameters = atoi(buffer);
503
504    Parameter *p = new Parameter[numParameters];
505
506    for(size_t i = 0; i < numParameters; i++) {
507        memset(buffer, 0, 256);
508        ReadMessage(commandSocketFD, buffer);
509        p[i].name = std::string(buffer);
510
511        memset(buffer, 0, 256);
512        ReadMessage(commandSocketFD, buffer);
513        p[i].value = atof(buffer);
514    }
515
516    /* Receive Set of Observables */
517    memset(buffer, 0, 256);
518    ReadMessage(commandSocketFD, buffer);
519    uint32_t numObservables = atoi(buffer);
520
521    Observable *o = new Observable[numObservables];
522
523    for(size_t i = 0; i < numObservables; i++) {
524        memset(buffer, 0, 256);
525        ReadMessage(commandSocketFD, buffer);
526        o[i].name = std::string(buffer);
527
528        memset(buffer, 0, 256);
529        ReadMessage(commandSocketFD, buffer);
530        o[i].value = atof(buffer);
531    } 
532
533    ReceiveFeedback(o,p);
534
535    delete [] o;
536    delete [] p;
537}
538
539
540void
541DSA_CE::PerformRequestOptimizationService()
542{
543    // THIS IS CURRENTLY IN DEMO MODE           
544
545
546    /* Receive Set of Observables */
547    LOG("\nCognitive Engine:: Receiving service name\n");
548
549    char buffer[256];
550    memset(buffer, 0, 256);
551    ReadMessage(commandSocketFD,buffer);
552    LOG("\nCognitive Engine:: Got service name, %s\n", buffer);
553
554    /* Receive Set of Observables */
555    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
556
557    memset(buffer, 0, 256);
558    ReadMessage(commandSocketFD,buffer);
559    uint32_t numObservables = atoi(buffer);
560
561    Observable *o = new Observable[numObservables];
562
563    for(size_t i = 0; i < numObservables; i++) {
564        memset(buffer, 0, 256);
565        ReadMessage(commandSocketFD, buffer);
566        o[i].name = std::string(buffer);
567
568        memset(buffer, 0, 256);
569        ReadMessage(commandSocketFD, buffer);
570        o[i].value = atof(buffer);
571    } 
572
573    /* Receive Set of current Parameters */
574    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
575
576    memset(buffer, 0, 256);
577    ReadMessage(commandSocketFD, buffer);
578    uint32_t numCurrentParameters = atoi(buffer);
579
580    Parameter *cp = new Parameter[numCurrentParameters];
581
582    for(size_t i = 0; i < numCurrentParameters; i++) {
583        memset(buffer, 0, 256);
584        ReadMessage(commandSocketFD, buffer);
585        cp[i].name = std::string(buffer);
586
587        memset(buffer, 0, 256);
588        ReadMessage(commandSocketFD, buffer);
589        cp[i].value = atof(buffer);
590    } 
591    LOG("Cognitive Engine:: Processing parameters....\n");
592
593    // TODO need to actually do something with the observables here
594   
595    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
596    char numParametersChar[10];
597    sprintf(numParametersChar, "%i", radioInfo->numParameters);
598    SendMessage(commandSocketFD, numParametersChar);
599    for(size_t i = 0; i < radioInfo->numParameters; i++) {
600        SendMessage(commandSocketFD, "test");
601        SendMessage(commandSocketFD, "00");
602    }
603
604    delete [] o;
605    delete [] cp;
606}
607
608
609void
610DSA_CE::PerformRequestOptimization()
611{
612        /* Receive Set of Observables */
613        LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
614
615    char buffer[256];
616        memset(buffer, 0, 256);
617        ReadMessage(commandSocketFD,buffer);
618        uint32_t numObservables = atoi(buffer);
619
620        Observable *o = new Observable[numObservables];
621
622        for(size_t i = 0; i < numObservables; i++) {
623                memset(buffer, 0, 256);
624                ReadMessage(commandSocketFD, buffer);
625                o[i].name = std::string(buffer);
626
627                memset(buffer, 0, 256);
628                ReadMessage(commandSocketFD, buffer);
629                o[i].value = atof(buffer);
630        } 
631
632        /* Receive Set of current Parameters */
633        LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
634
635        memset(buffer, 0, 256);
636        ReadMessage(commandSocketFD, buffer);
637        uint32_t numCurrentParameters = atoi(buffer);
638
639        Parameter *cp = new Parameter[numCurrentParameters];
640
641        for(size_t i = 0; i < numCurrentParameters; i++) {
642                memset(buffer, 0, 256);
643                ReadMessage(commandSocketFD, buffer);
644                cp[i].name = std::string(buffer);
645
646                memset(buffer, 0, 256);
647                ReadMessage(commandSocketFD, buffer);
648                cp[i].value = atof(buffer);
649        } 
650        LOG("Cognitive Engine:: Processing parameters....\n");
651
652        Parameter *solutionSet;
653       
654        solutionSet = GetSolution(o,cp);
655
656        // TODO need to actually do something with the observables here
657   
658        LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
659        char numParametersChar[10];
660        char solutionValue[50];
661        sprintf(numParametersChar, "%i", radioInfo->numParameters);
662        SendMessage(commandSocketFD, numParametersChar);
663        for(size_t i = 0; i < radioInfo->numParameters; i++) {
664                SendMessage(commandSocketFD, solutionSet[i].name.c_str());
665                memset(solutionValue, 0, 50);
666                sprintf(solutionValue, "%f", solutionSet[i].value);
667                SendMessage(commandSocketFD, solutionValue);
668        }
669
670        delete [] o;
671        delete [] cp;
672}
673
674
675void
676DSA_CE::PerformQueryComponentType()
677{
678        SendComponentType();
679}
680
681
682void
683DSA_CE::PerformConnectSML()
684{
685        /* This command implies that we are disconnecting from the shell and
686         * connecting to a SML component. */
687        char serverName[256];
688        char serverPort[256];
689        // TODO is this going to end up being too slow?
690        memset(serverName, 0, 256);
691        memset(serverPort, 0, 256);
692
693        ReadMessage(commandSocketFD, serverName);
694        ReadMessage(commandSocketFD, serverPort);
695
696        /* Only continue if we are currently connected to a shell. */
697        if(!SML_present) {
698                DeregisterComponent();
699
700                shutdown(commandSocketFD, 2);
701                close(commandSocketFD);
702
703                ConnectToRemoteComponent(serverName, serverPort, true);
704        }
705}
706
707
708void
709DSA_CE::PerformDisconnectSML()
710{
711        /* This command implies that we are disconnecting from the SML and
712         * connecting to a shell component. */
713        char serverName[256];
714        char serverPort[256];
715        // TODO is this going to end up being too slow?
716        memset(serverName, 0, 256);
717        memset(serverPort, 0, 256);
718
719        ReadMessage(commandSocketFD, serverName);
720        ReadMessage(commandSocketFD, serverPort);
721
722        /* We only want to do this if we are actually connected to an SML
723         * currently. */
724        if(SML_present) {
725                DeregisterServices();
726
727                shutdown(commandSocketFD, 2);
728                close(commandSocketFD);
729
730                ConnectToRemoteComponent(serverName, serverPort, false);
731        }
732}
733
734
735void
736DSA_CE::PerformResetEngineCognitive()
737{
738        Reset();
739}
740
741
742void
743DSA_CE::PerformShutdownEngineCognitive()
744{
745        Shutdown();
746}
747 
Note: See TracBrowser for help on using the browser.