00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <sys/types.h>
00061 #include <netdb.h>
00062 #include <unistd.h>
00063 #include <sys/time.h>
00064 #include <sys/socket.h>
00065 #include <netinet/in.h>
00066 #include <signal.h>
00067 #include <errno.h>
00068 #include <set>
00069 #include <iostream>
00070 #include "orientation.hh"
00071 #include "intersenseorientation.hh"
00072 #include "position.hh"
00073 #include "gpsd_position.hh"
00074
00075
00076 using namespace std;
00077
00078 #ifdef __APPLE__
00079 typedef unsigned int socklen_t;
00080 #endif
00081
00082
00083
00084 #define DEFAULT_PORT 2948
00085
00086
00087
00088 double currentTime() {
00089 static struct timeval tv;
00090 gettimeofday(&tv, NULL);
00091 return ( tv.tv_sec + (tv.tv_usec / 1000000.0) );
00092 }
00093
00094
00095 void usage() {
00096 cout << "usage: trackerd [-P PORT] [-o OTYPE] [-p PTYPE] [-od DEV] [-os SPEED] [-ph HOST] [-pp PORT]\n" <<
00097 "\t-P PORT\tuse PORT for socket port (default is " << DEFAULT_PORT << "\n" <<
00098 "\t-o TYPE\tuse TYPE for orientation device 0 (intersense, fake)\n" <<
00099 "\t-p TYPE\tuse TYPE for position device 0 (gpsd, fake)\n" <<
00100 "\t-od DEV\tuse DEV for orientation device name (Default /dev/isense)\n" <<
00101 "\t-os SPEED\tuse SPEED baud for orientation device. (Default 115200)\n" <<
00102 "\t-of FREQ\tminimum tracker read frequency in seconds (Default 0.04)\n" <<
00103 "\t-ph HOST\tuse HOST for for position server host\n" <<
00104 "\t-pp PORT\tuse PORT for position server port\n" <<
00105 "\t-pf FREQ\tmininum tracker read frequency in seconds (Default is 0.04)\n" <<
00106 endl;
00107 }
00108
00109
00110
00111 class FakeOrientation : public Orientation {
00112 public:
00113 virtual void getOrientationMatrix(double m[3][3]) {
00114 m[0][0] = m[0][1] = m[0][2] =
00115 m[1][0] = m[1][1] = m[1][2] =
00116 m[2][0] = m[2][1] = m[2][2] = 42.0;
00117 }
00118
00119 virtual void getEulerAngles(double* y, double* p, double* r) {
00120 *y = *p = *r = 23.0;
00121 }
00122 };
00123
00124 class FakePosition : public Position {
00125 public:
00126 virtual void getPosition(double* x, double* y, double* z) {
00127 *x = *y = *z = 0;
00128 }
00129 };
00130
00131
00132
00133
00134
00135 int main(int argc, char** argv) {
00136 int port = DEFAULT_PORT;
00137 char* ori_type = 0;
00138 char* ori_dev = "/dev/isense";
00139 int ori_devspeed = 115200;
00140 Orientation* ori = NULL;
00141 char* pos_host = "localhost";
00142 int pos_port = GPSD_DEFAULT_PORT;
00143 char* pos_type = 0;
00144 Position* pos = NULL;
00145 double ori_freq = 0.04;
00146 double pos_freq = 0.04;
00147 double last_ori_read = 0;
00148 double last_pos_read = 0;
00149
00150
00151
00152
00153 for(int i = 1; i < argc; i++) {
00154 if(!strcmp(argv[i], "-o")) {
00155 ori_type = strdup(argv[++i]);
00156 } else if(!strcmp(argv[i], "-od")) {
00157 ori_dev = strdup(argv[++i]);
00158 } else if(!strcmp(argv[i], "-os")) {
00159 ori_devspeed = atoi(argv[++i]);
00160 } else if (!strcmp(argv[i], "-P")) {
00161 port = atoi( argv[++i] );
00162 } else if (!strcmp(argv[i], "-p")) {
00163 pos_type = strdup(argv[++i]);
00164 } else if (!strcmp(argv[i], "-ph")) {
00165 pos_host = strdup(argv[++i]);
00166 } else if (!strcmp(argv[i], "-pp")) {
00167 pos_port = atoi(argv[++i]);
00168 } else if (!strcmp(argv[i], "-of")) {
00169 ori_freq = atof(argv[++i]);
00170 } else if (!strcmp(argv[i], "-pf")) {
00171 pos_freq = atof(argv[++i]);
00172 } else {
00173 usage();
00174 exit(0);
00175 }
00176 }
00177
00178 cerr << "creating tracking interfaces... ori_type = " << string( ori_type?ori_type:"NULL" ) << " pos_type = " << string( pos_type?pos_type:"NULL" ) << endl;
00179
00180
00181
00182 try {
00183 if(ori_type == 0)
00184 ori = 0;
00185 else if(strcmp(ori_type, "fake")==0)
00186 ori = new FakeOrientation();
00187 #ifdef HAVE_INTERSENSE
00188 else if(strcmp(ori_type, "intersense") == 0)
00189 ori = new IntersenseOrientation(ori_dev, ori_devspeed);
00190 #endif
00191 else {
00192 cerr << "Unrecognized orientation tracker type. Use \"-o intersense\" or \"-o fake\".\n";
00193 exit(-1);
00194 }
00195 } catch(exception& e) {
00196 cerr << "trackerd: Error connecting to " << ori_type << " orientation tracker device " << ori_dev << " at " << ori_devspeed << " baud! " << e.what();
00197 exit(-2);
00198 }
00199
00200
00201 try {
00202 if(pos_type == 0)
00203 pos = 0;
00204 else if(strcmp(pos_type, "fake")==0)
00205 pos = new FakePosition();
00206 else if(strcmp(pos_type, "gpsd") == 0)
00207 pos = new GPSDPosition(pos_host, pos_port);
00208 else {
00209 cerr << "Unrecognized position tracker type. Use \"-p gpsd\" or \"-p fake\".\n";
00210 exit(-1);
00211 }
00212 } catch(exception& e) {
00213 cerr << "trackerd: Error connecting to " << pos_type << " position tracker server at " << pos_host << " port " << pos_port << "! " << e.what();
00214 exit(-2);
00215 }
00216
00217
00218
00219 cout << "trackerd: Opening tcp socket at port " << port << "...\n";
00220 int server_socket = socket(AF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto);
00221
00222 cerr << "socket is: " << server_socket << endl;
00223
00224 if(server_socket < 0) {
00225 cerr << "trackerd: error creating socket: " << strerror(errno) << "\n";
00226 exit(-1);
00227 }
00228
00229 int one = 1;
00230 if(setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0) {
00231 cerr << "trackerd: setting socket options: " << strerror(errno) << endl ; exit(-1);
00232 }
00233 struct sockaddr_in addr;
00234 memset(&addr, 0, sizeof(addr));
00235 addr.sin_addr.s_addr = htonl(INADDR_ANY);
00236 addr.sin_port = htons(port);
00237 addr.sin_family = AF_INET;
00238 if(bind(server_socket, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
00239 cerr << "trackerd: error binding address with port " << port << ": " << strerror(errno) << endl;
00240 exit(-1);
00241 }
00242 if( listen(server_socket, 5) < 0) {
00243 cerr << "trackerd: error listening on socket: " << strerror(errno) << endl;
00244 }
00245
00246 cout << "trackerd: ok. running...\n";
00247
00248 char buff[8];
00249 memset(buff, 0, sizeof(buff));
00250 char output[128];
00251 memset(output, 0, sizeof(output));
00252 double mat[3][3];
00253 double y, p, r, px, py, pz;
00254 int n;
00255 set<int> client_sockets;
00256 fd_set rfds;
00257 fd_set wfds;
00258 int max;
00259
00260
00261 if(ori) {
00262 try {
00263 ori->getOrientationMatrix(mat);
00264 ori->getEulerAngles(&y, &p, &r);
00265 last_ori_read = currentTime();
00266 } catch(exception& e) {
00267 cerr << "trackerd: Warning: error reading initial values from orientation device.\n";
00268 }
00269 }
00270 if(pos) {
00271 try {
00272 pos->getPosition(&px, &py, &pz);
00273 last_pos_read = currentTime();
00274 } catch(exception& e) {
00275 cerr << "trackerd: Warning: error reading initial values from position device.\n";
00276 }
00277 }
00278
00279 while(1) {
00280
00281
00282 FD_ZERO(&rfds);
00283 FD_ZERO(&wfds);
00284 FD_SET(server_socket, &rfds);
00285 max = server_socket;
00286 for(set<int>::const_iterator i = client_sockets.begin();
00287 i != client_sockets.end(); i++) {
00288 FD_SET(*i, &rfds);
00289 FD_SET(*i, &wfds);
00290 if(*i > max) max = *i;
00291 }
00292 if(select(max+1, &rfds, &wfds, NULL, NULL)) {
00293
00294
00295 if( FD_ISSET(server_socket, &rfds) ) {
00296 int s = accept(server_socket, NULL, 0);
00297 if(s == -1) {
00298 cerr << "trackerd: warning: error accepting client: " << strerror(errno) << "\n";
00299 continue;
00300 }
00301 client_sockets.insert(s);
00302 }
00303
00304
00305 for(set<int>::const_iterator i = client_sockets.begin();
00306 i != client_sockets.end(); i++) {
00307 if( FD_ISSET(*i, &rfds) && FD_ISSET(*i, &wfds) ) {
00308 int fd = *i;
00309
00310 memset(buff, 0, sizeof(buff));
00311 n = read( fd, buff, sizeof(buff) - 1);
00312
00313 if(n > 0) {
00314
00315 if( buff[n-1] == '\n' )
00316 buff[n-1] = '\0';
00317
00318 if(!strcmp(buff, "om:0")) {
00319 if(ori) {
00320 try {
00321 double now = currentTime();
00322 if(now - last_ori_read > ori_freq) {
00323 ori->getOrientationMatrix(mat);
00324 last_ori_read = now;
00325 }
00326 snprintf(output, sizeof(output), "om:0=%.8f,%.8f,%.8f;%.8f,%.8f,%.8f;%.8f,%.8f,%.8f\n",
00327 mat[0][0], mat[0][1], mat[0][2],
00328 mat[1][0], mat[1][1], mat[1][2],
00329 mat[2][0], mat[2][1], mat[2][2]);
00330 } catch(exception& e) {
00331 snprintf(output, sizeof(output), "om:0=ERROR:Error reading device: %s\n", e.what());
00332 }
00333 } else {
00334 snprintf(output, sizeof(output), "om:0=ERROR:No device\n");
00335 }
00336 } else if(!strcmp(buff, "oa:0")) {
00337 if(ori) {
00338 try {
00339 double now = currentTime();
00340 if(now - last_ori_read > ori_freq) {
00341 ori->getEulerAngles(&y, &p, &r);
00342 last_ori_read = now;
00343 }
00344 snprintf(output, sizeof(output), "oa:0=%.8f,%.8f,%.8f\n", y, p, r);
00345 } catch(exception& e) {
00346 snprintf(output, sizeof(output), "oa:0=ERROR:Error reading device: %s\n", e.what());
00347 }
00348 } else {
00349 snprintf(output, sizeof(output), "oa:0=ERROR:No device\n");
00350 }
00351 } else if(!strcmp(buff, "p:0")) {
00352 if(pos) {
00353 try {
00354 double now = currentTime();
00355 if(now - last_pos_read > pos_freq) {
00356 pos->getPosition(&px, &py, &pz);
00357 last_pos_read = now;
00358 }
00359 snprintf(output, sizeof(output), "p:0=%.8f,%.8f,%.8f\n", px, py, pz);
00360 } catch(exception& e) {
00361 snprintf(output, sizeof(output), "p:0=ERROR:Error reading device: %s\n", e.what());
00362 }
00363 } else {
00364 snprintf(output, sizeof(output), "p:0=ERROR:No device\n");
00365 }
00366 } else {
00367 snprintf(output, sizeof(output), "%s=ERROR:Unknown command\n", buff);
00368 }
00369
00370 write(fd, output, strlen(output));
00371
00372 } else if(n == 0) {
00373
00374 close(fd);
00375 client_sockets.erase(fd);
00376 } else {
00377 fprintf(stderr, "trackerd: Error reading from fd %d. closing socket.", fd);
00378 close(fd);
00379 client_sockets.erase(fd);
00380 }
00381 }
00382 }
00383 }
00384 }
00385 }