Privacy
An open-source, flexible 3D physical simulation framework
ConnexionHID.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2011, 2012, DFKI GmbH Robotics Innovation Center
3  *
4  * This file is part of the MARS simulation framework.
5  *
6  * MARS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation, either version 3
9  * of the License, or (at your option) any later version.
10  *
11  * MARS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with MARS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "../ConnexionHID.h"
22 
23 #if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0501)
24  #undef _WIN32_WINNT
25  #define _WIN32_WINNT 0x0601
26 #endif
27 
28 #include <mars/utils/Mutex.h>
29 #include <QApplication>
30 #include <cmath>
31 #include <windows.h>
32 
33 namespace mars {
34  namespace plugins {
35  namespace connexion_plugin {
36 
37  static int idleFrameCount[3] = {0,0,0};
38  static int idleThreshold = 4;
39 
40  bool myEventFilter(void *message, long *result);
41 
42  // let's have some global variables. great!
45 
46 
47  int registerRawDevices(HWND hwndMessagesWindow) {
48  RAWINPUTDEVICE sRawInputDevices[1];
49  sRawInputDevices[0].usUsagePage = 0x01;
50  sRawInputDevices[0].usUsage = 0x08;
51  sRawInputDevices[0].dwFlags = 0x00;
52  sRawInputDevices[0].hwndTarget = 0x00;
53  //RIM_TYPEHID;
54 
55  unsigned int uiNumDevices = sizeof(sRawInputDevices)/sizeof(sRawInputDevices[0]);
56  unsigned int cbSize = sizeof(sRawInputDevices[0]);
57 
58  unsigned int i;
59  for (i = 0; i < uiNumDevices; ++i) {
60  sRawInputDevices[i].hwndTarget = hwndMessagesWindow;
61  }
62  return RegisterRawInputDevices(sRawInputDevices, uiNumDevices, cbSize);
63  }
64 
65 
66  int initConnexionHID(void* windowID) {
67  tmpValues.tx = 0.0;
68  tmpValues.ty = 0.0;
69  tmpValues.tz = 0.0;
70  tmpValues.rx = 0.0;
71  tmpValues.ry = 0.0;
72  tmpValues.rz = 0.0;
73  tmpValues.button1 = 0;
74  tmpValues.button2 = 0;
75 
76  qApp->setEventFilter(myEventFilter);
77 
78  HWND handleForMessages = (HWND)windowID;
79  return registerRawDevices(handleForMessages);
80  }
81 
82  void getValue(mars::interfaces::sReal *coordinates,
83  struct connexionValues *rawValues) {
84  valueMutex.lock();
85  for(int i = 0; i < 3; ++i) {
86  ++idleFrameCount[i];
87  }
88  *rawValues = tmpValues;
89 
90  coordinates[0] = tmpValues.tx * fabs(tmpValues.tx * 0.001);
91  coordinates[1] = -tmpValues.tz * fabs(tmpValues.tz * 0.001);
92  coordinates[2] = -tmpValues.ty * fabs(tmpValues.ty * 0.001);
93  coordinates[3] = tmpValues.rx * fabs(tmpValues.rx * 0.0008);
94  coordinates[4] = -tmpValues.rz * fabs(tmpValues.rz * 0.0008);
95  coordinates[5] = -tmpValues.ry * fabs(tmpValues.ry * 0.0008);
96 
97  if(idleFrameCount[0] > idleThreshold) {
98  tmpValues.tx = 0.0;
99  tmpValues.ty = 0.0;
100  tmpValues.tz = 0.0;
101  }
102  if(idleFrameCount[1] > idleThreshold) {
103  tmpValues.rx = 0.0;
104  tmpValues.ry = 0.0;
105  tmpValues.rz = 0.0;
106  }
107  if(idleFrameCount[2] > idleThreshold) {
108  tmpValues.button1 = 0;
109  tmpValues.button2 = 0;
110  }
111  valueMutex.unlock();
112  }
113 
114  void closeConnexionHID() {
115  }
116 
117 
118  bool myEventFilter(void *message, long *result) {
119 
120  MSG *msgStruct = (MSG*) message;
121 
122  if (msgStruct->message == WM_INPUT) {
123 
124 
125  //cout << "Message: WM_INPUT erhalten" << endl;
126 
127  unsigned int dwSize = 0;
128 
129  GetRawInputData((HRAWINPUT)msgStruct->lParam, RID_INPUT, NULL,
130  &dwSize, sizeof(RAWINPUTHEADER));
131 
132  LPBYTE lpb = new BYTE[dwSize];
133 
134  if (GetRawInputData((HRAWINPUT)msgStruct->lParam, RID_INPUT,
135  lpb, &dwSize, sizeof(RAWINPUTHEADER))
136  != dwSize) {
137  delete[] lpb;
138  return false;
139  }
140 
141  RAWINPUT* raw = (RAWINPUT*) lpb;
142 
143  if (raw->header.dwType != RIM_TYPEHID) {
144  delete[] lpb;
145  return false;
146  }
147 
148  RID_DEVICE_INFO sRidDeviceInfo;
149  sRidDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
150  dwSize = sizeof(RID_DEVICE_INFO);
151 
152  if (GetRawInputDeviceInfo(raw->header.hDevice,
153  RIDI_DEVICEINFO,
154  &sRidDeviceInfo,
155  &dwSize) == dwSize) {
156  if (sRidDeviceInfo.hid.dwVendorId == LOGITECH_VENDOR_ID) {
157  if (raw->data.hid.bRawData == 0x01) {
158  // Translation vector
159 
160  short *pnData = reinterpret_cast <short*> (&raw->data.hid.bRawData + 1);
161  //cout << "packet1 X: " << pnData[0] << " Y: " << pnData[1] << " Z: " << pnData[2] << endl;
162  // while(is_waiting) Sleep(1);
163 
164  valueMutex.lock();
165  tmpValues.tx = pnData[0];
166  tmpValues.ty = pnData[1];
167  tmpValues.tz = pnData[2];
168  idleFrameCount[0] = 0;
169  valueMutex.unlock();
170  } else if (raw->data.hid.bRawData == 0x02) {
171  // Direct rotation vector (NOT Euler)
172  short *pnData = reinterpret_cast <short*> (&raw->data.hid.bRawData + 1);
173  //cout << "packet2 rX: " << pnData[0] << " rY: " << pnData[1] << " rZ: " << pnData[2] << endl;
174  valueMutex.lock();
175  tmpValues.rx = pnData[0];
176  tmpValues.ry = pnData[1];
177  tmpValues.rz = pnData[2];
178  idleFrameCount[1] = 0;
179  valueMutex.unlock();
180  } else if (raw->data.hid.bRawData == 0x03) {
181  // State of the keys
182  unsigned long dwKeyState = *reinterpret_cast <unsigned long*> (&raw->data.hid.bRawData + 1);
183  if (dwKeyState & 1) {
184  valueMutex.lock();
185  tmpValues.button1 = 1;
186  idleFrameCount[2] = 0;
187  valueMutex.unlock();
188  }
189  if (dwKeyState & 2) {
190  valueMutex.lock();
191  tmpValues.button2 = 1;
192  idleFrameCount[2] = 0;
193  valueMutex.unlock();
194  }
195  //cout << "key pressed: " << dwKeyState << endl;
196  }
197  }
198  }
199 
200  // Do something
201  *result = 1;
202  delete[] lpb;
203  return true;
204  }
205  else {
206  // We do not want to handle this message so pass back to Windows
207  // to handle it in a default way
208  return false;
209  }
210  }
211 
212  } // end of namespace connexion_plugin
213  } // end of namespace plugins
214 } // end of namespace mars
static mars::utils::Mutex valueMutex
static connexionValues tmpValues
int registerRawDevices(HWND hwndMessagesWindow)
void getValue(interfaces::sReal *coordiantes, struct connexionValues *rawValues)
MutexError unlock()
Definition: Mutex.cpp:77
int initConnexionHID(void *windowID)
double sReal
Definition: MARSDefs.h:49
#define LOGITECH_VENDOR_ID
Definition: ConnexionHID.h:26
bool myEventFilter(void *message, long *result)
Copyright 2012, DFKI GmbH Robotics Innovation Center.
MutexError lock()
locks the Mutex
Definition: Mutex.cpp:61