00001 #include <hokuyo/hokuyo.h>
00002 #include <time.h>
00003 #include <sys/time.h>
00004 #include <algorithm>
00005
00006 static uint64_t timeHelper()
00007 {
00008 #if POSIX_TIMERS > 0
00009 struct timespec curtime;
00010 clock_gettime(CLOCK_REALTIME, &curtime);
00011 return (uint64_t)(curtime.tv_sec) * 1000000000 + (uint64_t)(curtime.tv_nsec);
00012 #else
00013 struct timeval timeofday;
00014 gettimeofday(&timeofday,NULL);
00015 return (uint64_t)(timeofday.tv_sec) * 1000000000 + (uint64_t)(timeofday.tv_usec) * 1000;
00016 #endif
00017 }
00018
00019 template <class C>
00020 C median(std::vector<C> &v)
00021 {
00022 std::vector<long long int>::iterator start = v.begin();
00023 std::vector<long long int>::iterator end = v.end();
00024 std::vector<long long int>::iterator median = start + (end - start) / 2;
00025
00026
00027 std::nth_element(start, median, end);
00028
00029
00030
00031
00032
00033 return *median;
00034 }
00035
00036 long long int getClockOffset(hokuyo::Laser &laser, int reps)
00037 {
00038 std::vector<long long int> offset(reps);
00039 int timeout = 1000;
00040
00041 laser.sendCmd("TM0",timeout);
00042 for (int i = 0; i < reps; i++)
00043 {
00044 long long int prestamp = timeHelper();
00045 laser.sendCmd("TM1",timeout);
00046 long long int hokuyostamp = laser.readTime();
00047 long long int poststamp = timeHelper();
00048 offset[i] = hokuyostamp - (prestamp + poststamp) / 2;
00049 printf("%lli %lli %lli - ", prestamp, hokuyostamp, poststamp);
00050 }
00051 laser.sendCmd("TM2",timeout);
00052
00053 return median(offset);
00054 }
00055
00056 long long int getScanOffset(hokuyo::Laser &laser, int reps)
00057 {
00058 std::vector<long long int> offset(reps);
00059 int timeout = 1000;
00060
00061 if (reps > 99)
00062 reps = 99;
00063
00064 if (laser.requestScans(1, -2, 2, 0, 0, reps, timeout) != 0)
00065 {
00066 fprintf(stderr, "Error requesting scan.\n");
00067 return 1;
00068 }
00069
00070 hokuyo::LaserScan scan;
00071 for (int i = 0; i < reps; i++)
00072 {
00073 laser.serviceScan(scan, timeout);
00074 offset[i] = scan.self_time_stamp - scan.system_time_stamp;
00075 printf("%lli %lli - ", scan.self_time_stamp, scan.system_time_stamp);
00076 }
00077
00078 return median(offset);
00079 }
00080
00081 long long int getDataOffset(hokuyo::Laser &laser, int cycles)
00082 {
00083 int ckreps = 1;
00084 int scanreps = 1;
00085 long long int pre = getClockOffset(laser, ckreps);
00086 std::vector<long long int> samples(cycles);
00087 for (int i = 0; i < cycles; i++)
00088 {
00089 long long int scan = getScanOffset(laser, ckreps);
00090 long long int post = getClockOffset(laser, scanreps);
00091 samples[i] = scan - (post+pre)/2;
00092
00093
00094 pre = post;
00095 }
00096
00097 printf("%lli\n", median(samples));
00098 return median(samples);
00099 }
00100
00101 int main(int argc, char **argv)
00102 {
00103 if (argc != 2)
00104 {
00105 fprintf(stderr, "usage: timestamp_test <port>\n");
00106 return 1;
00107 }
00108
00109 char *port = argv[1];
00110
00111 hokuyo::Laser laser;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 hokuyo::LaserScan scan_;
00166
00167 laser.open(port);
00168 while (true)
00169 {
00170 try {
00171
00172
00173 {
00174 laser.laserOn();
00175 laser.requestScans(true, -2.3562, 2.3562, 0, 0);
00176
00177 laser.serviceScan(scan_);
00178 }
00179
00180
00181 }
00182 catch (hokuyo::Exception e)
00183 {
00184 fprintf(stderr, "%s\n", e.what());
00185 }
00186 try {
00187 laser.stopScanning();
00188 }
00189 catch (hokuyo::Exception e)
00190 {
00191 fprintf(stderr, "%s\n", e.what());
00192 }
00193
00194 try {
00195
00196 }
00197 catch (hokuyo::Exception e)
00198 {
00199 fprintf(stderr, "%s\n", e.what());
00200 }
00201 }
00202 }