#ifndef INCLUDED_ANALOGFLY
#define INCLUDED_ANALOGFLY
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#ifndef _WIN32
#include <sys/time.h>
#endif
#include "vrpn_Tracker.h"
#include "vrpn_Analog.h"
#include "vrpn_Button.h"
#include <quat.h>
// This parameter is passed to the constructor for the AnalogFly; it describes
// the channel mapping and parameters of that mapping, as well as the button
// that will be used to reset the tracker when it is pushed. Any entry which
// has a NULL pointer for the name is disabled.
class vrpn_TAF_axis {
public:
vrpn_TAF_axis (void)
{ name = NULL; channel = 0; offset = 0.0f; thresh = 0.0f;
scale = 1.0f; power = 1.0f; };
char * name; //< Name of the Analog device driving this axis
int channel; //< Which channel to use from the Analog device
float offset; //< Offset to apply to values from this channel to reach 0
float thresh; //< Threshold to apply after offset within which values count as zero
float scale; //< Scale applied to values after offset and threshold
float power; //< Power to which values are taken after scaling
};
class vrpn_Tracker_AnalogFlyParam {
public:
vrpn_Tracker_AnalogFlyParam (void) {
x.name = y.name = z.name =
sx.name = sy.name = sz.name = reset_name = NULL;
}
vrpn_TAF_axis x, y, z;
vrpn_TAF_axis sx, sy, sz;
char * reset_name;
int reset_which;
};
class vrpn_Tracker_AnalogFly; // Forward reference
class vrpn_TAF_fullaxis {
public:
vrpn_TAF_fullaxis (void) { ana = NULL; value = 0.0; af = NULL; };
vrpn_TAF_axis axis;
vrpn_Analog_Remote * ana;
vrpn_Tracker_AnalogFly * af;
double value;
};
// tracker into a tracker by interpreting the joystick
// positions as either position or velocity inputs and "flying" the user
// around based on analog values.
// The "absolute" parameter tells whether the tracker integrates differential
// changes (the default, with FALSE) or takes the analog values as absolute
// positions or orientations.
// The mapping from analog channels to directions (or orientation changes) is
// described in the vrpn_Tracker_AnalogFlyParam parameter. For translations,
// values above threshold are multiplied by the scale and then taken to the
// power; the result is the number of meters (or meters per second) to move
// in that direction. For rotations, the result is taken as the number of
// revolutions (or revolutions per second) around the given axis.
// Note that the reset button has no effect on an absolute tracker.
// The time reported by absolute trackers is as of the last report they have
// had from their analog devices. The time reported by differential trackers
// is the local time that the report was generated. This is to allow a
// gen-locked camera tracker to have its time values passed forward through
// the AnalogFly class.
// If reportChanges is TRUE, updates are ONLY sent if there has been a
// change since the last update, in which case they are generated no faster
// than update_rate.
class vrpn_Tracker_AnalogFly : public vrpn_Tracker {
public:
vrpn_Tracker_AnalogFly (const char * name, vrpn_Connection * trackercon,
vrpn_Tracker_AnalogFlyParam * params,
float update_rate, vrpn_bool absolute = vrpn_FALSE,
vrpn_bool reportChanges = VRPN_FALSE);
virtual ~vrpn_Tracker_AnalogFly (void);
virtual void mainloop ();
virtual void reset (void);
void update (q_matrix_type &);
static void handle_joystick (void *, const vrpn_ANALOGCB);
static int handle_newConnection (void *, vrpn_HANDLERPARAM);
protected:
double d_update_interval; //< How long to wait between sends
struct timeval d_prevtime; //< Time of the previous report
vrpn_bool d_absolute; //< Report absolute (vs. differential)?
vrpn_bool d_reportChanges;
vrpn_TAF_fullaxis d_x, d_y, d_z, d_sx, d_sy, d_sz;
vrpn_Button_Remote * d_reset_button;
int d_which_button;
q_matrix_type d_initMatrix, d_currentMatrix;
void update_matrix_based_on_values (double time_interval);
void convert_matrix_to_tracker (void);
vrpn_bool shouldReport (double elapsedInterval) const;
int setup_channel (vrpn_TAF_fullaxis * full);
int teardown_channel (vrpn_TAF_fullaxis * full);
static void handle_analog_update (void * userdata,
const vrpn_ANALOGCB info);
static void handle_reset_press (void * userdata, const vrpn_BUTTONCB info);
};
#endif