Fast Research Interface Library  Manual and Documentation
src/FastResearchInterfaceLibrary/DataLogging.cpp
Go to the documentation of this file.
00001 //  ---------------------- Doxygen info ----------------------
00051 //  ----------------------------------------------------------
00052 //   For a convenient reading of this file's source code,
00053 //   please use a tab width of four characters.
00054 //  ----------------------------------------------------------
00055 
00056 
00057 #include <DataLogging.h>
00058 #include <FastResearchInterface.h>
00059 #include <OSAbstraction.h>
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <time.h>
00063 #include <errno.h>
00064 #include <string.h>
00065 
00066 
00067 
00068 #define NUMBER_OF_ELEMENTS_PER_ENTRY    58
00069 #define OUTPUT_FILE_STRING_LENGTH       1024
00070 #define TIME_STRING_LENGTH              128
00071 
00072 #ifndef PI
00073 #define PI          3.1415926535897932384626433832795
00074 #endif
00075 
00076 #ifndef RAD
00077 #define RAD(A)  ((A) * PI / 180.0 )
00078 #endif
00079 
00080 #ifndef DEG
00081 #define DEG(A)  ((A) * 180.0 / PI )
00082 #endif
00083 
00084 
00085 // ****************************************************************
00086 // Constructor 
00087 //
00088 DataLogging::DataLogging(       const char          *RobotName
00089                             ,   const char          *LoggingPath
00090                             ,   const char          *LoggingFileName
00091                             ,   const unsigned int  &MaxNumberOfEntries)
00092 {
00093     unsigned int            i       =   0;
00094 
00095     this->MachineName               =   (char*)RobotName;
00096     this->OutputPath                =   (char*)LoggingPath;
00097     this->OutputFileName            =   (char*)LoggingFileName;
00098     this->MaximumNumberOfEntries    =   MaxNumberOfEntries;
00099     this->CurrentObjectState        =   DataLogging::WriteToFileCalled;
00100     this->OutputFileHandler         =   NULL;
00101     this->OutputCounter             =   0;
00102     this->CurrentControlScheme      =   0;
00103 
00104     this->LoggingMemory             =   new float*[NUMBER_OF_ELEMENTS_PER_ENTRY];
00105 
00106     for (i = 0; i < NUMBER_OF_ELEMENTS_PER_ENTRY; i++)
00107     {
00108         this->LoggingMemory[i]      =   new float[MaxNumberOfEntries];
00109 
00110         memset(     this->LoggingMemory[i]
00111                ,    0x0
00112                ,    this->MaximumNumberOfEntries * sizeof(float)    );
00113     }
00114 
00115     this->CompleteOutputFileString  =   new char[OUTPUT_FILE_STRING_LENGTH];
00116 
00117     memset(     this->CompleteOutputFileString
00118             ,   0x0
00119             ,   OUTPUT_FILE_STRING_LENGTH * sizeof(char));
00120 
00121 }
00122 
00123 
00124 // ****************************************************************
00125 // Destructor
00126 //
00127 DataLogging::~DataLogging(void)
00128 {
00129     unsigned int            i       =   0;
00130 
00131     if (this->CurrentObjectState == DataLogging::PrepareLoggingCalled)
00132     {
00133         this->WriteToFile();
00134     }
00135 
00136     for (i = 0; i < NUMBER_OF_ELEMENTS_PER_ENTRY; i++)
00137     {
00138         delete[]    LoggingMemory[i];
00139     }
00140 
00141     delete[]    LoggingMemory;
00142     delete[]    this->CompleteOutputFileString;
00143 }
00144 
00145 
00146 // ****************************************************************
00147 // PrepareLogging()
00148 //
00149 int DataLogging::PrepareLogging(        const unsigned int  &ControlScheme
00150                                     ,   const char          *FileIdentifier)
00151 {
00152     char                TimeString[TIME_STRING_LENGTH];
00153 
00154     unsigned int        i       =   0;
00155 
00156     time_t              CurrentDayTime;
00157 
00158     memset(     TimeString
00159             ,   0x0
00160             ,   TIME_STRING_LENGTH * sizeof(char));
00161 
00162     this->CurrentControlScheme  =   ControlScheme;
00163 
00164     if (this->CurrentObjectState    ==  DataLogging::PrepareLoggingCalled)
00165     {
00166         this->WriteToFile();
00167     }
00168 
00169     GetSystemTimeInSeconds(true);
00170 
00171 
00172 
00173     //REMOVE
00174 
00175     //------------------------
00176     
00177 #ifdef _NTO_    
00178     
00179     struct _clockperiod     ClockResolution;
00180 
00181     ClockResolution.nsec = 10000;   //ns
00182     ClockResolution.fract = 0;
00183 
00184     ClockPeriod(CLOCK_REALTIME, &ClockResolution, NULL, 0);
00185     //------------------------
00186     
00187 #endif
00188 
00189     memset(     this->CompleteOutputFileString
00190             ,   0x0
00191             ,   OUTPUT_FILE_STRING_LENGTH * sizeof(char));
00192 
00193     for (i = 0; i < NUMBER_OF_ELEMENTS_PER_ENTRY; i++)
00194     {
00195         memset(     this->LoggingMemory[i]
00196                ,    0x0
00197                ,    this->MaximumNumberOfEntries * sizeof(float)    );
00198     }
00199 
00200     CurrentDayTime = time(NULL);
00201     strftime(TimeString, TIME_STRING_LENGTH, "%y%m%d-%H%M%S", localtime(&CurrentDayTime));
00202     if (FileIdentifier == NULL)
00203     {
00204         sprintf(this->CompleteOutputFileString, "%s%s-%s-%s", this->OutputPath, TimeString, this->MachineName, this->OutputFileName);
00205     }
00206     else
00207     {
00208         sprintf(this->CompleteOutputFileString, "%s%s-%s-%s-%s", this->OutputPath, TimeString, FileIdentifier, this->MachineName, this->OutputFileName);
00209     }
00210 
00211     if ( (this->OutputFileHandler = fopen(this->CompleteOutputFileString, "w") ) == NULL)
00212     {
00213         return(EBADF);
00214     }
00215     else
00216     {
00217         fprintf(this->OutputFileHandler, "Logging file of the KUKA Fast Research Interface: %s\n", this->CompleteOutputFileString);
00218         fprintf(this->OutputFileHandler, "This file contains all important control values and importable to Matlab and MS Excel.\n");
00219         fprintf(this->OutputFileHandler, "%s\n", ctime( &CurrentDayTime));
00220         fprintf(this->OutputFileHandler, "Robot name: %s\n", this->MachineName);
00221 
00222         switch (this->CurrentControlScheme)
00223         {
00224         case FastResearchInterface::JOINT_POSITION_CONTROL:
00225             fprintf(this->OutputFileHandler, "Active control scheme: joint position control\n\n");
00226             fprintf(this->OutputFileHandler, "Counter   KRCTime LocalTime   ActFJ1  ActFJ2  ActFJ3  ActFJ4  ActFJ5  ActFJ6  ActFJ7  UDesJ1  UDesJ2  UDesJ3  UDesJ4  UDesJ5  UDesJ6  UDesJ7  ActJ1   ActJ2   ActJ3   ActJ4   ActJ5   ActJ6   ActJ7   KDesJ1  KDesJ2  KDesJ3  KDesJ4  KDesJ5  KDesJ6  KDesJ7\n");
00227             break;
00228         case FastResearchInterface::CART_IMPEDANCE_CONTROL:
00229             fprintf(this->OutputFileHandler, "Active control scheme: Cartesian impedance control\n\n");
00230             fprintf(this->OutputFileHandler, "Counter   KRCTime LocalTime   DesKx   DesKy   DesKz   DesKa   DesKb   DesKc   DesDx   DesDy   DesDz   DesDa   DesDb   DesDc   UDesFx  UDesFy  UDesFz  UDesFa  UDesFb  UDesFc\n");
00231             break;
00232         case FastResearchInterface::JOINT_IMPEDANCE_CONTROL:
00233             fprintf(this->OutputFileHandler, "Active control scheme: joint impedance control\n\n");
00234             fprintf(this->OutputFileHandler, "Counter   KRCTime LocalTime   ActFJ1  ActFJ2  ActFJ3  ActFJ4  ActFJ5  ActFJ6  ActFJ7  UDesPJ1 UDesPJ2 UDesPJ3 UDesPJ4 UDesPJ5 UDesPJ6 UDesPJ7 ActPJ1  ActPJ2  ActPJ3  ActPJ4  ActPJ5  ActPJ6  ActPJ7  KDesPJ1 KDesPJ2 KDesPJ3 KDesPJ4 KDesPJ5 KDesPJ6 KDesPJ7 DesKJ1  DesKJ2  DesKJ3  DesKJ4  DesKJ5  DesKJ6  DesKJ7  DesDJ1  DesDJ2  DesDJ3  DesDJ4  DesDJ5  DesDJ6  DesDJ7  UDesFJ1 UDesFJ2 UDesFJ3 UDesFJ4 UDesFJ5 UDesFJ6 UDesFJ7 KOffPJ1 KOffPJ2 KOffPJ3 KOffPJ4 KOffPJ5 KOffPJ6 KOffPJ7\n");
00235             break;
00236         default:
00237             return(EINVAL);
00238         }
00239     }
00240 
00241     fflush(this->OutputFileHandler);
00242 
00243     this->CurrentObjectState    =   DataLogging::PrepareLoggingCalled;
00244     this->OutputCounter         =   0;
00245 
00246     return(EOK);
00247 }
00248 
00249 
00250 // ****************************************************************
00251 // AddEntry()
00252 //
00253 void DataLogging::AddEntry(     const tFriMsrData       &ReceivedFRIData
00254                             ,   const tFriCmdData       &SentFRIData        )
00255 {
00256     unsigned int            i       =   0;
00257 
00258     this->LoggingMemory[ 0][this->OutputCounter % this->MaximumNumberOfEntries] =   ReceivedFRIData.intf.timestamp;
00259     this->LoggingMemory[ 1][this->OutputCounter % this->MaximumNumberOfEntries] =   GetSystemTimeInSeconds();
00260 
00261     if (this->CurrentControlScheme == FastResearchInterface::JOINT_POSITION_CONTROL)
00262     {
00263         for (i = 0; i < LBR_MNJ; i++)
00264         {
00265             this->LoggingMemory[ 2 +               i][this->OutputCounter % this->MaximumNumberOfEntries] =         ReceivedFRIData.data.msrJntTrq  [i] ;
00266             this->LoggingMemory[ 2 + 1 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    SentFRIData.cmd.jntPos          [i]);
00267             this->LoggingMemory[ 2 + 2 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    ReceivedFRIData.data.msrJntPos  [i]);
00268             this->LoggingMemory[ 2 + 3 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    ReceivedFRIData.data.cmdJntPos  [i]);
00269         }
00270     }
00271 
00272     if (this->CurrentControlScheme == FastResearchInterface::CART_IMPEDANCE_CONTROL)
00273     {
00274         for (i = 0; i < FRI_CART_VEC; i++)
00275         {
00277             this->LoggingMemory[ 2 +                    i][this->OutputCounter % this->MaximumNumberOfEntries] = SentFRIData.cmd.cartStiffness      [i];
00278             this->LoggingMemory[ 2 + 1 * FRI_CART_VEC + i][this->OutputCounter % this->MaximumNumberOfEntries] = SentFRIData.cmd.cartDamping        [i];
00279             this->LoggingMemory[ 2 + 2 * FRI_CART_VEC + i][this->OutputCounter % this->MaximumNumberOfEntries] = SentFRIData.cmd.addTcpFT           [i];
00280         }
00281     }
00282 
00283     if (this->CurrentControlScheme == FastResearchInterface::JOINT_IMPEDANCE_CONTROL)
00284     {
00285         for (i = 0; i < LBR_MNJ; i++)
00286         {
00287             this->LoggingMemory[ 2 +               i][this->OutputCounter % this->MaximumNumberOfEntries] =         ReceivedFRIData.data.msrJntTrq          [i] ;
00288             this->LoggingMemory[ 2 +     LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    SentFRIData.cmd.jntPos                  [i]);
00289             this->LoggingMemory[ 2 + 2 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    ReceivedFRIData.data.msrJntPos          [i]);
00290             this->LoggingMemory[ 2 + 3 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    ReceivedFRIData.data.cmdJntPos          [i]);
00291             this->LoggingMemory[ 2 + 4 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] =         SentFRIData.cmd.jntStiffness            [i] ;
00292             this->LoggingMemory[ 2 + 5 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] =         SentFRIData.cmd.jntDamping              [i] ;
00293             this->LoggingMemory[ 2 + 6 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] =         SentFRIData.cmd.addJntTrq               [i] ;
00294             this->LoggingMemory[ 2 + 7 * LBR_MNJ + i][this->OutputCounter % this->MaximumNumberOfEntries] = DEG(    ReceivedFRIData.data.cmdJntPosFriOffset [i]);
00295         }
00296     }
00297 
00298     this->OutputCounter++;
00299 
00300     return;
00301 }
00302 
00303 
00304 // ****************************************************************
00305 // WriteToFile()
00306 //
00307 int DataLogging::WriteToFile(void)
00308 {
00309     int                 ReturnValue         =   0;
00310 
00311     unsigned int        StartIndex          =   0
00312                     ,   StopIndex           =   0
00313                     ,   Counter             =   0
00314                     ,   i                   =   0
00315                     ,   ElementsPerLine     =   0;
00316 
00317     if (this->CurrentObjectState    !=  DataLogging::PrepareLoggingCalled)
00318     {
00319         return(EPERM);
00320     }
00321     else
00322     {
00323         this->CurrentObjectState    =   DataLogging::WriteToFileCalled;
00324     }
00325 
00326     //REMOVE
00327     //------------------------
00328 #ifdef _NTO_        
00329     struct _clockperiod     ClockResolution;
00330 
00331     ClockResolution.nsec = 1000000; //ns
00332     ClockResolution.fract = 0;
00333 
00334     ClockPeriod(CLOCK_REALTIME, &ClockResolution, NULL, 0);
00335 #endif
00336     //------------------------
00337 
00338     if (this->OutputCounter > this->MaximumNumberOfEntries)
00339     {
00340         StartIndex  =   (this->OutputCounter + 1) % this->MaximumNumberOfEntries;
00341         StopIndex   =   StartIndex + this->MaximumNumberOfEntries - 1;
00342     }
00343     else
00344     {
00345         StartIndex  =   0;
00346         StopIndex   =   this->OutputCounter - 1;
00347     }
00348 
00349     switch (this->CurrentControlScheme)
00350     {
00351     case FastResearchInterface::JOINT_POSITION_CONTROL:
00352         ElementsPerLine =   2 + 4 * LBR_MNJ;
00353         break;
00354     case FastResearchInterface::CART_IMPEDANCE_CONTROL:
00355         ElementsPerLine =   2 + 3 * FRI_CART_VEC;
00356         break;
00357     case FastResearchInterface::JOINT_IMPEDANCE_CONTROL:
00358         ElementsPerLine =   2 + 8 * LBR_MNJ;
00359         break;
00360     default:
00361         return(EINVAL);
00362     }
00363 
00364     while (StopIndex >= StartIndex)
00365     {
00366         Counter++;
00367         fprintf(this->OutputFileHandler, "%d", Counter);
00368         for (i = 0; i < ElementsPerLine; i++)
00369         {
00370             fprintf(this->OutputFileHandler, "  %12.6f", this->LoggingMemory[i][StartIndex]);
00371         }
00372         fprintf(this->OutputFileHandler, "\n");
00373         StartIndex++;
00374     }
00375 
00376     fflush(this->OutputFileHandler);
00377     ReturnValue =   fclose(this->OutputFileHandler);
00378 
00379     if (ReturnValue == 0)
00380     {
00381         return(EOK);
00382     }
00383     else
00384     {
00385         return(ReturnValue);
00386     }
00387 }
00388 
This document was generated with Doxygen on Thu Apr 12 2012 11:18:54. User documentation of the Fast Research Interface Library for the KUKA Lightweight Robot IV by the Stanford Robotics Research Group. Copyright 2010–2012.