00001 /*************************************************************** 00002 00003 Mini Grand Challenge 2010 00004 Pennsylvania State University - Robotics Club 00005 Learn more at www.psurobotics.org 00006 Protected by the GNU General Public License 00007 00008 This source file is developed and maintained by: 00009 + Jeremy Bridon jgbridon@gmail.com 00010 00011 File: BaseComponent.cpp/h 00012 Desc: The base class that all components should derive from. 00013 This class is a pure virtual class and cannot be instantiated. 00014 To create a component, you must create your own class and derive 00015 from this class. You must overload the "Update" function with 00016 your own code. Update is managed, such that it is only called when 00017 there is new data and/or when the allocated time block is appropriate. 00018 The interla I/O is managed with the communications class. 00019 00020 A configuration file may also be loaded by this base component. 00021 The config file loaded is "[component name].cfg". The component name 00022 for the file *must* be all lowercase. The contents of the config 00023 file must be key-data pairs. The key string must not be spaced and 00024 then followed by any data form (int, float, string) that ends with 00025 the newline (or end of file). There is a finite number of data pairs 00026 that can be saved (see the constant), but length is of variable size. 00027 You must use the "LoadInt", "LoadFloat", or "LoadString" functions. 00028 The only pre-defined string/data pair is the server IP (defined as 00029 "ServerIP") and the port (defined as "ServerPort"). 00030 00031 BaseComponent does spit out three data types that are associated 00032 with performance measuremens. This is send out every one (1) seconds. 00033 These data type names are as follows, with the respective data type 00034 and description: 00035 00036 PerformanceInputTime is of type float - Average time recieved input took 00037 PerformanceCycleCount is of type int - Update call count in one (1) seconds 00038 PerformanceCycleTime is of type float - The time each update call took 00039 00040 More performance variables may be posted as this class is still under 00041 development. 00042 00043 NOTE: 00044 THIS CURRENT IMPLEMENTATION *DOES* FULLY SUPPORT MULTI-PAGE DATA, 00045 but it is not yet checked! 00046 00047 NOTE 2: 00048 WE MUST VALIDATE THE NEW DICTIONARY USE! Validation and performance 00049 testing is needed! 00050 00051 NOTE 3: 00052 There is a possible performance / query issue which is if multiple 00053 components query the same data, does only one get it or both get it? 00054 00055 ***************************************************************/ 00056 00057 // Inclusion guard 00058 #ifndef __BASECOMPONENT_H_ 00059 #define __BASECOMPONENT_H_ 00060 00061 // Standard includes 00062 #include "Utilities.h" 00063 #include "Dictionary.h" 00064 00065 #include <string.h> // Used as the key-type for the internal map / dictionary 00066 00068 #define COMMODEL_QUEUE_SIZE 1 00069 00070 // Define some special constants that are used for all IPC communications 00072 #define COMMODEL_NAME "ComModelData" 00073 00075 #define COMMODEL_STRUCT "{[char: 64], [char: 64], [char: 1024], int, int, int, int, int, int}" 00076 00077 // Define the sizes which are seen above in COMMODEL_STRUCT 00078 #define COMMODEL_DATATYPE_NAMELENGTH 64 00079 #define COMMODEL_DATAPAGE_SIZE 1024 00080 00081 // Define the look-up table of the config file 00082 #define CONFIG_TABLE_LENGTH 32 00083 00084 // Define the performance counter size 00085 #define INPUT_TIMES_MAX 16 00086 00087 00092 struct ComModelDataPage 00093 { 00094 // Buffers 00095 char OriginComponent[COMMODEL_DATATYPE_NAMELENGTH]; 00096 char DataType[COMMODEL_DATATYPE_NAMELENGTH]; 00097 char Data[COMMODEL_DATAPAGE_SIZE]; 00098 00099 // Lengths 00100 int DataLength; 00101 int TotalDataLength; 00102 int PageID; 00103 int PageCount; 00104 00105 // Time that this message is posted (Specific to the sent-system info); Since OS epoch time 00106 unsigned int Seconds; 00107 unsigned int Milliseconds; 00108 }; 00109 00112 struct ComModelBlock 00113 { 00114 // Buffers 00115 char* DataBuffer; 00116 int BufferByteSize; 00117 00118 // Time the message is posted (Specific to the sent-system info); Since OS epoch time 00119 unsigned int Seconds; 00120 unsigned int Milliseconds; 00121 }; 00122 00124 class BaseComponent 00125 { 00126 00127 protected: 00128 00133 BaseComponent(const char* ComponentName, float AllocatedTime, const char* CentralIP = NULL, int Port = 1381); 00134 00136 ~BaseComponent(); 00137 00139 void SetDependency(const char* GivenComponentName); 00140 00144 virtual int Update() = 0; // Pure virtual function 00145 00146 00150 bool LoadInt(const char* Key, int* Data); 00151 00155 bool LoadFloat(const char* Key, float* Data); 00156 00161 bool LoadString(const char* Key, char** Data); 00162 00164 static void __Run(); 00165 00166 public: 00167 00170 void Stop(); 00171 00174 void Run(); 00175 00176 /* I don't like putting these files in public, but the choice is to 00177 * either put general image sending code in BaseComponent, or let 00178 * functions outside BaseComponent send and receive data. 00179 */ 00180 00184 int GetDataByteCount(const char* ComponentName, const char* DataType); 00185 00191 int GetData(const char* ComponentName, const char* DataType, void* DataBuffer, unsigned int* SecondsSent = NULL, unsigned int* MillisecondsSent = NULL); 00192 00196 int SendData(const char* DataType, const void* DataBuffer, int BufferByteSize); 00197 private: 00198 00200 ComModelBlock* GetDataBlock(const char* GivenComponentName, const char* GivenDataType); 00201 00204 int LoadConfig(const char* FileName); 00205 00207 char* ConfigTable[CONFIG_TABLE_LENGTH][2]; 00208 00210 bool RunLoop; 00211 00213 float AllocatedTime; 00214 00215 // Client / server info for CMU IPC 00216 char* ComponentName; 00217 char* CentralIP; 00218 int Port; 00219 00220 }; 00221 00222 // End of inclusion guard 00223 #endif
1.5.5