vrpn 07.35
Virtual Reality Peripheral Network
 
Loading...
Searching...
No Matches
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
52vrpn_int32 vrpn_Analog::getNumChannels(void) const { return num_channel; }
53
54vrpn_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
71void 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
94void 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 &&
117 d_connection->pack_message(len, timestamp, channel_m_id, d_sender_id,
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 vrpn_strcpy(portname, port);
143 }
144 baudrate = baud;
145
146 // Open the serial port we're going to use
147 if ((serial_fd = vrpn_open_commport(portname, baudrate, bits, parity,
148 rts_flow)) == -1) {
149 fprintf(stderr, "vrpn_Serial_Analog: Cannot Open serial port\n");
151 }
152
153 // Reset the analog and find out what time it is
156}
157
159{
160 // Close com port when destroyed.
161 if (serial_fd != -1) {
163 }
164}
165
166#endif // VRPN_CLIENT_ONLY
167
169 vrpn_int32 numChannels)
170 : vrpn_Analog(name, c)
171{
172 this->setNumChannels(numChannels);
173
174 // Check if we got a connection.
175 if (d_connection == NULL) {
176 fprintf(stderr, "vrpn_Analog_Server: Can't get connection!\n");
177 }
178}
179
180// virtual
181void vrpn_Analog_Server::report_changes(vrpn_uint32 class_of_service,
182 const struct timeval time)
183{
184 vrpn_Analog::report_changes(class_of_service, time);
185}
186
187// virtual
188void vrpn_Analog_Server::report(vrpn_uint32 class_of_service,
189 const struct timeval time)
190{
191 vrpn_Analog::report(class_of_service, time);
192}
193
194vrpn_int32 vrpn_Analog_Server::setNumChannels(vrpn_int32 sizeRequested)
195{
196 if (sizeRequested < 0) sizeRequested = 0;
197 if (sizeRequested > vrpn_CHANNEL_MAX) sizeRequested = vrpn_CHANNEL_MAX;
198 num_channel = sizeRequested;
199 return num_channel;
200}
201
204 vrpn_int32 numChannels)
205 : vrpn_Analog_Server(name, c, numChannels)
206{
207 int i;
208
209 for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
210 clipvals[i].minimum_val = -1.0;
211 clipvals[i].lower_zero = 0.0;
212 clipvals[i].upper_zero = 0.0;
213 clipvals[i].maximum_val = 1.0;
214 }
215}
216
225 double lowzero, double highzero,
226 double max)
227{
228 if ((chan < 0) || (chan >= vrpn_CHANNEL_MAX)) {
229 fprintf(
230 stderr,
231 "vrpn_Clipping_Analog_Server::setClipValues: Bad channel (%d)\n",
232 chan);
233 return -1;
234 }
235 if ((lowzero < min) || (highzero < lowzero) || (max < highzero)) {
236 fprintf(stderr, "vrpn_Clipping_Analog_Server::setClipValues: Out of "
237 "order mapping\n");
238 return -1;
239 }
240
241 clipvals[chan].minimum_val = min;
242 clipvals[chan].lower_zero = lowzero;
243 clipvals[chan].upper_zero = highzero;
244 clipvals[chan].maximum_val = max;
245
246 return 0;
247}
248
253{
254 if ((chan < 0) || (chan >= vrpn_CHANNEL_MAX)) {
255 fprintf(
256 stderr,
257 "vrpn_Clipping_Analog_Server::setChannelValue: Bad channel (%d)\n",
258 chan);
259 return -1;
260 }
261
262 // Figure out which clipping values to use
263 clipvals_struct clips = clipvals[chan];
264
265 // See if it should be clipped to zero, high, or low. Zero is checked
266 // first so that the range can be compress to [0..1] or [-1..0] by setting
267 // a zero value equal to a clip value.
268 if ((value >= clips.lower_zero) && (value <= clips.upper_zero)) {
269 channel[chan] = 0.0;
270 }
271 else if (value <= clips.minimum_val) {
272 channel[chan] = -1.0;
273 }
274 else if (value >= clips.maximum_val) {
275 channel[chan] = 1.0;
276
277 // If we are below the minzero, then we should map to the -1..0 range.
278 // Otherwise, map to the 0..1 range. Note that if we have reached this
279 // point, the range we are mapped to has not been collapsed, so we won't
280 // get divide-by-zero problems and such.
281 }
282 else if (value > clips.lower_zero) {
283 channel[chan] =
284 (value - clips.upper_zero) / (clips.maximum_val - clips.upper_zero);
285 }
286 else {
287 // Larger negative number (minus smaller negative [net positive]) is
288 // negative
289 // Negative number divided by positive number is negative.
290 channel[chan] =
291 (value - clips.lower_zero) / (clips.lower_zero - clips.minimum_val);
292 }
293
294 return 0;
295}
296
297// ************* CLIENT ROUTINES ****************************
298
300 : vrpn_Analog(name, c)
301{
302 vrpn_int32 i;
303
304 // Register a handler for the change callback from this device,
305 // if we got a connection.
306 if (d_connection != NULL) {
308 this, d_sender_id)) {
309 fprintf(stderr, "vrpn_Analog_Remote: can't register handler\n");
310 d_connection = NULL;
311 }
312 }
313 else {
314 fprintf(stderr, "vrpn_Analog_Remote: Can't get connection!\n");
315 }
316
317 // At the start, as far as the client knows, the device could have
318 // max channels -- the number of channels is specified in each
319 // message.
321 for (i = 0; i < vrpn_CHANNEL_MAX; i++) {
322 channel[i] = last[i] = 0;
323 }
325}
326
328{
329 if (d_connection) {
330 d_connection->mainloop();
332 }
333}
334
337{
338 const char *bufptr = p.buffer;
339 vrpn_float64 numchannelD; //< Number of channels passed in a double (yuck!)
341 vrpn_ANALOGCB cp;
342
343 cp.msg_time = p.msg_time;
344 vrpn_unbuffer(&bufptr, &numchannelD);
345 cp.num_channel = (long)numchannelD;
346 me->num_channel = cp.num_channel;
347 for (vrpn_int32 i = 0; i < cp.num_channel; i++) {
348 vrpn_unbuffer(&bufptr, &cp.channel[i]);
349 }
350
351 // Go down the list of callbacks that have been registered.
352 // Fill in the parameter and call each.
354
355 return 0;
356}
vrpn_Callback_List< vrpn_ANALOGCB > d_callback_list
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p)
vrpn_Analog_Remote(const char *name, vrpn_Connection *c=NULL)
virtual void mainloop()
Called once through each main loop iteration to handle updates. Remote object mainloop() should call ...
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.
vrpn_Analog_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
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.
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 ...
vrpn_int32 getNumChannels(void) const
Definition vrpn_Analog.C:52
vrpn_float64 last[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:39
vrpn_float64 channel[vrpn_CHANNEL_MAX]
Definition vrpn_Analog.h:38
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
void print(void)
Definition vrpn_Analog.C:42
virtual vrpn_int32 encode_to(char *buf)
Definition vrpn_Analog.C:54
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
vrpn_int32 channel_m_id
Definition vrpn_Analog.h:42
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 client_mainloop(void)
Handles functions that all clients should provide in their mainloop() (warning of no server,...
vrpn_int32 d_sender_id
Sender ID registered with the connection.
vrpn_BaseClass(const char *name, vrpn_Connection *c=NULL)
Names the device and assigns or opens connection, calls registration methods.
virtual int init(void)
Initialize things that the constructor can't. Returns 0 on success, -1 on failure.
void call_handlers(const CALLBACK_STRUCT &info)
This will pass the referenced parameter as a const to all the callbacks.
clipvals_struct clipvals[vrpn_CHANNEL_MAX]
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 ...
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...
vrpn_Clipping_Analog_Server(const char *name, vrpn_Connection *c, vrpn_int32 numChannels=vrpn_CHANNEL_MAX)
Generic connection class not specific to the transport mechanism.
unsigned char buffer[1024]
Definition vrpn_Analog.h:75
char portname[1024]
Definition vrpn_Analog.h:73
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)
vrpn_int32 num_channel
struct timeval msg_time
vrpn_float64 channel[vrpn_CHANNEL_MAX]
This structure is what is passed to a vrpn_Connection message callback.
const char * buffer
struct timeval msg_time
const int vrpn_ANALOG_FAIL
Definition vrpn_Analog.h:23
const struct timeval vrpn_ANALOG_NOW
Definition vrpn_Analog.h:26
const int vrpn_ANALOG_RESETTING
Definition vrpn_Analog.h:22
#define vrpn_CHANNEL_MAX
Definition vrpn_Analog.h:16
int vrpn_close_commport(int comm)
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_Serial: Pulls all the serial port routines into one file to make porting to new operating system...
vrpn_SER_PARITY
Definition vrpn_Serial.h:15
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.
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.
void vrpn_strcpy(char(&to)[charCount], const char *pSrc)
Null-terminated-string copy function that both guarantees not to overrun the buffer and guarantees th...
#define vrpn_gettimeofday
Definition vrpn_Shared.h:99
#define min(x, y)