vrpn  07.33
Virtual Reality Peripheral Network
vrpn_Analog.C
Go to the documentation of this file.
1 #include "vrpn_Analog.h"
2 #include <stdio.h>
3 #include <string.h>
4 // Include vrpn_Shared.h _first_ to avoid conflicts with sys/time.h
5 // and netinet/in.h and ...
6 #include "vrpn_Shared.h"
7 
8 #ifndef VRPN_CLIENT_ONLY
9 #include "vrpn_Serial.h"
10 #endif
11 
12 //#define VERBOSE
13 
15  : vrpn_BaseClass(name, c)
16  , num_channel(0)
17 {
18  // Call the base class' init routine
20 
21  // Set the time to 0 just to have something there.
22  timestamp.tv_usec = timestamp.tv_sec = 0;
23  // Initialize the values in the channels,
24  // gets rid of uninitialized memory read error in Purify
25  // and makes sure any initial value change gets reported.
26  for (vrpn_int32 i = 0; i < vrpn_CHANNEL_MAX; i++) {
27  channel[i] = last[i] = 0;
28  }
29 }
30 
32 {
33  channel_m_id = d_connection->register_message_type("vrpn_Analog Channel");
34  if (channel_m_id == -1) {
35  return -1;
36  }
37  else {
38  return 0;
39  }
40 }
41 
43 {
44  printf("Analog Report: ");
45  for (vrpn_int32 i = 0; i < num_channel; i++) {
46  // printf("Channel[%d]= %f\t", i, channel[i]);
47  printf("%f\t", channel[i]);
48  }
49  printf("\n");
50 }
51 
52 vrpn_int32 vrpn_Analog::getNumChannels(void) const { return num_channel; }
53 
54 vrpn_int32 vrpn_Analog::encode_to(char *buf)
55 {
56  // Message includes: vrpn_float64 AnalogNum, vrpn_float64 state
57  // Byte order of each needs to be reversed to match network standard
58 
59  vrpn_float64 double_chan = num_channel;
60  int buflen = (vrpn_CHANNEL_MAX + 1) * sizeof(vrpn_float64);
61 
62  vrpn_buffer(&buf, &buflen, double_chan);
63  for (int i = 0; i < num_channel; i++) {
64  vrpn_buffer(&buf, &buflen, channel[i]);
65  last[i] = channel[i];
66  }
67 
68  return (num_channel + 1) * sizeof(vrpn_float64);
69 }
70 
71 void vrpn_Analog::report_changes(vrpn_uint32 class_of_service,
72  const struct timeval time)
73 {
74  vrpn_int32 i;
75  vrpn_int32 change = 0;
76 
77  if (d_connection) {
78  for (i = 0; i < num_channel; i++) {
79  if (channel[i] != last[i]) change = 1;
80  last[i] = channel[i];
81  }
82  if (!change) {
83 #ifdef VERBOSE
84  fprintf(stderr, "No change.\n");
85 #endif
86  return;
87  }
88  }
89 
90  // there is indeed some change, send it;
91  vrpn_Analog::report(class_of_service, time);
92 }
93 
94 void vrpn_Analog::report(vrpn_uint32 class_of_service,
95  const struct timeval time)
96 {
97  // msgbuf must be float64-aligned!
98  vrpn_float64 fbuf[vrpn_CHANNEL_MAX + 1];
99  char *msgbuf = (char *)fbuf;
100 
101  vrpn_int32 len;
102 
103  // Replace the time value with the current time if the user passed in the
104  // constant time referring to "now".
105  if ((time.tv_sec == vrpn_ANALOG_NOW.tv_sec) &&
106  (time.tv_usec == vrpn_ANALOG_NOW.tv_usec)) {
108  }
109  else {
110  timestamp = time;
111  }
112  len = vrpn_Analog::encode_to(msgbuf);
113 #ifdef VERBOSE
114  print();
115 #endif
116  if (d_connection &&
118  msgbuf, class_of_service)) {
119  fprintf(stderr, "vrpn_Analog: cannot write message: tossing\n");
120  }
121 }
122 
123 #ifndef VRPN_CLIENT_ONLY
125  const char *port, int baud, int bits,
126  vrpn_SER_PARITY parity, bool rts_flow)
127  : vrpn_Analog(name, c)
128  , serial_fd(-1)
129  , baudrate(0)
130  , bufcounter(0)
131 {
132  // Initialize
133  portname[0] = '\0';
134  buffer[0] = '\0';
135  // Find out the port name and baud rate;
136  if (port == NULL) {
137  fprintf(stderr, "vrpn_Serial_Analog: NULL port name\n");
139  return;
140  }
141  else {
142  strncpy(portname, port, sizeof(portname));
143  portname[sizeof(portname) - 1] = '\0';
144  }
145  baudrate = baud;
146 
147  // Open the serial port we're going to use
148  if ((serial_fd = vrpn_open_commport(portname, baudrate, bits, parity,
149  rts_flow)) == -1) {
150  fprintf(stderr, "vrpn_Serial_Analog: Cannot Open serial port\n");
152  }
153 
154  // Reset the tracker and find out what time it is
157 }
158 
160 {
161  // Close com port when destroyed.
162  if (serial_fd != -1) {
164  }
165 }
166 
167 #endif // VRPN_CLIENT_ONLY
168 
170  vrpn_int32 numChannels)
171  : vrpn_Analog(name, c)
172 {
173  this->setNumChannels(numChannels);
174 
175  // Check if we got a connection.
176  if (d_connection == NULL) {
177  fprintf(stderr, "vrpn_Analog_Server: Can't get connection!\n");
178  }
179 }
180 
181 // virtual
182 void vrpn_Analog_Server::report_changes(vrpn_uint32 class_of_service,
183  const struct timeval time)
184 {
185  vrpn_Analog::report_changes(class_of_service, time);
186 }
187 
188 // virtual
189 void vrpn_Analog_Server::report(vrpn_uint32 class_of_service,
190  const struct timeval time)
191 {
192  vrpn_Analog::report(class_of_service, time);
193 }
194 
195 vrpn_int32 vrpn_Analog_Server::setNumChannels(vrpn_int32 sizeRequested)
196 {
197  if (sizeRequested < 0) sizeRequested = 0;
198  if (sizeRequested > vrpn_CHANNEL_MAX) sizeRequested = vrpn_CHANNEL_MAX;
199  num_channel = sizeRequested;
200  return num_channel;
201 }
202 
204  vrpn_Connection *c,
205  vrpn_int32 numChannels)
206  : vrpn_Analog_Server(name, c, numChannels)
207 {
208  int i;
209 
210  for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
211  clipvals[i].minimum_val = -1.0;
212  clipvals[i].lower_zero = 0.0;
213  clipvals[i].upper_zero = 0.0;
214  clipvals[i].maximum_val = 1.0;
215  }
216 }
217 
226  double lowzero, double highzero,
227  double max)
228 {
229  if ((chan < 0) || (chan >= vrpn_CHANNEL_MAX)) {
230  fprintf(
231  stderr,
232  "vrpn_Clipping_Analog_Server::setClipValues: Bad channel (%d)\n",
233  chan);
234  return -1;
235  }
236  if ((lowzero < min) || (highzero < lowzero) || (max < highzero)) {
237  fprintf(stderr, "vrpn_Clipping_Analog_Server::setClipValues: Out of "
238  "order mapping\n");
239  return -1;
240  }
241 
242  clipvals[chan].minimum_val = min;
243  clipvals[chan].lower_zero = lowzero;
244  clipvals[chan].upper_zero = highzero;
245  clipvals[chan].maximum_val = max;
246 
247  return 0;
248 }
249 
254 {
255  if ((chan < 0) || (chan >= vrpn_CHANNEL_MAX)) {
256  fprintf(
257  stderr,
258  "vrpn_Clipping_Analog_Server::setChannelValue: Bad channel (%d)\n",
259  chan);
260  return -1;
261  }
262 
263  // Figure out which clipping values to use
264  clipvals_struct clips = clipvals[chan];
265 
266  // See if it should be clipped to zero, high, or low. Zero is checked
267  // first so that the range can be compress to [0..1] or [-1..0] by setting
268  // a zero value equal to a clip value.
269  if ((value >= clips.lower_zero) && (value <= clips.upper_zero)) {
270  channel[chan] = 0.0;
271  }
272  else if (value <= clips.minimum_val) {
273  channel[chan] = -1.0;
274  }
275  else if (value >= clips.maximum_val) {
276  channel[chan] = 1.0;
277 
278  // If we are below the minzero, then we should map to the -1..0 range.
279  // Otherwise, map to the 0..1 range. Note that if we have reached this
280  // point, the range we are mapped to has not been collapsed, so we won't
281  // get divide-by-zero problems and such.
282  }
283  else if (value > clips.lower_zero) {
284  channel[chan] =
285  (value - clips.upper_zero) / (clips.maximum_val - clips.upper_zero);
286  }
287  else {
288  // Larger negative number (minus smaller negative [net positive]) is
289  // negative
290  // Negative number divided by positive number is negative.
291  channel[chan] =
292  (value - clips.lower_zero) / (clips.lower_zero - clips.minimum_val);
293  }
294 
295  return 0;
296 }
297 
298 // ************* CLIENT ROUTINES ****************************
299 
301  : vrpn_Analog(name, c)
302 {
303  vrpn_int32 i;
304 
305  // Register a handler for the change callback from this device,
306  // if we got a connection.
307  if (d_connection != NULL) {
309  this, d_sender_id)) {
310  fprintf(stderr, "vrpn_Analog_Remote: can't register handler\n");
311  d_connection = NULL;
312  }
313  }
314  else {
315  fprintf(stderr, "vrpn_Analog_Remote: Can't get connection!\n");
316  }
317 
318  // At the start, as far as the client knows, the device could have
319  // max channels -- the number of channels is specified in each
320  // message.
322  for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
323  channel[i] = last[i] = 0;
324  }
326 }
327 
329 {
330  if (d_connection) {
332  client_mainloop();
333  }
334 }
335 
338 {
339  const char *bufptr = p.buffer;
340  vrpn_float64 numchannelD; //< Number of channels passed in a double (yuck!)
342  vrpn_ANALOGCB cp;
343 
344  cp.msg_time = p.msg_time;
345  vrpn_unbuffer(&bufptr, &numchannelD);
346  cp.num_channel = (long)numchannelD;
347  me->num_channel = cp.num_channel;
348  for (vrpn_int32 i = 0; i < cp.num_channel; i++) {
349  vrpn_unbuffer(&bufptr, &cp.channel[i]);
350  }
351 
352  // Go down the list of callbacks that have been registered.
353  // Fill in the parameter and call each.
355 
356  return 0;
357 }
vrpn_Serial_Analog::vrpn_Serial_Analog
vrpn_Serial_Analog(const char *name, vrpn_Connection *connection, const char *port, int baud=9600, int bits=8, vrpn_SER_PARITY parity=vrpn_SER_PARITY_NONE, bool rts_flow=false)
Definition: vrpn_Analog.C:124
vrpn_Analog_Server::vrpn_Analog_Server
vrpn_Analog_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
Definition: vrpn_Analog.C:169
vrpn_BaseClassUnique::register_autodeleted_handler
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.
Definition: vrpn_BaseClass.C:503
vrpn_Connection::pack_message
virtual int pack_message(vrpn_uint32 len, struct timeval time, vrpn_int32 type, vrpn_int32 sender, const char *buffer, vrpn_uint32 class_of_service)
Pack a message that will be sent the next time mainloop() is called. Turn off the RELIABLE flag if yo...
Definition: vrpn_Connection.C:4632
vrpn_BaseClassUnique::client_mainloop
void client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
Definition: vrpn_BaseClass.C:637
vrpn_Analog::encode_to
virtual vrpn_int32 encode_to(char *buf)
Definition: vrpn_Analog.C:54
vrpn_Analog::status
int status
Definition: vrpn_Analog.h:43
min
#define min(x, y)
Definition: vrpn_WiiMote.C:47
vrpn_Analog::channel
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:38
vrpn_Analog_Server::setNumChannels
vrpn_int32 setNumChannels(vrpn_int32 sizeRequested)
Sets the size of the array; returns the size actually set. (May be clamped to vrpn_CHANNEL_MAX) This ...
Definition: vrpn_Analog.C:195
vrpn_Clipping_Analog_Server::setClipValues
int setClipValues(int channel, double min, double lowzero, double highzero, double max)
Set the clipping values for the specified channel. min maps to -1, values between lowzero and highzer...
Definition: vrpn_Analog.C:225
vrpn_Serial_Analog::buffer
unsigned char buffer[1024]
Definition: vrpn_Analog.h:75
vrpn_Clipping_Analog_Server::clipvals
clipvals_struct clipvals[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:158
vrpn_ANALOG_FAIL
const int vrpn_ANALOG_FAIL
Definition: vrpn_Analog.h:23
vrpn_Analog_Server
Definition: vrpn_Analog.h:95
vrpn_Analog::report
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
vrpn_Analog_Remote
Definition: vrpn_Analog.h:181
vrpn_BaseClassUnique::userdata
void * userdata
Definition: vrpn_BaseClass.h:287
vrpn_Analog
Definition: vrpn_Analog.h:28
vrpn_Analog::timestamp
struct timeval timestamp
Definition: vrpn_Analog.h:41
vrpn_CHANNEL_MAX
#define vrpn_CHANNEL_MAX
Definition: vrpn_Analog.h:16
vrpn_Analog_Remote::d_callback_list
vrpn_Callback_List< vrpn_ANALOGCB > d_callback_list
Definition: vrpn_Analog.h:204
vrpn_Analog::channel_m_id
vrpn_int32 channel_m_id
Definition: vrpn_Analog.h:42
vrpn_Serial.h
vrpn_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_Analog::vrpn_Analog
vrpn_Analog(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Analog.C:14
vrpn_Clipping_Analog_Server::setChannelValue
int setChannelValue(int channel, double value)
This method should be used to set the value of a channel. It will be scaled and clipped as described ...
Definition: vrpn_Analog.C:253
vrpn_unbuffer
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
Definition: vrpn_Shared.C:312
vrpn_Clipping_Analog_Server::vrpn_Clipping_Analog_Server
vrpn_Clipping_Analog_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
Definition: vrpn_Analog.C:203
vrpn_SER_PARITY
vrpn_SER_PARITY
Definition: vrpn_Serial.h:15
vrpn_ANALOG_NOW
const struct timeval vrpn_ANALOG_NOW
Definition: vrpn_Analog.h:26
vrpn_BaseClassUnique::d_connection
vrpn_Connection * d_connection
Connection that this object talks to.
Definition: vrpn_BaseClass.h:224
vrpn_HANDLERPARAM::buffer
const char * buffer
Definition: vrpn_Connection.h:49
vrpn_Connection::register_message_type
virtual vrpn_int32 register_message_type(const char *name)
Definition: vrpn_Connection.C:5074
vrpn_ANALOG_RESETTING
const int vrpn_ANALOG_RESETTING
Definition: vrpn_Analog.h:22
vrpn_HANDLERPARAM
This structure is what is passed to a vrpn_Connection message callback.
Definition: vrpn_Connection.h:44
vrpn_Shared.h
vrpn_Clipping_Analog_Server::clipvals_struct::minimum_val
double minimum_val
Definition: vrpn_Analog.h:152
vrpn_BaseClassUnique::d_sender_id
vrpn_int32 d_sender_id
Sender ID registered with the connection.
Definition: vrpn_BaseClass.h:228
vrpn_Analog_Remote::handle_change_message
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p)
Definition: vrpn_Analog.C:336
vrpn_Analog::getNumChannels
vrpn_int32 getNumChannels(void) const
Definition: vrpn_Analog.C:52
vrpn_Analog_Server::report
virtual void report(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Makes public the protected base class function.
Definition: vrpn_Analog.C:189
vrpn_Analog_Remote::mainloop
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
Definition: vrpn_Analog.C:328
vrpn_Connection::mainloop
virtual int mainloop(const struct timeval *timeout=NULL)=0
Call each time through program main loop to handle receiving any incoming messages and sending any pa...
vrpn_HANDLERPARAM::msg_time
struct timeval msg_time
Definition: vrpn_Connection.h:47
vrpn_Serial_Analog::serial_fd
int serial_fd
Definition: vrpn_Analog.h:72
vrpn_Connection
Generic connection class not specific to the transport mechanism.
Definition: vrpn_Connection.h:510
vrpn_Analog::num_channel
vrpn_int32 num_channel
Definition: vrpn_Analog.h:40
vrpn_Serial_Analog::baudrate
int baudrate
Definition: vrpn_Analog.h:74
vrpn_Analog::print
void print(void)
Definition: vrpn_Analog.C:42
vrpn_gettimeofday
#define vrpn_gettimeofday
Definition: vrpn_Shared.h:89
vrpn_Clipping_Analog_Server::clipvals_struct::upper_zero
double upper_zero
Definition: vrpn_Analog.h:154
vrpn_Clipping_Analog_Server::clipvals_struct
Definition: vrpn_Analog.h:151
vrpn_close_commport
int vrpn_close_commport(int comm)
Definition: vrpn_Serial.C:345
vrpn_Analog.h
vrpn_Analog::last
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition: vrpn_Analog.h:39
vrpn_Serial_Analog::portname
char portname[1024]
Definition: vrpn_Analog.h:73
vrpn_BaseClass::init
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
Definition: vrpn_BaseClass.C:363
vrpn_Analog_Server::report_changes
virtual void report_changes(vrpn_uint32 class_of_service=vrpn_CONNECTION_LOW_LATENCY, const struct timeval time=vrpn_ANALOG_NOW)
Makes public the protected base class function.
Definition: vrpn_Analog.C:182
vrpn_buffer
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
Definition: vrpn_Shared.C:241
vrpn_Clipping_Analog_Server::clipvals_struct::lower_zero
double lower_zero
Definition: vrpn_Analog.h:153
vrpn_open_commport
int vrpn_open_commport(const char *portname, long baud, int charsize, vrpn_SER_PARITY parity, bool rts_flow)
Open a serial port, given its name and baud rate.
Definition: vrpn_Serial.C:54
vrpn_Clipping_Analog_Server::clipvals_struct::maximum_val
double maximum_val
Definition: vrpn_Analog.h:155
vrpn_Callback_List::call_handlers
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
Definition: vrpn_BaseClass.h:451
vrpn_Analog::report_changes
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
vrpn_Analog_Remote::vrpn_Analog_Remote
vrpn_Analog_Remote(const char *name, vrpn_Connection *c=NULL)
Definition: vrpn_Analog.C:300
vrpn_Serial_Analog::~vrpn_Serial_Analog
~vrpn_Serial_Analog()
Definition: vrpn_Analog.C:159
vrpn_BaseClass
Class from which all user-level (and other) classes that communicate with vrpn_Connections should der...
Definition: vrpn_BaseClass.h:313
vrpn_Analog::register_types
virtual int register_types(void)
Register the types of messages this device sends/receives. Return 0 on success, -1 on fail.
Definition: vrpn_Analog.C:31