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
00032 #include <hitec5980sg/hitec5980sg.h>
00033
00034 hitec_5980SG::hitec_5980SG(const char*pdevice)
00035 {
00036
00037 device=(char*)malloc((strlen(pdevice)+10)*sizeof(char));
00038 strcpy(device,pdevice);
00039
00040
00041 minimum=600;
00042 center=1500;
00043 maximum=2400;
00044 HSR_5980SG_MAX_ANGULAR_SPEED=340.5;
00045 HSR_5498SG_MAX_ANGULAR_SPEED=263.12;
00046 active=false;
00047
00048
00049 struct termios params;
00050 int ret;
00051
00052 memset( ¶ms,0, sizeof(params));
00053
00054
00055
00056 port = open( device, O_RDWR | O_NONBLOCK );
00057 if(port == -1)
00058 {
00059 perror("Failed to open port");
00060 return;
00061 }
00062
00063
00064
00065 params.c_cflag = B19200 | CS8 | CLOCAL | CREAD | CSTOPB | IGNPAR;
00066 params.c_iflag = IGNPAR;
00067 params.c_oflag = 0;
00068
00069 ret=tcsetattr(port, TCSANOW, ¶ms );
00070 if( ret < 0 )
00071 {
00072 perror("Set serial communication parameters failed");
00073 return;
00074 }
00075
00076
00077 fflush(stdout);
00078
00079
00080 char msg[7];
00081
00082 msg[0]=0x80;
00083 msg[1]=0x00;
00084 msg[2]=0x00;
00085 msg[3]=0x00;
00086 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00087 msg[5]=0x00;
00088 msg[6]=0x00;
00089
00090
00091 CleanBuffer();
00092
00093
00094 ret = write(port,&msg,sizeof(msg));
00095 if(ret<0)
00096 {
00097 perror("Serial communication setup failed...");
00098 return;
00099 }
00100
00101 active=true;
00102
00103 return;
00104 }
00105
00106 hitec_5980SG::~hitec_5980SG()
00107 {
00108 try
00109 {
00110 if(active)
00111 close(port);
00112 }
00113 catch(char * str)
00114 {
00115 perror("Error closing COMM port.");
00116 perror(str);
00117 perror("Retrying...");
00118 try
00119 {
00120 close(port);
00121 }
00122 catch(char * str)
00123 {
00124 perror(str);
00125 perror("FAILED TO CLOSE COMM.");
00126 }
00127 }
00128 }
00129
00130 short unsigned int hitec_5980SG::SetPosition(int id,int position)
00131 {
00132 int ret;
00133 char msg[7];
00134 short unsigned int responce;
00135
00136
00137
00138 if(!active)
00139 return 0xFFFF;
00140
00141 if(position>maximum)
00142 return 0xFFFF;
00143 else if(position<minimum)
00144 return 0xFFFF;
00145
00146
00147 msg[0]=0x80;
00148 msg[1]=id;
00149 msg[2]=position>>8;
00150 msg[3]=(char)position;
00151 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00152 msg[5]=0x00;
00153 msg[6]=0x00;
00154
00155
00156 CleanBuffer();
00157
00158
00159 ret = write(port,&msg,sizeof(msg));
00160 if(ret<0)
00161 {
00162 return 0xFFFF;
00163 }
00164
00165 responce=ReadResponse();
00166
00167 return responce;
00168 }
00169
00170 short unsigned int hitec_5980SG::SetSpeedPosition(int id,int speed)
00171 {
00172 int ret;
00173 char msg[7];
00174
00175 if(!active)
00176 return 0xFFFF;
00177
00178
00179 msg[0]=0x80;
00180 msg[1]=0xE9;
00181 msg[2]=id;
00182 if(speed>255) msg[3]=255; else if (speed<0) msg[3]=0; else msg[3]=speed;
00183 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00184 msg[5]=0x00;
00185 msg[6]=0x00;
00186
00187
00188 CleanBuffer();
00189
00190
00191 ret = write(port,&msg,sizeof(msg));
00192 if(ret<0)
00193 return 0xFFFF;
00194
00195 usleep(1000);
00196
00197 ret=ReadResponse();
00198 if(ret<0 || ret==0xFFFF)
00199 return 0xFFFF;
00200
00201 return ret;
00202 }
00203
00204 short unsigned int hitec_5980SG::SetPositionAllServos(short unsigned int position)
00205 {
00206 int ret;
00207 char msg[7];
00208 short unsigned int responce;
00209
00210
00211 if(!active)
00212 return 0xFFFF;
00213
00214 if(position>maximum)
00215 return 0xFFFF;
00216
00217 if(position<minimum)
00218 return 0xFFFF;
00219
00220
00221 msg[0]=0x80;
00222 msg[1]=0xE6;
00223 msg[2]=position>>8;
00224 msg[3]=(char)position;
00225 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00226 msg[5]=0x00;
00227 msg[6]=0x00;
00228
00229
00230 CleanBuffer();
00231
00232
00233 ret = write(port,&msg,sizeof(msg));
00234 if(ret<0)
00235 return 0xFFFF;
00236
00237 responce=ReadResponse();
00238
00239 return responce;
00240 }
00241
00242 short int hitec_5980SG::GetVersionAndID(void)
00243 {
00244 int ret;
00245 char msg[7];
00246
00247 char data[7];
00248 int nbytes_to_read=0;
00249
00250
00251 msg[0]=0x80;
00252 msg[1]=0xE7;
00253 msg[2]=0;
00254 msg[3]=0;
00255 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00256 msg[5]=0x00;
00257 msg[6]=0x00;
00258
00259
00260 CleanBuffer();
00261
00262
00263 ret = write(port,&msg,sizeof(msg));
00264 if(ret<0)
00265 return 0xFFFF;
00266
00267 if(!active)
00268 return 0xFFFF;
00269
00271 while(nbytes_to_read!=7)
00272 {
00273 ret=ioctl(port,FIONREAD,&nbytes_to_read);
00274 usleep(1000);
00275 }
00276
00277 ret=read(port,&data,7);
00278 if(ret!=7)
00279 return 0xFFFF;
00280
00281 return (0x00FF & data[6]);
00282 }
00283
00284 short unsigned int hitec_5980SG::ReleaseServos(void)
00285 {
00286 int ret;
00287 char msg[7];
00288 short int responce;
00289
00290
00291 if(!active)
00292 return 0xFFFF;
00293
00294
00295 msg[0]=0x80;
00296 msg[1]=0xEF;
00297 msg[2]=0;
00298 msg[3]=0;
00299 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00300 msg[5]=0x00;
00301 msg[6]=0x00;
00302
00303
00304 CleanBuffer();
00305
00306
00307 ret = write(port,&msg,sizeof(msg));
00308 if(ret<0)
00309 return 0xFFFF;
00310
00311 char data[7];
00312 int nbytes_to_read=0;
00313
00315 while(nbytes_to_read!=7)
00316 {
00317 ret=ioctl(port,FIONREAD,&nbytes_to_read);
00318 usleep(1000);
00319 }
00320
00321 ret=read(port,&data,7);
00322 if(ret!=7)
00323 return 0xFFFF;
00324
00325 responce=(0x00FF & data[5]);
00326
00327
00328 if(responce!=3)
00329 return 0xFFFF;
00330 else
00331 return 3;
00332 }
00333
00334 short unsigned int hitec_5980SG::SetServoID(int id)
00335 {
00336 int ret;
00337 char msg[7];
00338
00339
00340 char data[7];
00341 int nbytes_to_read=0;
00342
00343
00344 msg[0]=0x80;
00345 msg[1]=0xE2;
00346 msg[2]=0x29;
00347 msg[3]=id;
00348 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00349 msg[5]=0x00;
00350 msg[6]=0x00;
00351
00352
00353 CleanBuffer();
00354
00355
00356 ret = write(port,&msg,sizeof(msg));
00357 if(ret<0)
00358 {
00359 return 0xFFFF;
00360 }
00361
00362 if(!active)
00363 return 0xFFFF;
00364
00366 while(nbytes_to_read!=7)
00367 {
00368 ret=ioctl(port,FIONREAD,&nbytes_to_read);
00369 usleep(1000);
00370 }
00371
00372 ret=read(port,&data,7);
00373 if(ret!=7)
00374 return 0xFFFF;
00375
00376 return (0x00FF & data[6]);
00377 }
00378
00379 short unsigned int hitec_5980SG::SetGoStop(short unsigned int value)
00380 {
00381 int ret;
00382 char msg[7];
00383 short unsigned int responce;
00384 int sendvalue;
00385
00386
00387 if(!active)
00388 return 0xFFFF;
00389
00390 if(value>=1)
00391 sendvalue=1;
00392 else
00393 sendvalue=0;
00394
00395
00396 msg[0]=0x80;
00397 msg[1]=0xEB;
00398 msg[2]=sendvalue;
00399 msg[3]=0;
00400 msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
00401 msg[5]=0x00;
00402 msg[6]=0x00;
00403
00404
00405 CleanBuffer();
00406
00407
00408 ret = write(port,&msg,sizeof(msg));
00409 if(ret<0)
00410 {
00411 return 0xFFFF;
00412 }
00413
00414 char data[7];
00415 int nbytes_to_read=0;
00416
00418 while(nbytes_to_read!=7)
00419 {
00420 ret=ioctl(port,FIONREAD,&nbytes_to_read);
00421 usleep(1000);
00422 }
00423
00424 ret=read(port,&data,7);
00425 if(ret!=7)
00426 return 0xFFFF;
00427
00428 responce=(0x00FF & data[5]);
00429
00430 if(responce!=3)
00431 return 0xFFFF;
00432 else
00433 return 3;
00434 }
00435
00436 bool hitec_5980SG::IsActive(void)
00437 {
00438 return active;
00439 }
00440
00441 short unsigned int hitec_5980SG::ReadResponse(char*response_1,char*response_2)
00442 {
00443 int ret=1;
00444 char data[7];
00445 int nbytes_to_read=0;
00446 double diff_time;
00447 time_t start,end;
00448
00449 if(!active)
00450 return 0xFFFF;
00451
00452 time (&start);
00453 while(nbytes_to_read!=7)
00454 {
00455 ret=ioctl(port,FIONREAD,&nbytes_to_read);
00456 usleep(1000);
00457 time (&end);
00458 diff_time=difftime ( end, start);
00459 if(diff_time>1.)
00460 return 0xFFFF;
00461 }
00462
00463 ret=read(port,&data,7);
00464 if(ret!=7)
00465 return 0xFFFF;
00466
00467 if(response_1 && response_2)
00468 {
00469 *response_1=data[5];
00470 *response_2=data[6];
00471 }
00472
00473 return (0xFF00 & (data[5]<<8)) | (0x00FF & data[6]);
00474 }
00475
00476 void hitec_5980SG::CleanBuffer(void)
00477 {
00478 int ret=1;
00479 char data;
00480
00481 if(!active)
00482 return;
00483
00484 while(ret!=0)
00485 {
00486 ret=read(port,&data,1);
00487 if(ret<0)
00488 return;
00489 }
00490 }
00491
00492 short unsigned int hitec_5980SG::ConvertAngularSpeedToServoSpeed(double angular_speed, unsigned int Servo_type)
00493 {
00494
00495 double max_speed;
00496 short unsigned int return_value;
00497 if(Servo_type==HSR_5980SG)
00498 {
00499 max_speed=HSR_5980SG_MAX_ANGULAR_SPEED;
00500 }
00501 else if(Servo_type==HSR_5498SG)
00502 {
00503 max_speed=HSR_5498SG_MAX_ANGULAR_SPEED;
00504 }
00505 else
00506 return 1;
00507
00508
00509 if(fabs(angular_speed)>=max_speed){
00510 return 255;}
00511 else{
00512 return_value = round((255./max_speed) * fabs(angular_speed));}
00513
00514 if(return_value<1){
00515
00516 return 0xFFFF;}
00517 else
00518 return return_value;
00519 }