Este proyecto tiene como objetivo ilustrar el uso del dispositivo Phantom y el toolkit de desarrollo OpenHaptics, sus principales librerías: HLAPI y HDAPI y el manejo de callbacks para alto y bajo nivel
Dispositivo háptico que permite a los usuarios tocar y manipular objetos virtuales gracias a la retroalimentación de fuerza que proporciona. Posee un diseño portátil y un tamaño compacto, facilita la interacción gracias a su lápiz con 2 botones que permite 6 grados de libertad
Toolkit de desarrollo para crear aplicaciones destinadas a ser utilizadas con los dispositivos phantom, está desarrollada para ser programada en lenguaje C++, preferiblemente bajo Visual Studio posee 3 APIs de desarrollo: QuickHaptics: para desarrollos rápidos y sencillos, permite callbacks básicos y retroalimentación háptica en un solo sentido HDAPI: proporciona control total sobre la retroalimentación haptica y el dispositivo en general, permitiendo generar fuerzas, controlar la dirección, intensidad, duración y momento de aplicación de estas HLAPI: Programación de alto nivel utilizando OpenGl, al estar construida sobre la HDAPI facilita al desarrollador la creación de tareas hápticas: detección de colisiones, generación de fuerzas Las instrucciones para instalar el toolkit y configurar el entorno de desarrollo en Visual Studio 2010 fueron sacadas de las siguientes paginas:
http://www.sensable.com/documents/documents/OpenHaptics_Install_Win.pdf http://isa.umh.es/opensurg/guiones/g6v0.pdf
El programa implementa callbacks anidados con los cuales se pueden ejercer fuerzas sinusoidales creadas previamente empleando la librería HDAPI cuando el proxy encuentra una de las figuras creadas con OpenGl e identificadas bajo la HLAPI de la siguiente forma:
void HLCALLBACK touchCylinderCapCallback(HLenum event, HLuint object, HLenum thread, HLcache *cache, void *userdata) {
std::cout << "Touched CylinderCap" << std::endl; sonidotambor1(); hdUnschedule(calibrationHandle1); hdUnschedule(calibrationHandle2); hdUnschedule(calibrationHandle); calibrationHandle1 = hdScheduleAsynchronous(VibrationCallbackT, 0, HD_DEFAULT_SCHEDULER_PRIORITY);
if(cont<2) { cont++; std::cout<<cont++; } else { hdUnschedule(calibrationHandle1); hdUnschedule(calibrationHandle2); hdUnschedule(calibrationHandle); cont=0; }
}
calibrationHandle1 contiene el llamado al callback de la HDAPI el cual se realiza de manera asíncrona para que pueda ser invocado y detenido en tiempo de ejecución este callback esta hecho de la siguiente forma:
HDCallbackCode HDCALLBACK VibrationCallbackT(void *pUserData) {
hduVector3Dd directionT; directionT.set(0,1,0); HDErrorInfo errorT; hduVector3Dd forceT; HDdouble instRateT; static HDdouble timerT = 0; gVibrationFreqT=30; gVibrationAmplitudeT=1;
hdBeginFrame(hdGetCurrentDevice()); /* Use the reciprocal of the instantaneous rate as a timer. */ hdGetDoublev(HD_INSTANTANEOUS_UPDATE_RATE, &instRateT); timerT += 1.0 / instRateT;
/* Apply a sinusoidal force in the direction of motion. */ hduVecScale(forceT, directionT, gVibrationAmplitudeT * sin(timerT * gVibrationFreqT)); hdSetDoublev(HD_CURRENT_FORCE, forceT);
if(cont<200) {cont++; std::cout<<cont++;
} gVibrationFreqT=10; hdEndFrame(hdGetCurrentDevice()); gVibrationFreqT=10;
/* Check if an error occurred while attempting to render the force. */ if (HD_DEVICE_ERROR(errorT = hdGetError())) { hduPrintError(stderr, &errorT, "Error detected during scheduler callback.\n");
if (hduIsSchedulerError(&errorT)) { return HD_CALLBACK_DONE; } } gVibrationFreqT=10; return HD_CALLBACK_CONTINUE;
}
Para la creación de las figuras se emplea OpenGl
void drawSphere() {
glPushMatrix(); glTranslatef(-0.8, -.4, 0); glutSolidSphere(0.3, 30, 30); glPopMatrix();
}
Y para que HLAPI las identifique y las asocie como una figura háptica:
void drawSceneHaptics() {
hlBeginFrame(); hlBeginShape(HL_SHAPE_FEEDBACK_BUFFER, gSphereShapeId); hlTouchableFace(HL_FRONT); drawSphere(); hlEndShape(); hlEndFrame();
}
Para la incorporación del sonido en el demo se utiliza la librería de windows winmm.dll, la cual ya viene presente en la mayoría de sistemas por lo que solamente es necesario incluirla en nuestro proyecto utilizando la instrucción #include <windows.h> #include <mmsystem.h> e incluir la librería winmm.lib en nuestro proyecto de Visual Studio la función utilizada para el sonido es esta: PlaySound(TEXT(“platillo.wav”), NULL, SND_ALIAS | SND_APPLICATION); siendo platillo.wav un archivo de sonido ubicado en la carpeta de nuestro proyecto, esta función puede ser invocada en cualquier lugar del programa, pero para nuestro caso la ubicamos dentro de los diferentes callbacks de la HLAPI anteriormente creados de forma que el sonido sea reproducido al tocar alguna de las superficies hápticas creadas
Aca puede descargar todos los archivos necesarios para hacer funcionar el programa http://sistemas.uniandes.edu.co/ai3da1210/dokuwiki/lib/exe/fetch.php?media=hapticbatery.zip
El siguiente video muestra la interaccion entre el usuario y la bateria haptica, mostrando las diferentes vibraciones creadas al tocar cualquiera de los 3 objetos de la bateria y los diferentes sonidos que producen