vrpn 07.35
Virtual Reality Peripheral Network
 
Loading...
Searching...
No Matches
vrpn_Vality.C
Go to the documentation of this file.
1// vrpn_Vality.C: VRPN driver for Vality devices
2
3#include <stdio.h> // for fprintf, stderr, NULL
4#include <string.h> // for memset
5#include <math.h> // for fabs
6
7#include "vrpn_Vality.h"
8#include "vrpn_MessageMacros.h" // for VRPN_MSG_INFO, VRPN_MSG_WARNING, VRPN_MSG_ERROR
10
11#if defined(VRPN_USE_HID)
12
13static const double POLL_INTERVAL = 1e+6 / 30.0; // If we have not heard, ask.
14
15// USB vendor and product IDs for the models we support
16static const vrpn_uint16 VALITY_VENDOR = 0x0483;
17static const vrpn_uint16 VALITY_VGLASS = 0x5740;
18
21 vrpn_uint16 vendor, vrpn_uint16 product)
22 : vrpn_BaseClass(name, c)
24 , _filter(filter)
25{
26 init_hid();
27}
28
30{
31 try {
32 delete _filter;
33 } catch (...) {
34 fprintf(stderr, "vrpn_Vality::~vrpn_Vality(): delete failed\n");
35 return;
36 }
37}
38
40{
41 // Get notifications when clients connect and disconnect
44}
45
46void vrpn_Vality::on_data_received(size_t bytes, vrpn_uint8 *buffer)
47{
48 decodePacket(bytes, buffer);
49}
50
52{
53 return 0;
54}
55
56int vrpn_Vality::on_connect(void * /*thisPtr*/, vrpn_HANDLERPARAM /*p*/)
57{
58 return 0;
59}
60
64 new vrpn_HidProductAcceptor(VALITY_VENDOR, VALITY_VGLASS),
65 name, c, VALITY_VENDOR, VALITY_VGLASS)
66 , vrpn_Analog(name, c)
67{
69
70 // Initialize the state of all the analogs
71 memset(channel, 0, sizeof(channel));
72 memset(last, 0, sizeof(last));
73}
74
76{
77 update();
79 struct timeval current_time;
80 vrpn_gettimeofday(&current_time, NULL);
81 if (vrpn_TimevalDuration(current_time, _timestamp) > POLL_INTERVAL ) {
82 _timestamp = current_time;
84
85 // Call the server_mainloop on our unique base class.
87 }
88}
89
90void vrpn_Vality_vGlass::report(vrpn_uint32 class_of_service)
91{
93 {
95 }
96
98 {
99 vrpn_Analog::report(class_of_service);
100 }
101}
102
103void vrpn_Vality_vGlass::report_changes(vrpn_uint32 class_of_service)
104{
106 {
108 }
109
111 {
112 vrpn_Analog::report_changes(class_of_service);
113 }
114}
115
116void vrpn_Vality_vGlass::decodePacket(size_t bytes, vrpn_uint8 *buffer)
117{
118 // There is only one type of report, which is 62 bytes long on Windows but
119 // which only contains data in the first 24 bytes, so we just make sure that
120 // the report is long enough and starts with 1 (the proper report type).
121 if (bytes < 24) {
122 VRPN_MSG_ERROR("Message too short, ignoring");
123 return;
124 }
125
126 if (buffer[0] != 1) {
127 VRPN_MSG_ERROR("Unrecognized message type, ignoring");
128 return;
129 }
130
131 // Decode the report, storing our values into the analog channels.
132 uint8_t *bufptr;
133
134 // Decode the accelerometer values into channels 0=X, 1=Y, 2=Z.
135 // Converts from [-1..1] to meters/second/second using the typical
136 // sensitivity from the data sheet and the range set in the initialization
137 // code in the firmware, which is +/- 16G.
138 // The data appears to be stored in little-endian format.
139 // NOTE: The BMI160 used by the vGlass reports the negative of
140 // the acceleration vector, so we need to invert it after decoding it.
141 static const double MSS_SCALE = (1.0 / 32767) * 16 * 9.807;
142 bufptr = &buffer[12];
143 channel[0] = -vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MSS_SCALE;
144 channel[1] = -vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MSS_SCALE;
145 channel[2] = -vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MSS_SCALE;
146
147 // Decode the rotational velocity values into channels 3=X, 4=Y, 5=Z.
148 // Converts from [-1..1] to radians/second using the typical
149 // sensitivity from the data sheet and the default range (the range is not
150 // set in the initialization code in the firmware), so assuming that the
151 // register setting is 0 (+/- 2000 degrees/second).
152 // The data appears to be stored in little-endian format.
153 static const double RS_SCALE = (1.0 / 32767) * 2000 * (VRPN_PI/180);
154 bufptr = &buffer[6];
155 channel[3] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * RS_SCALE;
156 channel[4] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * RS_SCALE;
157 channel[5] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * RS_SCALE;
158
159 // Decode the magnetometer values into channels 6=X, 7=Y, 8=Z.
160 // Converts from [-1..1] to Tesla and then from Tesla to Gauss
161 // using the typical sensitivity from the AK09916 data sheet and the
162 // specified range of values (not quite the entire 16-bit range).
163 // The data appears to be stored in little-endian format.
164 // NOTE: The data does not appear to be consistent, so these readings
165 // are note very helpful as of 7/11/2019. Until we can get our hands on
166 // a unit and debug this, we'll leave these readings out.
167 /*
168 static const double MAG_SCALE = (4912.0 / 32752);
169 bufptr = &buffer[18];
170 channel[6] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MAG_SCALE;
171 channel[7] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MAG_SCALE;
172 channel[8] = vrpn_unbuffer_from_little_endian<vrpn_int16>(bufptr) * MAG_SCALE;
173 */
174}
175
176// End of VRPN_USE_HID
177#endif
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:39
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
vrpn_Analog(const char *name, vrpn_Connection *c=NULL)
Definition vrpn_Analog.C:14
struct timeval timestamp
Definition vrpn_Analog.h:41
vrpn_int32 num_channel
Definition vrpn_Analog.h:40
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report whether something has changed or not (for servers) Optionally, tell what time to stamp ...
Definition vrpn_Analog.C:94
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Send a report only if something has changed (for servers) Optionally, tell what time to stamp the val...
Definition vrpn_Analog.C:71
int register_autodeleted_handler(vrpn_int32 type, vrpn_MESSAGEHANDLER handler, void *userdata, vrpn_int32 sender=vrpn_ANY_SENDER)
Registers a handler with the connection, and remembers to delete at destruction.
vrpn_Connection * d_connection
Connection that this object talks to.
void server_mainloop(void)
Handles functions that all servers should provide in their mainloop() (ping/pong, for example) Should...
vrpn_BaseClass(const char *name, vrpn_Connection *c=NULL)
Names the device and assigns or opens connection, calls registration methods.
Generic connection class not specific to the transport mechanism.
vrpn_uint16 product() const
Returns USB product ID of connected device May not contain valid if an already-open device was provid...
vrpn_HidInterface(vrpn_HidAcceptor *acceptor, vrpn_uint16 vendor=0, vrpn_uint16 product=0, hid_device *device=NULL)
Constructor If we already have a HID device from some other source, it can be passed and we'll take o...
virtual void update()
Polls the device buffers and causes on_data_received callbacks if appropriate You NEED to call this f...
vrpn_uint16 vendor() const
Returns USB vendor ID of connected device May not contain valid if an already-open device was provide...
Accepts any device with the given vendor and product IDs.
vrpn_Vality_vGlass(const char *name, vrpn_Connection *c=0)
Definition vrpn_Vality.C:61
void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
void decodePacket(size_t bytes, vrpn_uint8 *buffer)
void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY)
Definition vrpn_Vality.C:90
virtual void mainloop(void)
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition vrpn_Vality.C:75
void on_data_received(size_t bytes, vrpn_uint8 *buffer)
Derived class reimplements this callback.
Definition vrpn_Vality.C:46
static int VRPN_CALLBACK on_last_disconnect(void *thisPtr, vrpn_HANDLERPARAM p)
Definition vrpn_Vality.C:51
struct timeval _timestamp
Definition vrpn_Vality.h:36
void init_hid(void)
Definition vrpn_Vality.C:39
virtual ~vrpn_Vality(void)
Definition vrpn_Vality.C:29
vrpn_Vality(vrpn_HidAcceptor *filter, const char *name, vrpn_Connection *c=0, vrpn_uint16 vendor=0, vrpn_uint16 product=0)
Definition vrpn_Vality.C:19
vrpn_HidAcceptor * _filter
Definition vrpn_Vality.h:37
virtual void decodePacket(size_t bytes, vrpn_uint8 *buffer)=0
static int VRPN_CALLBACK on_connect(void *thisPtr, vrpn_HANDLERPARAM p)
Definition vrpn_Vality.C:56
This structure is what is passed to a vrpn_Connection message callback.
#define VRPN_SUPPRESS_EMPTY_OBJECT_WARNING()
const char * vrpn_dropped_last_connection
const char * vrpn_got_connection
#define POLL_INTERVAL
Definition vrpn_IDEA.C:26
Header containing macros formerly duplicated in a lot of implementation files.
#define VRPN_MSG_ERROR(msg)
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99
#define VRPN_PI
Definition vrpn_Shared.h:13