-
Notifications
You must be signed in to change notification settings - Fork 1
/
vrpn_Analog.h
210 lines (170 loc) · 7.69 KB
/
vrpn_Analog.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ifndef VRPN_ANALOG_H
#define VRPN_ANALOG_H
#include <stddef.h> // for NULL
#include "vrpn_BaseClass.h" // for vrpn_Callback_List, etc
#include "vrpn_Configure.h" // for VRPN_API, VRPN_CALLBACK
#include "vrpn_Connection.h" // for vrpn_CONNECTION_LOW_LATENCY, etc
#include "vrpn_Shared.h" // for timeval
#include "vrpn_Types.h" // for vrpn_int32, vrpn_float64, etc
#ifndef VRPN_CLIENT_ONLY
#include "vrpn_Serial.h" // for ::vrpn_SER_PARITY_NONE, etc
#endif
#define vrpn_CHANNEL_MAX 128
// analog status flags
const int vrpn_ANALOG_SYNCING = (2);
const int vrpn_ANALOG_REPORT_READY = (1);
const int vrpn_ANALOG_PARTIAL = (0);
const int vrpn_ANALOG_RESETTING = (-1);
const int vrpn_ANALOG_FAIL = (-2);
// Analog time value meaning "go find out what time it is right now"
const struct timeval vrpn_ANALOG_NOW = {0, 0};
class VRPN_API vrpn_Analog : public vrpn_BaseClass {
public:
vrpn_Analog(const char *name, vrpn_Connection *c = NULL);
// Print the status of the analog device
void print(void);
vrpn_int32 getNumChannels(void) const;
protected:
vrpn_float64 channel[vrpn_CHANNEL_MAX];
vrpn_float64 last[vrpn_CHANNEL_MAX];
vrpn_int32 num_channel;
struct timeval timestamp;
vrpn_int32 channel_m_id; //< channel message id (message from server)
int status;
virtual int register_types(void);
//------------------------------------------------------------------
// Routines used to send data from the server
virtual vrpn_int32 encode_to(char *buf);
/// Send a report only if something has changed (for servers)
/// Optionally, tell what time to stamp the value with
virtual void
report_changes(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 the value with
virtual void
report(vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY,
const struct timeval time = vrpn_ANALOG_NOW);
};
#ifndef VRPN_CLIENT_ONLY
class VRPN_API vrpn_Serial_Analog : public vrpn_Analog {
public:
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_Serial_Analog();
protected:
int serial_fd;
char portname[1024];
int baudrate;
unsigned char buffer[1024];
int bufcounter;
int read_available_characters(char *buffer, int bytes);
};
#endif
// vrpn_Analog_Server
// Tom Hudson, March 1999
//
// A *Sample* Analog server. Use this or derive your own from vrpn_Analog with
// this as a guide.
//
// Write whatever values you want into channels(), then call report()
// or report_changes(). (Original spec only called for report_changes(),
// but vrpn_Analog's assumption that "no new data = same data" doesn't
// match the BLT stripchart assumption of "no intervening data = ramp".
//
// For a sample application, see server_src/sample_analog.C
class VRPN_API vrpn_Analog_Server : public vrpn_Analog {
public:
vrpn_Analog_Server(const char *name, vrpn_Connection *c,
vrpn_int32 numChannels = vrpn_CHANNEL_MAX);
/// Makes public the protected base class function
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
virtual void
report(vrpn_uint32 class_of_service = vrpn_CONNECTION_LOW_LATENCY,
const struct timeval time = vrpn_ANALOG_NOW);
/// For this server, the user must normally call report() or
/// report_changes() directly. This mainloop() only takes
/// care of the things any server object should do.
virtual void mainloop() { server_mainloop(); };
/// Exposes an array of values for the user to write into.
vrpn_float64 *channels(void) { return channel; }
/// Sets the size of the array; returns the size actually set.
/// (May be clamped to vrpn_CHANNEL_MAX)
/// This should be used before mainloop is ever called.
vrpn_int32 setNumChannels(vrpn_int32 sizeRequested);
};
/// Analog server that can scale and clip its range to -1..1.
// This is useful for joysticks, to allow them to be centered and
// scaled to cover the whole range. Rather than writing directly
// into the channels array, call the setChannel() method.
class VRPN_API vrpn_Clipping_Analog_Server : public vrpn_Analog_Server {
public:
vrpn_Clipping_Analog_Server(const char *name, vrpn_Connection *c,
vrpn_int32 numChannels = vrpn_CHANNEL_MAX);
/// Set the clipping values for the specified channel.
/// min maps to -1, values between lowzero and highzero map to 0,
/// max maps to 1. Values less than min map to -1, values larger
/// than max map to 1. Default for each channel is -1,0,0,1
/// It is possible to compress the range to [0..1] by setting the
/// minimum equal to the lowzero.
/// Returns 0 on success, -1 on failure.
int setClipValues(int channel, double min, double lowzero, double highzero,
double max);
/// This method should be used to set the value of a channel.
/// It will be scaled and clipped as described in setClipValues.
/// It returns 0 on success and -1 on failure.
int setChannelValue(int channel, double value);
protected:
typedef struct {
double minimum_val; // Value mapped to -1
double lower_zero; // Minimum value mapped to 0
double upper_zero; // Maximum value mapped to 0
double maximum_val; // Value mapped to 1
} clipvals_struct;
clipvals_struct clipvals[vrpn_CHANNEL_MAX];
};
//----------------------------------------------------------
//************** Users deal with the following *************
// User routine to handle a change in analog values. This is called when
// the analog callback is called (when a message from its counterpart
// across the connection arrives).
typedef struct _vrpn_ANALOGCB {
struct timeval msg_time; // Timestamp of analog data
vrpn_int32 num_channel; // how many channels
vrpn_float64 channel[vrpn_CHANNEL_MAX]; // analog values
} vrpn_ANALOGCB;
typedef void(VRPN_CALLBACK *vrpn_ANALOGCHANGEHANDLER)(void *userdata,
const vrpn_ANALOGCB info);
// Open an analog device that is on the other end of a connection
// and handle updates from it. This is the type of analog device
// that user code will deal with.
class VRPN_API vrpn_Analog_Remote : public vrpn_Analog {
public:
// The name of the analog device to connect to
// Optional argument to be used when the Remote should listen on
// a connection that is already open.
vrpn_Analog_Remote(const char *name, vrpn_Connection *c = NULL);
// This routine calls the mainloop of the connection it's on
virtual void mainloop();
// (un)Register a callback handler to handle analog value change
virtual int register_change_handler(void *userdata,
vrpn_ANALOGCHANGEHANDLER handler)
{
return d_callback_list.register_handler(userdata, handler);
};
virtual int unregister_change_handler(void *userdata,
vrpn_ANALOGCHANGEHANDLER handler)
{
return d_callback_list.unregister_handler(userdata, handler);
}
protected:
vrpn_Callback_List<vrpn_ANALOGCB> d_callback_list;
static int VRPN_CALLBACK
handle_change_message(void *userdata, vrpn_HANDLERPARAM p);
};
#endif