00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00032 #include <hd_hl_apis_callbacks.h>
00033
00034 using namespace std;
00035
00036 extern DeviceData RawDeviceData;
00037
00038
00039
00040
00041 HDCallbackCode HDCALLBACK updateDeviceCallback(void *pUserData)
00042 {
00043 DeviceData *RawDeviceData=(DeviceData*)pUserData;
00044
00045 int nButtons = 0;
00046
00047 static HDdouble T[16];
00048 static hduMatrix M;
00049
00050 hdBeginFrame(hdGetCurrentDevice());
00051
00052
00053 hdGetIntegerv(HD_CURRENT_BUTTONS, &nButtons);
00054
00055
00056 RawDeviceData->m_button1State = (nButtons & HD_DEVICE_BUTTON_1) ? HD_TRUE : HD_FALSE;
00057
00058
00059 RawDeviceData->m_button2State = (nButtons & HD_DEVICE_BUTTON_2) ? HD_TRUE : HD_FALSE;
00060
00061
00062 hdGetDoublev(HD_CURRENT_POSITION, RawDeviceData->m_devicePosition);
00063
00064
00065 hdGetDoublev(HD_CURRENT_JOINT_ANGLES, RawDeviceData->jointAngles);
00066
00067
00068 hdGetDoublev(HD_CURRENT_GIMBAL_ANGLES, RawDeviceData->gimbalAngles);
00069
00070
00071 hdGetDoublev(HD_MOTOR_TEMPERATURE, RawDeviceData->motor_temperature);
00072
00073
00074 hdGetDoublev(HD_CURRENT_TRANSFORM, T);
00075 M = hduMatrix(T);
00076 M.transpose();
00077 RawDeviceData->end_effector_transform = M;
00078
00079
00080 RawDeviceData->m_error = hdGetError();
00081
00082
00083 hdEndFrame(hdGetCurrentDevice());
00084
00085 return HD_CALLBACK_CONTINUE;
00086 }
00087
00088 HDCallbackCode HDCALLBACK updateDeviceParametersCallback(void *pUserData)
00089 {
00090 shared_vars_t*RobotVars=(shared_vars_t*)pUserData;
00091
00092
00093 hdGetDoublev(HD_NOMINAL_MAX_STIFFNESS, &(RobotVars->phantom_data.max_stiffness));
00094
00095
00096 hdGetDoublev(HD_NOMINAL_MAX_DAMPING, &(RobotVars->phantom_data.max_damping));
00097
00098
00099 hdGetDoublev(HD_NOMINAL_MAX_FORCE, &(RobotVars->phantom_data.max_force));
00100
00101
00102 hdGetDoublev(HD_NOMINAL_MAX_CONTINUOUS_FORCE, &(RobotVars->phantom_data.max_continuous_force));
00103
00104 return HD_CALLBACK_DONE;
00105 }
00106
00107 HDCallbackCode HDCALLBACK copyDeviceDataCallback(void *pUserData)
00108 {
00109 shared_vars_t*RobotVars=(shared_vars_t*)pUserData;
00110 static double rotVals[4][4];
00111 #if ROS_VERSION_MINIMUM(1, 8, 0) //At least FUERTE, V. Santos, 27-Mai-2013,23:34
00112 static tf::Quaternion q;
00113 static tf::Matrix3x3 mat;
00114 #else
00115 static btQuaternion q;
00116 static btMatrix3x3 mat;
00117 #endif
00118
00119 if(!RobotVars->parameters.exit_status)
00120 {
00121
00122 if((bool)RawDeviceData.m_button1State==TRUE && (bool)RobotVars->phantom_data.m_button1State==FALSE)
00123 {
00124 RobotVars->phantom_data.m_button1Clicked=!RobotVars->phantom_data.m_button1Clicked;
00125 }
00126
00127
00128 if((bool)RawDeviceData.m_button2State==TRUE && (bool)RobotVars->phantom_data.m_button2State==FALSE)
00129 {
00130 RobotVars->phantom_data.m_button2Clicked=!RobotVars->phantom_data.m_button2Clicked;
00131 }
00132
00133
00134 if(RawDeviceData.m_button1State!=RobotVars->phantom_data.m_button1State)
00135 {
00136 RobotVars->phantom_data.m_button1State=RawDeviceData.m_button1State;
00137 }
00138
00139 if(RawDeviceData.m_button2State!=RobotVars->phantom_data.m_button2State)
00140 {
00141 RobotVars->phantom_data.m_button2State=RawDeviceData.m_button2State;
00142 }
00143
00144
00145 if(RawDeviceData.m_devicePosition[0]!=RobotVars->phantom_data.m_devicePosition[0] ||
00146 RawDeviceData.m_devicePosition[1]!=RobotVars->phantom_data.m_devicePosition[1] ||
00147 RawDeviceData.m_devicePosition[2]!=RobotVars->phantom_data.m_devicePosition[2])
00148 {
00149
00150 if(RobotVars->parameters.coordinate_resolution==1.)
00151 {
00152
00153 RobotVars->phantom_data.m_devicePosition[0]=round(RawDeviceData.m_devicePosition[2]);
00154 RobotVars->phantom_data.m_devicePosition[1]=round(RawDeviceData.m_devicePosition[0]);
00155 RobotVars->phantom_data.m_devicePosition[2]=round(RawDeviceData.m_devicePosition[1]);
00156 }
00157 else
00158 {
00159
00160 RobotVars->phantom_data.m_devicePosition[0]=RetrievePrecisionFromDouble(RawDeviceData.m_devicePosition[2],RobotVars->parameters.coordinate_resolution);
00161 RobotVars->phantom_data.m_devicePosition[1]=RetrievePrecisionFromDouble(RawDeviceData.m_devicePosition[0],RobotVars->parameters.coordinate_resolution);
00162 RobotVars->phantom_data.m_devicePosition[2]=RetrievePrecisionFromDouble(RawDeviceData.m_devicePosition[1],RobotVars->parameters.coordinate_resolution);
00163 }
00164 }
00165 if(RobotVars->parameters.cntrl_pos_back_front<0.)
00166 {
00167 RobotVars->phantom_data.m_devicePosition[0] = -RobotVars->phantom_data.m_devicePosition[0];
00168 RobotVars->phantom_data.m_devicePosition[1] = -RobotVars->phantom_data.m_devicePosition[1];
00169 }
00170
00171
00172
00173 if(RawDeviceData.jointAngles[0]!=RobotVars->phantom_data.jointAngles[0] || RawDeviceData.jointAngles[1]!=RobotVars->phantom_data.jointAngles[1] ||RawDeviceData.jointAngles[2]!=RobotVars->phantom_data.jointAngles[2])
00174 {
00175
00176
00177 RobotVars->phantom_data.jointAngles=RawDeviceData.jointAngles * (180./M_PI);
00178 }
00179
00180
00181 if(RawDeviceData.gimbalAngles[0]!=RobotVars->phantom_data.gimbalAngles[0] || RawDeviceData.gimbalAngles[1]!=RobotVars->phantom_data.gimbalAngles[1] ||RawDeviceData.gimbalAngles[2]!=RobotVars->phantom_data.gimbalAngles[2])
00182 {
00183
00184
00185 RobotVars->phantom_data.gimbalAngles = RawDeviceData.gimbalAngles * (180./M_PI);
00186 }
00187
00188 if(RawDeviceData.motor_temperature[0] != RobotVars->phantom_data.motor_temperature[0] ||
00189 RawDeviceData.motor_temperature[1] != RobotVars->phantom_data.motor_temperature[1] ||
00190 RawDeviceData.motor_temperature[2] != RobotVars->phantom_data.motor_temperature[2])
00191 {
00192
00193 memcpy(&(RobotVars->phantom_data.motor_temperature),&(RawDeviceData.motor_temperature),sizeof(RawDeviceData.motor_temperature));
00194 }
00195
00196
00197
00198 RobotVars->phantom_data.phantom_to_base_point.setOrigin( tf::Vector3( RawDeviceData.m_devicePosition[0], RawDeviceData.m_devicePosition[1], RawDeviceData.m_devicePosition[2]) );
00199
00200 RawDeviceData.end_effector_transform.get(rotVals);
00201
00202 #if ROS_VERSION_MINIMUM(1, 8, 0) //At least FUERTE, V. Santos, 27-Mai-2013,23:34
00203 mat = tf::Matrix3x3(rotVals[0][0], rotVals[0][1], rotVals[0][2],
00204 rotVals[1][0], rotVals[1][1], rotVals[1][2],
00205 rotVals[2][0], rotVals[2][1], rotVals[2][2]);
00206 #else
00207 mat = btMatrix3x3(rotVals[0][0], rotVals[0][1], rotVals[0][2],
00208 rotVals[1][0], rotVals[1][1], rotVals[1][2],
00209 rotVals[2][0], rotVals[2][1], rotVals[2][2]);
00210
00211 #endif
00212 mat.getRotation(q);
00213
00214 RobotVars->phantom_data.phantom_to_base_point.setRotation( q );
00215
00216 RobotVars->phantom_data.base_point_to_pen_tip.setOrigin( tf::Vector3( 0,0,-40));
00217
00218 #if ROS_VERSION_MINIMUM(1, 8, 0) //At least FUERTE, V. Santos, 27-Mai-2013,23:34
00219 mat = tf::Matrix3x3(1, 0,0,
00220 0,1,0,
00221 0,0,1);
00222 #else
00223 mat = btMatrix3x3(1, 0,0,
00224 0,1,0,
00225 0,0,1);
00226 #endif
00227 mat.getRotation(q);
00228 RobotVars->phantom_data.base_point_to_pen_tip.setRotation( q );
00229
00230
00231
00232 RobotVars->phantom_data.m_error = RawDeviceData.m_error;
00233 }
00234
00235 return HD_CALLBACK_DONE;
00236 }
00237
00238 HDCallbackCode HDCALLBACK forcefeedbackCallback(void *pUserData)
00239 {
00240 shared_vars_t*RobotVars=(shared_vars_t*)pUserData;
00241 static timespec loop_rate_start,loop_rate_stop;
00242 long double time_in_seconds;
00243 static int counter=0;
00244 static hduVector3Dd TOTAL_FORCE_1=hduVector3Dd(0.,0.,0.), TOTAL_FORCE_2=hduVector3Dd(0.,0.,0.);
00245 static bool first_run = FALSE;
00246
00247 static hduVector3Dd GRAVITY_COMPENSATION_FORCE = TransformWorldCoordinatesToPHaNToMCoordinates(hduVector3Dd(0,0,(PHANToM_TOOLTIP_MASS * 9.81)));
00248
00249
00250 HDErrorInfo error;
00251
00252
00253 if(RobotVars->haptics_data.chosen_demo == 1 && RobotVars->haptic_loop_start)
00254 {
00255
00256 TOTAL_FORCE_1 = CalculateWorkspaceDemoForce(RobotVars);
00257
00258
00259 if(TOTAL_FORCE_1.magnitude() > 0.)
00260 {
00261 hlBeginFrame();
00262 hdSetDoublev(HD_CURRENT_FORCE, TOTAL_FORCE_1);
00263 hlEndFrame();
00264 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(TOTAL_FORCE_1);
00265 }
00266 else
00267 {
00268
00269 hlBeginFrame();
00270 hdSetDoublev(HD_CURRENT_FORCE, GRAVITY_COMPENSATION_FORCE);
00271 hlEndFrame();
00272 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(GRAVITY_COMPENSATION_FORCE);
00273 }
00274
00275 if (HD_DEVICE_ERROR(error = hdGetError()))
00276 {
00277 hduPrintError(stderr, &error, "Error during force feedback callback\n");
00278
00279 if (hduIsSchedulerError(&error))
00280 {
00281 return HD_CALLBACK_DONE;
00282 }
00283 }
00284
00285
00286 if(counter<100)
00287 counter++;
00288 else
00289 {
00290 clock_gettime(CLOCK_REALTIME, &loop_rate_stop);
00291 time_in_seconds =
00292 ((long double)loop_rate_stop.tv_sec + ((long double)loop_rate_stop.tv_nsec / (long double)1e9)) -
00293 ((long double)loop_rate_start.tv_sec + ((long double)loop_rate_start.tv_nsec / (long double)1e9));
00294 RobotVars->parameters.haptics_rate = round((long double)counter / (time_in_seconds));
00295 clock_gettime(CLOCK_REALTIME, &loop_rate_start);
00296 counter = 0;
00297 }
00298 }
00299
00300 else if(RobotVars->haptics_data.chosen_demo == 2 && RobotVars->haptic_loop_start)
00301 {
00302
00303 TOTAL_FORCE_1 = CalculateWorkspaceDemoForce(RobotVars);
00304
00305
00306 if(RobotVars->haptics_data.demo_2_point_1.magnitude() > 0. &&
00307 RobotVars->haptics_data.demo_2_point_2.magnitude() > 0. &&
00308 RobotVars->haptics_data.demo_2_point_3.magnitude() > 0. &&
00309 first_run == FALSE)
00310 {
00311 std::cout<<"Building Plane...";
00312 Demo2_BuildPlane(RobotVars);
00313 std::cout<<"...DONE!"<<std::endl;
00314 first_run = TRUE;
00315 }
00316 else if(RobotVars->haptics_data.demo_2_point_1.magnitude() > 0. &&
00317 RobotVars->haptics_data.demo_2_point_2.magnitude() > 0. &&
00318 RobotVars->haptics_data.demo_2_point_3.magnitude() > 0.&&
00319 first_run == TRUE)
00320 {
00321
00322 TOTAL_FORCE_2 = CalculatePlaneDrawingDemoForce(RobotVars);
00323 }
00324 else
00325 {
00326
00327 if(RobotVars->phantom_data.m_button2Clicked)
00328 {
00329
00330
00331
00332 hduVector3Dd joystick_position = RobotVars->phantom_data.m_devicePosition;
00333
00334 if(RobotVars->haptics_data.demo_2_point_1.magnitude() == 0. &&
00335 RobotVars->haptics_data.demo_2_point_2.magnitude() == 0. &&
00336 RobotVars->haptics_data.demo_2_point_3.magnitude() == 0.)
00337 {
00338 RobotVars->haptics_data.demo_2_point_1 = joystick_position;
00339 cout<<"Setting Point 1 to: "<<RobotVars->haptics_data.demo_2_point_1<<endl;
00340 RobotVars->phantom_data.m_button2Clicked=!RobotVars->phantom_data.m_button2Clicked;
00341 }
00342 if(RobotVars->haptics_data.demo_2_point_1.magnitude() != 0. &&
00343 RobotVars->haptics_data.demo_2_point_2.magnitude() == 0. &&
00344 RobotVars->haptics_data.demo_2_point_3.magnitude() == 0. &&
00345 RobotVars->haptics_data.demo_2_point_1 != joystick_position)
00346 {
00347 RobotVars->haptics_data.demo_2_point_2 = joystick_position;
00348 cout<<"Setting Point 2 to: "<<RobotVars->haptics_data.demo_2_point_2<<endl;
00349 RobotVars->phantom_data.m_button2Clicked=!RobotVars->phantom_data.m_button2Clicked;
00350 }
00351 if(RobotVars->haptics_data.demo_2_point_1.magnitude() != 0. &&
00352 RobotVars->haptics_data.demo_2_point_2.magnitude() != 0. &&
00353 RobotVars->haptics_data.demo_2_point_3.magnitude() == 0. &&
00354 RobotVars->haptics_data.demo_2_point_1 != joystick_position &&
00355 RobotVars->haptics_data.demo_2_point_2 != joystick_position)
00356 {
00357 RobotVars->haptics_data.demo_2_point_3 = joystick_position;
00358 cout<<"Setting Point 3 to: "<<RobotVars->haptics_data.demo_2_point_3<<endl;
00359 RobotVars->phantom_data.m_button2Clicked=!RobotVars->phantom_data.m_button2Clicked;
00360 }
00361 }
00362 first_run = FALSE;
00363 }
00364
00365
00366
00367
00368
00369 if(TOTAL_FORCE_1.magnitude() > 0. || TOTAL_FORCE_2.magnitude() > 0.)
00370 {
00371 hlBeginFrame();
00372 hdSetDoublev(HD_CURRENT_FORCE, TOTAL_FORCE_1+TOTAL_FORCE_2);
00373 hlEndFrame();
00374 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(TOTAL_FORCE_1+TOTAL_FORCE_2);
00375 }
00376 else
00377 {
00378
00379 hlBeginFrame();
00380 hdSetDoublev(HD_CURRENT_FORCE, GRAVITY_COMPENSATION_FORCE);
00381 hlEndFrame();
00382 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(GRAVITY_COMPENSATION_FORCE);
00383 }
00384
00385 if (HD_DEVICE_ERROR(error = hdGetError()))
00386 {
00387 hduPrintError(stderr, &error, "Error during force feedback callback\n");
00388
00389 if (hduIsSchedulerError(&error))
00390 {
00391 return HD_CALLBACK_DONE;
00392 }
00393 }
00394
00395
00396 if(counter<100)
00397 counter++;
00398 else
00399 {
00400 clock_gettime(CLOCK_REALTIME, &loop_rate_stop);
00401 time_in_seconds =
00402 ((long double)loop_rate_stop.tv_sec + ((long double)loop_rate_stop.tv_nsec / (long double)1e9)) -
00403 ((long double)loop_rate_start.tv_sec + ((long double)loop_rate_start.tv_nsec / (long double)1e9));
00404 RobotVars->parameters.haptics_rate = round((long double)counter / (time_in_seconds));
00405 clock_gettime(CLOCK_REALTIME, &loop_rate_start);
00406 counter = 0;
00407 }
00408
00409
00410 }
00411
00412 else if(RobotVars->haptics_data.chosen_demo == 3 && RobotVars->haptic_loop_start)
00413 {
00414
00415 hlBeginFrame();
00416 hdSetDoublev(HD_CURRENT_FORCE, GRAVITY_COMPENSATION_FORCE);
00417 hlEndFrame();
00418 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(GRAVITY_COMPENSATION_FORCE);
00419
00420 if(counter<100)
00421 counter++;
00422 else
00423 {
00424 clock_gettime(CLOCK_REALTIME, &loop_rate_stop);
00425 time_in_seconds =
00426 ((long double)loop_rate_stop.tv_sec + ((long double)loop_rate_stop.tv_nsec / (long double)1e9)) -
00427 ((long double)loop_rate_start.tv_sec + ((long double)loop_rate_start.tv_nsec / (long double)1e9));
00428 RobotVars->parameters.haptics_rate = round((long double)counter / (time_in_seconds));
00429 clock_gettime(CLOCK_REALTIME, &loop_rate_start);
00430 counter = 0;
00431 }
00432 }
00433
00434 else if(RobotVars->haptics_data.chosen_demo == 4 && RobotVars->haptic_loop_start)
00435 {
00436
00437
00438 hduVector3Dd COP_force = Leg_COP_Monitoring(RobotVars);
00439
00440 if(COP_force.magnitude() > 0.0 || TOTAL_FORCE_1.magnitude() > 0.0)
00441 {
00442 hlBeginFrame();
00443 hdSetDoublev(HD_CURRENT_FORCE, TransformWorldCoordinatesToPHaNToMCoordinates(COP_force) + TOTAL_FORCE_1);
00444 hlEndFrame();
00445 RobotVars->haptics_data.applied_force = COP_force + TransformPHANToMCoordinatesToWorldCoordinates(TOTAL_FORCE_1);
00446 }
00447 else
00448 {
00449
00450 hlBeginFrame();
00451 hdSetDoublev(HD_CURRENT_FORCE, GRAVITY_COMPENSATION_FORCE);
00452 hlEndFrame();
00453 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(GRAVITY_COMPENSATION_FORCE);
00454 }
00455
00456 if(counter<100)
00457 counter++;
00458 else
00459 {
00460 clock_gettime(CLOCK_REALTIME, &loop_rate_stop);
00461 time_in_seconds =
00462 ((long double)loop_rate_stop.tv_sec + ((long double)loop_rate_stop.tv_nsec / (long double)1e9)) -
00463 ((long double)loop_rate_start.tv_sec + ((long double)loop_rate_start.tv_nsec / (long double)1e9));
00464 RobotVars->parameters.haptics_rate = round((long double)counter / (time_in_seconds));
00465 clock_gettime(CLOCK_REALTIME, &loop_rate_start);
00466 counter = 0;
00467 }
00468 }
00469 else if(RobotVars->haptics_data.chosen_demo == 0 && RobotVars->haptic_loop_start)
00470 {
00471
00472 hlBeginFrame();
00473 hdSetDoublev(HD_CURRENT_FORCE, GRAVITY_COMPENSATION_FORCE);
00474 hlEndFrame();
00475 RobotVars->haptics_data.applied_force = TransformPHANToMCoordinatesToWorldCoordinates(GRAVITY_COMPENSATION_FORCE);
00476
00477
00478 if(counter<100)
00479 counter++;
00480 else
00481 {
00482 clock_gettime(CLOCK_REALTIME, &loop_rate_stop);
00483 time_in_seconds =
00484 ((long double)loop_rate_stop.tv_sec + ((long double)loop_rate_stop.tv_nsec / (long double)1e9)) -
00485 ((long double)loop_rate_start.tv_sec + ((long double)loop_rate_start.tv_nsec / (long double)1e9));
00486 RobotVars->parameters.haptics_rate = round((long double)counter / (time_in_seconds));
00487 clock_gettime(CLOCK_REALTIME, &loop_rate_start);
00488 counter = 0;
00489 }
00490 }
00491 else
00492 {
00493 RobotVars->parameters.haptics_rate = 0.;
00494 counter = 0;
00495 if(RobotVars->haptics_data.demo_2_point_1.magnitude() != 0.)
00496 {
00497 RobotVars->haptics_data.demo_2_point_1 = hduVector3Dd(0,0,0);
00498 RobotVars->haptics_data.demo_2_point_2 = hduVector3Dd(0,0,0);
00499 RobotVars->haptics_data.demo_2_point_3 = hduVector3Dd(0,0,0);
00500 TOTAL_FORCE_1=hduVector3Dd(0.,0.,0.);
00501 TOTAL_FORCE_2=hduVector3Dd(0.,0.,0.);
00502 first_run = FALSE;
00503 }
00504 RobotVars->haptics_data.applied_force = hduVector3Dd(0,0,0);
00505 }
00506
00507
00508 if(!RobotVars->parameters.exit_status)
00509 {
00510
00511 return HD_CALLBACK_CONTINUE;
00512 }
00513 else
00514 {
00515 return HD_CALLBACK_DONE;
00516 }
00517 }
00518
00519 HDCallbackCode HDCALLBACK CalibrationCallback(void *pUserData)
00520 {
00521 shared_vars_t*RobotVars=(shared_vars_t*)pUserData;
00522
00523 if(RobotVars->phantom_data.need_update && RobotVars->phantom_data.phantom_on)
00524 {
00525 int calibrationStyle= HD_CALIBRATION_INKWELL;
00526
00527 hdBeginFrame(hdGetCurrentDevice());
00528 HDenum status = hdCheckCalibration();
00529 hdEndFrame(hdGetCurrentDevice());
00530
00531 if (status == HD_CALIBRATION_OK)
00532 {
00533 printf("PHANToM calibration OK! Will not update.\n");
00534 }
00535 else
00536 {
00537 hdUpdateCalibration(calibrationStyle);
00538 printf("PHANToM successfully calibrated!\n");
00539 }
00540 RobotVars->phantom_data.need_update=FALSE;
00541 }
00542
00543 return HD_CALLBACK_CONTINUE;
00544 }