root/vtcross/trunk/src/cognitive_engines/CBR_CE/CBR_CE.cpp @ 532

Revision 532, 18.9 KB (checked in by bhilburn, 14 years ago)

Recreated the CognitiveEngine? class, inherited and implemented it with
the CBR_CE test class. Seems to be working so far.

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 a default implementation for a case-based-reasoning based
18 * cognitive engine.
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/containers.h"
31#include "vtcross/debug.h"
32#include "vtcross/error.h"
33#include "vtcross/socketcomm.h"
34
35
36using namespace std;
37
38
39class CBR_CE : public CognitiveEngine
40{
41    public:
42        /*! Default constructor. */
43        CBR_CE(){};
44
45        /*! Default destructor. */
46        ~CBR_CE(){};
47
48        /*! \brief Preferred constructor.
49         *
50         * Overloaded constructor that creates a cognitive engine object and
51         * connects it to either the shell or an SML, depening on the SML bool.
52         *
53         * The 'numFields' parameter sets how large the parameter, observable,
54         * and utility arrays should be upon instantiation.
55         */
56        CBR_CE(const char* serverName, const char* serverPort, \
57                const int32_t numFields, const bool SML) \
58            : CognitiveEngine(serverName, serverPort, numFields, SML){}
59
60
61        void RegisterServices();
62        void DeregisterServices();
63
64        /*! \brief Request that the CE optimize a set of parameters.
65         *
66         * Find the most optimal set of transmission parameters given certain
67         * observables and possibly a service if the SML component is present
68         * and active. */
69        Parameter *GetSolution(Observable *observables, \
70                Parameter *currentParameters);
71        Parameter *GetSolution(Observable *observables, \
72                Parameter *currentParameters, std::string service);
73
74        /*! \brief Receive feedback from the radio
75         *
76         * Receive a feedback from the radio regarding the performance of a
77         * certain set of parameters, possibly associated with a service.
78         *
79         * Feedback is a single set of performance statistics that is achieved
80         * corresponding to a specific set of transmission parameters.  Feedback
81         * helps a Cognitive Engine make better future decisions based upon
82         * more accurate performance statistics.
83         */
84        void ReceiveFeedback(Observable *observables,Parameter *parameters);
85        void ReceiveFeedback(Observable *observables, Parameter *parameters, \
86                std::string service);
87
88
89        /*! \brief Initialize the CE and prepare it for operation.
90         *
91         * BuildCognitiveEngine performs the CE implementation specific work
92         * that defines the internals of a CE.  For example, a CBR CE engine
93         * would build the case-base reasoner or create the database, a neural
94         * network based CE may perform the initial training, a GA based CE
95         * may build the chromosome structure.
96         */
97        void BuildCognitiveEngine();
98
99        /*! \brief Each of these functions responds to a specific command.
100         *
101         * These functions are left principally un-implemented. It is the duty
102         * of child classes to implement these functions, as they define the
103         * cognitive engine's functionality.
104         */
105        void PerformUpdatePerformance();
106        void PerformRequestOptimizationService();
107        void PerformRequestOptimization();
108        void PerformQueryComponentType();
109        void PerformConnectSML();
110        void PerformDisconnectSML();
111        void PerformResetEngineCognitive();
112        void PerformShutdownEngineCognitive();
113
114        CBR *myCBR;
115};
116
117
118void
119CBR_CE::RegisterServices()
120{
121    LOG("Cognitive Engine:: Registering services.\n");
122
123    SendMessage(commandSocketFD, "register_service");
124    SendMessage(commandSocketFD, "test_srv");
125
126    SendMessage(commandSocketFD, "register_service");
127    SendMessage(commandSocketFD, "test_srv1");
128
129    SendMessage(commandSocketFD, "register_service");
130    SendMessage(commandSocketFD, "test_srv2");
131
132    SendMessage(commandSocketFD, "register_service");
133    SendMessage(commandSocketFD, "test_srv3");
134
135}
136
137
138void
139CBR_CE::DeregisterServices()
140{
141    LOG("Cognitive Engine:: Deregistering services.\n");
142
143    SendMessage(commandSocketFD, "deregister_service");
144    SendMessage(commandSocketFD, "test_srv");
145
146    SendMessage(commandSocketFD, "deregister_service");
147    SendMessage(commandSocketFD, "test_srv1");
148
149    SendMessage(commandSocketFD, "deregister_service");
150    SendMessage(commandSocketFD, "test_srv2");
151
152    SendMessage(commandSocketFD, "deregister_service");
153    SendMessage(commandSocketFD, "test_srv3");
154
155}
156
157
158Parameter*
159CBR_CE::GetSolution(Observable *observables, Parameter *currentParameters)
160{
161    LOG("Cognitive Engine:: Generating solution.\n");
162
163    string searchNames[radioInfo->numUtilities];
164
165    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
166        searchNames[i] = observables[i].name;
167    }
168
169    float searchVals[radioInfo->numUtilities];
170
171    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
172        searchVals[i] = uList[i].target;
173    }
174
175    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters \
176                             + radioInfo->numObservables + 1;
177   
178    float returnValues[numberColumns];
179   
180    int searchOps[radioInfo->numUtilities];
181    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
182
183        /* If the goal is to maximum, set the search operation to
184         * return values greater than the target.
185         *
186         * If the goal is to minimize, set the search operation to
187         * return values less than the target.
188         *
189         * NOTE: the values '2' and '4' here are from some old preprocesser
190         * definitions, which I will copy here until I can figure out just what
191         * exactly they were for:
192                42      #define EQ 0    // equals
193                43      #define NE 1    // not equals
194                44      #define GT 2    // greater than
195                45      #define GE 3    // greater than or equal to
196                46      #define LT 4    // less than
197                47      #define LE 5    // less than or equal to
198         */
199        if(strcmp(uList[i].goal.c_str(), "max") == 0) {
200            searchOps[i] = 2;
201        } else if(strcmp(uList[i].goal.c_str(), "min") == 0) {
202            searchOps[i] = 4;
203        }
204    }
205
206    /* CBR specific call */
207    uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals,
208            radioInfo->numUtilities, returnValues);
209
210    if(rc == 0){
211        /* Adapt the returned parameters to meet the objective */
212        LOG("Cognitive Engine:: Found\n");
213
214        /* Should do a random adaptation.. */
215        if(returnValues[numberColumns-1] < 0) {
216            returnValues[2] = returnValues[2] - 15;
217            returnValues[3] = returnValues[3] - 2;
218        } else {
219            returnValues[2] = returnValues[2] + 15;
220            returnValues[3] = returnValues[3] + 2;
221        }
222    } else if(rc == 31337) {
223        LOG("Cognitive Engine:: Not Found.\n");
224        /* No rows in the CBR, pick default parameters */
225        /* Currently this is hard coded and implementation specific! */
226        returnValues[2] = currentParameters[0].value + 5;
227        returnValues[3] = currentParameters[1].value + 10;
228       
229    } else {
230        LOG("Cognitive Engine:: Search return an invalid value.\n");
231    }
232
233    size_t returnValueIndex = 0;
234    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
235        uList[i].value = returnValues[returnValueIndex];
236        returnValueIndex++;
237    }
238    for(size_t i = 0; i < radioInfo->numParameters; i++) {
239        pList[i].value = returnValues[returnValueIndex];
240        returnValueIndex++;
241    }
242    for(size_t i = 0; i < radioInfo->numObservables; i++) {
243        oList[i].value = returnValues[returnValueIndex];
244        returnValueIndex++;
245    }
246    returnValues[returnValueIndex] = 0;
247
248    string allNames[numberColumns];
249    size_t allNameIndex = 0;
250    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
251        allNames[allNameIndex] = uList[i].name;
252        returnValues[allNameIndex] = uList[i].target;
253        allNameIndex++;
254    }
255    for(size_t i = 0; i < radioInfo->numParameters; i++) {
256        allNames[allNameIndex] = pList[i].name;
257        allNameIndex++;
258    }
259    for(size_t i = 0; i < radioInfo->numObservables; i++) {
260        allNames[allNameIndex] = oList[i].name;
261        returnValues[allNameIndex] = 0;
262        allNameIndex++;
263    }
264    allNames[allNameIndex] = "utility";
265
266    // Add row to CBR.
267    myCBR->AddRow(allNames, returnValues, returnValueIndex + 1);
268
269    return pList;
270}
271
272
273Parameter*
274CBR_CE::GetSolution(Observable *observables, \
275        Parameter *currentParameters, std::string service)
276{
277    LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str());
278
279    return pList;
280}
281
282
283void
284CBR_CE::ReceiveFeedback(Observable *observables, Parameter *parameters)
285{
286    LOG("Cognitive Engine:: Receiving feedback.\n");
287   
288    uint32_t numberColumns = radioInfo->numParameters + radioInfo->numUtilities;
289
290    uint32_t obsColumns = radioInfo->numObservables + 1;
291
292    float valList[numberColumns];
293    float obsVals[numberColumns];
294    string nameList[numberColumns];
295    string obsList[obsColumns];
296
297    size_t columnObsIndex = 0;
298    for (size_t i = 0; i < radioInfo->numObservables; i++){
299        obsList[columnObsIndex] = observables[i].name;
300        columnObsIndex++;
301    } 
302    obsList[columnObsIndex] = "utility";
303
304    size_t columnIndex = 0;
305    for (size_t i = 0; i < radioInfo->numParameters; i++){
306        nameList[columnIndex] = parameters[i].name;
307        columnIndex++;
308    }   
309    for (size_t i = 0; i < radioInfo->numUtilities; i++){
310        nameList[columnIndex] = uList[i].name;
311        columnIndex++;
312    }   
313
314    size_t obsValueIndex = 0;
315    for(size_t i = 0; i < radioInfo->numObservables; i++) {
316        obsVals[obsValueIndex] = observables[i].value;
317        obsValueIndex++;
318    }
319
320    /* Calculate Utility */
321    float newUtilityValue = 0;
322
323    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
324        newUtilityValue = newUtilityValue + (uList[i].target - observables[i].value);
325    }
326    obsVals[obsValueIndex] = newUtilityValue;
327
328    size_t returnValueIndex = 0;
329    for(size_t i = 0; i < radioInfo->numParameters; i++) {
330        valList[returnValueIndex] = parameters[i].value;
331        returnValueIndex++;
332    }
333    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
334        valList[returnValueIndex] = uList[i].target;
335        returnValueIndex++;
336    }
337}
338
339
340void
341CBR_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \
342    std::string service)
343{
344    LOG("Cognitive Engine:: Receiving feedback.\n");
345}
346
347
348void
349CBR_CE::BuildCognitiveEngine()
350{
351    string filename = "ex1";
352    string tablename = "data";
353
354    uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters \
355                             + radioInfo->numObservables + 1;
356
357    string cols[numberColumns];
358
359    size_t columnIndex = 0;
360    for (size_t i = 0; i < radioInfo->numUtilities; i++){
361        cols[columnIndex] = uList[i].name;
362        columnIndex++;
363    }   
364    for (size_t i = 0; i < radioInfo->numParameters; i++){
365        cols[columnIndex] = pList[i].name;
366        columnIndex++;
367    }   
368    for (size_t i = 0; i < radioInfo->numObservables; i++){
369        cols[columnIndex] = oList[i].name;
370        columnIndex++;
371    }   
372    cols[columnIndex] = "utility";
373
374    myCBR = new CBR(filename, tablename, cols, numberColumns);
375}
376
377
378void
379CBR_CE::PerformUpdatePerformance()
380{
381    /* Receive Set of current Parameters */
382    char buffer[256];
383    memset(buffer, 0, 256);
384    ReadMessage(commandSocketFD, buffer);
385    uint32_t numParameters = atoi(buffer);
386
387    Parameter *p = new Parameter[numParameters];
388
389    for(size_t i = 0; i < numParameters; i++) {
390        memset(buffer, 0, 256);
391        ReadMessage(commandSocketFD, buffer);
392        p[i].name = std::string(buffer);
393
394        memset(buffer, 0, 256);
395        ReadMessage(commandSocketFD, buffer);
396        p[i].value = atof(buffer);
397    }
398
399    /* Receive Set of Observables */
400    memset(buffer, 0, 256);
401    ReadMessage(commandSocketFD, buffer);
402    uint32_t numObservables = atoi(buffer);
403
404    Observable *o = new Observable[numObservables];
405
406    for(size_t i = 0; i < numObservables; i++) {
407        memset(buffer, 0, 256);
408        ReadMessage(commandSocketFD, buffer);
409        o[i].name = std::string(buffer);
410
411        memset(buffer, 0, 256);
412        ReadMessage(commandSocketFD, buffer);
413        o[i].value = atof(buffer);
414    } 
415
416    ReceiveFeedback(o, p);
417
418    delete [] o;
419    delete [] p;
420}
421
422
423void
424CBR_CE::PerformRequestOptimizationService()
425{
426   // THIS IS CURRENTLY IN DEMO MODE           
427
428    /* Receive Set of Observables */
429    LOG("\nCognitive Engine:: Receiving service name\n");
430
431    char buffer[256];
432    memset(buffer, 0, 256);
433    ReadMessage(commandSocketFD,buffer);
434    LOG("\nCognitive Engine:: Got service name, %s\n", buffer);
435
436    /* Receive Set of Observables */
437    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
438
439    memset(buffer, 0, 256);
440    ReadMessage(commandSocketFD,buffer);
441    uint32_t numObservables = atoi(buffer);
442
443    Observable *o = new Observable[numObservables];
444
445    for(size_t i = 0; i < numObservables; i++) {
446        memset(buffer, 0, 256);
447        ReadMessage(commandSocketFD, buffer);
448        o[i].name = std::string(buffer);
449
450        memset(buffer, 0, 256);
451        ReadMessage(commandSocketFD, buffer);
452        o[i].value = atof(buffer);
453    } 
454
455    /* Receive Set of current Parameters */
456    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
457
458    memset(buffer, 0, 256);
459    ReadMessage(commandSocketFD, buffer);
460    uint32_t numCurrentParameters = atoi(buffer);
461
462    Parameter *cp = new Parameter[numCurrentParameters];
463
464    for(size_t i = 0; i < numCurrentParameters; i++) {
465        memset(buffer, 0, 256);
466        ReadMessage(commandSocketFD, buffer);
467        cp[i].name = std::string(buffer);
468
469        memset(buffer, 0, 256);
470        ReadMessage(commandSocketFD, buffer);
471        cp[i].value = atof(buffer);
472    } 
473    LOG("Cognitive Engine:: Processing parameters....\n");
474
475    //Parameter *solutionSet;
476   
477    //solutionSet = GetSolution(o,cp);
478
479    // TODO need to actually do something with the observables here
480   
481    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
482    char numParametersChar[10];
483    //char solutionValue[50];
484    sprintf(numParametersChar, "%i", radioInfo->numParameters);
485    SendMessage(commandSocketFD, numParametersChar);
486    for(size_t i = 0; i < radioInfo->numParameters; i++) {
487        // TODO What's with all the commented-out code?
488        //SendMessage(commandSocketFD, solutionSet[i].name.c_str());
489        SendMessage(commandSocketFD, "test");
490        //memset(solutionValue, 0, 50);
491        //sprintf(solutionValue, "%f", solutionSet[i].value);
492        //SendMessage(commandSocketFD, solutionValue);
493        SendMessage(commandSocketFD, "00");
494    }
495
496    delete [] o;
497    delete [] cp;
498
499}
500
501
502void
503CBR_CE::PerformRequestOptimization()
504{
505    /* Receive Set of Observables */
506    LOG("\nCognitive Engine:: Receiving Observable Parameters\n");
507
508    char buffer[256];
509    memset(buffer, 0, 256);
510    ReadMessage(commandSocketFD,buffer);
511    uint32_t numObservables = atoi(buffer);
512
513    Observable *o = new Observable[numObservables];
514
515    for(size_t i = 0; i < numObservables; i++) {
516        memset(buffer, 0, 256);
517        ReadMessage(commandSocketFD, buffer);
518        o[i].name = std::string(buffer);
519
520        memset(buffer, 0, 256);
521        ReadMessage(commandSocketFD, buffer);
522        o[i].value = atof(buffer);
523    } 
524
525    /* Receive Set of current Parameters */
526    LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
527
528    memset(buffer, 0, 256);
529    ReadMessage(commandSocketFD, buffer);
530    uint32_t numCurrentParameters = atoi(buffer);
531
532    Parameter *cp = new Parameter[numCurrentParameters];
533
534    for(size_t i = 0; i < numCurrentParameters; i++) {
535        memset(buffer, 0, 256);
536        ReadMessage(commandSocketFD, buffer);
537        cp[i].name = std::string(buffer);
538
539        memset(buffer, 0, 256);
540        ReadMessage(commandSocketFD, buffer);
541        cp[i].value = atof(buffer);
542    } 
543    LOG("Cognitive Engine:: Processing parameters....\n");
544
545    Parameter *solutionSet;
546   
547    solutionSet = GetSolution(o,cp);
548
549    // TODO need to actually do something with the observables here
550   
551    LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
552    char numParametersChar[10];
553    char solutionValue[50];
554    sprintf(numParametersChar, "%i", radioInfo->numParameters);
555    SendMessage(commandSocketFD, numParametersChar);
556    for(size_t i = 0; i < radioInfo->numParameters; i++) {
557        SendMessage(commandSocketFD, solutionSet[i].name.c_str());
558        memset(solutionValue, 0, 50);
559        sprintf(solutionValue, "%f", solutionSet[i].value);
560        SendMessage(commandSocketFD, solutionValue);
561    }
562
563    delete [] o;
564    delete [] cp;
565}
566
567
568void
569CBR_CE::PerformQueryComponentType()
570{
571    SendComponentType();
572}
573
574
575void
576CBR_CE::PerformConnectSML()
577{
578    /* This command implies that we are disconnecting from the shell and
579     * connecting to a SML component. */
580    char serverName[256];
581    char serverPort[256];
582
583    // TODO is this going to end up being too slow?
584    memset(serverName, 0, 256);
585    memset(serverPort, 0, 256);
586
587    ReadMessage(commandSocketFD, serverName);
588    ReadMessage(commandSocketFD, serverPort);
589
590    /* Only continue if we are currently connected to a shell. */
591    if(!SML_present) {
592        DeregisterComponent();
593
594        shutdown(commandSocketFD, 2);
595        close(commandSocketFD);
596
597        ConnectToRemoteComponent(serverName, serverPort, true);
598    }
599}
600
601
602void
603CBR_CE::PerformDisconnectSML()
604{
605    /* This command implies that we are disconnecting from the SML and
606     * connecting to a shell component. */
607    char serverName[256];
608    char serverPort[256];
609
610    // TODO is this going to end up being too slow?
611    memset(serverName, 0, 256);
612    memset(serverPort, 0, 256);
613
614    ReadMessage(commandSocketFD, serverName);
615    ReadMessage(commandSocketFD, serverPort);
616
617    /* We only want to do this if we are actually connected to an SML
618     * currently. */
619    if(SML_present) {
620        DeregisterServices();
621
622        shutdown(commandSocketFD, 2);
623        close(commandSocketFD);
624
625        ConnectToRemoteComponent(serverName, serverPort, false);
626    }
627}
628
629
630void
631CBR_CE::PerformResetEngineCognitive()
632{
633    Reset();
634}
635
636
637void
638CBR_CE::PerformShutdownEngineCognitive()
639{
640    Shutdown();
641}
642 
Note: See TracBrowser for help on using the browser.