#ifndef VRPN_ANALOG_H
#define VRPN_ANALOG_H
#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);
#include "vrpn_Connection.h"
#include "vrpn_BaseClass.h"
#ifndef VRPN_CLIENT_ONLY
#include "vrpn_Serial.h"
#endif
class 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);
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);
virtual void report_changes (vrpn_uint32 class_of_service
= vrpn_CONNECTION_LOW_LATENCY);
virtual void report (vrpn_uint32 class_of_service
= vrpn_CONNECTION_LOW_LATENCY);
};
#ifndef VRPN_CLIENT_ONLY
class 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);
~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_Analog_Server : public vrpn_Analog {
public:
vrpn_Analog_Server (const char * name, vrpn_Connection * c);
virtual ~vrpn_Analog_Server (void);
virtual void report_changes (vrpn_uint32 class_of_service
= vrpn_CONNECTION_LOW_LATENCY);
virtual void report (vrpn_uint32 class_of_service
= vrpn_CONNECTION_LOW_LATENCY);
virtual void mainloop () { server_mainloop(); };
vrpn_float64* channels (void);
vrpn_int32 numChannels (void) const;
vrpn_int32 setNumChannels (vrpn_int32 sizeRequested);
};
// 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_Clipping_Analog_Server : public vrpn_Analog_Server {
public:
vrpn_Clipping_Analog_Server(const char *name, vrpn_Connection *c);
int setClipValues(int channel, double min, double lowzero, double
highzero, double max);
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 {
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_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_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);
virtual ~vrpn_Analog_Remote (void);
// 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);
virtual int unregister_change_handler(void *userdata,
vrpn_ANALOGCHANGEHANDLER handler);
protected:
typedef struct vrpn_RBCS {
void *userdata;
vrpn_ANALOGCHANGEHANDLER handler;
struct vrpn_RBCS *next;
} vrpn_ANALOGCHANGELIST;
vrpn_ANALOGCHANGELIST *change_list;
static int handle_change_message(void *userdata, vrpn_HANDLERPARAM p);
};
#endif