hitec5980sg.cpp
Go to the documentation of this file.
1 /**************************************************************************************************
2  Software License Agreement (BSD License)
3 
4  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without modification, are permitted
8  provided that the following conditions are met:
9 
10  *Redistributions of source code must retain the above copyright notice, this list of
11  conditions and the following disclaimer.
12  *Redistributions in binary form must reproduce the above copyright notice, this list of
13  conditions and the following disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  *Neither the name of the University of Aveiro nor the names of its contributors may be used to
16  endorse or promote products derived from this software without specific prior written permission.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
19  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
21  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ***************************************************************************************************/
33 
34 hitec_5980SG::hitec_5980SG(const char*pdevice)
35 {
36  //Get the device
37  device=(char*)malloc((strlen(pdevice)+10)*sizeof(char));
38  strcpy(device,pdevice);
39 
40  //Set the standard center, minimum and maximum position
41  minimum=600;
42  center=1500;
43  maximum=2400;
44  HSR_5980SG_MAX_ANGULAR_SPEED=340.5; /*deg/second @6V feed (calculated by W.Lage[2011] for HSR-5980SG) [3.525% inferior to manufacturer speed]*/
45  HSR_5498SG_MAX_ANGULAR_SPEED=263.12; /* supposed real speed | hitec value is 0.22s/60deg=272.72deg/s @6V on wich I apply the 3.525% factor*/
46  active=false;//comm off-line
47 
48  //Comm config params
49  struct termios params;
50  int ret;
51 
52  memset( &params,0, sizeof(params)); //setting all structure values to zero
53 
54  //Opens port comm with the servos
55  // printf("Opening COMM %s ... \n",device);fflush(stdout);
56  port = open( device, O_RDWR | O_NONBLOCK ); //open com device. read write and non blocking modes
57  if(port == -1) //if could not open
58  {
59  perror("Failed to open port");
60  return;
61  }
62  // printf("Done\n");
63 
64  // printf("Setting new parameters ... ");fflush(stdout);
65  params.c_cflag = B19200 | CS8 | CLOCAL | CREAD | CSTOPB | IGNPAR;
66  params.c_iflag = IGNPAR;
67  params.c_oflag = 0;
68 
69  ret=tcsetattr(port, TCSANOW, &params ); // set serial communication parameters
70  if( ret < 0 )
71  {
72  perror("Set serial communication parameters failed");
73  return;
74  }
75 
76  // printf("Done\n");
77  fflush(stdout);
78 
79  // send dummy instruction to activate comms
80  char msg[7];
81  //Create message
82  msg[0]=0x80;
83  msg[1]=0x00;
84  msg[2]=0x00;
85  msg[3]=0x00;
86  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
87  msg[5]=0x00;//Return 1
88  msg[6]=0x00;//Return 2
89 
90  //Clean input buffer
91  CleanBuffer();
92 
93  //Send message
94  ret = write(port,&msg,sizeof(msg));
95  if(ret<0)
96  {
97  perror("Serial communication setup failed...");
98  return;
99  }
100 
101  active=true;//Comm is now active
102 
103  return;
104 }
105 
107 {
108  try
109  {
110  if(active)
111  close(port);
112  }
113  catch(char * str)
114  {
115  perror("Error closing COMM port.");
116  perror(str);
117  perror("Retrying...");
118  try
119  {
120  close(port);
121  }
122  catch(char * str)
123  {
124  perror(str);
125  perror("FAILED TO CLOSE COMM.");
126  }
127  }
128 }
129 
130 short unsigned int hitec_5980SG::SetPosition(int id,int position)
131 {
132  int ret;
133  char msg[7];
134  short unsigned int responce;
135 
136 
137  // Check impossibilities
138  if(!active)
139  return 0xFFFF;
140 
141  if(position>maximum)
142  return 0xFFFF;
143  else if(position<minimum)
144  return 0xFFFF;
145 
146  //Create message
147  msg[0]=0x80;
148  msg[1]=id;//id of the servo to move
149  msg[2]=position>>8;//position high
150  msg[3]=(char)position;//position low
151  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
152  msg[5]=0x00;//Return 1
153  msg[6]=0x00;//Return 2
154 
155  //Clean input buffer
156  CleanBuffer();
157 
158  //Send message
159  ret = write(port,&msg,sizeof(msg));
160  if(ret<0)
161  {
162  return 0xFFFF;
163  }
164 
165  responce=ReadResponse();
166 
167  return responce;
168 }
169 
170 short unsigned int hitec_5980SG::SetSpeedPosition(int id,int speed)
171 {
172  int ret;
173  char msg[7];
174 
175  if(!active)
176  return 0xFFFF;
177 
178  //Create message
179  msg[0]=0x80;
180  msg[1]=0xE9;//command
181  msg[2]=id;//id of the servo
182  if(speed>255) msg[3]=255; else if (speed<0) msg[3]=0; else msg[3]=speed;//speed
183  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
184  msg[5]=0x00;//Return 1
185  msg[6]=0x00;//Return 2
186 
187  //Clean input buffer
188  CleanBuffer();
189 
190  //Send message
191  ret = write(port,&msg,sizeof(msg));
192  if(ret<0)
193  return 0xFFFF;
194 
195  usleep(1000); /*IS THIS NEEDED????*/
196 
197  ret=ReadResponse();
198  if(ret<0 || ret==0xFFFF)
199  return 0xFFFF;
200 
201  return ret;
202 }
203 
204 short unsigned int hitec_5980SG::SetPositionAllServos(short unsigned int position)
205 {
206  int ret;
207  char msg[7];
208  short unsigned int responce;
209 
210  // Check impossibilities
211  if(!active)
212  return 0xFFFF;
213 
214  if(position>maximum)
215  return 0xFFFF;
216 
217  if(position<minimum)
218  return 0xFFFF;
219 
220  //Create message
221  msg[0]=0x80;
222  msg[1]=0xE6; /*COMMAND TO ORDER ANY SERVO TO COMPLY*/
223  msg[2]=position>>8;//position high
224  msg[3]=(char)position;//position low
225  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
226  msg[5]=0x00;//Return 1
227  msg[6]=0x00;//Return 2
228 
229  //Clean input buffer
230  CleanBuffer();
231 
232  //Send message
233  ret = write(port,&msg,sizeof(msg));
234  if(ret<0)
235  return 0xFFFF;
236 
237  responce=ReadResponse();
238 
239  return responce;
240 }
241 
243 {
244  int ret;
245  char msg[7];
246 
247  char data[7];
248  int nbytes_to_read=0;
249 
250  //Create message
251  msg[0]=0x80;
252  msg[1]=0xE7; /*COMMAND TO OUTPUT ID NUMBER*/
253  msg[2]=0;
254  msg[3]=0;
255  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
256  msg[5]=0x00;//Return 1
257  msg[6]=0x00;//Return 2
258 
259  //Clean input buffer
260  CleanBuffer();
261 
262  //Send message
263  ret = write(port,&msg,sizeof(msg));
264  if(ret<0)
265  return 0xFFFF;
266 
267  if(!active)
268  return 0xFFFF;
269 
271  while(nbytes_to_read!=7)
272  {
273  ret=ioctl(port,FIONREAD,&nbytes_to_read);
274  usleep(1000);
275  }
276 
277  ret=read(port,&data,7);
278  if(ret!=7)
279  return 0xFFFF;
280 
281  return (0x00FF & data[6]);
282 }
283 
284 short unsigned int hitec_5980SG::ReleaseServos(void)
285 {
286  int ret;
287  char msg[7];
288  short int responce;
289 
290  // Check impossibilities
291  if(!active)
292  return 0xFFFF;
293 
294  //Create message
295  msg[0]=0x80;
296  msg[1]=0xEF; /*COMMAND TO POWER DOWN SERVO STATOR*/
297  msg[2]=0;
298  msg[3]=0;
299  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
300  msg[5]=0x00;//Return 1
301  msg[6]=0x00;//Return 2
302 
303  //Clean input buffer
304  CleanBuffer();
305 
306  //Send message
307  ret = write(port,&msg,sizeof(msg));
308  if(ret<0)
309  return 0xFFFF;
310 
311  char data[7];
312  int nbytes_to_read=0;
313 
315  while(nbytes_to_read!=7)
316  {
317  ret=ioctl(port,FIONREAD,&nbytes_to_read);
318  usleep(1000);
319  }
320 
321  ret=read(port,&data,7);
322  if(ret!=7)
323  return 0xFFFF;
324 
325  responce=(0x00FF & data[5]);
326 
327  /*DON'T MIND THIS PIECE OF CODE | BUS PROBLEMS...*/
328  if(responce!=3)
329  return 0xFFFF;
330  else
331  return 3;
332 }
333 
334 short unsigned int hitec_5980SG::SetServoID(int id)
335 {
336  int ret;
337  char msg[7];
338 
339 
340  char data[7];
341  int nbytes_to_read=0;
342 
343  //Create message
344  msg[0]=0x80;
345  msg[1]=0xE2; /*COMMAND TO SET VALUE TO A MEMORY POSITION*/
346  msg[2]=0x29; /*ID MEMORY POSITION*/
347  msg[3]=id;
348  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
349  msg[5]=0x00;//Return 1
350  msg[6]=0x00;//Return 2
351 
352  //Clean input buffer
353  CleanBuffer();
354 
355  //Send message
356  ret = write(port,&msg,sizeof(msg));
357  if(ret<0)
358  {
359  return 0xFFFF;
360  }
361 
362  if(!active)
363  return 0xFFFF;
364 
366  while(nbytes_to_read!=7)
367  {
368  ret=ioctl(port,FIONREAD,&nbytes_to_read);
369  usleep(1000);
370  }
371 
372  ret=read(port,&data,7);
373  if(ret!=7)
374  return 0xFFFF;
375 
376  return (0x00FF & data[6]);
377 }
378 
379 short unsigned int hitec_5980SG::SetGoStop(short unsigned int value)
380 {
381  int ret;
382  char msg[7];
383  short unsigned int responce;
384  int sendvalue;
385 
386  // Check impossibilities
387  if(!active)
388  return 0xFFFF;
389 
390  if(value>=1)
391  sendvalue=1;
392  else
393  sendvalue=0;
394 
395  //Create message
396  msg[0]=0x80;
397  msg[1]=0xEB; /*COMMANDO FOR STOP/GO*/
398  msg[2]=sendvalue;
399  msg[3]=0;
400  msg[4]=256 - (0x80 + msg[1] + msg[2] + msg[3])%256;
401  msg[5]=0x00;//Return 1
402  msg[6]=0x00;//Return 2
403 
404  //Clean input buffer
405  CleanBuffer();
406 
407  //Send message
408  ret = write(port,&msg,sizeof(msg));
409  if(ret<0)
410  {
411  return 0xFFFF;
412  }
413 
414  char data[7];
415  int nbytes_to_read=0;
416 
418  while(nbytes_to_read!=7)
419  {
420  ret=ioctl(port,FIONREAD,&nbytes_to_read);
421  usleep(1000);
422  }
423 
424  ret=read(port,&data,7);
425  if(ret!=7)
426  return 0xFFFF;
427 
428  responce=(0x00FF & data[5]);
429  /*DON'T MIND THIS PIECE OF CODE | BUS PROBLEMS...*/
430  if(responce!=3)
431  return 0xFFFF;
432  else
433  return 3;
434 }
435 
437 {
438  return active;
439 }
440 
441 short unsigned int hitec_5980SG::ReadResponse(char*response_1,char*response_2)
442 {
443  int ret=1;
444  char data[7];
445  int nbytes_to_read=0;
446  double diff_time;
447  time_t start,end;
448 
449  if(!active)
450  return 0xFFFF;
451 
452  time (&start);
453  while(nbytes_to_read!=7)
454  {
455  ret=ioctl(port,FIONREAD,&nbytes_to_read);
456  usleep(1000);
457  time (&end);
458  diff_time=difftime ( end, start);
459  if(diff_time>1.)
460  return 0xFFFF; /*CONNECTION TIMED OUT | 1_SEC SEEMS TOO MUCH BUT I'LL KEEP IT...*/
461  }
462 
463  ret=read(port,&data,7);
464  if(ret!=7)
465  return 0xFFFF;
466 
467  if(response_1 && response_2)
468  {
469  *response_1=data[5];
470  *response_2=data[6];
471  }
472 
473  return (0xFF00 & (data[5]<<8)) | (0x00FF & data[6]);
474 }
475 
477 {
478  int ret=1;
479  char data;
480 
481  if(!active)
482  return;
483 
484  while(ret!=0)
485  {
486  ret=read(port,&data,1);
487  if(ret<0)
488  return;
489  }
490 }
491 
492 short unsigned int hitec_5980SG::ConvertAngularSpeedToServoSpeed(double angular_speed, unsigned int Servo_type)
493 {
494  //choose servo motor type
495  double max_speed;
496  short unsigned int return_value;
497  if(Servo_type==HSR_5980SG)
498  {
500  }
501  else if(Servo_type==HSR_5498SG)
502  {
504  }
505  else
506  return 1;
507 
508  //convert servo digital speed
509  if(fabs(angular_speed)>=max_speed){
510  return 255;}
511  else{
512  return_value = round((255./max_speed) * fabs(angular_speed));}
513 
514  if(return_value<1){
515  //means the servo will not move [STOP ZONE]
516  return 0xFFFF;}
517  else
518  return return_value;
519 }
short unsigned int maximum
Maximum position of the servo.
Definition: hitec5980sg.h:204
double HSR_5498SG_MAX_ANGULAR_SPEED
Maximum angular speed of the servo HSR-5498SG.
Definition: hitec5980sg.h:210
short unsigned int SetSpeedPosition(int id, int speed)
Set velocity and read position of the servo.
short unsigned int minimum
Minimum position of the servo.
Definition: hitec5980sg.h:201
double HSR_5980SG_MAX_ANGULAR_SPEED
Maximum angular speed of the servo HSR-5980SG.
Definition: hitec5980sg.h:207
void CleanBuffer(void)
Cleans the buffer.
#define HSR_5980SG
Definition: hitec5980sg.h:48
short unsigned int SetServoID(int id)
Sets servo ID.
~hitec_5980SG()
De-constructor.
short unsigned int SetPositionAllServos(short unsigned int position)
Sets the target position of all servos in the bus.
short unsigned int ConvertAngularSpeedToServoSpeed(double angular_speed, unsigned int Servo_type)
Converts angular speed to servo speed range [1...255].
#define HSR_5498SG
Definition: hitec5980sg.h:49
short unsigned int ReadResponse(char *response_1=NULL, char *response_2=NULL)
Reads the response to a command.
bool IsActive(void)
Checks por activation.
Class hitec_5980SG declararion.
char * device
Communication device to use.
Definition: hitec5980sg.h:195
short unsigned int ReleaseServos(void)
Releases all the servos in the bus.
short unsigned int center
Center position of the servo.
Definition: hitec5980sg.h:198
short unsigned int SetGoStop(short unsigned int value)
Sends command go/stop to all servos in the bus.
int port
Communication port to use.
Definition: hitec5980sg.h:192
short int GetVersionAndID(void)
Gets servos version and id's.
hitec_5980SG(const char *pdevice)
Constructor.
Definition: hitec5980sg.cpp:34
bool active
This variable indicates that the communication is active.
Definition: hitec5980sg.h:189
short unsigned int SetPosition(int id, int position)
Sets the target position of a servo.


hitec5980sg
Author(s): Pedro Cruz, Jorge Almeida
autogenerated on Mon Mar 2 2015 01:31:40