![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsSensAble_hduRecord.cpp 00003 00004 Modified from SensAble hduRecord.cpp 00005 00006 SUKITTI PUNAK (11/27/2006) 00007 UPDATE (11/27/2006) 00008 ******************************************************************************/ 00009 #include "TAPsSensAble_hduRecord.hpp" 00010 // Using Inclusion Model (i.e. definitions are included in declarations) 00011 // (this name.cpp is included in name.hpp) 00012 // Each friend is defined directly inside its declaration. 00013 00014 00015 // Original comment from hduRecord.cpp 00016 /***************************************************************************** 00017 00018 Copyright (c) 2004 SensAble Technologies, Inc. All rights reserved. 00019 00020 OpenHaptics(TM) toolkit. The material embodied in this software and use of 00021 this software is subject to the terms and conditions of the clickthrough 00022 Development License Agreement. 00023 00024 For questions, comments or bug reports, go to forums at: 00025 http://dsc.sensable.com 00026 00027 Module Name: 00028 00029 hduRecord.cpp 00030 00031 Description: 00032 00033 Records device data from the scheduler for a specified number of ticks, and 00034 with option to add additional user data. 00035 00036 ******************************************************************************/ 00037 00038 //#include "hduAfx.h" 00039 00040 #include <iostream> 00041 00042 #include <HDU/hduRecord.h> 00043 #include <HDU/hduVector.h> 00044 00045 #include <HD/hdCompilerConfig.h> 00046 #include <HD/hdScheduler.h> 00047 #include <HD/hdDevice.h> 00048 00049 BEGIN_NAMESPACE_TAPs__Haptic 00050 //============================================================================= 00051 00052 #if defined WIN32 00053 # include <process.h> 00054 typedef void thread_rv; 00055 #elif defined(linux) || defined(__APPLE__) 00056 # include <pthread.h> 00057 typedef void* thread_rv; 00058 #endif 00059 00060 /* Scheduler callback for getting data for each iteration. */ 00061 HDCallbackCode HDCALLBACK SensAble_RecordLoopCallback ( 00062 void * SensAble_hduRecorder ); 00063 00064 /* Thread callback for writing out data to file. */ 00065 thread_rv SensAble_RecordWriteCallback( void * data ); 00066 00067 /****************************************************************************** 00068 Data packet for each iteration. 00069 ******************************************************************************/ 00070 struct SensAble_hduRecorderPacket 00071 { 00072 hduVector3Dd m_force; 00073 hduVector3Dd m_position; 00074 hduVector3Dd m_velocity; 00075 char * m_userData; 00076 }; 00077 00078 /****************************************************************************** 00079 Main class that handles recording. 00080 ******************************************************************************/ 00081 class SensAble_hduRecorder 00082 { 00083 //--------------------------------------------------------------- 00084 public: 00085 SensAble_hduRecorder ( 00086 FILE * file, 00087 HDURecordCallback & pUserCallback, 00088 void * pUserCallbackData, 00089 int numData 00090 ); 00091 virtual ~SensAble_hduRecorder (); 00092 HDboolean Start (); 00093 HDboolean AddData (); 00094 void WriteDataToFile (); 00095 //--------------------------------- 00096 // HDSchedulerHandle is unsigned long. 00097 HDSchedulerHandle GetShedulerHandle () { return m_hdSchedulerHandle; } 00098 //----------------------- 00099 // HDboolean GetStatusCompletion () { 00100 // if ( m_hdSchedulerHandle == 0 ) return true; 00101 // return !hdWaitForCompletion( m_hdSchedulerHandle, HD_WAIT_CHECK_STATUS ); 00102 // } 00103 //--------------------------------------------------------------- 00104 private: 00105 SensAble_HDURecordCallback * m_pUserCallback; 00106 void * m_pUserCallbackData; 00107 FILE * m_file; 00108 int m_numData; 00109 int m_index; 00110 SensAble_hduRecorderPacket * m_data; 00111 //--------------------------------- 00112 // For checking completion status 00113 HDSchedulerHandle m_hdSchedulerHandle; 00114 }; 00115 00116 /****************************************************************************** 00117 Constructor 00118 ******************************************************************************/ 00119 SensAble_hduRecorder::SensAble_hduRecorder ( 00120 FILE * file, 00121 SensAble_HDURecordCallback & pUserCallback, 00122 void * pUserCallbackData, 00123 int numData 00124 ) : 00125 m_file( file ), 00126 m_pUserCallback( pUserCallback ), 00127 m_pUserCallbackData( pUserCallbackData ), 00128 m_numData( numData ), 00129 m_index( 0 ), 00130 m_data( 0 ), 00131 m_hdSchedulerHandle( 0 ) 00132 { 00133 m_data = new SensAble_hduRecorderPacket[ numData ]; 00134 } 00135 00136 /****************************************************************************** 00137 Destructor 00138 ******************************************************************************/ 00139 SensAble_hduRecorder::~SensAble_hduRecorder () 00140 { 00141 for ( int i = 0; i < m_numData; ++i ) { 00142 delete m_data[i].m_userData; 00143 } 00144 delete[] m_data; 00145 } 00146 00147 /****************************************************************************** 00148 Start the recording. Schedule a callback that records device data for 00149 every scheduler tick. 00150 ******************************************************************************/ 00151 HDboolean SensAble_hduRecorder::Start () 00152 { 00153 m_hdSchedulerHandle = hdScheduleAsynchronous( 00154 SensAble_RecordLoopCallback, 00155 this, 00156 HD_MIN_SCHEDULER_PRIORITY 00157 ); 00158 return ( m_hdSchedulerHandle == HD_INVALID_HANDLE ? false : true ); 00159 } 00160 00161 /****************************************************************************** 00162 Worker thread callback to write the data to file. 00163 ******************************************************************************/ 00164 thread_rv SensAble_RecordWriteCallback ( void * data ) 00165 { 00166 SensAble_hduRecorder * pRecord = ( SensAble_hduRecorder * ) data; 00167 pRecord->WriteDataToFile(); 00168 delete pRecord; 00169 } 00170 00171 /****************************************************************************** 00172 Write all the data out at once when the recording is done. 00173 ******************************************************************************/ 00174 void SensAble_hduRecorder::WriteDataToFile () 00175 { 00176 //* 00177 //--------------------------------------------------------------- 00178 // Without data names 00179 for ( int i = 0; i < m_numData; ++i ) { 00180 SensAble_hduRecorderPacket & data = m_data[i]; 00181 fprintf( m_file, "%d\t", i ); 00182 fprintf( m_file, "%f %f %f\t", 00183 data.m_force[0], 00184 data.m_force[1], 00185 data.m_force[2] ); 00186 fprintf( m_file,"%f %f %f\t", 00187 data.m_position[0], 00188 data.m_position[1], 00189 data.m_position[2] ); 00190 fprintf( m_file, "%f %f %f\t", 00191 data.m_velocity[0], 00192 data.m_velocity[1], 00193 data.m_velocity[2] ); 00194 fprintf( m_file,"%s\n",data.m_userData ); 00195 } 00196 //*/ 00197 /* 00198 //--------------------------------------------------------------- 00199 // With data names 00200 for ( int i = 0; i < m_numData; ++i ) { 00201 SensAble_hduRecorderPacket & data = m_data[i]; 00202 fprintf( m_file, "%d\t", i ); 00203 fprintf( m_file, "Force: %f %f %f\t\t", 00204 data.m_force[0], 00205 data.m_force[1], 00206 data.m_force[2] ); 00207 fprintf( m_file,"Position: %f %f %f\t\t", 00208 data.m_position[0], 00209 data.m_position[1], 00210 data.m_position[2] ); 00211 fprintf( m_file, "Velocity: %f %f %f\t\t", 00212 data.m_velocity[0], 00213 data.m_velocity[1], 00214 data.m_velocity[2] ); 00215 fprintf( m_file,"%s\n",data.m_userData ); 00216 } 00217 //*/ 00218 } 00219 00220 /****************************************************************************** 00221 Scheduler callback; at each scheduler tick, add one tick's worth of data. 00222 ******************************************************************************/ 00223 HDCallbackCode HDCALLBACK SensAble_RecordLoopCallback ( 00224 void * _SensAble_hduRecorder ) 00225 { 00226 SensAble_hduRecorder * pRecord = 00227 ( SensAble_hduRecorder * ) _SensAble_hduRecorder; 00228 HDboolean bDone = pRecord->AddData(); 00229 //--------------------------------------------------------------- 00230 // If done, then create another thread to write out the data. 00231 if ( bDone ) { 00232 #if defined( WIN32 ) 00233 _beginthread( SensAble_RecordWriteCallback, 0, pRecord ); 00234 #elif defined(linux) || defined(__APPLE__) 00235 pthread_create( NULL, NULL, SensAble_RecordWriteCallback, pRecord ); 00236 #endif 00237 return HD_CALLBACK_DONE; 00238 } 00239 //--------------------------------------------------------------- 00240 return HD_CALLBACK_CONTINUE; 00241 } 00242 00243 /****************************************************************************** 00244 Adds data for one tick. Return true if done 00245 ******************************************************************************/ 00246 HDboolean SensAble_hduRecorder::AddData () 00247 { 00248 //--------------------------------------------------------------- 00249 // Get the data and fill one packet. 00250 static SensAble_hduRecorderPacket data; 00251 hdGetDoublev( HD_CURRENT_FORCE, data.m_force ); 00252 hdGetDoublev( HD_CURRENT_POSITION, data.m_position ); 00253 hdGetDoublev( HD_CURRENT_VELOCITY, data.m_velocity ); 00254 data.m_userData = 0; 00255 if ( m_pUserCallback ) { 00256 char * userData = ( * m_pUserCallback )( m_pUserCallbackData ); 00257 data.m_userData = userData; 00258 } 00259 //--------------------------------------------------------------- 00260 // Either add the data to storage, or stop getting data 00261 // if the recorder has received the amount specified. 00262 if ( m_index < m_numData ) { 00263 m_data[m_index] = data; 00264 ++m_index; 00265 return false; 00266 } 00267 else { 00268 return true; 00269 } 00270 } 00271 00272 /****************************************************************************** 00273 Create a recorder, start recording. 00274 ******************************************************************************/ 00275 HDSchedulerHandle SensAble_hduStartRecord ( 00276 FILE * file, 00277 HDURecordCallback pCallback, 00278 void * pCallbackData, 00279 unsigned int nData 00280 ) 00281 { 00282 if ( !file ) { 00283 return false; 00284 } 00285 //------------------------------------------- 00286 SensAble_hduRecorder * pRecord = 00287 new SensAble_hduRecorder( 00288 file, 00289 *pCallback, 00290 pCallbackData, 00291 nData ); 00292 //------------------------------------------- 00293 if ( pRecord->Start() ) { 00294 return pRecord->GetShedulerHandle(); 00295 } 00296 else { 00297 delete pRecord; 00298 return 0; 00299 } 00300 } 00301 /*****************************************************************************/ 00302 //============================================================================= 00303 END_NAMESPACE_TAPs__Haptic 00304 //----------------------------------------------------------------------------- 00305 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00306 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----