diff --git a/Base/Devices/imstkHDAPIDeviceClient.cpp b/Base/Devices/imstkHDAPIDeviceClient.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a10bddd70b4e532c2de6b215fc0989ca77707bc5 --- /dev/null +++ b/Base/Devices/imstkHDAPIDeviceClient.cpp @@ -0,0 +1,102 @@ +/*========================================================================= + + Library: iMSTK + + Copyright (c) Kitware, Inc. & Center for Modeling, Simulation, + & Imaging in Medicine, Rensselaer Polytechnic Institute. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0.txt + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + =========================================================================*/ + +#include "imstkHDAPIDeviceClient.h" + +#include <HDU/hduVector.h> +#include <HDU/hduError.h> + +#include "g3log/g3log.hpp" + +namespace imstk { + +void +HDAPIDeviceClient::initModule() +{ + // Open Device + m_handle = hdInitDevice(this->getName().c_str()); + + // If failed + HDErrorInfo error; + if (HD_DEVICE_ERROR(error = hdGetError())) + { + LOG(FATAL) << "Failed to initialize Phantom Omni " << this->getName(); + m_handle = -1; + return; + } + + // Calibration + if (hdCheckCalibration() != HD_CALIBRATION_OK) + { + LOG(INFO) << "Move " << this->getName() << " in its dock to calibrate it."; + while (hdCheckCalibration() != HD_CALIBRATION_OK) + { + } + } + + // Success + LOG(INFO) << this->getName() << " successfully initialized."; + hdEnable(HD_FORCE_OUTPUT); + hdEnable(HD_FORCE_RAMPING); + hdStartScheduler(); +} + +void +HDAPIDeviceClient::runModule() +{ + hdScheduleSynchronous(hapticCallback, this, HD_MAX_SCHEDULER_PRIORITY); +} + +void +HDAPIDeviceClient::cleanUpModule() +{ + hdStopScheduler(); + hdDisableDevice(m_handle); +} + +HDCallbackCode HDCALLBACK +HDAPIDeviceClient::hapticCallback(void* pData) +{ + auto client = reinterpret_cast<HDAPIDeviceClient*>(pData); + auto handle = client->m_handle; + auto state = client->m_state; + + hdBeginFrame(handle); + + hdSetDoublev(HD_CURRENT_FORCE, client->m_force.data()); + hdGetDoublev(HD_CURRENT_POSITION, state.pos); + hdGetDoublev(HD_CURRENT_VELOCITY, state.vel); + hdGetDoublev(HD_CURRENT_TRANSFORM, state.trans); + hdGetIntegerv(HD_CURRENT_BUTTONS, &state.buttons); + + hdEndFrame(handle); + + client->m_position << state.pos[0], state.pos[1], state.pos[2]; + client->m_velocity << state.vel[0], state.vel[1], state.vel[2]; + client->m_orientation = (Eigen::Affine3d(Eigen::Matrix4d(state.trans))).rotation(); + client->m_buttons[0] = state.buttons & HD_DEVICE_BUTTON_1; + client->m_buttons[1] = state.buttons & HD_DEVICE_BUTTON_2; + client->m_buttons[2] = state.buttons & HD_DEVICE_BUTTON_3; + client->m_buttons[3] = state.buttons & HD_DEVICE_BUTTON_4; + + return HD_CALLBACK_CONTINUE; +} +} diff --git a/Base/Devices/imstkHDAPIDeviceClient.h b/Base/Devices/imstkHDAPIDeviceClient.h new file mode 100644 index 0000000000000000000000000000000000000000..d6b4c0ba239623ed13db8340e113b17c1eda332b --- /dev/null +++ b/Base/Devices/imstkHDAPIDeviceClient.h @@ -0,0 +1,73 @@ +/*========================================================================= + + Library: iMSTK + + Copyright (c) Kitware, Inc. & Center for Modeling, Simulation, + & Imaging in Medicine, Rensselaer Polytechnic Institute. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0.txt + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + =========================================================================*/ + +#ifndef imstkHDAPIDeviceClient_h +#define imstkHDAPIDeviceClient_h + +#include <map> + +#include "imstkDeviceClient.h" + +#include <HD/hd.h> + +#include <memory> + +namespace imstk { + +struct HD_state +{ + HDdouble pos[3]; + HDdouble vel[3]; + HDdouble trans[16]; + HDint buttons; +}; + +/// +/// \class HDAPIDeviceClient +/// \brief Subclass of DeviceClient for phantom omni +/// +class HDAPIDeviceClient : public DeviceClient +{ +public: + + HDAPIDeviceClient(std::string name): + DeviceClient(name, "localhost") + {} + + virtual ~HDAPIDeviceClient() {} + +protected: + + void initModule() override; + void runModule() override; + void cleanUpModule() override; + +private: + + static HDCallbackCode HDCALLBACK hapticCallback(void* pData); + + HHD m_handle; //!< device handle + HD_state m_state; //!< device reading state + +}; +} + +#endif // ifndef imstkHDAPIDeviceClient_h diff --git a/Examples/Sandbox/main.cpp b/Examples/Sandbox/main.cpp index abacade318eaf46abb5aac4cd69429b33ef108eb..9957e931407eabc9b558616d7418be38000b3cf0 100644 --- a/Examples/Sandbox/main.cpp +++ b/Examples/Sandbox/main.cpp @@ -28,6 +28,7 @@ #include "imstkOneToOneMap.h" // Devices +#include "imstkHDAPIDeviceClient.h" #include "imstkVRPNDeviceClient.h" #include "imstkVRPNDeviceServer.h" #include "imstkCameraController.h" @@ -259,35 +260,23 @@ void testObjectController() auto sdk = std::make_shared<imstk::SimulationManager>(); auto scene = sdk->createNewScene("SceneTestDevice"); - // Device server - auto server = std::make_shared<imstk::VRPNDeviceServer>("127.0.0.1"); - server->addDevice("device0", imstk::DeviceType::SPACE_EXPLORER_3DCONNEXION); - sdk->addDeviceServer(server); - // Device Client - auto client = std::make_shared<imstk::VRPNDeviceClient>("device0", "localhost"); // localhost = 127.0.0.1 + auto client = std::make_shared<imstk::HDAPIDeviceClient>("Default PHANToM", "localhost"); // localhost = 127.0.0.1 sdk->addDeviceClient(client); - // Plane - auto planeGeom = std::make_shared<imstk::Plane>(); - planeGeom->scale(5); - auto planeObj = std::make_shared<imstk::VisualObject>("VisualPlane"); - planeObj->setVisualGeometry(planeGeom); - scene->addSceneObject(planeObj); - - // Sphere - auto sphereGeom = std::make_shared<imstk::Sphere>(); - sphereGeom->setPosition(imstk::UP_VECTOR); - sphereGeom->scale(0.2); - auto sphereObj = std::make_shared<imstk::VirtualCouplingObject>("VirtualSphere", client, 20); - sphereObj->setVisualGeometry(sphereGeom); - sphereObj->setCollidingGeometry(sphereGeom); - scene->addSceneObject(sphereObj); + // Object + auto geom = std::make_shared<imstk::Cube>(); + geom->setPosition(imstk::UP_VECTOR); + geom->scale(2); + auto object = std::make_shared<imstk::VirtualCouplingObject>("VirtualObject", client, 0.1); + object->setVisualGeometry(geom); + object->setCollidingGeometry(geom); + scene->addSceneObject(object); // Update Camera position auto cam = scene->getCamera(); - cam->setPosition(imstk::Vec3d(0,3,10)); - cam->setFocalPoint(sphereGeom->getPosition()); + cam->setPosition(imstk::Vec3d(0,0,10)); + cam->setFocalPoint(geom->getPosition()); // Run sdk->setCurrentScene("SceneTestDevice");