sdhserial.cpp
Go to the documentation of this file.
1 //======================================================================
28 //======================================================================
29 
30 #include "sdhlibrary_settings.h"
31 
32 //----------------------------------------------------------------------
33 // System Includes - include with <>
34 //----------------------------------------------------------------------
35 
36 #include <assert.h>
37 #if ! SDH_USE_VCC
38 # include <unistd.h>
39 #endif
40 
41 //----------------------------------------------------------------------
42 // Project Includes - include with ""
43 //----------------------------------------------------------------------
44 
45 #include "util.h"
46 #include "sdhserial.h"
47 #include "crc.h"
48 #include "sdh_codes.h"
49 
50 //----------------------------------------------------------------------
51 // Defines, enums, unions, structs,
52 //----------------------------------------------------------------------
53 
54 
56 
57 enum {
59 };
60 
61 #if SDH_USE_VCC
62 #pragma pack(push,1) // for VCC (MS Visual Studio) we have to set the necessary 1 byte packing with this pragma
63 #endif
66 {
67  /*
68  * Unfortunately g++ 3.4.4 can NOT handle packed enums.
69  * Therefore we cannot use the eCommandCode type here
70  */
71  unsigned char cmd_code;
72  unsigned char nb_data_bytes;
73  unsigned char nb_valid_parameters;
74  union {
76  unsigned char parameter_bytes[ sizeof( float ) * eNUMBER_OF_ELEMENTS + sizeof(tCRCValue) ];
77  };
78 
83  sSDHBinaryRequest( eCommandCode command, double* value, bool use_crc16 );
84 
86  tCRCValue* CRC16() const
87  {
88  return (tCRCValue*) &(parameter_bytes[nb_data_bytes - sizeof( nb_valid_parameters ) - sizeof(tCRCValue)]);
89  }
90 
92  int GetNbBytesToSend() const
93  {
94  return sizeof( cmd_code ) + sizeof( nb_data_bytes ) + nb_data_bytes;
95  }
96 
97 } SDH__attribute__((packed));
98 
101 {
102  /*
103  * Unfortunately g++ 3.4.4 can NOT handle packed enums.
104  * Therefore we cannot use the eCommandCode and eReturnCode types here
105  */
106  unsigned char cmd_code;
107  unsigned char nb_data_bytes;
108  unsigned char nb_valid_parameters;
109  unsigned char status_code;
110  union {
112  unsigned char parameter_bytes[ sizeof( float ) * eNUMBER_OF_ELEMENTS + sizeof(tCRCValue) ];
113  };
114 
116  tCRCValue* CRC16() const
117  {
118  return (tCRCValue*) &(parameter_bytes[nb_data_bytes - sizeof( nb_valid_parameters ) - sizeof( status_code ) - sizeof(tCRCValue)]);
119  }
120 
122  void CheckCRC16() const;
123 
124 } SDH__attribute__((packed));
125 #if SDH_USE_VCC
126 #pragma pack(pop) // for VCC (MS Visual Studio) restore normal packing
127 #endif
128 
130 std::ostream& operator<<( std::ostream &stream, sSDHBinaryRequest const &request );
131 
133 std::ostream& operator<<( std::ostream &stream, sSDHBinaryResponse const &response );
134 
135 
137 
139 
140 //----------------------------------------------------------------------
141 // Global variables
142 //----------------------------------------------------------------------
143 
144 
145 //----------------------------------------------------------------------
146 // Function declarations
147 //----------------------------------------------------------------------
148 
149 
150 //----------------------------------------------------------------------
151 // Class declarations
152 //----------------------------------------------------------------------
153 
154 
155 sSDHBinaryRequest::sSDHBinaryRequest( eCommandCode command, double* value, bool use_crc16 )
156  :
157  cmd_code( (unsigned char) command ),
158  nb_data_bytes( sizeof( nb_valid_parameters ) ),
160 {
161  if ( value )
162  {
163  nb_data_bytes += sizeof( parameter );
164 
165  for ( int ai=0; ai<eNUMBER_OF_ELEMENTS; ai++ )
166  parameter[ ai ] = float( value[ai] );
167  }
168  if ( use_crc16 )
169  {
170  nb_data_bytes += 2;
171  cCRC_SDH checksum;
172  *CRC16() = checksum.AddBytes( (unsigned char*) &cmd_code,
173  GetNbBytesToSend() - sizeof( tCRCValue ) );
174  }
175 }
176 //-----------------------------------------------------------------
177 //-----------------------------------------------------------------
178 
180 {
181  cCRC_SDH checksum;
182  tCRCValue crc_calculated = checksum.AddBytes( (unsigned char*) &cmd_code,
183  sizeof( cmd_code ) + sizeof( nb_data_bytes ) + nb_data_bytes - sizeof( tCRCValue ) );
184  if ( crc_calculated != *CRC16() )
185  throw new cSDHErrorCommunication( cMsg( "CRC error in response expected 0x%04x but got 0x%04x", crc_calculated, *CRC16() ) );
186 }
187 //-----------------------------------------------------------------
188 //-----------------------------------------------------------------
189 
190 std::ostream & NS_SDH operator<<( std::ostream &stream, sSDHBinaryRequest const &request )
191 {
192  stream << "sSDHBinaryRequest:\n"
193  << " cmd_code=0x" << std::hex << std::setfill('0') << std::setw(2)<< int(request.cmd_code) << " (" << SDHCommandCodeToString( eCommandCode( request.cmd_code ) ) << ")\n"
194  << " nb_data_bytes=" << std::dec << int(request.nb_data_bytes) << "\n"
195  << " nb_valid_parameters=" << int(request.nb_valid_parameters) << "\n"
196  << " parameter=";
197  char const* sep = "";
198  for ( int i=0; i<request.nb_valid_parameters && i<eNUMBER_OF_ELEMENTS; i++ )
199  {
200  stream << sep << request.parameter[i];
201  sep = ",";
202  }
203  if ( request.nb_valid_parameters > eNUMBER_OF_ELEMENTS )
204  stream << sep << "... something is fishy here!";
205 
206  if ( (request.nb_data_bytes - sizeof( request.nb_valid_parameters )) % sizeof( float ) == sizeof( tCRCValue ) )
207  stream << "\n crc=0x" << std::hex << std::setfill('0') << std::setw(4) << *(request.CRC16()) << std::dec;
208  stream << "\n";
209  return stream;
210 }
211 //-----------------------------------------------------------------
212 
213 std::ostream & NS_SDH operator<<( std::ostream &stream, sSDHBinaryResponse const &response )
214 {
215  stream << "sSDHBinaryResponse:\n"
216  << " cmd_code=0x" << std::hex << std::setfill('0') << std::setw(2)<< int(response.cmd_code) << " (" << SDHCommandCodeToString( eCommandCode( response.cmd_code ) ) << ")\n"
217  << " nb_data_bytes=" << std::dec << int(response.nb_data_bytes) << "\n"
218  << " nb_valid_parameters=" << int(response.nb_valid_parameters) << "\n"
219  << " status_code=" << int(response.status_code) << " (" << SDHReturnCodeToString( eReturnCode( response.status_code ) ) << ")\n"
220  << " parameter=";
221  char const* sep = "";
222  for ( int i=0; i<response.nb_valid_parameters && i<eNUMBER_OF_ELEMENTS; i++ )
223  {
224  stream << sep << response.parameter[i];
225  sep = ",";
226  }
227  if ( response.nb_valid_parameters > eNUMBER_OF_ELEMENTS )
228  stream << sep << "... something is fishy here!";
229 
230  if ( (response.nb_data_bytes - sizeof( response.nb_valid_parameters ) - sizeof( response.status_code )) % sizeof( float ) == sizeof( tCRCValue ) )
231  stream << "\n crc=0x" << std::hex << std::setfill('0') << std::setw(4) << *(response.CRC16()) << std::dec;
232  stream << "\n";
233  return stream;
234 }
235 //-----------------------------------------------------------------
236 //-----------------------------------------------------------------
237 
238 cSDHSerial::cSDHSerial( int _debug_level )
239  :
240  // call base class constructors:
241  cSDHBase( _debug_level ),
242 
243  // init member objects:
244  com( NULL )
245 {
246  //---------------------
247  // type size checking
248  sSDHBinaryRequest request( eCommandCode(RC_OK), NULL, false ); // unused dummy variables, just used for checking offsets of members
249  sSDHBinaryResponse response;
250  /*
251  assert( sizeof( enum eCommandCodeEnum ) == 1 ); // fails when compiled with g++ v3.4.4!
252  assert( sizeof( eCommandCode ) == 1 ); // fails when compiled with g++ v3.4.4!
253  assert( sizeof( enum eReturnCodeEnum ) == 1 ); // fails when compiled with g++ v3.4.4!
254  assert( sizeof( eReturnCode ) == 1 ); // fails when compiled with g++ v3.4.4!
255  */
256  assert( sizeof( request.cmd_code ) == 1 );
257  assert( sizeof( request.nb_data_bytes ) == 1 );
258  assert( sizeof( request.nb_valid_parameters ) == 1 );
259  assert( ((unsigned char*) &(request.cmd_code) ) +1 == ((unsigned char*) &(request.nb_data_bytes) ) );
260  assert( ((unsigned char*) &(request.nb_data_bytes) ) +1 == ((unsigned char*) &(request.nb_valid_parameters) ) );
261  assert( ((unsigned char*) &(request.nb_valid_parameters) ) +1 == ((unsigned char*) &(request.parameter) ) );
262  assert( sizeof( response.cmd_code ) == 1 );
263  assert( sizeof( response.nb_data_bytes ) == 1 );
264  assert( sizeof( response.nb_valid_parameters ) == 1 );
265  assert( sizeof( response.status_code ) == 1 );
266  assert( ((unsigned char*) &(response.cmd_code) ) +1 == ((unsigned char*) &(response.nb_data_bytes) ) );
267  assert( ((unsigned char*) &(response.nb_data_bytes) ) +1 == ((unsigned char*) &(response.nb_valid_parameters) ) );
268  assert( ((unsigned char*) &(response.nb_valid_parameters) ) +1 == ((unsigned char*) &(response.status_code) ) );
269  assert( ((unsigned char*) &(response.status_code) ) +1 == ((unsigned char*) &(response.parameter) ) );
270  //---------------------
271 
272 
273  //---------------------
274  // Option handling:
275 
276  // use green as color for messages from cSDHSerial
277  cdbg.SetColor( "green" );
278  cdbg << "Debug messages of cSDHSerial are printed like this.\n";
279 
280  //---------------------
281  // initialize additional member variables:
282 
283  m_sequtime = 0.0; // !!!
284 
286 
287  EOL="\r\n";
288  //---------------------
289 }
290 //-----------------------------------------------------------------
291 
292 
294 {
295  com = _com;
296  assert( com != NULL );
297 
298  //---------------------
299  // open connection to SDH:
300 
301  nb_lines_to_ignore = 0;
302 
303  com->Open();
304  // the above call will succeed even if the hand is connected but off
305  //---------------------
306 
307 
308  //---------------------
309  // Clean up communication line. (To make sure that no previous
310  // communication that was received only partly by the SDH will
311  // lead to an error when sending the "ver" command below. This
312  // can happen if a PC program gets interrupted while in the
313  // middle of sending a command to the SDH. Then any new
314  // command for the SDH sent by the next PC program will
315  // confuse the SDH
316 
317  cSerialBase::cSetTimeoutTemporarily set_timeout_temporarily( com, 1.0 );
318  // previous timeout will be automatically restored when function is left (by return or exception)
319  try
320  {
321  com->write( " \r\n", 3 ); // empty command to terminate any potential partly received previous command
322  }
323  catch (cSDHErrorCommunication* e)
324  {
325  cdbg << "caught <" << *e << "> (ignored while cleaning up communication 1)\n";
326  delete e;
327  }
328 
329  try
330  {
331  // First try to read anything available.
332  // This is only necessary if the SDH with a debug firmware (like
333  // all v0.0.3.x releases) has been switched on recently and we are
334  // communicating via TCP (since the TCP stack on the SDH buffers the
335  // debug start messages forever).
336  // In all other cases this does no harm other than a small delay.
337  char dummy[1024];
338  dummy[0] = '\0';
339  int n = com->Read( dummy, 1024, 100000, true );
340  cdbg << "Read and ignored " << n << " bytes \"" << dummy << "\"\n"; cdbg.flush();
341  }
342  catch (cSDHErrorCommunication* e)
343  {
344  cdbg << "caught <" << *e << "> (ignored while cleaning up communication 2)\n";
345  delete e;
346  }
347  //---------------------
348 
349 
350  //---------------------
351  // to make sure that the SDH is connected:
352  // try to get the SDH firmware version with timeout
353  try
354  {
355  Send( "ver" );
356  }
357  catch (cSDHErrorCommunication* e)
358  {
359  cdbg << "caught <" << *e << ">\n";
360  //std::cerr << "SDHLibrary-CPP: cSDHSerial.Open(): Timeout while trying to get SDH firmware version\n Is the SDH really connected and powered?\n";
361 
362  Close(); // make sure this cSDHSerial object does not appear open in case of error
363 
364  cSDHErrorCommunication* e2 = new cSDHErrorCommunication( cMsg( "Could not connect to SDH firmware! Is the SDH really connected and powered? (Sending \"ver\" caused: %s)", e->what() ) );
365  delete e;
366 
367  throw e2;
368  }
369  //---------------------
370 }
371 //-----------------------------------------------------------------
372 
373 
375 {
376  com->Close();
377 }
378 //-----------------------------------------------------------------
379 
380 
381 bool cSDHSerial::IsOpen( void )
382 {
383  return com != NULL && com->IsOpen();
384 }
385 //----------------------------------------------------------------------
386 
387 
388 
389 void cSDHSerial::Send( char const* s, int nb_lines, int nb_lines_total, int max_retries )
390 //void cSDHSerial::Send( char const* s, int nb_lines, int nb_lines_total )
391 {
392  int retries = max_retries; // retry sending at most this many times
393  while (retries > 0)
394  {
395  try
396  {
397  //---------------------
398  // first read all lines to ignore (replies of previous commands)
399  while ( nb_lines_to_ignore > 0 )
400  {
401  com->readline( reply.NextLine(), reply.eMAX_CHARS, "\n" );
402  nb_lines_to_ignore -= 1;
403  cdbg << "ignoring line <" << reply.CurrentLine() << ">\n";
404 
405  reply.Reset();
406  }
407  //---------------------
408 
409 
411  reply.Reset();
412 
413  //---------------------
414  // send new command to SDH
415  cdbg << "cSDHSerial::Send: sending command '" << s << "' to SDH\n";
416  cdbg << " nb_lines=" << nb_lines << " nb_lines_total=" << nb_lines_total << " nb_lines_to_ignore=" << nb_lines_to_ignore << "\n";
417 
418  com->write( s );
419  com->write( EOL );
420 
421  cdbg << "sent command\n";
422  //---------------------
423 
424  //---------------------
425  // read reply if requested
426  while (nb_lines == All || nb_lines > 0)
427  {
428 
429  //---------------------
430  // now read requested reply lines of current command
431  com->readline( reply.NextLine(), reply.eMAX_CHARS, "\n" );
432  cdbg << "read line '" << reply.CurrentLine() << "'\n";
433  if (nb_lines != All)
434  {
435  nb_lines -= 1;
436  }
437  if (nb_lines_total != All)
438  {
439  nb_lines_total -= 1;
440  }
441 
442  // remove beginning and trailing "\r\n" of the line just read
443 
444  // remove beginning "\r\n"-s:
445  char* startp = reply.CurrentLine();
446 
447  startp[ reply.eMAX_CHARS ] = '\0';
448  // strchr will also find the matching \0 char!
449  while ( *startp != '\0' && strchr( "\r\n", *startp ) != NULL )
450  {
451  startp += 1;
452  }
453  if ( startp != reply.CurrentLine() )
454  {
455  memmove( reply.CurrentLine(), startp, strlen( startp ) );
456  }
457 
458  // remove trailing "\r\n"-s:
459  char* endp = reply.CurrentLine() + strlen( reply.CurrentLine() )-1;
460  while ( endp >= reply.CurrentLine() && strchr( "\r\n", *endp ) != NULL )
461  {
462  *endp = '\0';
463  endp -= 1;
464  }
465 
466  cdbg << "appending cleaned up line '" << reply.CurrentLine() << "'\n";
467  if (reply.CurrentLine()[0] != '@')
468  {
469  break;
470  }
471  //---------------------
472  }
473 
474  //---------------------
475  // remember if there are more lines to be ignored next time
476  if (nb_lines_total != All)
477  {
478  nb_lines_to_ignore = nb_lines_total;
479  }
480  cdbg << nb_lines_to_ignore <<" lines remain to be ignored\n";
481  //---------------------
482 
483  //---------------------
484  // set state if possible
485  if (nb_lines_to_ignore == 0)
486  {
488  }
489  //---------------------
490 
491  // finished, so no more retries needed
492  retries = 0;
493 
494  } // end of try
495  catch (cSDHErrorCommunication* e)
496  {
497  // some communication error occured, so retry:
498  retries -= 1;
499  if (retries <= 0)
500  {
501  cdbg << "Retried sending, but still got errors from SDH!\n";
502  // rethrow e:
503  throw;
504  }
505  cdbg << "ignoring cSDHErrorCommunication: " << *e << "\n";
506 
507  // resync first:
508  Sync();
509  //now start over again
510 
511  } // end of catch
512  } // end of while (retries > 0)
513  cdbg << "got reply: " << reply;
514 }
515 //-----------------------------------------------------------------
516 
517 
519 {
520  //---------------------
521  // check first char of last line of lines
522 
523  if (reply[-1][0] == 'E')
524  {
525  // it is an error message:
526  sscanf( reply[-1] +1, "%d", (int*) (&firmware_state) );
527  cdbg << "got error reply '" << reply[-1] << "' = " << firmware_state << " = " << firmware_error_codes[firmware_state] << "\n";
528  throw new cSDHErrorCommunication( cMsg( "SDH firmware reports error %d = %s", firmware_state, firmware_error_codes[firmware_state]) );
529  }
530 
531  else if (reply[-1][0] == '@')
532  {
533  // it is an debug message (should not happen):
534  throw new cSDHErrorCommunication( cMsg( "Cannot get SDH firmware state from lines" ) );
535  }
536 
537  else
538  {
539  // it is a normal "command completed" line:
541  }
542 }
543 //-----------------------------------------------------------------
544 
545 
546 double cSDHSerial::GetDuration( char* line )
547 {
548  char* pattern_at = strstr( line, "=" );
549 
550  if (pattern_at == NULL)
551  throw new cSDHErrorCommunication( cMsg( "Could not extract duration from lines '%s'", line ) );
552 
553  double duration;
554  sscanf( pattern_at, "=%lf", &duration );
555 
556  cdbg << "extracted duration " << duration << "\n";
557  return duration;
558 }
559 //-----------------------------------------------------------------
560 
561 
563 {
564  // Actual input/output for the command looks like:
565  //--
566  // get_duration
567  // GET_DURATION=4.51
568  //
569  // before firmware 0.0.3.1 output input/output for the command looks like:
570  // get_duration
571  // @max distance=45.06, T=4.51s, num_points: 451
572  // GET_DURATION=4.51
573 
574  //---------------------
575  // settings for sequ/non-sequ:
576  int nb_lines_total = 1;
577  int nb_lines = nb_lines_total;
578  //---------------------
579 
580  //---------------------
581  // send command and parse reply
582  Send( "get_duration", nb_lines, nb_lines_total );
583  double T = GetDuration( reply[0] );
584  //---------------------
585 
586  return T;
587 }
588 //----------------------------------------------------------------------
589 
590 
592 {
593  // first read all lines to ignore (replies of previous commands)
594  while ( nb_lines_to_ignore > 0 )
595  {
596  com->readline( reply.NextLine(), reply.eMAX_CHARS, "\n" );
597  nb_lines_to_ignore -= 1;
598  cdbg << "syncing: ignoring line <" << reply.CurrentLine() << ">\n";
599 
600  reply.Reset();
601  }
602  if (reply.Length() > 0)
604 }
605 //-----------------------------------------------------------------
606 
607 void cSDHSerial::BinarySync( double timeout_s )
608 {
609  // read and ignore all bytes available within timeout_s
610  char* buffer[ 256 ];
611  int nb_bytes_received = com->Read( buffer, 256, long(timeout_s*1E6), false );
612  cdbg << "cSDHSerial::BinarySync: ignoring " << nb_bytes_received << " bytes\n";
613 }
614 //-----------------------------------------------------------------
615 
617 {
618  // read all lines until timeout
619  while (1)
620  {
621  try
622  {
623  com->readline( reply.NextLine(), reply.eMAX_CHARS, "\n", true );
624  cdbg << "syncing unknown: ignoring line <" << reply.CurrentLine() << ">\n";
625 
626  reply.Reset();
627  }
628  catch (cSerialBaseException* e)
629  {
630  cdbg << __FILE__ << ":" << __LINE__ << " ignoring cSerialBaseException: " << *e << "\n";
631  delete e;
632  break;
633  }
634  }
635  if (reply.Length() > 0)
637 }
638 //-----------------------------------------------------------------
639 
640 
641 cSimpleVector cSDHSerial::AxisCommand( char const* command, int axis, double* value )
642 {
643 #if SDH_USE_VCC
644  int cutoff = static_cast<int>(strlen(command)) + 1;
645 #else
646  int cutoff = strlen( command ) + 1;
647 #endif
648  int cutoff1 = cutoff +3;
649  char cmd[ cSimpleStringList::eMAX_CHARS ];
650  int retries = 3; // retry sending at most this many times
651  while (retries > 0)
652  {
653  try
654  {
655  if (axis == All && value == NULL)
656  {
657  Send( command );
658  return cSimpleVector( NUMBER_OF_AXES, reply[0]+cutoff );
659  }
660 
661  if (axis != All)
662  {
663  CheckIndex( axis, NUMBER_OF_AXES, "axis" );
664  if (value == NULL)
665  {
666 #if SDH_USE_VCC
667  _snprintf_s( cmd, cSimpleStringList::eMAX_CHARS, cSimpleStringList::eMAX_CHARS-1, "%s(%d)", command, axis );
668 #else
669  snprintf( cmd, cSimpleStringList::eMAX_CHARS-1, "%s(%d)", command, axis );
670 #endif
671  Send( cmd );
672  return cSimpleVector( 1, axis, reply[0]+cutoff1 );
673  }
674 
675 #if SDH_USE_VCC
676  _snprintf_s( cmd, cSimpleStringList::eMAX_CHARS, cSimpleStringList::eMAX_CHARS-1, "%s(%d)=%12.3f", command, axis, *value );
677 #else
678  snprintf( cmd, cSimpleStringList::eMAX_CHARS-1, "%s(%d)=%12.3f", command, axis, *value );
679 #endif
680  Send( cmd );
681  return cSimpleVector( 1, axis, reply[0]+cutoff1 );
682  }
683 
684  if (axis == All)
685  {
686  Send( cMsg( "%s=%f,%f,%f,%f,%f,%f,%f", command, value[0], value[1], value[2], value[3], value[4], value[5], value[6] ).c_str() );
687  return cSimpleVector( NUMBER_OF_AXES, reply[0] + cutoff );
688  }
689 
690  throw new cSDHErrorInvalidParameter( cMsg( "Invalid parameter in AxisCommand( command=%s, axis=%d, value=%f )'", command, axis, *value ) );
691 
692  } // end of try
693  //catch (cSimpleVectorException* e)
694  catch (cSDHLibraryException* e)
695  {
696  // these errors seem to happen on linux only (not cygwin) where a reply can be partly received:
697 
698  // assume some communication error occured, so retry:
699  retries -= 1;
700  if (retries > 0)
701  //cdbg << __FILE__ << ":" << __LINE__ << " ignoring cSimpleVectorException: " << *e << "\n";
702  cdbg << __FILE__ << ":" << __LINE__ << " ignoring cSDHLibraryException: " << *e << " (retrying)\n";
703  else
704  {
705  cdbg << __FILE__ << ":" << __LINE__ << " retried but giving up now\n";
706  // rethrow e:
707  throw;
708  }
709 
710  // resync first:
711  Sync();
712  //now start over again
713 
714  delete e;
715 
716  } // end of catch
717 
718  } // end of while (retries > 0)
719 
720  cdbg << "Retried sending, but still didnt work!\n";
721  throw new cSDHLibraryException( "cSDHLibraryException", cMsg( "Unknown error while retrying" ) );
722 }
723 //----------------------------------------------------------------------
724 
725 cSimpleVector cSDHSerial::BinaryAxisCommand( eCommandCode command, int axis, double* value )
726 {
727  bool use_crc16 = com->UseCRC16();
728  sSDHBinaryRequest request( command, value, use_crc16 );
729  sSDHBinaryResponse response;
730 
731  int nb_bytes_to_receive =
732  sizeof( response.cmd_code )
733  + sizeof( response.nb_data_bytes )
734  + sizeof( response.nb_valid_parameters )
735  + sizeof( response.status_code )
736  + sizeof( request.parameter )
737  + ((use_crc16)? sizeof( tCRCValue ) : 0); // ANOTE: this will fail if the response unexpectedly contains a CRC (But this should not happen)
738 
739  int retries = 3; // retry sending at most this many times
740  while (retries > 0)
741  {
742  try
743  {
744  if ( cdbg.GetFlag() )
745  cdbg << "cSDHSerial::BinaryAxisCommand: sending '" << request << "' to SDH\n";
746 
747  com->write( (char*)(&request), request.GetNbBytesToSend() );
748 
749  int nb_bytes_received = com->Read( &response, nb_bytes_to_receive, long( com->GetTimeout() * 1E6 ), false );
750 
751  if ( nb_bytes_received != nb_bytes_to_receive )
752  throw new cSDHErrorCommunication( cMsg( "Received only %d/%d binary bytes", nb_bytes_received, nb_bytes_to_receive ) );
753 
754  if ( cdbg.GetFlag() )
755  cdbg << "cSDHSerial::BinaryAxisCommand: received '" << response << "' from SDH\n";
756 
757  if ( use_crc16 )
758  response.CheckCRC16();
759 
761  if ( response.status_code != RC_OK )
762  throw new cSDHErrorCommunication( cMsg( "Received error code 0x%02x (%s) from SDH", response.status_code, SDHReturnCodeToString( eReturnCode( response.status_code ) ) ) );
763 
764  if ( axis == All )
765  return cSimpleVector( NUMBER_OF_AXES, 0, response.parameter );
766  else
767  return cSimpleVector( 1, axis, &(response.parameter[ axis ]) );
768 
769  } // end of try
770  catch (cSDHLibraryException* e)
771  {
772  // these errors seem to happen on linux only (not cygwin) where a reply can be partly received:
773 
774  // assume some communication error occured, so retry:
775  retries -= 1;
776  if (retries > 0)
777  cdbg << __FILE__ << ":" << __LINE__ << " ignoring cSDHLibraryException: " << *e << " (retrying)\n";
778  else
779  {
780  cdbg << __FILE__ << ":" << __LINE__ << " retried but giving up now\n";
781  // rethrow e:
782  throw;
783  }
784 
785  // resync first:
786  BinarySync();
787  //now start over again
788 
789  delete e;
790 
791  } // end of catch
792 
793  } // end of while (retries > 0)
794 
795  cdbg << "Retried sending, but still didnt work!\n";
796  throw new cSDHLibraryException( "cSDHLibraryException", cMsg( "Unknown error while retrying" ) );
797 }
798 //----------------------------------------------------------------------
799 
800 cSimpleVector cSDHSerial::pid( int axis, double* p, double* i, double* d )
801 {
802  CheckIndex( axis, NUMBER_OF_AXES, "axis" );
803 
804  if (p == NULL && i == NULL && d == NULL)
805  {
806  Send( cMsg( "pid(%d)", axis ).c_str() );
807  return cSimpleVector( 3, reply[0] + 7 );
808  }
809  if (p != NULL && i != NULL && d != NULL)
810  {
811  Send( cMsg( "pid(%d)=%f,%f,%f", axis, *p, *i, *d ).c_str() );
812  return cSimpleVector( 3, reply[0]+7 );
813  }
814 
815  throw new cSDHErrorInvalidParameter( cMsg( "Invalid parameter in call' pid(axis=%d, p=%f, i=%f, d=%f )'", axis, *p, *i, *d ) );
816 }
817 //-----------------------------------------------------------------
818 
819 
820 cSimpleVector cSDHSerial::kv( int axis, double* kv )
821 {
822  if (axis == All)
823  {
824  // SDH firmware cannot handle setting / getting all values at once
825  // so emulate that
826 
827  // get/set all kv:
828 
829  cSimpleVector rv;
830 
831  for ( int i=0; i < NUMBER_OF_AXES; i++ )
832  {
833  cSimpleVector rvi;
834 
835  if (kv == NULL)
836  rvi = AxisCommand( "kv", i, NULL );
837  else
838  rvi = AxisCommand( "kv", i, &(kv[i]) );
839  rv[i] = rvi[i];
840  }
841  return rv;
842  }
843  else
844  {
845  return AxisCommand( "kv", axis, kv );
846  }
847 }
848 //-----------------------------------------------------------------
849 
850 
851 cSimpleVector cSDHSerial::ilim( int axis, double* limit )
852 {
853 #if SDH_USE_BINARY_COMMUNICATION
854  return BinaryAxisCommand( CMDC_ILIM, axis, limit );
855 #else
856  return AxisCommand( "ilim", axis, limit );
857 #endif
858 }
859 //-----------------------------------------------------------------
860 
861 
862 cSimpleVector cSDHSerial::power( int axis, double* flag )
863 {
864  // Actual input/output for the command looks like:
865  //--
866  // power=0,0,0,0,0,0,0
867  // POWER=0,0,0,0,0,0,0
868 
869 #if SDH_USE_BINARY_COMMUNICATION
870  return BinaryAxisCommand( CMDC_POWER, axis, flag );
871 #else
872  return AxisCommand( "power", axis, flag );
873 #endif
874 }
875 //----------------------------------------------------------------------
876 
877 
878 void cSDHSerial::demo( bool onoff )
879 {
880  Send( cMsg( "demo=%d", int( onoff ) ).c_str() );
881 }
882 //-----------------------------------------------------------------
883 
884 
885 int cSDHSerial::property( char const* propname, int value )
886 {
887  Send( cMsg( "%s=%d", propname, value ).c_str() );
888  int v;
889  sscanf( reply[0] + strlen(propname), "%d", &v );
890  return v;
891 }
892 //-----------------------------------------------------------------
893 
894 
895 int cSDHSerial::user_errors( int value )
896 {
897  return property( "user_errors", value );
898 }
899 //-----------------------------------------------------------------
900 
901 
902 int cSDHSerial::terminal( int value )
903 {
904  return property( "terminal", value );
905 }
906 //-----------------------------------------------------------------
907 
908 
909 int cSDHSerial::debug( int value )
910 {
911  return property( "debug", value );
912 }
913 //-----------------------------------------------------------------
914 
915 
916 cSimpleVector cSDHSerial::v( int axis, double* velocity )
917 {
918 #if SDH_USE_BINARY_COMMUNICATION
919  return BinaryAxisCommand( CMDC_V, axis, velocity );
920 #else
921  return AxisCommand( "v", axis, velocity );
922 #endif
923 }
924 //-----------------------------------------------------------------
925 
926 
927 cSimpleVector cSDHSerial::tvav( int axis, double* velocity )
928 {
929 #if SDH_USE_BINARY_COMMUNICATION
930  return BinaryAxisCommand( CMDC_TVAV, axis, velocity );
931 #else
932  return AxisCommand( "tvav", axis, velocity );
933 #endif
934 }
935 //-----------------------------------------------------------------
936 
937 
938 cSimpleVector cSDHSerial::vlim( int axis, double* /*dummy*/ )
939 {
940  return AxisCommand( "vlim", axis, NULL );
941 }
942 //-----------------------------------------------------------------
943 
944 
945 cSimpleVector cSDHSerial::alim( int axis, double* /*dummy*/ )
946 {
947  return AxisCommand( "alim", axis, NULL );
948 }
949 //-----------------------------------------------------------------
950 
951 
952 cSimpleVector cSDHSerial::a( int axis, double* acceleration )
953 {
954 #if SDH_USE_BINARY_COMMUNICATION
955  return BinaryAxisCommand( CMDC_A, axis, acceleration );
956 #else
957  return AxisCommand( "a", axis, acceleration );
958 #endif
959 }
960 //-----------------------------------------------------------------
961 
962 
963 cSimpleVector cSDHSerial::p( int axis, double* angle )
964 {
965 #if SDH_USE_BINARY_COMMUNICATION
966  return BinaryAxisCommand( CMDC_P, axis, angle );
967 #else
968  return AxisCommand( "p", axis, angle );
969 #endif
970 }
971 //-----------------------------------------------------------------
972 
973 
974 cSimpleVector cSDHSerial::tpap( int axis, double* angle )
975 {
976 #if SDH_USE_BINARY_COMMUNICATION
977  return BinaryAxisCommand( CMDC_TPAP, axis, angle );
978 #else
979  return AxisCommand( "tpap", axis, angle );
980 #endif
981 }
982 //-----------------------------------------------------------------
983 
984 
985 double cSDHSerial::m( bool sequ )
986 {
987  // Actual input/output for the command looks like:
988  //--
989  // m
990  // M=4.51
991  //
992  // Before Firmware 0.0.3.1 input/output for the command looked like:
993  // --
994  // m
995  // @Enabling all axis
996  // @max distance=45.06, T=4.51s, num_points: 451
997  // m
998 
999  //---------------------
1000  // settings for sequential/non-sequential:
1001  int nb_lines_total = 1;
1002  int nb_lines = nb_lines_total;
1003  //---------------------
1004 
1005  //---------------------
1006  // send command and parse reply
1007  Send( "m", nb_lines, nb_lines_total );
1008 
1009 
1010  double T = GetDuration( reply[0] );
1011  //---------------------
1012 
1013  // the SDH firmware does NOT produce an output after the command has finished
1014  if (sequ)
1015  // so just wait as long as the movement will take
1016  SleepSec( T + m_sequtime );
1017 
1018  return T;
1019 }
1020 //-----------------------------------------------------------------
1021 
1022 
1023 void cSDHSerial::stop( void )
1024 {
1025  Send( "stop" );
1026 }
1027 //----------------------------------------------------------------------
1028 
1029 
1031 {
1032  char cmd[5];
1033  if ( velocity_profile < 0 )
1034  sprintf( cmd, "vp" );
1035  else if ( velocity_profile < eVP_DIMENSION )
1036  sprintf( cmd, "vp=%d", velocity_profile );
1037  else
1038  throw new cSDHErrorInvalidParameter( cMsg( "Invalid parameter in vp( velocity_profile=%d )'", velocity_profile ) );
1039 
1040  Send( cmd );
1041 
1042  int new_vp;
1043  sscanf( reply[0]+3, "%d", &new_vp );
1044  return (eVelocityProfile) new_vp;
1045 }
1046 //----------------------------------------------------------------------
1047 
1048 
1050 {
1051  char cmd[6];
1052  if ( controller == eCT_INVALID )
1053  sprintf( cmd, "con" );
1054  else if ( controller < eCT_DIMENSION )
1055  sprintf( cmd, "con=%d", controller );
1056  else
1057  throw new cSDHErrorInvalidParameter( cMsg( "Invalid parameter in con( controller=%d )'", controller ) );
1058 
1059  Send( cmd );
1060 
1061  int new_con;
1062  sscanf( reply[0]+4, "%d", &new_con );
1063  return (eControllerType) new_con;
1064 }
1065 //----------------------------------------------------------------------
1066 
1067 
1068 cSimpleVector cSDHSerial::pos( int axis, double* /*dummy*/ )
1069 {
1070 #if SDH_USE_BINARY_COMMUNICATION
1071  return BinaryAxisCommand( CMDC_POS, axis );
1072 #else
1073  return AxisCommand( "pos", axis );
1074 #endif
1075 }
1076 //----------------------------------------------------------------------
1077 
1078 cSimpleVector cSDHSerial::pos_save( int axis, double* value )
1079 {
1080  return AxisCommand( "pos_save", axis, value );
1081 }
1082 //----------------------------------------------------------------------
1083 
1084 
1085 cSimpleVector cSDHSerial::ref( int axis, double* value )
1086 {
1087  // referncing is done with 25 deg/s thus it may take up to 180/25 = 7.2s plus safety time = 10s
1088  cSerialBase::cSetTimeoutTemporarily set_timeout_temporarily( com, 10.0 );
1089  // previous timeout will be automatically restored when function is left (by return or exception)
1090 
1091  return AxisCommand( "ref", axis, value );
1092 }
1093 //----------------------------------------------------------------------
1094 
1095 
1096 cSimpleVector cSDHSerial::vel( int axis, double* /*dummy*/ )
1097 {
1098 #if SDH_USE_BINARY_COMMUNICATION
1099  return BinaryAxisCommand( CMDC_VEL, axis );
1100 #else
1101  return AxisCommand( "vel", axis );
1102 #endif
1103 }
1104 //----------------------------------------------------------------------
1105 
1106 
1107 cSimpleVector cSDHSerial::rvel( int axis, double* /*dummy*/ )
1108 {
1109 #if SDH_USE_BINARY_COMMUNICATION
1110  return BinaryAxisCommand( CMDC_RVEL, axis );
1111 #else
1112  return AxisCommand( "rvel", axis );
1113 #endif
1114 }
1115 //----------------------------------------------------------------------
1116 
1117 
1118 cSimpleVector cSDHSerial::state( int axis, double* /*dummy*/ )
1119 {
1120 #if SDH_USE_BINARY_COMMUNICATION
1121  return BinaryAxisCommand( CMDC_STATE, axis );
1122 #else
1123  return AxisCommand( "state", axis );
1124 #endif
1125 }
1126 //-----------------------------------------------------------------
1127 
1128 
1130 {
1131  cSimpleVector rv;
1132 
1133  Send( "temp" );
1134 
1135  sscanf( reply[0] + 5, "%lf,%lf,%lf,%lf,%lf,%lf,%lf", &(rv[0]), &(rv[1]), &(rv[2]), &(rv[3]), &(rv[4]), &(rv[5]), &(rv[6]) );
1136  return rv;
1137 }
1138 //-----------------------------------------------------------------
1139 
1140 
1142 {
1143  cSimpleVector dummy;
1144  cSimpleVector rv;
1145 
1146  Send( "temp" );
1147 
1148  sscanf( reply[0] + 5, "%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",
1149  &(dummy[0]), &(dummy[1]), &(dummy[2]), &(dummy[3]), &(dummy[4]), &(dummy[5]), &(dummy[6]),
1150  &(rv[0]), &(rv[1]) );
1151  return rv;
1152 }
1153 //-----------------------------------------------------------------
1154 
1155 
1156 char* cSDHSerial::ver( void )
1157 {
1158  Send( "ver" );
1159  return reply[0] + 4;
1160 }
1161 //-----------------------------------------------------------------
1162 
1163 
1165 {
1166  Send( "ver_date" );
1167  return reply[0] + 9;
1168 }
1169 //-----------------------------------------------------------------
1170 
1171 
1172 char* cSDHSerial::id( void )
1173 {
1174  Send( "id" );
1175  return reply[0] + 3;
1176 }
1177 //-----------------------------------------------------------------
1178 
1179 
1180 char* cSDHSerial::sn( void )
1181 {
1182  Send( "sn" );
1183  return reply[0] + 3;
1184 }
1185 //-----------------------------------------------------------------
1186 
1187 
1188 char* cSDHSerial::soc( void )
1189 {
1190  Send( "soc" );
1191  return reply[0] + 4;
1192 }
1193 //-----------------------------------------------------------------
1194 
1195 
1197 {
1198  Send( "soc_date" );
1199  return reply[0] + 9;
1200 }
1201 //-----------------------------------------------------------------
1202 
1203 
1205 {
1206  Send( "numaxis" );
1208  int numaxis;
1209  sscanf( reply[0]+8, "%d", &numaxis );
1210  return numaxis;
1211 }
1212 //----------------------------------------------------------------------
1213 
1214 
1215 cSimpleVector cSDHSerial::igrip( int axis, double* limit )
1216 {
1217  return AxisCommand( "igrip", axis, limit );
1218 }
1219 //-----------------------------------------------------------------
1220 
1221 
1222 cSimpleVector cSDHSerial::ihold( int axis, double* limit )
1223 {
1224  return AxisCommand( "ihold", axis, limit );
1225 }
1226 //-----------------------------------------------------------------
1227 
1228 
1229 double cSDHSerial::selgrip( eGraspId grip, bool /*sequ*/ )
1230 {
1231  // Actual input/output for the command looks like:
1232  //--
1233  // selgrip=1
1234  // SELGRIP=0.0,1
1235  //
1236  // Before firmware 0.0.3.1 actual input/output for the command looked like:
1237  //--
1238  // selgrip=1
1239  // NO LONGER SENT! @Krit prox angle -0.00
1240  // NO LONGER SENT! @Joint finger 1 proximal (-34.72 deg) is not critical.
1241  // NO LONGER SENT! @Joint finger 2 proximal (-34.54 deg) is not critical.
1242  // NO LONGER SENT! @Joint finger 3 proximal (-35.15 deg) is not critical.
1243  // @Enabling all axis
1244  // @Setting current limit to @1.0 @0.5 @0.5 @0.5 @0.5 @0.5 @0.5 @
1245  // @max distance=0.00, T=0.00s, num_points: 1
1246  // @max distance=0.00, T=0.00s, num_points: 1
1247  // @Setting current limit to @0.1 @0.2 @0.2 @0.2 @0.2 @0.2 @0.2 @
1248  // @Disabling axis 0
1249  // SELGRIP=1
1250 
1251  CheckIndex( grip, eGID_DIMENSION, "grip" );
1252 
1253  //---------------------
1254  // ensure sin square velocity profile is used:
1255  vp( eVP_SIN_SQUARE );
1256  //---------------------
1257 
1258  //---------------------
1259  // settings for sequential/non-sequential:
1260  int nb_lines_total = 1;
1261  int nb_lines = nb_lines_total;
1262  //---------------------
1263 
1264  //---------------------
1265  // send command and parse reply
1266  Send( cMsg( "selgrip=%d", grip).c_str(), nb_lines, nb_lines_total );
1267 
1268  double T;
1269  T = GetDuration( reply[0] );
1270  //---------------------
1271 
1272  return T;
1273 }
1274 //-----------------------------------------------------------------
1275 
1276 
1277 double cSDHSerial::grip( double close, double velocity, bool /*sequ*/ )
1278 {
1279  // Actual input/output for the command looks like:
1280  //--
1281  // grip=0.1,40
1282  // GRIP=0.42,0.1
1283  //
1284  // Before firmware 0.0.3.1 actual input/output for the command looked like:
1285  //--
1286  // grip=0.1,40
1287  // no longer sent @Grip vector is: @0.0 @-66.8 @66.8 @-66.8 @66.8 @-66.8 @66.8 @
1288  // @Enabling finger axis
1289  // @Setting current limit to @1.0 @0.5 @0.5 @0.5 @0.5 @0.5 @0.5 @
1290  // @max distance=8.31, T=0.42s, num_points: 42
1291  // @Setting current limit to @0.1 @0.2 @0.2 @0.2 @0.2 @0.2 @0.2 @
1292  // GRIP=0.1
1293 
1294  CheckRange( close, 0.0, 1.0, "close ratio" );
1295  CheckRange( velocity, 0.0+eps, 100.0, "velocity" );
1296 
1297  //---------------------
1298  // ensure sin square velocity profile is used:
1299  vp( eVP_SIN_SQUARE );
1300  //---------------------
1301 
1302  //---------------------
1303  // settings for sequential/non-sequential:
1304  int nb_lines_total = 1;
1305  int nb_lines = nb_lines_total;
1306  //---------------------
1307 
1308  //---------------------
1309  // send command and parse reply
1310  char cmd[] = "grip=CCCCCCCCCCCCCCC,VVVVVVVVVVVVVVV";
1311  sprintf( cmd, "grip=%f,%f", close, velocity );
1312  Send( cmd, nb_lines, nb_lines_total );
1313 
1314  double T = GetDuration( reply[0] );
1315  //---------------------
1316 
1317  return T;
1318 }
1319 //----------------------------------------------------------------------
1320 
1321 
1322 //======================================================================
1323 /*
1324  Here are some settings for the emacs/xemacs editor (and can be safely ignored):
1325  (e.g. to explicitely set C++ mode for *.h header files)
1326 
1327  Local Variables:
1328  mode:C++
1329  mode:ELSE
1330  End:
1331 */
1332 //======================================================================
data structure with binary data for response from SDH to PC
Definition: sdhserial.cpp:100
A meta-value that means "access all possible values".
Definition: sdhbase.h:103
void Reset()
reset list
CMDC_STATE
float parameter[eNUMBER_OF_ELEMENTS]
Definition: sdhserial.cpp:75
static char const * firmware_error_codes[]
A mapping from eErrorCode error code enums to strings with human readable error messages.
Definition: sdhbase.h:285
sin square velocity profile
Definition: sdhbase.h:194
The base class to control the SCHUNK Dexterous Hand.
Definition: sdhbase.h:97
void CheckIndex(int index, int maxindex, char const *name="")
Check if index is in [0 .. maxindex-1] or All. Throw a cSDHErrorInvalidParameter exception if not...
Definition: sdhbase.cpp:169
tCRCValue * CRC16() const
return a ptr to the CRC value in parameter_bytes, assuming that nb_data_bytes is correct (including t...
Definition: sdhserial.cpp:116
unsigned char nb_data_bytes
Definition: sdhserial.cpp:107
cSimpleVector temp(void)
Definition: sdhserial.cpp:1129
void SetColor(char const *color)
Definition: dbg.h:170
int GetNbBytesToSend() const
return the total number of bytes to send
Definition: sdhserial.cpp:92
eGraspId
The enum values of the known grasps.
Definition: sdhbase.h:162
char * CurrentLine()
Return the current line.
CMDC_POWER
virtual double GetTimeout()
get the timeout for next readline() calls (negative value means: no timeout, wait for ever) ...
Definition: serialbase.h:157
void CheckCRC16() const
check the CRC value in parameter_bytes. Throw an exception if check fails
Definition: sdhserial.cpp:179
enum eReturnCodeEnum eReturnCode
typedef for eCommandCodeEnum, see there
int nb_lines_to_ignore
number of remaining reply lines of a previous (non-sequential) command
Definition: sdhserial.h:115
cSimpleVector pos(int axis=All, double *dummy=NULL)
Definition: sdhserial.cpp:1068
CMDC_POS
cSimpleVector v(int axis=All, double *velocity=NULL)
Definition: sdhserial.cpp:916
CMDC_TPAP
Endmarker and dimension.
Definition: sdhbase.h:186
USING_NAMESPACE_SDH char const *NS_SDH SDHCommandCodeToString(eCommandCode cc)
Definition: sdh_codes.cpp:64
A simple vector implementation.
Definition: simplevector.h:91
void demo(bool onoff)
Definition: sdhserial.cpp:878
cSimpleVector BinaryAxisCommand(eCommandCode command, int axis=All, double *value=NULL)
Definition: sdhserial.cpp:725
char * soc(void)
Definition: sdhserial.cpp:1188
#define NULL
Definition: getopt1.c:56
void CheckCRC16() const
check the CRC value in parameter_bytes. Throw an exception if check fails
Endmarker and dimension.
Definition: sdhbase.h:171
int terminal(int value)
Definition: sdhserial.cpp:902
CMDC_RVEL
char * ver_date(void)
Definition: sdhserial.cpp:1164
CMDC_VEL
unsigned char nb_valid_parameters
Definition: sdhserial.cpp:73
NAMESPACE_SDH_START typedef UInt16 tCRCValue
the data type used to calculate and exchange CRC values with DSACON32m (16 bit integer) ...
Definition: crc.h:54
cSimpleVector vel(int axis=All, double *dummy=NULL)
Definition: sdhserial.cpp:1096
double m(bool sequ)
Definition: sdhserial.cpp:985
cSimpleVector ref(int axis=All, double *value=NULL)
Definition: sdhserial.cpp:1085
char const * EOL
String to use as "End Of Line" marker when sending to SDH.
Definition: sdhserial.h:105
This file contains interface to cCRC, a class to handle CRC calculation.
char const *NS_SDH SDHReturnCodeToString(eReturnCode rc)
Definition: sdh_codes.cpp:124
cSimpleVector tvav(int axis=All, double *velocity=NULL)
Definition: sdhserial.cpp:927
virtual bool IsOpen(void)=0
Return true if communication channel is open.
void Open(cSerialBase *_com)
Definition: sdhserial.cpp:293
CMDC_TVAV
cSimpleVector ihold(int axis=All, double *limit=NULL)
Definition: sdhserial.cpp:1222
This file contains function to convert the binary command codes of the SDH. To use this from a non gc...
cSimpleVector temp_electronics(void)
Definition: sdhserial.cpp:1141
cSimpleVector a(int axis=All, double *acceleration=NULL)
Definition: sdhserial.cpp:952
float parameter[eNUMBER_OF_ELEMENTS]
Definition: sdhserial.cpp:111
cSimpleVector vlim(int axis=All, double *dummy=NULL)
Definition: sdhserial.cpp:938
void BinarySync(double timeout_s=0.5)
Definition: sdhserial.cpp:607
void SleepSec(double t)
Definition: util.cpp:155
eVelocityProfile
An enum for all possible SDH internal velocity profile types.
Definition: sdhbase.h:191
char * soc_date(void)
Definition: sdhserial.cpp:1196
double selgrip(eGraspId grip, bool sequ)
Definition: sdhserial.cpp:1229
eErrorCode firmware_state
the last known state of the SDH firmware
Definition: sdhbase.h:309
eControllerType con(eControllerType controller)
Definition: sdhserial.cpp:1049
cSimpleVector rvel(int axis, double *dummy=NULL)
Definition: sdhserial.cpp:1107
cSimpleVector ilim(int axis=All, double *limit=NULL)
Definition: sdhserial.cpp:851
helper class to set timeout of _serial_base on construction and reset to previous value on destructio...
Definition: serialbase.h:163
cSimpleVector AxisCommand(char const *command, int axis=All, double *value=NULL)
Definition: sdhserial.cpp:641
cSimpleVector pos_save(int axis=All, double *value=NULL)
Definition: sdhserial.cpp:1078
Low-level communication class to access a serial port.
Definition: serialbase.h:105
RC_OK
Success, no error.
cSimpleVector tpap(int axis=All, double *angle=NULL)
Definition: sdhserial.cpp:974
cSimpleVector p(int axis=All, double *angle=NULL)
Definition: sdhserial.cpp:963
#define NAMESPACE_SDH_START
int NUMBER_OF_AXES
The number of axes.
Definition: sdhbase.h:297
void stop(void)
Definition: sdhserial.cpp:1023
char * sn(void)
Definition: sdhserial.cpp:1180
unsigned char cmd_code
Definition: sdhserial.cpp:106
data structure with binary data for request from PC to SDH
Definition: sdhserial.cpp:65
Base class for exceptions in the SDHLibrary-CPP.
Definition: sdhexception.h:132
std::ostream & flush()
Definition: dbg.h:289
#define NS_SDH
virtual bool IsOpen(void)
Definition: sdhserial.cpp:381
int numaxis(void)
Definition: sdhserial.cpp:1204
Interface of auxilliary utility functions for SDHLibrary-CPP.
invalid controller_type (needed for cSDHSerial::con() to indicate "read current controller type") ...
Definition: sdhbase.h:178
char * NextLine()
Return the next line, this increases current_line.
union sSDHBinaryRequest::@3 SDH__attribute__
double GetDuration(char *line)
Definition: sdhserial.cpp:546
void Sync()
Definition: sdhserial.cpp:591
enum eCommandCodeEnum eCommandCode
typedef for eCommandCodeEnum, see there
void CheckRange(double value, double minvalue, double maxvalue, char const *name="")
Check if value is in [minvalue .. maxvalue]. Throw a cSDHErrorInvalidParameter exception if not...
Definition: sdhbase.cpp:177
eControllerType
An enum for all possible SDH internal controller types (order must match that in the SDH firmware in ...
Definition: sdhbase.h:176
cSimpleVector pid(int axis, double *p=NULL, double *i=NULL, double *d=NULL)
Definition: sdhserial.cpp:800
cDBG cdbg
debug stream to print colored debug messages
Definition: sdhbase.h:279
char * ver(void)
Definition: sdhserial.cpp:1156
cSimpleVector state(int axis=All, double *dummy=NULL)
Definition: sdhserial.cpp:1118
double get_duration(void)
Definition: sdhserial.cpp:562
eErrorCode
Definition: sdhbase.h:112
cSimpleStringList reply
Space for the replies from the SDH.
Definition: sdhserial.h:112
#define USING_NAMESPACE_SDH
virtual int write(char const *ptr, int len=0)=0
Write data to a previously opened port.
Interface of class #SDH::cSDHSerial.
double grip(double close, double velocity, bool sequ)
Definition: sdhserial.cpp:1277
int user_errors(int value)
Definition: sdhserial.cpp:895
cSimpleVector alim(int axis=All, double *dummy=NULL)
Definition: sdhserial.cpp:945
tCRCValue AddBytes(unsigned char *bytes, int nb_bytes)
insert nb_bytes from bytes into CRC calculation and return the new current CRC checksum ...
Definition: crc.h:111
virtual bool UseCRC16()
Definition: serialbase.h:270
unsigned char status_code
Definition: sdhserial.cpp:109
A derived CRC class that uses a CRC table and initial value suitable for protecing the binary communi...
Definition: crc.h:170
#define NAMESPACE_SDH_END
Derived exception class for exceptions related to communication between the SDHLibrary and the SDH...
Definition: sdhexception.h:206
void ExtractFirmwareState()
Definition: sdhserial.cpp:518
cSimpleVector igrip(int axis=All, double *limit=NULL)
Definition: sdhserial.cpp:1215
This file contains settings to make the SDHLibrary compile on differen systems:
unsigned char parameter_bytes[sizeof(float) *eNUMBER_OF_ELEMENTS+sizeof(tCRCValue)]
Definition: sdhserial.cpp:76
virtual void Open(void)=0
Open rs232 port port.
eVelocityProfile vp(eVelocityProfile velocity_profile=eVP_INVALID)
Definition: sdhserial.cpp:1030
int debug(int value)
Definition: sdhserial.cpp:909
sSDHBinaryRequest(eCommandCode command, double *value, bool use_crc16)
Definition: sdhserial.cpp:155
void Close()
Definition: sdhserial.cpp:374
Derived exception class for low-level serial communication related exceptions.
Definition: serialbase.h:86
tCRCValue * CRC16() const
return a ptr to the CRC value in parameter_bytes, assuming that nb_data_bytes is correct (including t...
Definition: sdhserial.cpp:86
cSDHSerial(int _debug_level=0)
Constructor of cSDHSerial.
Definition: sdhserial.cpp:238
virtual void Close(void)=0
Close the previously opened communication channel.
endmarker and dimension
Definition: sdhbase.h:197
Class for short, fixed maximum length text messages.
Definition: sdhexception.h:77
Derived exception class for exceptions related to invalid parameters.
Definition: sdhbase.h:78
virtual ssize_t Read(void *data, ssize_t size, long timeout_us, bool return_on_less_data)=0
void Send(char const *s, int nb_lines=All, int nb_lines_total=All, int max_retries=3)
Definition: sdhserial.cpp:389
cSimpleVector power(int axis=All, double *flag=NULL)
Definition: sdhserial.cpp:862
CMDC_ILIM
cSerialBase * com
The communication object to the serial device (RS232 port or ESD CAN net)
Definition: sdhserial.h:108
double eps
epsilon value (max absolute deviation of reported values from actual hardware values) (needed since S...
Definition: sdhbase.h:315
unsigned char nb_valid_parameters
Definition: sdhserial.cpp:108
bool GetFlag(void) const
Definition: dbg.h:158
int Length() const
Return number of lines stored.
unsigned char cmd_code
Definition: sdhserial.cpp:71
void SyncUnknown()
Definition: sdhserial.cpp:616
int property(char const *propname, int value)
Definition: sdhserial.cpp:885
double m_sequtime
additional time in seconds to wait for sequential execution of m command (as these are always execute...
Definition: sdhserial.h:102
number of elements in vector
Definition: simplevector.h:97
char * id(void)
Definition: sdhserial.cpp:1172
unsigned char nb_data_bytes
Definition: sdhserial.cpp:72
virtual char * readline(char *line, int size, char const *eol="\, bool return_on_less_data=false)
Read a line from the device.
Definition: serialbase.cpp:76
cSimpleVector kv(int axis=All, double *kv=NULL)
Definition: sdhserial.cpp:820
std::ostream & operator<<(std::ostream &stream, sSDHBinaryRequest const &request)
helper functions to insert a human readable form of the request into stream
Definition: sdhserial.cpp:190


sdhlibrary_cpp
Author(s): Dirk Osswald
autogenerated on Mon Feb 28 2022 23:41:51