7 #include "imstkOpenHapticDeviceManager.h" 8 #include "imstkOpenHapticDeviceClient.h" 9 #include "imstkLogger.h" 23 HDdouble angularVel[3];
24 HDdouble transform[16];
40 HDErrorInfo error = hdGetError();
41 if (error.errorCode == HD_SUCCESS)
48 bool anotherFatalError = isFatalError(message);
50 bool isFatal = ((error.errorCode != HD_WARM_MOTORS)
51 && (error.errorCode != HD_EXCEEDED_MAX_FORCE)
52 && (error.errorCode != HD_EXCEEDED_MAX_FORCE_IMPULSE)
53 && (error.errorCode != HD_EXCEEDED_MAX_VELOCITY)
54 && (error.errorCode != HD_FORCE_ERROR));
56 LOG(WARNING) <<
"Phantom: " << message <<
57 std::endl <<
" Error text: '" << hdGetErrorString(error.errorCode) <<
"'" << std::endl <<
58 " Error code: 0x" << std::hex << std::setw(4) << std::setfill(
'0') << error.errorCode <<
59 " (internal: " << std::dec << error.internalErrorCode <<
")" << std::endl;
61 return (isFatal || anotherFatalError);
64 static HDCallbackCode HDCALLBACK hapticCallback(
void* pData)
69 for (
int num = 0; num < impl->m_deviceClients.size(); ++num)
71 HHD handle = impl->m_handles[num];
74 if (handle == HD_BAD_HANDLE || handle == HD_INVALID_HANDLE)
80 #ifdef IMSTK_OPENHAPTICS_DEBUG 83 force = Vec3d::Zero();
84 LOG(WARNING) <<
"Force has NANs";
90 hdSetDoublev(HD_CURRENT_FORCE, force.data());
91 hdGetDoublev(HD_CURRENT_POSITION, state.pos);
92 hdGetDoublev(HD_CURRENT_VELOCITY, state.vel);
93 hdGetDoublev(HD_CURRENT_ANGULAR_VELOCITY, state.angularVel);
94 hdGetDoublev(HD_CURRENT_TRANSFORM, state.transform);
95 hdGetIntegerv(HD_CURRENT_BUTTONS, &state.buttons);
99 CHECK(!isFatalError(
"Error in device update"));
102 const Quatd orientation = Quatd((Eigen::Affine3d(Eigen::Matrix4d(state.transform))).rotation());
105 client->
m_position << state.pos[0] * 0.001, state.pos[1] * 0.001, state.pos[2] * 0.001;
106 client->
m_velocity << state.vel[0] * 0.001, state.vel[1] * 0.001, state.vel[2] * 0.001;
107 client->
m_angularVelocity << state.angularVel[0], state.angularVel[1], state.angularVel[2];
112 for (
int i = 0; i < 4; i++)
115 if ((state.buttons & (1 << i)) && !client->m_buttons[i])
117 client->m_buttons[i] =
true;
118 client->m_events.push_back({ i, BUTTON_PRESSED });
121 else if (!(state.buttons & (1 << i)) && client->m_buttons[i])
123 client->m_buttons[i] =
false;
124 client->m_events.push_back({ i, BUTTON_RELEASED });
130 return HD_CALLBACK_CONTINUE;
133 std::shared_ptr<imstk::OpenHapticDeviceClient> makeDeviceClient(std::string name)
135 auto client = std::make_shared<imstk::OpenHapticDeviceClient>(name);
136 m_deviceClients.push_back(client);
142 for (
const auto& client : m_deviceClients)
144 client->initialize();
147 HDErrorInfo errorFlush;
148 while (HD_DEVICE_ERROR(errorFlush = hdGetError())) {}
152 auto name = client->getDeviceName();
156 handle = hdInitDevice(HD_DEFAULT_DEVICE);
160 handle = hdInitDevice(name.c_str());
163 CHECK(!isFatalError(
"Failed to initialize device"));
165 m_handles.push_back(handle);
167 hdMakeCurrentDevice(handle);
176 HDstring str = hdGetString(HD_DEVICE_SERIAL_NUMBER);
177 client->setDeviceName(
"Device_" + std::string(str));
181 hdEnable(HD_FORCE_OUTPUT);
182 hdEnable(HD_FORCE_RAMPING);
184 CHECK(!isFatalError(
"Failed to enable forces"));
186 LOG(INFO) <<
"\"" << client->getDeviceName() <<
"\" successfully initialized.";
190 m_schedulerHandle = hdScheduleAsynchronous(hapticCallback,
this, HD_MAX_SCHEDULER_PRIORITY);
192 CHECK(!isFatalError(
"Failed to schedule callback"));
198 for (
const auto& client : m_deviceClients)
207 hdUnschedule(m_schedulerHandle);
208 for (
const auto handle : m_handles)
210 hdDisableDevice(handle);
211 CHECK(!isFatalError(
"Failed to Disable device"));
216 HDSchedulerHandle m_schedulerHandle = 0;
217 std::vector<std::shared_ptr<imstk::OpenHapticDeviceClient>> m_deviceClients;
218 std::vector<HHD> m_handles;
221 OpenHapticDeviceManager::OpenHapticDeviceManager() :
226 setMuteUpdateEvents(
true);
229 std::shared_ptr<DeviceClient>
230 OpenHapticDeviceManager::makeDeviceClient(std::string name)
234 LOG(WARNING) <<
"Can't add device client after initialization.";
237 return m_impl->makeDeviceClient(name);
241 OpenHapticDeviceManager::initModule()
245 LOG(WARNING) <<
"OpenHapticDeviceManager already initialized. Reinitialization not implemented.";
248 return m_impl->init();
252 OpenHapticDeviceManager::updateModule()
258 OpenHapticDeviceManager::uninitModule()
void unlock()
End a thread-safe region.
Vec3d m_angularVelocity
Angular velocity of the end effector.
Vec3d getForce()
Get/Set the device force.
ParallelUtils::SpinLock m_dataLock
Used for button and analog data.
ParallelUtils::SpinLock m_transformLock
Used for devices filling data from other threads.
static bool isFatalError(const char *message)
Quatd m_orientation
Orientation of the end effector.
void lock()
Start a thread-safe region, where only one thread can execute at a time until a call to the unlock fu...
Vec3d m_velocity
Linear velocity of end effector.
Vec3d m_position
Position of end effector.
Subclass of DeviceClient for phantom omni Holds and updates the data sync or on its own thread Holder...