root/vtcross/branches/engineTreeFix/src/cognitive_engines/DSA_CE/DSA_CognitiveEngine.cpp @ 526

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