Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <math.h>
00019 #include <vector>
00020 #include <stdio.h>
00021 #include <sstream>
00022 #include <cob_canopen_motor/ElmoRecorder.h>
00023 #include <cob_canopen_motor/CanDriveHarmonica.h>
00024
00025 ElmoRecorder::ElmoRecorder(CanDriveHarmonica * pParentHarmonicaDrive) {
00026 m_pHarmonicaDrive = pParentHarmonicaDrive;
00027
00028 m_bIsInitialized = false;
00029 m_iReadoutRecorderTry = 0;
00030 }
00031
00032 ElmoRecorder::~ElmoRecorder() {
00033 }
00034
00035 bool ElmoRecorder::isInitialized(bool initNow) {
00036 if(initNow) m_bIsInitialized = true;
00037 return m_bIsInitialized;
00038 }
00039
00040 int ElmoRecorder::configureElmoRecorder(int iRecordingGap, int driveID, int startImmediately){
00041 m_iDriveID = driveID;
00042
00043 if(startImmediately >=2 ) startImmediately = 1;
00044
00045 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'R', 0, 0);
00046
00047
00048
00049
00050
00051 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'C', 0, 33283);
00052
00053 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'P', 3, 0);
00054
00055 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'G', 0, iRecordingGap);
00056
00057
00058 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'L', 0, 1024);
00059
00060
00061
00062
00063
00064 m_pHarmonicaDrive->IntprtSetInt(8, 'R', 'R', 0, startImmediately + 1);
00065
00066 m_fRecordingStepSec = 0.000090 * 4 * iRecordingGap;
00067
00068 return 0;
00069 }
00070
00071 int ElmoRecorder::readoutRecorderTry(int iObjSubIndex) {
00072
00073
00074
00075 m_iReadoutRecorderTry = 1;
00076 m_iCurrentObject = iObjSubIndex;
00077
00078 m_pHarmonicaDrive->requestStatus();
00079
00080 return 0;
00081 }
00082
00083 int ElmoRecorder::readoutRecorderTryStatus(int iStatusReg, segData& SDOData) {
00084 if(m_iReadoutRecorderTry == 0) return 0;
00085
00086 m_iReadoutRecorderTry = 0;
00087
00088
00089 int iRecorderStatus = (0x30000 & iStatusReg) >> 16;
00090
00091 if(iRecorderStatus == 0) {
00092 std::cout << "Recorder " << m_iDriveID << " inactive with no valid data to upload" << std::endl;
00093 SDOData.statusFlag = segData::SDO_SEG_FREE;
00094 } else if(iRecorderStatus == 1) {
00095 std::cout << "Recorder " << m_iDriveID << " waiting for a trigger event" << std::endl;
00096 SDOData.statusFlag = segData::SDO_SEG_FREE;
00097 } else if(iRecorderStatus == 2) {
00098 std::cout << "Recorder " << m_iDriveID << " finished, valid data ready for use" << std::endl;
00099 readoutRecorder(m_iCurrentObject);
00100
00101 } else if(iRecorderStatus == 3) {
00102 std::cout << "Recorder " << m_iDriveID << " is still recording" << std::endl;
00103 SDOData.statusFlag = segData::SDO_SEG_FREE;
00104 }
00105
00106 return 0;
00107 }
00108
00109 int ElmoRecorder::readoutRecorder(int iObjSubIndex){
00110
00111 int iObjIndex = 0x2030;
00112
00113 m_pHarmonicaDrive->sendSDOUpload(iObjIndex, iObjSubIndex);
00114 m_iCurrentObject = iObjSubIndex;
00115
00116 return 0;
00117 }
00118
00119 int ElmoRecorder::processData(segData& SDOData) {
00120 int iItemSize = 4;
00121 int iItemCount = 0;
00122 unsigned int iNumDataItems = 0;
00123 bool bCollectFloats = true;
00124 float fFloatingPointFactor = 0;
00125
00126 std::vector<float> vfResData[2];
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141 switch ((SDOData.data[0] >> 4) ) {
00142 case 4:
00143 bCollectFloats = false;
00144 iItemSize = 4;
00145 break;
00146 case 5:
00147 bCollectFloats = true;
00148 iItemSize = 4;
00149 break;
00150 case 1:
00151 bCollectFloats = true;
00152 iItemSize = 2;
00153 break;
00154 default:
00155 bCollectFloats = false;
00156 iItemSize = 4;
00157 break;
00158 }
00159 std::cout << ">>>>>ElmoRec: HEADER INFOS<<<<<\nData type is: " << (SDOData.data[0] >> 4) << std::endl;
00160
00161
00162
00163
00164
00165 iNumDataItems = (SDOData.data[2] << 8 | SDOData.data[1]);
00166
00167
00168
00169 fFloatingPointFactor = convertBinaryToFloat( (SDOData.data[6] << 24) | (SDOData.data[5] << 16) | (SDOData.data[4] << 8) | (SDOData.data[3]) );
00170 std::cout << "Floating point factor for recorded values is: " << fFloatingPointFactor << std::endl;
00171
00172
00173 if( ((SDOData.numTotalBytes-7)/iItemSize) != iNumDataItems)
00174 std::cout << "SDODataSize announced in SDO-Header" << ((SDOData.numTotalBytes-7)/iItemSize) << " differs from NumDataItems by ElmoData-Header" << iNumDataItems << std::endl;
00175
00176
00177
00178 vfResData[0].assign(iNumDataItems, 0.0);
00179 vfResData[1].assign(iNumDataItems, 0.0);
00180 iItemCount = 0;
00181
00182
00183 for(unsigned int i=7;i<=SDOData.data.size() - iItemSize; i=i+iItemSize) {
00184 if(bCollectFloats) {
00185 if(iItemSize == 4)
00186 vfResData[1][iItemCount] = fFloatingPointFactor * convertBinaryToFloat( (SDOData.data[i] << 0) | (SDOData.data[i+1] << 8) | (SDOData.data[i+2] << 16) | (SDOData.data[i+3] << 24) );
00187
00188
00189 if(iItemCount == 120)
00190 std::cout << (unsigned int)( (SDOData.data[i] << 0) | (SDOData.data[i+1] << 8) | (SDOData.data[i+2] << 16) | (SDOData.data[i+3] << 24) ) << std::endl;
00191
00192 else vfResData[1][iItemCount] = fFloatingPointFactor * convertBinaryToHalfFloat( (SDOData.data[i] << 0) | (SDOData.data[i+1] << 8) | (SDOData.data[i+2] << 16) | (SDOData.data[i+3] << 24) );
00193 iItemCount ++;
00194 } else {
00195 vfResData[1][iItemCount] = fFloatingPointFactor * (float)( (SDOData.data[i] << 0) | (SDOData.data[i+1] << 8) | (SDOData.data[i+2] << 16) | (SDOData.data[i+3] << 24) );
00196 iItemCount ++;
00197 }
00198
00199 vfResData[0][iItemCount] = m_fRecordingStepSec * iItemCount;
00200 }
00201
00202 logToFile(m_sLogFilename, vfResData);
00203
00204 SDOData.statusFlag = segData::SDO_SEG_FREE;
00205 return 0;
00206 }
00207
00208 int ElmoRecorder::setLogFilename(std::string sLogFileprefix) {
00209 m_sLogFilename = sLogFileprefix;
00210 return 0;
00211 }
00212
00213
00214
00215 float ElmoRecorder::convertBinaryToFloat(unsigned int iBinaryRepresentation) {
00216
00217 int iSign;
00218 int iExponent;
00219 unsigned int iMantissa;
00220 float iNumMantissa = 0.0f;
00221
00222 if((iBinaryRepresentation & (1 << 31)) == 0)
00223 iSign = 1;
00224 else
00225 iSign = -1;
00226
00227 iExponent = ((iBinaryRepresentation >> 23) & 0xFF) - 127;
00228
00229 iMantissa = (iBinaryRepresentation & 0x7FFFFF);
00230
00231 iNumMantissa = 1.0f;
00232
00233 for(int i=1; i<=23; i++) {
00234 if((iMantissa & (1 << (23-i))) > 0) {
00235 iNumMantissa = iNumMantissa + pow(2,(-1)*i);
00236 }
00237 }
00238
00239 return iSign * pow(2,iExponent) * iNumMantissa;
00240 }
00241
00242 float ElmoRecorder::convertBinaryToHalfFloat(unsigned int iBinaryRepresentation) {
00243
00244 int iSign;
00245 int iExponent;
00246 unsigned int iMantissa;
00247 float iNumMantissa = 0.0f;
00248
00249 if((iBinaryRepresentation & (1 << 15)) == 0)
00250 iSign = 1;
00251 else
00252 iSign = -1;
00253
00254 iExponent = ((iBinaryRepresentation >> 10) & 0x1F) - 15;
00255
00256 iMantissa = (iBinaryRepresentation & 0x3FF);
00257
00258 iNumMantissa = 1.0f;
00259
00260 for(int i=1; i<=10; i++) {
00261 if((iMantissa & (1 << (10-i))) > 0) {
00262 iNumMantissa = iNumMantissa + pow(2,(-1)*i);
00263 }
00264 }
00265
00266 return iSign * pow(2,iExponent) * iNumMantissa;
00267 }
00268
00269
00270 int ElmoRecorder::logToFile(std::string filename, std::vector<float> vtValues[]) {
00271 std::stringstream outputFileName;
00272 outputFileName << filename << "mot_" << m_iDriveID << "_" << m_iCurrentObject << ".log";
00273
00274 FILE* pFile;
00275
00276 pFile = fopen(outputFileName.str().c_str(), "w");
00277
00278
00279 if( pFile == NULL )
00280 {
00281 std::cout << "Error while writing file: " << outputFileName.str() << " Maybe the selected folder does'nt exist." << std::endl;
00282 }
00283 else
00284 {
00285
00286 for (unsigned int i = 0; i < vtValues[0].size(); i++)
00287 fprintf(pFile, "%e %e\n", vtValues[0][i], vtValues[1][i]);
00288 fclose(pFile);
00289 }
00290
00291 return true;
00292 }