/vrpn_Tracker_SpacePoint.C

https://gitlab.com/sat-metalab/vrpn · C · 98 lines · 50 code · 19 blank · 29 comment · 6 complexity · b5b3d09617555b53897fdde2dce8f8e6 MD5 · raw file

  1. /*
  2. * vrpn_Tracker_SpacePoint.cpp
  3. *
  4. * Created on: Nov 22, 2010
  5. * Author: janoc
  6. */
  7. #include <stdio.h> // for fprintf, stderr
  8. #include <string.h> // for memset
  9. #include "vrpn_Connection.h" // for vrpn_CONNECTION_LOW_LATENCY, etc
  10. #include "vrpn_Tracker_SpacePoint.h"
  11. const unsigned SPACEPOINT_VENDOR = 0x20ff;
  12. const unsigned SPACEPOINT_PRODUCT = 0x0100;
  13. VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
  14. #ifdef VRPN_USE_HID
  15. vrpn_Tracker_SpacePoint::vrpn_Tracker_SpacePoint(const char * name, vrpn_Connection * trackercon) :
  16. vrpn_Tracker(name, trackercon), vrpn_Button(name, trackercon),
  17. vrpn_HidInterface(new vrpn_HidProductAcceptor(SPACEPOINT_VENDOR, SPACEPOINT_PRODUCT),
  18. SPACEPOINT_VENDOR, SPACEPOINT_PRODUCT)
  19. {
  20. memset(d_quat, 0, 4 * sizeof(float));
  21. d_quat[3] = 1.0;
  22. vrpn_Button::num_buttons = 2;
  23. vrpn_gettimeofday(&_timestamp, NULL);
  24. }
  25. void vrpn_Tracker_SpacePoint::on_data_received(size_t bytes, vrpn_uint8 *buffer)
  26. {
  27. /*
  28. * Horrible kludge - as we do not have a way to select the correct endpoint, we have to use a hack
  29. * to identify the correct device. In Windows the SpacePoint appears as 2 devices with same VID/PID, one for each endpoint
  30. * The correct device sends a report 15 bytes long. If we get a report of a different length, we try to open
  31. * the other device instead.
  32. */
  33. // test from the app note
  34. // the quaternion should be: 0.2474, -0.1697, -0.1713, 0.9384
  35. /*
  36. bytes = 15;
  37. vrpn_uint8 test_dta[] =
  38. { 0x2f, 0x85, 0x23, 0x8a, 0x5b, 0x90, 0xac, 0x9f, 0x49, 0x6a, 0x12, 0x6a, 0x1e, 0xf8, 0xd0 };
  39. memcpy(buffer, test_dta, 15 * sizeof(vrpn_uint8));
  40. */
  41. if (bytes == 15) {
  42. vrpn_uint8 * bufptr = buffer + 6;
  43. for (int i = 0; i < 4; i++) {
  44. d_quat[i] = (vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr) - 32768) / 32768.0;
  45. }
  46. buttons[0] = buffer[14] & 0x1;
  47. buttons[1] = buffer[14] & 0x2;
  48. // Find out what time we received the new information, then send any
  49. // changes to the client.
  50. vrpn_gettimeofday(&_timestamp, NULL);
  51. vrpn_Tracker::timestamp = _timestamp;
  52. vrpn_Button::timestamp = _timestamp;
  53. // send tracker orientation
  54. d_sensor = 0;
  55. memset(pos, 0, sizeof(vrpn_float64) * 3); // no position
  56. char msgbuf[1000];
  57. int len = vrpn_Tracker::encode_to(msgbuf);
  58. if (d_connection->pack_message(len, _timestamp, position_m_id, d_sender_id, msgbuf, vrpn_CONNECTION_LOW_LATENCY)) {
  59. fprintf(stderr, "SpacePoint tracker: can't write message: tossing\n");
  60. }
  61. // send buttons
  62. vrpn_Button::report_changes();
  63. } else {
  64. // try the other iface
  65. // as we are keeping the first one open,
  66. // it will not enumerate and we get the next one. Horrible kludge :(
  67. reconnect();
  68. }
  69. }
  70. void vrpn_Tracker_SpacePoint::mainloop()
  71. {
  72. if (connected()) {
  73. // device update. This will call on_data_received() if we get something.
  74. update();
  75. // server update
  76. server_mainloop();
  77. }
  78. }
  79. #endif