16
// NOTE: the poser class borrows heavily from the vrpn_Tracker code.
17
// The poser is basically the inverse of a tracker.
18
// We are only handling pose and velocity updates for now...acceleration
19
// will come later, as needed.
21
#include "vrpn_Connection.h"
22
#include "vrpn_BaseClass.h"
24
class VRPN_API vrpn_Poser : public vrpn_BaseClass {
26
vrpn_Poser (const char * name, vrpn_Connection * c = NULL );
28
virtual ~vrpn_Poser (void);
30
void p_print(); // print the current pose
31
void p_print_vel(); // print the current velocity
33
// a poser server should call the following to register the
34
// default xform and workspace request handlers
35
// int register_server_handlers(void);
39
vrpn_int32 req_position_m_id; // ID of poser position message
40
vrpn_int32 req_position_relative_m_id; // ID of poser position delta message
41
vrpn_int32 req_velocity_m_id; // ID of poser velocity message
42
vrpn_int32 req_velocity_relative_m_id; // ID of poser velocity delta message
44
// Description of current state
45
vrpn_float64 p_pos[3], p_quat[4]; // Current pose, (x,y,z), (qx,qy,qz,qw)
46
vrpn_float64 p_vel[3], p_vel_quat[4]; // Current velocity and dQuat/vel_quat_dt
47
vrpn_float64 p_vel_quat_dt; // delta time (in secs) for vel_quat
48
struct timeval p_timestamp; // Current timestamp
50
// Minimum and maximum values available for the position and velocity values
52
vrpn_float64 p_pos_min[3], p_pos_max[3], p_pos_rot_min[3], p_pos_rot_max[3],
53
p_vel_min[3], p_vel_max[3], p_vel_rot_min[3], p_vel_rot_max[3];
55
virtual int register_types(void); // Called by BaseClass init()
57
virtual int encode_to(char* buf); // Encodes the position
58
virtual int encode_vel_to(char* buf); // Encodes the velocity
60
virtual void set_pose( const struct timeval t, // Sets the pose internally
61
const vrpn_float64 position[3],
62
const vrpn_float64 quaternion[4] );
63
virtual void set_pose_relative( const struct timeval t, // Increments the pose internally
64
const vrpn_float64 position_delta[3], // pos_new = position_delta + pos_old
65
const vrpn_float64 quaternion[4] ); // q_new = quaternion * q_old
66
virtual void set_pose_velocity( const struct timeval t, // Sets the velocity internally
67
const vrpn_float64 position[3],
68
const vrpn_float64 quaternion[4],
69
const vrpn_float64 interval );
70
virtual void set_pose_velocity_relative( const struct timeval t, // Increments the velocity internally
71
const vrpn_float64 velocity_delta[3], // vel_new = velocity_delta + vel_old
72
const vrpn_float64 quaternion[4], // q_new = quaternion * q_old
73
const vrpn_float64 interval_delta ); // interval_new = interval_delta + interval_old
76
//------------------------------------------------------------------------------------
79
///A structure for Call-Backs related to Vrpn Poser Server
80
typedef struct _vrpn_POSERCB {
81
struct timeval msg_time; // Timestamp
82
///NOTE: I think since we have different routines for handling velocity and position poser requests,
83
/// putting poser and quaternions for both doesn't make sense. Instead, the change handler should
84
/// take care of packing correct poser and quaternion.
89
typedef void (VRPN_CALLBACK *vrpn_POSERHANDLER) (void * userdata,
90
const vrpn_POSERCB info);
93
//------------------------------------------------------------------------------------
95
// Users supply the routines to handle requests from the client
97
// This is a sample basic poser server
100
class VRPN_API vrpn_Poser_Server: public vrpn_Poser {
102
vrpn_Poser_Server (const char* name, vrpn_Connection* c);
104
/// This function should be called each time through app mainloop.
105
virtual void mainloop();
107
int register_change_handler(void *userdata, vrpn_POSERHANDLER handler) {
108
return d_callback_list.register_handler(userdata, handler);
110
int unregister_change_handler(void *userdata, vrpn_POSERHANDLER handler) {
111
return d_callback_list.unregister_handler(userdata, handler);
114
int register_relative_change_handler( void* userdata, vrpn_POSERHANDLER handler )
115
{ return d_relative_callback_list.register_handler( userdata, handler ); }
116
int unregister_relative_change_handler( void* userdata, vrpn_POSERHANDLER handler )
117
{ return d_relative_callback_list.unregister_handler( userdata, handler ); }
120
static int VRPN_CALLBACK handle_change_message(void *userdata, vrpn_HANDLERPARAM p);
121
static int VRPN_CALLBACK handle_relative_change_message(void *userdata, vrpn_HANDLERPARAM p);
122
static int VRPN_CALLBACK handle_vel_change_message(void *userdata, vrpn_HANDLERPARAM p);
123
static int VRPN_CALLBACK handle_relative_vel_change_message(void *userdata, vrpn_HANDLERPARAM p);
124
vrpn_Callback_List<vrpn_POSERCB> d_callback_list;
125
vrpn_Callback_List<vrpn_POSERCB> d_relative_callback_list;
128
//------------------------------------------------------------------------------------
131
// Open a poser that is on the other end of a connection for sending updates to it.
132
class VRPN_API vrpn_Poser_Remote: public vrpn_Poser {
134
// The name of the poser to connect to, including connection name,
135
// for example "poser@magnesium.cs.unc.edu". If you already
136
// have the connection open, you can specify it as the second parameter.
137
// This allows both servers and clients in the same thread, for example.
138
// If it is not specified, then the connection will be looked up based
139
// on the name passed in.
140
vrpn_Poser_Remote (const char* name, vrpn_Connection* c = NULL);
142
// unregister all of the handlers registered with the connection
143
virtual ~vrpn_Poser_Remote (void);
145
// This routine calls the mainloop of the connection it's on
146
virtual void mainloop();
148
// Routines to set the state of the poser
149
int request_pose(const struct timeval t, const vrpn_float64 position[3], const vrpn_float64 quaternion[4]);
150
int request_pose_relative(const struct timeval t, const vrpn_float64 position_delta[3], const vrpn_float64 quaternion[4]);
151
int request_pose_velocity( const struct timeval t, const vrpn_float64 velocity[3],
152
const vrpn_float64 quaternion[4], const vrpn_float64 interval );
153
int request_pose_velocity_relative( const struct timeval t, const vrpn_float64 velocity_delta[3],
154
const vrpn_float64 quaternion[4], const vrpn_float64 interval_delta );
157
virtual int client_send_pose(); // Sends the current pose. Called by request_pose
158
virtual int client_send_pose_relative(); // Sends the current pose delta. Called by request_pose_relative
159
virtual int client_send_pose_velocity(); // Sends the current velocity. Called by request_pose_velocity
160
virtual int client_send_pose_velocity_relative(); // Sends the current velocity delta. Called by request_pose_velocity_relative