00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <ptu46/ptu46_driver.h>
00043
00044
00045 #include <sys/types.h>
00046 #include <sys/stat.h>
00047 #include <fcntl.h>
00048 #include <termios.h>
00049 #include <stdio.h>
00050 #include <strings.h>
00051 #include <unistd.h>
00052 #include <stdlib.h>
00053 #include <errno.h>
00054 #include <string.h>
00055 #include <math.h>
00056
00057 namespace PTU46 {
00058
00059
00060
00061
00062
00063
00064 PTU46::PTU46(const char * port, int rate) {
00065 tr = pr = 1;
00066 fd = -1;
00067
00068
00069
00070 fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
00071 if ( fd<0 ) {
00072 fprintf(stderr, "Could not open serial device %s\n",port);
00073 return;
00074 }
00075 fcntl(fd,F_SETFL, 0);
00076
00077
00078 tcgetattr(fd, &oldtio);
00079
00080
00081
00082
00083
00084 struct termios newtio;
00085 memset(&newtio, 0,sizeof(newtio));
00086 newtio.c_cflag = CS8 | CLOCAL | CREAD;
00087 newtio.c_iflag = IGNPAR;
00088 newtio.c_oflag = 0;
00089 newtio.c_lflag = ICANON;
00090
00091 speed_t sp = B9600;
00092 switch (rate) {
00093 case 0:
00094 sp = B0;
00095 break;
00096 case 50:
00097 sp = B50;
00098 break;
00099 case 75:
00100 sp = B75;
00101 break;
00102 case 110:
00103 sp = B110;
00104 break;
00105 case 134:
00106 sp = B134;
00107 break;
00108 case 150:
00109 sp = B150;
00110 break;
00111 case 200:
00112 sp = B200;
00113 break;
00114 case 300:
00115 sp = B300;
00116 break;
00117 case 600:
00118 sp = B600;
00119 break;
00120 case 1200:
00121 sp = B1200;
00122 break;
00123 case 2400:
00124 sp = B2400;
00125 break;
00126 case 4800:
00127 sp = B4800;
00128 break;
00129 case 9600:
00130 sp = B9600;
00131 break;
00132 case 19200:
00133 sp = B19200;
00134 break;
00135 case 38400:
00136 sp = B38400;
00137 break;
00138 default:
00139 fprintf(stderr,"Failed to set serial baud rate: %d\n", rate);
00140 Disconnect();
00141 return;
00142 }
00143
00144 if (cfsetispeed(&newtio, sp) < 0 || cfsetospeed(&newtio, sp) < 0) {
00145 fprintf(stderr,"Failed to set serial baud rate: %d\n", rate);
00146 Disconnect();
00147 return;
00148 }
00149
00150 tcflush(fd, TCIFLUSH);
00151 tcsetattr(fd, TCSANOW, &newtio);
00152
00153
00154 Write(" ");
00155 usleep(100000);
00156 tcflush(fd, TCIFLUSH);
00157
00158 Write("ft ");
00159 Write("ed ");
00160 Write("ci ");
00161
00162
00163 usleep(200000);
00164 tcflush(fd, TCIFLUSH);
00165
00166
00167 tr = GetRes(PTU46_TILT);
00168 pr = GetRes(PTU46_PAN);
00169
00170 PMin = GetLimit(PTU46_PAN, PTU46_MIN);
00171 PMax = GetLimit(PTU46_PAN, PTU46_MAX);
00172 TMin = GetLimit(PTU46_TILT, PTU46_MIN);
00173 TMax = GetLimit(PTU46_TILT, PTU46_MAX);
00174 PSMin = GetLimit(PTU46_PAN, PTU46_MIN_SPEED);
00175 PSMax = GetLimit(PTU46_PAN, PTU46_MAX_SPEED);
00176 TSMin = GetLimit(PTU46_TILT, PTU46_MIN_SPEED);
00177 TSMax = GetLimit(PTU46_TILT, PTU46_MAX_SPEED);
00178
00179 if (tr <= 0 || pr <= 0 || PMin == 0 || PMax == 0 || TMin == 0 || TMax == 0) {
00180
00181 Write(" r ");
00182
00183
00184 int len = 0;
00185 char temp;
00186 char response[10] = "!T!T!P!P*";
00187
00188 for (int i = 0; i < 9; ++i) {
00189 while ((len = read(fd, &temp, 1 )) == 0) {};
00190 if ((len != 1) || (temp != response[i])) {
00191 fprintf(stderr,"Error Resetting Pan Tilt unit\n");
00192 fprintf(stderr,"Stopping access to pan-tilt unit\n");
00193 Disconnect();
00194 }
00195 }
00196
00197
00198 usleep(100000);
00199 tcflush(fd, TCIFLUSH);
00200
00201
00202
00203 tr = GetRes(PTU46_TILT);
00204 pr = GetRes(PTU46_PAN);
00205
00206 PMin = GetLimit(PTU46_PAN, PTU46_MIN);
00207 PMax = GetLimit(PTU46_PAN, PTU46_MAX);
00208 TMin = GetLimit(PTU46_TILT, PTU46_MIN);
00209 TMax = GetLimit(PTU46_TILT, PTU46_MAX);
00210 PSMin = GetLimit(PTU46_PAN, PTU46_MIN_SPEED);
00211 PSMax = GetLimit(PTU46_PAN, PTU46_MAX_SPEED);
00212 TSMin = GetLimit(PTU46_TILT, PTU46_MIN_SPEED);
00213 TSMax = GetLimit(PTU46_TILT, PTU46_MAX_SPEED);
00214
00215 if (tr <= 0 || pr <= 0 || PMin == 0 || PMax == 0 || TMin == 0 || TMax == 0) {
00216
00217 fprintf(stderr,"Error getting pan-tilt resolution...is the serial port correct?\n");
00218 fprintf(stderr,"Stopping access to pan-tilt unit\n");
00219 Disconnect();
00220 }
00221 }
00222 }
00223
00224
00225 PTU46::~PTU46() {
00226 Disconnect();
00227 }
00228
00229 void PTU46::Disconnect() {
00230 if (fd > 0) {
00231
00232 tcsetattr(fd, TCSANOW, &oldtio);
00233
00234 close(fd);
00235 fd = -1;
00236 }
00237 }
00238
00239 int PTU46::Write(const char * data, int length) {
00240
00241 if (fd < 0)
00242 return -1;
00243
00244
00245 if (length == 0)
00246 length = strlen(data);
00247
00248
00249 if (write(fd, data, length) < length) {
00250 fprintf(stderr,"Error writing to Pan Tilt Unit, disabling\n");
00251 Disconnect();
00252 return -1;
00253 }
00254 return 0;
00255 }
00256
00257
00258
00259 float PTU46::GetRes(char type) {
00260 if (fd < 0)
00261 return -1;
00262 char cmd[4] = " r ";
00263 cmd[0] = type;
00264
00265
00266 int len = 0;
00267 Write(cmd);
00268 len = read(fd, buffer, PTU46_BUFFER_LEN );
00269
00270 if (len < 3 || buffer[0] != '*') {
00271 fprintf(stderr,"Error getting pan-tilt res\n");
00272 return -1;
00273 }
00274
00275 buffer[len] = '\0';
00276 double z = strtod(&buffer[2],NULL);
00277 z = z/3600;
00278 return z*M_PI/180;
00279 }
00280
00281
00282 int PTU46::GetLimit(char type, char LimType) {
00283 if (fd < 0)
00284 return -1;
00285 char cmd[4] = " ";
00286 cmd[0] = type;
00287 cmd[1] = LimType;
00288
00289
00290 int len = 0;
00291 Write(cmd);
00292 len = read(fd, buffer, PTU46_BUFFER_LEN );
00293
00294 if (len < 3 || buffer[0] != '*') {
00295 fprintf(stderr,"Error getting pan-tilt limit\n");
00296 return -1;
00297 }
00298
00299 buffer[len] = '\0';
00300 return strtol(&buffer[2],NULL,0);
00301 }
00302
00303
00304
00305 float PTU46::GetPosition (char type) {
00306 if (fd < 0)
00307 return -1;
00308
00309 char cmd[4] = " p ";
00310 cmd[0] = type;
00311
00312
00313 int len = 0;
00314 Write (cmd);
00315 len = read (fd, buffer, PTU46_BUFFER_LEN );
00316
00317 if (len < 3 || buffer[0] != '*') {
00318 fprintf(stderr,"Error getting pan-tilt pos\n");
00319 return -1;
00320 }
00321
00322 buffer[len] = '\0';
00323
00324 return strtod (&buffer[2],NULL) * GetResolution(type);
00325 }
00326
00327
00328
00329 bool PTU46::SetPosition (char type, float pos, bool Block) {
00330 if (fd < 0)
00331 return false;
00332
00333
00334 int Count = static_cast<int> (pos/GetResolution(type));
00335
00336
00337 if (Count < (type == PTU46_TILT ? TMin : PMin) || Count > (type == PTU46_TILT ? TMax : PMax)) {
00338 fprintf (stderr,"Pan Tilt Value out of Range: %c %f(%d) (%d-%d)\n", type, pos, Count, (type == PTU46_TILT ? TMin : PMin),(type == PTU46_TILT ? TMax : PMax));
00339 return false;
00340 }
00341
00342 char cmd[16];
00343 snprintf (cmd,16,"%cp%d ",type,Count);
00344
00345
00346 int len = 0;
00347 Write (cmd);
00348 len = read (fd, buffer, PTU46_BUFFER_LEN );
00349
00350 if (len <= 0 || buffer[0] != '*') {
00351 fprintf(stderr,"Error setting pan-tilt pos\n");
00352 return false;
00353 }
00354
00355 if (Block)
00356 while (GetPosition (type) != pos) {};
00357
00358 return true;
00359 }
00360
00361
00362 float PTU46::GetSpeed (char type) {
00363 if (fd < 0)
00364 return -1;
00365
00366 char cmd[4] = " s ";
00367 cmd[0] = type;
00368
00369
00370 int len = 0;
00371 Write (cmd);
00372 len = read (fd, buffer, PTU46_BUFFER_LEN );
00373
00374 if (len < 3 || buffer[0] != '*') {
00375 fprintf (stderr,"Error getting pan-tilt speed\n");
00376 return -1;
00377 }
00378
00379 buffer[len] = '\0';
00380
00381 return strtod(&buffer[2],NULL) * GetResolution(type);
00382 }
00383
00384
00385
00386
00387 bool PTU46::SetSpeed (char type, float pos) {
00388 if (fd < 0)
00389 return false;
00390
00391
00392 int Count = static_cast<int> (pos/GetResolution(type));
00393
00394 if (abs(Count) < (type == PTU46_TILT ? TSMin : PSMin) || abs(Count) > (type == PTU46_TILT ? TSMax : PSMax)) {
00395 fprintf (stderr,"Pan Tilt Speed Value out of Range: %c %f(%d) (%d-%d)\n", type, pos, Count, (type == PTU46_TILT ? TSMin : PSMin),(type == PTU46_TILT ? TSMax : PSMax));
00396 return false;
00397 }
00398
00399 char cmd[16];
00400 snprintf (cmd,16,"%cs%d ",type,Count);
00401
00402
00403 int len = 0;
00404 Write (cmd);
00405 len = read (fd, buffer, PTU46_BUFFER_LEN );
00406
00407 if (len <= 0 || buffer[0] != '*') {
00408 fprintf (stderr,"Error setting pan-tilt speed\n");
00409 return false;
00410 }
00411 return true;
00412 }
00413
00414
00415
00416 bool PTU46::SetMode (char type) {
00417 if (fd < 0)
00418 return false;
00419
00420 char cmd[4] = "c ";
00421 cmd[1] = type;
00422
00423
00424 int len = 0;
00425 Write (cmd);
00426 len = read (fd, buffer, PTU46_BUFFER_LEN );
00427
00428 if (len <= 0 || buffer[0] != '*') {
00429 fprintf (stderr,"Error setting pan-tilt move mode\n");
00430 return false;
00431 }
00432 return true;
00433 }
00434
00435
00436 char PTU46::GetMode () {
00437 if (fd < 0)
00438 return -1;
00439
00440
00441 int len = 0;
00442 Write ("c ");
00443 len = read (fd, buffer, PTU46_BUFFER_LEN );
00444
00445 if (len < 3 || buffer[0] != '*') {
00446 fprintf (stderr,"Error getting pan-tilt pos\n");
00447 return -1;
00448 }
00449
00450 if (buffer[2] == 'p')
00451 return PTU46_VELOCITY;
00452 else if (buffer[2] == 'i')
00453 return PTU46_POSITION;
00454 else
00455 return -1;
00456 }
00457
00458 }