VRPN main page
Obtaining VRPN
VRPN Support
Installing and Testing
Compiling and Modifying
Client code
Server code
Troubleshooting
Connections
Logging and Playback
Shared Objects
Clock Synchronization
Coming attractions & suggestions
UNC-specific information
Table of Contents
| |
/*****************************************************************************\
vrpn_Clock.h
--
Description : Note: for both types of clocks (server and client), users
need only to pass in the station which runs the
clock server (a name from the sdi_devices file).
The vrpn_Clock class takes care of the actual clock
device name (since there is only one clock device).
(i.e., you just say vrpn_Clock("server name") or
vrpn_Clock_Remote("server name"), where "server name"
is an entry in the .sdi_devices file.)
----------------------------------------------------------------------------
Author: weberh
Created: Sat Dec 13 11:21:15 1997
Revised: Sat Dec 20 08:25:44 1997 by weberh
$Source: /afs/unc/proj/stm/src/CVS_repository/vrpn_html/Clock_h.html,v $
$Locker: $
$Revision: 1.4 $
\*****************************************************************************/
#ifndef _VRPN_CLOCK_H_
#define _VRPN_CLOCK_H_
#include "vrpn_Connection.h"
class vrpn_Connection;
#define CLOCK_VERSION 0x10
// Base class for clock servers. Definition of remote/client
// clock class for the user is at the end.
class vrpn_Clock {
public:
vrpn_Clock(char *name, vrpn_Connection *c = NULL);
virtual void mainloop(void) = 0; // Report changes to connection
protected:
vrpn_Connection *connection;
long clockServer_id; // ID of this clock to connection
long queryMsg_id; // ID of clockQuery message to connection
long replyMsg_id; // ID of clockReply message to connection
virtual int encode_to(char *buf, const struct timeval& tvSRep,
const struct timeval& tvCReq,
int cChars, const char* pch);
};
class vrpn_Clock_Server : public vrpn_Clock {
public:
vrpn_Clock_Server(vrpn_Connection *c);
// Called once through each main loop iteration to handle
// clock updates.
virtual void mainloop(void); // Report changes to connection
static int clockQueryHandler( void *userdata, vrpn_HANDLERPARAM p );
};
//----------------------------------------------------------
// ************* Users deal with the following *************
// User routine to handle messages regarding the clock offset between
// the server host and the client host.
// Right now this is called a short while after the mainloop is
// first called. In a future version this might regularly re-sync the
// host and client whenever a new clock_sync_handler is registered.
// It is best to call this before the server is sending all kinds of
// other messages.
// The clock sync procedure takes 1 second to run.
typedef struct {
struct timeval msg_time; // Local time of this sync message
struct timeval tvClockOffset; // Local time - remote time in msecs
struct timeval tvHalfRoundTrip; // half of the roundtrip time
// for the roundtrip used to calc offset
} vrpn_CLOCKCB;
typedef void (*vrpn_CLOCKSYNCHANDLER)(void *userdata,
const vrpn_CLOCKCB& info);
// Connect to a clock server that is on the other end of a connection
// and figure out the offset between the local and remote clocks
// This is the type of clock that user code will deal with.
// You need only supply the server name (no device name) and the
// desired frequency (in hz) of clock sync updates. IF THE FREQ IS
// NEGATIVE, THEN YOU WILL GET NO AUTOMATIC SYNCS. At any time you
// can get a very accurate sync by calling fullSync();
#ifndef _WIN32
// special message identifiers for remote clock syncs
#define VRPN_CLOCK_FULL_SYNC 1
#define VRPN_CLOCK_QUICK_SYNC 2
class vrpn_Clock_Remote: public vrpn_Clock {
public:
// The name of the station which runs the clock server to connect to
// (from sdi_devices), and the frequency at which to do quick re-syncs
// (1 hz by default). If the user specifies a freq < 0, then there will
// be no quick syncs -- they will have to request syncs with fullSync().
// The final arg is the number of reports over which the user wants to
// maintain a window from which the offset routine will choose the min
// round trip report and use the offset from that trip.
// A high setting (e.g., 40) works well for arrangements with little drift
// while a low setting (e.g., 3) works well when drift is present.
// See cMaxQuickRecords below for more detail.
vrpn_Clock_Remote(char *name, double dFreq=1, int cOffsetWindow=3);
virtual ~vrpn_Clock_Remote();
// This routine calls does the sync and calls the mainloop of the
// connection it's on
virtual void mainloop(void);
// (un)Register a callback to handle a clock sync
virtual int register_clock_sync_handler(void *userdata,
vrpn_CLOCKSYNCHANDLER handler);
virtual int unregister_clock_sync_handler(void *userdata,
vrpn_CLOCKSYNCHANDLER handler);
// request a high accuracy sync
void fullSync();
protected:
long clockClient_id; // vrpn id for this client
// vars for stats on clock for quick sync
int fDoQuickSyncs;
int cQuickBounces;
// CC does not like this, so ...
// const int cMaxQuickDiffs=5
// This is the number of reports the clock keeps track of and
// chooses the offset from the min round trip from these.
// This is a balance between drift compensation and
// accuracy. In the absence of drift, this should
// be very large. In the presence of drift it needs
// to be very small. 5 seems to work well -- this means
// that drift will accumulate for at most 5*1/freq secs,
// and that a few consecutive long roundtrips will not
// reduce the accuracy of the offset.
int cMaxQuickRecords;
struct timeval *rgtvHalfRoundTrip;
struct timeval *rgtvClockOffset;
int irgtvQuick;
double dQuickIntervalMsecs;
struct timeval tvQuickLastSync;
// vars for stats on clock for full sync
int fDoFullSync;
int cBounces;
struct timeval tvMinHalfRoundTrip;
// offset to report to user
struct timeval tvFullClockOffset;
// vars for user specified handlers
typedef struct _vrpn_CLOCKSYNCLIST {
void *userdata;
vrpn_CLOCKSYNCHANDLER handler;
struct _vrpn_CLOCKSYNCLIST *next;
} vrpn_CLOCKSYNCLIST;
vrpn_CLOCKSYNCLIST *change_list;
static int quickSyncClockServerReplyHandler(void *userdata,
vrpn_HANDLERPARAM p);
static int fullSyncClockServerReplyHandler(void *userdata,
vrpn_HANDLERPARAM p);
};
#endif // ifndef _WIN32
#endif // ifndef _VRPN_CLOCK_H_
/*****************************************************************************\
$Log: Clock_h.html,v $
Revision 1.4 2002/07/30 18:39:56 taylorr
Changed several things.
Revision 1.3 2000/10/15 21:01:31 taylorr
This version removes the frames and updates several pages.
Revision 1.2 1999/06/10 18:04:00 juliano
There were two places whrere this documentation lived. One was under
CVS control, the other was not. I manually merged the changes from
both places. If you notice anything wrong, please fix it.
I will check out into the published web directory
(.../stm/etc/www/manual/vrpn) after doing this commit. From then on,
you may edit either in that directory, or in your own. Please do a
cvs commit after editing the files. If you edit in
your own, you also need to do a cvs update in the published directory.
These files have been edited with Microsoft FrontPage98. There are
extra files that FrontPage created. They have been checked in, but
shouldn't hurt anything. (they were already checked in before I
started all this, so I just updated those files.)
Revision 1.2 1998/01/08 23:32:49 weberh
Summary of changes
1) vrpn_Tracker_Ceiling is now in the cvs repository instead of just
the tracker hierarchy
2) vrpn uses doubles to transmit tracker data instead of floats
3) vrpn has a vrpn_ALIGN macro and uses 8 byte alignment
4) vrpn_Synchronized_Connection class was derived from regular connection
and transforms time stamps to the local time frame (see html man pages
for more info)
5) vrpn_Shared was modified to support time stamp math ops and gettimeofday
under win nt/95
Revision 2.0 1997/12/21 05:13:40 weberh
WORKING!
Revision 1.2 1997/12/20 00:02:12 weberh
cleaned up.
Revision 1.1 1997/12/16 19:39:34 weberh
Initial revision
Revision 1.1 1997/12/15 21:25:09 weberh
Added the vrpn_Clock class to vrpn to allow users (and eventually a
connection) to find out the offset between the server and client clock so
that users can know, in local time, when events happened on remote servers.
There are two basic modes -- fullSync (on request only) and quickSync
(default). See the .h file for more info.
Other changes included updating vrpn_Shared.h with time val diff and sum
operators and changing the pc version of gettimeofday so that it gets
0.8 usec resolution rather than 6 ms resolution.
I also changed a few things so that the entire package will compile under
g++ or CC on sgi, hp, or win 95/nt.
\*****************************************************************************/
|