dsa.cpp
Go to the documentation of this file.
1 //======================================================================
27 //======================================================================
28 
29 #include "sdhlibrary_settings.h"
30 
31 //----------------------------------------------------------------------
32 // System Includes - include with <>
33 //----------------------------------------------------------------------
34 #if SDH_USE_VCC
35 // To prevent windef.h from defining evil macros for min/max:
36 #define NOMINMAX
37 #endif
38 
39 #include <assert.h>
40 #include <iostream>
41 #include <iomanip>
42 
43 //----------------------------------------------------------------------
44 // Project Includes - include with ""
45 //----------------------------------------------------------------------
46 
47 #include "dsa.h"
48 #include "sdhbase.h" // for g_sdh_debug_log
49 #include "util.h"
50 #include "tcpserial.h"
51 
52 //----------------------------------------------------------------------
53 // Defines, enums, unions, structs
54 //----------------------------------------------------------------------
55 
56 
58 
61 {
71  eDSA_LOOP = 0x06,
80 };
81 //----------------------------------------------------------------------
82 // Global variables (declarations)
83 //----------------------------------------------------------------------
84 
85 
86 //----------------------------------------------------------------------
87 // External functions (function declarations)
88 //----------------------------------------------------------------------
89 
90 
91 //----------------------------------------------------------------------
92 // Function prototypes (function declarations)
93 //----------------------------------------------------------------------
94 
95 
96 //----------------------------------------------------------------------
97 // Class declarations
98 //----------------------------------------------------------------------
99 
100 
102 {
103  cCRC_DSACON32m checksum;
104  int bytes_written = 0;
105  int len;
106 
107 #if SDH_USE_VCC
108  // VCC cannot create variable size arrays on the stack; so use the heap
109  char* buffer = new char[ payload_len+8 ];
110  try
111  {
112 #else
113  // gcc knows how to allocate variable size arrays on the stack
114  char buffer[ payload_len + 8 ]; // 8 = 3 (preamble) + 1 (command) + 2 (len) + 2 (CRC)
115 #endif
116  buffer[0] = (UInt8) 0xaa;
117  buffer[1] = (UInt8) 0xaa;
118  buffer[2] = (UInt8) 0xaa;
119  buffer[3] = command;
120  buffer[4] = ((UInt8*) &payload_len)[0];
121  buffer[5] = ((UInt8*) &payload_len)[1];
122 
123  if ( payload_len > 0)
124  {
125  // command and payload length are included in checksum (if used)
126  checksum.AddByte( command );
127  checksum.AddByte( buffer[4] );
128  checksum.AddByte( buffer[5] );
129  }
130  unsigned int i;
131  for ( i=0; i < payload_len; i++)
132  {
133  checksum.AddByte( payload[ i ] );
134  buffer[ 6+i ] = payload[i];
135  }
136 
137  if ( payload_len > 0)
138  {
139  // there is a payload, so the checksum is sent along with the data
140  len = payload_len + 8;
141  buffer[len-2] = checksum.GetCRC_LB();
142  buffer[len-1] = checksum.GetCRC_HB();
143  }
144  else
145  {
146  // no payload => no checksum
147  len = 6;
148  }
149 
150  bytes_written = com->write( buffer, len );
151 
152 #if SDH_USE_VCC
153  }
154  catch (...)
155  {
156  // we have to delete[] the buffer, even if the try block above throws an exception:
157  delete[] buffer;
158  throw; // rethrow exception
159  }
160  // we have to delete[] the buffer if no exception was thrown
161  delete[] buffer;
162 #endif
163 
164  if ( bytes_written != len )
165  throw new cDSAException( cMsg( "Could only write %d/%d bytes to DSACON32m", bytes_written, len ) );
166 }
167 //-----------------------------------------------------------------
168 
169 void cDSA::ReadResponse( sResponse* response, UInt8 command_id )
170 {
171  assert( response != NULL );
172 
173  int retries_frames = 0;
174  while ( retries_frames++ < 5 )
175  {
176  //---------------------
177  // read at most DSA_MAX_PREAMBLE_SEARCH bytes until a valid preamble 0xaa, 0xaa, 0xaa is found
178  UInt16 i;
179  UInt8 byte;
180  int nb_preamble_bytes = 0;
181  ssize_t bytes_read = 0;
182  bool found = false;
183  int retries = 0;
184  do {
185  try {
186  bytes_read = com->Read( &byte, 1, read_timeout_us, false );
187  }
188  catch ( cSerialBaseException* e )
189  {
190  // ignore timeout
191  dbg << "Caught cSerialBaseException " << e->what() << ", rethrowing as cDSAException timeout\n";
192  delete e;
193  bytes_read = 0;
194  }
195  if ( bytes_read == 0 )
196  throw new cDSAException( cMsg( "Timeout while reading preamble from remote DSACON32m controller" ) );
197 
198  retries++;
199  if ( byte == 0xaa )
200  {
201  nb_preamble_bytes++;
202  dbg << "found valid preamble byte no " << nb_preamble_bytes << "\n";
203  }
204  else
205  {
206  nb_preamble_bytes = 0;
207  dbg << "ignoring invalid preamble byte " << int(byte) << "\n";
208  }
209 
210  found = nb_preamble_bytes == 3;
211  } while ( !found && retries < DSA_MAX_PREAMBLE_SEARCH );
212 
213  if ( !found )
214  throw new cDSAException( cMsg( "Could not find valid preamble in %ld data bytes from remote DSACON32m controller", bytes_read ) );
215  //---------------------
216 
217  //---------------------
218  // read and check command ID and size:
219  bytes_read = com->Read( response, 3, read_timeout_us, false );
220  if ( bytes_read != 3 )
221  {
222  throw new cDSAException( cMsg( "Could only read %ld/3 header bytes from remote DSACON32m controller", bytes_read ) );
223  }
224  //---------------------
225 
226  //---------------------
227  // check if its the expected response and if enough space in payload of response:
228  if ( response->packet_id != command_id || response->payload == NULL || response->max_payload_size < (int) response->size )
229  {
230  // no, so read and forget the data plus checksum (to keep communication line clean)
231 #if SDH_USE_VCC
232  // VCC cannot create variable size arrays on the stack; so use the heap
233  char* buffer = new char[ response->size+2 ];
234  try
235  {
236 #else
237  // gcc knows how to allocate variable size arrays on the stack
238  char buffer[ response->size+2 ];
239 #endif
240 
241  int nb_bytes_ignored = com->Read( buffer, response->size+2, read_timeout_us, false );
242  dbg << "Read and ignored " << nb_bytes_ignored << " bytes of response " << *response << "\n";
243 
244 #if SDH_USE_VCC
245  }
246  catch (...)
247  {
248  // we have to delete[] the buffer, even if the try block above throws an exception:
249  delete[] buffer;
250  throw; // rethrow exception
251  }
252  // we have to delete[] the buffer if no exception was thrown
253  delete[] buffer;
254 #endif
255 
256  // it is a common case that the answer is a normal "full-frame"
257  // response from the DSACON32m, since it can send data
258  // automatically in "push-mode". So just ignore such a response
259  // and try to read the next response:
260  if ( response->packet_id != command_id && response->packet_id == UInt8(eDSA_FULL_FRAME) )
261  continue;
262 
263  // else report an error
264  throw new cDSAException( cMsg( "Unexpected response. Expected command_id 0x%02x with up to %d payload bytes, but got command_id 0x%02x with %d payload bytes", (int) command_id, (int) response->max_payload_size, (int) response->packet_id, response->size ) );
265  }
266  //---------------------
267 
268  //---------------------
269  // read indicated rest (excluding checksum)
270  bytes_read = com->Read( response->payload, response->size, read_timeout_us, false );
271  if ( bytes_read != response->size )
272  {
273  throw new cDSAException( cMsg( "Could only read %ld/%d payload bytes from remote DSACON32m controller", bytes_read, response->size ) );
274  }
275  //---------------------
276 
277  //---------------------
278  // read and check checksum, if given
279  if ( response->size > 0 )
280  {
281  UInt16 checksum_received;
282  cCRC_DSACON32m checksum_calculated;
283 
284  bytes_read = com->Read( (void*) &checksum_received, sizeof( checksum_received ), read_timeout_us, false );
285  if ( bytes_read != sizeof( checksum_received ) )
286  throw new cDSAException( cMsg( "Could only read %ld/2 checksum bytes from remote DSACON32m controller", bytes_read ) );
287 
288  checksum_calculated.AddByte( response->packet_id );
289  checksum_calculated.AddByte( ((UInt8*) &response->size)[0] );
290  checksum_calculated.AddByte( ((UInt8*) &response->size)[1] );
291  for ( i=0; i < response->size; i++ )
292  checksum_calculated.AddByte( response->payload[i] );
293 
294  if ( checksum_received != checksum_calculated.GetCRC() )
295  {
296  dbg << "Checksum Error, got 0x" << std::hex << checksum_received << " but expected 0x" << std::hex << checksum_calculated.GetCRC() << "\n";
297  dbg << "response = " << *response << "\n";
298 
299  // ??? maybe this should be silently ignored ???
300  throw new cDSAException( cMsg( "Checksum Error, got 0x%x but expected 0x%x", checksum_received, checksum_calculated.GetCRC() ) );
301  }
302  else
303  dbg << "Checksum OK\n";
304  }
305  //---------------------
306 
307  return;
308  }
309  throw new cDSAException( cMsg( "Retried %d times but could not get expected response with command_id 0x%02x and up to %d payload bytes.", retries_frames, (int) command_id, (int) response->max_payload_size ) );
310 }
311 //-----------------------------------------------------------------
312 
313 
314 void cDSA::ReadControllerInfo( sControllerInfo* _controller_info )
315 {
316  sResponse response( (UInt8*) _controller_info, sizeof( *_controller_info ) );
317 
319 
320  // !!! somehow the controller sends only 18 bytes although 19 are expected
321  //if ( response.size != sizeof( *_controller_info ) )
322  // throw new cDSAException( cMsg( "Response with controllerinfo has unexpected size %d (expected %d)", response.size, sizeof(*_controller_info) ) );
323  if ( 18 != response.size )
324  throw new cDSAException( cMsg( "Response with controllerinfo has unexpected size %d (expected %d)", response.size, 18 ) );
325 }
326 //-----------------------------------------------------------------
327 
328 
329 void cDSA::ReadSensorInfo( sSensorInfo* _sensor_info )
330 {
331  sResponse response( (UInt8*) _sensor_info, sizeof( *_sensor_info ) );
332 
334 
335  if ( response.size != sizeof( *_sensor_info ) )
336  throw new cDSAException( cMsg( "Response with sensorinfo has unexpected size %d (expected %ld)", response.size, sizeof(*_sensor_info) ) );
337 }
338 //----------------------------------------------------------------------
339 
340 
341 void cDSA::ReadMatrixInfo( sMatrixInfo* _matrix_info )
342 {
343  sResponse response( (UInt8*) _matrix_info, sizeof( *_matrix_info ) );
344 
346 
347  if ( response.size != sizeof( *_matrix_info ) )
348  throw new cDSAException( cMsg( "Response with matrixinfo has unexpected size %d (expected %ld)", response.size, sizeof(*_matrix_info) ) );
349 }
350 //-----------------------------------------------------------------
351 
352 
354 {
355  // provide a buffer with space for a full frame without RLE
356  // this might fail if RLE is used and the data is not RLE "friendly"
357  int buffersize = 5 + nb_cells * sizeof( tTexel );
358 #if SDH_USE_VCC
359  // VCC cannot create variable size arrays on the stack; so use the heap
360  UInt8* buffer = new UInt8[ buffersize ];
361  try
362  {
363 #else
364  // gcc knows how to allocate variable size arrays on the stack
365  UInt8 buffer[ buffersize ];
366 #endif
367  sResponse response( buffer, buffersize );
368  ReadResponse( &response, UInt8(eDSA_FULL_FRAME) );
369 
370  //---------------------
371  // since DSACON32m might send data in push mode there might be more frames
372  // available in the input buffer of the OS. E.g. if the processor has a high load.
373  // so we have to try to read all frames available and use the last one.
374  //cSimpleTime read_others_start; //FIX ME: remove me
375 
376  cSetValueTemporarily<long> set_read_timeout_us_temporarily( &read_timeout_us, 0L );
377  // old value of read_timeout_us will be automatically restored when leaving this function (on return or on exception)
378 
379  bool read_another = m_read_another;
380  while ( read_another )
381  {
382  try
383  {
384  ReadResponse( &response, UInt8(eDSA_FULL_FRAME) );
385  //std::cerr << "Read another pending frame!\n"; //FIX ME: remove me
386  }
387  catch ( cDSAException* e )
388  {
389  // timeout occured, so no more frames available
390  delete e;
391  //std::cerr << "No more frames available\n"; //FIX ME: remove me
392  read_another = false;
393  }
394  }
395  //double read_others_elapsed = read_others_start.Elapsed();//FIX ME: remove me
396  //std::cerr << "Reading others took " << read_others_elapsed << "s\n"; //FIX ME: remove me
397  //---------------------
398 
399 
400  // size cannot be checked here since it may depend on the data sent (if RLE is used)
401 
402  ParseFrame( &response, frame_p );
403 
404 #if SDH_USE_VCC
405  }
406  catch (...)
407  {
408  // we have to delete[] the buffer, even if the try block above throws an exception:
409  delete[] buffer;
410  throw; // rethrow exception
411  }
412  // we have to delete[] the buffer if no exception was thrown
413  delete[] buffer;
414 #endif
415 
416 
417  /*
418  * DSACON32m firmware release up to and including 288 except 269
419  * are not able to handle single frame acquisition. Instead they
420  * start sending as fast as possible right away.
421  *
422  * So stop acquiring immediately after frame was received
423  */
425  {
426  dbg << "switching off acquiring single frames\n";
427  SetFramerate( 0, true, false );
428  FlushInput( 50000, 1000 ); // wait 50ms for first byte since hand sends with 30 fps => 33ms
429  }
430 }
431 //-----------------------------------------------------------------
432 
433 
435 {
437  ReadControllerInfo( _controller_info );
438 }
439 //-----------------------------------------------------------------
440 
441 
442 void cDSA::QuerySensorInfo( sSensorInfo* _sensor_info )
443 {
445  ReadSensorInfo( _sensor_info );
446 }
447 //-----------------------------------------------------------------
448 
449 
450 void cDSA::QueryMatrixInfo( sMatrixInfo* _matrix_info, int matrix_no )
451 {
453  ReadMatrixInfo( _matrix_info );
454 }
455 //----------------------------------------------------------------------
456 
457 
459 {
460  if ( texel_offset != NULL )
461  {
462  delete[] texel_offset;
463  texel_offset = NULL;
464  }
465 
466  if ( matrix_info != NULL )
467  {
468  delete[] matrix_info;
469  matrix_info = NULL;
470  }
471 
472 
474  assert( matrix_info != NULL );
475 
476  texel_offset = new int[ sensor_info.nb_matrices ];
477  assert( texel_offset != NULL );
478 
479  nb_cells = 0;
480 
481  unsigned int i;
482  for ( i=0; i<sensor_info.nb_matrices; i++ )
483  {
484  texel_offset[i] = nb_cells;
485  QueryMatrixInfo( &(matrix_info[i]), i );
486  VAR( dbg, matrix_info[i] );
487 
489  }
490  VAR( dbg, nb_cells );
491 }
492 //-----------------------------------------------------------------
493 
494 
495 void cDSA::ParseFrame( sResponse* response, sTactileSensorFrame* frame_p )
496 {
497  unsigned int i = 0; // index of next unparsed data byte in payload
498 
499  //---------------------
500  // copy timestamp and flags from response
501  frame_p->timestamp = *(UInt32*) &(response->payload[ i ]);
502  i+=4;
503  VAR( dbg, frame_p->timestamp );
504 
505  frame_p->flags = response->payload[ i ];
506  i+=1;
507  VAR( dbg, (int)frame_p->flags );
508 
509  bool do_RLE = frame_p->flags & (1<<0);
510  VAR( dbg, do_RLE );
511  //---------------------
512 
513  //---------------------
514  // for the first frame: record reported timestamp (time of DS) and now (time of pc)
515  if (start_dsa == 0)
516  {
517  start_pc.StoreNow();
518  start_dsa = frame_p->timestamp;
519  //dbg << "Init start_dsa %d\n" % (start_dsa )
520  }
521  //---------------------
522 
523  if ( dbg.GetFlag() )
524  {
525  double diff_pc = start_pc.Elapsed();
526  UInt32 diff_dsa = frame_p->timestamp - start_dsa;
527  dbg.PDM( "ParseFrame: elapsed ms pc,dsa = %6u,%6u %6u age %6lu\n", (unsigned int) (diff_pc*1000.0), (unsigned int) diff_dsa, (unsigned int)(((unsigned int)(diff_pc*1000.0))-diff_dsa), GetAgeOfFrame(frame_p) );
528  }
529 
530  //---------------------
531  // copy received data from response to frame
532  int j = 0; // counter for frame elements
533  if (do_RLE)
534  {
535  //---------------------
536  // decode RLE encoded frame:
537 
538  UInt16 rle_unit;
539  tTexel v;
540  UInt8 n;
541  while (i+1 < response->size)
542  {
543  rle_unit = *((UInt16*) &(response->payload[ i ]));
544  v = rle_unit & 0x0fff;
545  n = rle_unit >> 12;
546  while (n > 0)
547  {
548  //response->frame append( v )
549  if (j<nb_cells)
550  {
551  frame_p->texel[ j ] = v;
552  }
553  n -= 1;
554  j += 1;
555  }
556  i += sizeof( rle_unit );
557  }
558  if ( j != nb_cells )
559  throw new cDSAException( cMsg( "Received RLE encoded frame contains %d texels, but %d are expected", j, nb_cells ) );
560 
561  //---------------------
562  }
563  else
564  {
565  //---------------------
566  // copy non RLE encoded frame:
567 
568  if ( response->size - i != (UInt16) (nb_cells * sizeof( tTexel )) )
569  throw new cDSAException( cMsg( "Received non RLE encoded frame contains %d bytes, but %ld are expected", response->size - i, nb_cells * sizeof( tTexel ) ) );
570 
571  memcpy( frame_p->texel, &(response->payload[ i ]), response->size - i );
572  //---------------------
573  }
574 }
575 //-----------------------------------------------------------------
576 
577 void cDSA::Init( int debug_level )
578 {
579  dbg << "Debug messages of class cDSA are printed like this.\n";
580 
581  //---------------------
582  // check compilation settings (whether the compiler, especially vcc packed structures correctly or not):
583  assert( sizeof( sControllerInfo ) == 19 );
584  assert( sizeof( sSensorInfo ) == 12 );
585  assert( sizeof( sMatrixInfo ) == 52 );
586  assert( sizeof( sResponse ) == 7 + sizeof( char* ) ); // on 64 bit systems the char* might be 8 bytes!
587  //---------------------
588  assert( com != NULL );
589 
590  com->dbg.SetFlag( debug_level-1 > 0);
591 
592  Open();
593 }
594 //-----------------------------------------------------------------
595 
596 cDSA::cDSA( int debug_level, int port, char const* device_format_string )
597  : // init members:
598  m_read_another(false),
599  dbg ( (debug_level>0), "blue", g_sdh_debug_log ),
600  com (NULL),
601  do_RLE (false ),
602  matrix_info (NULL),
603  frame (),
604  nb_cells ( 0 ),
605  texel_offset (NULL),
606  read_timeout_us (1000000), // 1s
607  start_pc (),
608  start_dsa (0),
611  force_factor (1.0),
612  calib_pressure (0.000473), // N/(mm*mm)
613  calib_voltage (592.1), // "what the DSA reports:" ~mV
614  acquiring_single_frame (false)
615 
616 {
617  com = new cRS232( port, 115200, 1.0, device_format_string );
618  Init( debug_level );
619 }
620 //-----------------------------------------------------------------
621 
622 cDSA::cDSA( int debug_level, char const* _tcp_adr, int _tcp_port, double _timeout )
623  : // init members:
624  m_read_another(false),
625  dbg ( (debug_level>0), "blue", g_sdh_debug_log ),
626  com (NULL),
627  do_RLE (false ),
628  matrix_info (NULL),
629  frame (),
630  nb_cells ( 0 ),
631  texel_offset (NULL),
632  read_timeout_us (1000000), // 1s
633  start_pc (),
634  start_dsa (0),
637  force_factor (1.0),
638  calib_pressure (0.000473), // N/(mm*mm)
639  calib_voltage (592.1), // "what the DSA reports:" ~mV
640  acquiring_single_frame (false)
641 {
642  com = new cTCPSerial( _tcp_adr, _tcp_port, _timeout );
643  Init( debug_level );
644 }
645 //-----------------------------------------------------------------
646 
647 void cDSA::FlushInput( long timeout_us_first, long timeout_us_subsequent )
648 {
649  int bytes_read, bytes_read_total = 0;
650  long timeout_us = timeout_us_first;
651  do {
652  UInt8 byte[4096];
653  try {
654  bytes_read = com->Read( &byte, 4096, timeout_us, true );
655  }
656  catch ( cSerialBaseException* e )
657  {
658  delete e;
659  bytes_read = 0;
660  // ignore timeout exception
661  break;
662  }
663  bytes_read_total += bytes_read;
664  timeout_us = timeout_us_subsequent;
665  } while (bytes_read > 0);
666  dbg << "ignoring " << bytes_read_total << " old bytes of garbage from device\n";
667 }
668 //-----------------------------------------------------------------
669 
670 
671 void cDSA::Open(void)
672 {
673  com->Open();
674 
675  //---------------------
676  // Set framerate of remote DSACON32m to 0 first.
677  // This is necessary since the remote DSACON32m might still be sending frames
678  // from a previous command of another process.
679  // An exception may be thrown if the response for the command gets messed up
680  // with old sent frames, so ignore these.
681  // Additionally we have to ignore the "Detect terminal presence" codes sent by the
682  // DSACON32m after power up / reset. These codes ("\x1b[5n" = 0x1b 0x5b 0x35 0x6e)
683  // are sent 3 times within 0.82 seconds approximately 7 seconds after power up.
684  // The DSACON32m will accept commands only after this time (ca. 8 seconds).
685  {
686  cSetValueTemporarily<long> set_read_timeout_us_temporarily( &read_timeout_us, 3000000L ); // 3000000us = 3s => 3 retries = 4 tries a 3s = 12s > 8s = power up time of DSACON32m
687  // old value of read_timeout_us will be automatically restored when leaving this function (on return or on exception)
688 
689  SetFramerateRetries( 0, true, false, 3, false );
690  }
691  //---------------------
692 
693  //---------------------
694  // clean up communication line
695  FlushInput( 1000000, 1000 );
696  //---------------------
697 
698 
699  //---------------------
700  // now query the controller, sensor and matrix info from the remote DSACON32m controller
702  VAR( dbg, controller_info );
703 
705  VAR( dbg, sensor_info );
706 
707  // read this from data ???
708  //sensor_info.bit_resolution = 12;
709  //sensor_info.maxvalue = (1 << sensor_info.bit_resolution)-1;
710 
712  //---------------------
713 
714  //---------------------
715  // now we know the dimension of the attached sensors, so get space for a full frame
716  frame.texel = new tTexel[ nb_cells ];
717  //---------------------
718 
719 }
720 //----------------------------------------------------------------------
721 
722 
723 
725 {
726 
727  if ( frame.texel != NULL )
728  delete[] frame.texel;
729 
730  if ( texel_offset != NULL )
731  delete[] texel_offset;
732 
733  if ( matrix_info != NULL )
734  delete[] matrix_info;
735 }
736 //----------------------------------------------------------------------
737 
738 
739 void cDSA::Close(void)
740 {
741  dbg << "Closing\n";
742  SetFramerateRetries( 0, true, false, 0, true );
743  com->Close();
744 }
745 //-----------------------------------------------------------------
746 
747 
748 void cDSA::ReadAndCheckErrorResponse( char const* msg, UInt8 command_id )
749 {
751  sResponse response( (UInt8*) &error_code, sizeof( error_code ) ); // we expect only 2 bytes payload in the answer (the error code)
752  ReadResponse( &response, command_id );
753 
754  if ( response.size != 2 )
755  {
756  throw new cDSAException( cMsg( "Invalid response from DSACON32m for %s, expected 2 bytes but got %d", msg, response.size ) );
757  }
758  else if ( error_code != E_SUCCESS )
759  {
760  throw new cDSAException( cMsg( "Error response from DSACON32m for %s, errorcode = %d (%s)", msg, error_code, ErrorCodeToString( error_code ) ) );
761  }
762 }
763 //-----------------------------------------------------------------
764 
765 
766 void cDSA::SetFramerate( UInt16 framerate, bool do_RLE, bool do_data_acquisition )
767 {
768  dbg << "cDSA::SetFramerate, setting framerate to " << framerate << " do_data_acquisition= " << do_data_acquisition << "\n";
769  UInt8 flags = 0;
770 
771  if ( do_data_acquisition )
772  {
773  flags |= (1<<7);
774  }
775 
776  //if ( do_single_shot )
777  // flags |= (1<<6);
778 
779  //if ( do_internal_trigger )
780  // flags |= (1<<5);
781 
782  //if ( do_level_trigger )
783  // flags |= (1<<4);
784 
785  //if ( do_rising_high )
786  // flags |= (1<<3);
787 
788  if ( do_RLE )
789  {
790  flags |= (1<<0);
791  }
792 
793  UInt8 buffer[ 3 ];
794  buffer[0] = flags;
795  buffer[1] = ((UInt8*) &framerate)[0];
796  buffer[2] = ((UInt8*) &framerate)[1];
797 
798  WriteCommandWithPayload( UInt8(eDSA_CONFIGURE_DATA_ACQUISITION), buffer, sizeof( buffer ) );
800  dbg << "acknowledge ok\n";
801 
802  if ( framerate==0 && do_data_acquisition )
803  acquiring_single_frame = true;
804  else
805  acquiring_single_frame = false;
806 }
807 //-----------------------------------------------------------------
808 
809 
810 void cDSA::SetFramerateRetries( UInt16 framerate, bool do_RLE, bool do_data_acquisition, unsigned int retries, bool ignore_exceptions )
811 {
812  do
813  {
814  try
815  {
816  SetFramerate( framerate, do_RLE, do_data_acquisition );
817  // in case of success we just return
818  return;
819  }
820  catch ( cDSAException* e )
821  {
822  if ( retries-- == 0 && !ignore_exceptions )
823  throw; // rethrow in case of retries exceeded
824  // catch and ignore exceptions which might result from an invalid response
825  dbg << "ignoring Caught exception: " << e->what() << "\n";
826  delete e;
827  }
828  // retry: reopen the interface and try again:
829  //com->Close();
830  //com->Open();
831  } while ( retries>0 );
832 }
833 //-----------------------------------------------------------------
834 
835 
836 void cDSA::SetMatrixSensitivity( int matrix_no,
837  double sensitivity,
838  bool do_all_matrices,
839  bool do_reset,
840  bool do_persistent )
841 {
842 #if SDH_USE_VCC
843 #pragma pack(push,1) // for VCC (MS Visual Studio) we have to set the necessary 1 byte packing with this pragma
844 #endif
845  struct sSetSensitivity
846  {
847  UInt8 flags;
848  UInt8 matrix_no;
849  float sensitivity;
850  } SDH__attribute__((__packed__)); // for gcc we have to set the necessary 1 byte packing with this attribute;
851 #if SDH_USE_VCC
852 #pragma pack(pop) // for VCC (MS Visual Studio) restore normal packing
853 #endif
854 
855  sSetSensitivity set_sensitivity;
856 
857  set_sensitivity.flags = 0;
858  if ( do_persistent )
859  set_sensitivity.flags |= (1<<7);
860  if ( do_all_matrices )
861  set_sensitivity.flags |= (1<<1);
862  if ( do_reset )
863  set_sensitivity.flags |= (1<<0);
864 
865  set_sensitivity.matrix_no = (UInt8) matrix_no;
866  set_sensitivity.sensitivity = (float) sensitivity;
867 
868  WriteCommandWithPayload( UInt8(eDSA_ADJUST_MATRIX_SENSITIVITY), (UInt8*) &set_sensitivity, sizeof(set_sensitivity) );
869 
870  // Due to a bug in the firmware there will be no answer when writing persistently
871  if ( ! do_persistent )
872  ReadAndCheckErrorResponse( "cDSA::SetMatrixSensitivity", UInt8(eDSA_ADJUST_MATRIX_SENSITIVITY) );
873 
874  dbg << "SetMatrixSensitivity ok\n";
875 }
876 
877 
878 //-----------------------------------------------------------------
880 {
882 
883  sSensitivityInfo sensitivity_info;
884 
885  sResponse response( (UInt8*) &sensitivity_info, sizeof( sensitivity_info ) );
887 
888  if ( response.size != sizeof( sensitivity_info ) )
889  {
890  throw new cDSAException( cMsg( "Invalid response from DSACON32m for cDSA::GetMatrixSensitivity(), expected %ld bytes but got %d", sizeof( sensitivity_info ), response.size ) );
891  }
892  else if (response.payload[0] != 0 || response.payload[1] != 0 )
893  {
894  throw new cDSAException( cMsg( "Error response from DSACON32m for cDSA::GetMatrixSensitivity(), errorcode = %d (%s)", sensitivity_info.error_code, ErrorCodeToString( sensitivity_info.error_code ) ) );
895  }
896  dbg << "GetMatrixSensitivity ok\n";
897 
898  return sensitivity_info;
899 }
900 
901 //-----------------------------------------------------------------
902 void cDSA::SetMatrixThreshold( int matrix_no,
903  UInt16 threshold,
904  bool do_all_matrices,
905  bool do_reset,
906  bool do_persistent )
907 {
908  if ( controller_info.sw_version < 268 )
909  throw new cDSAException( cMsg( "Cannot adjust matrix threshold with current DSACON32m firmware (R%d)! Please update to R268 or above.)", controller_info.sw_version ) );
910 
911  int flags = 0;
912  if ( do_persistent )
913  flags |= (1<<7);
914  if ( do_all_matrices )
915  flags |= (1<<1);
916  if ( do_reset )
917  flags |= (1<<0);
918 
919  UInt8 buffer[ 4 ];
920  buffer[0] = flags;
921  buffer[1] = matrix_no & 0xff;
922  memcpy( &(buffer[2]), &threshold, sizeof( threshold ) );
923  WriteCommandWithPayload( UInt8(eDSA_SET_MATRIX_THRESHOLD), buffer, sizeof(buffer) );
924 
925  // Due to a bug in the firmware there will be no answer when writing persistently
926  if ( ! do_persistent )
927  ReadAndCheckErrorResponse( "cDSA::SetMatrixThreshold", UInt8(eDSA_SET_MATRIX_THRESHOLD) );
928 
929  dbg << "SetMatrixThreshold ok\n";
930 }
931 
932 
933 //-----------------------------------------------------------------
935 {
936  if ( controller_info.sw_version < 268 )
937  throw new cDSAException( cMsg( "cDSA::GetMatrixThreshold() Cannot read matrix threshold with current DSACON32m firmware (R%d)! Please update to R268 or above.", controller_info.sw_version ) );
938 
940 
941  UInt8 buffer[ 4 ];
942  sResponse response( buffer, sizeof(buffer) );
944 
945 
946  if ( response.size != sizeof( buffer ) )
947  {
948  throw new cDSAException( cMsg( "cDSA::GetMatrixThreshold() Invalid response from DSACON32m, expected %ld bytes but got %d", sizeof( buffer ), response.size ) );
949  }
950  else if (response.payload[0] != 0 || response.payload[1] != 0 )
951  {
953  memcpy( (void*) &error_code, (void*) &(buffer[0]), sizeof( error_code ) );
954  throw new cDSAException( cMsg( "cDSA::GetMatrixThreshold() Error response from DSACON32m, errorcode = %d (%s)", error_code, ErrorCodeToString( error_code ) ) );
955  }
956  dbg << "GetMatrixThreshold ok\n";
957 
958  UInt16 threshold;
959  memcpy( (void*) &threshold, (void*) &(buffer[2]), sizeof( threshold ) );
960  return threshold;
961 }
962 
963 
964 //-----------------------------------------------------------------
965 cDSA::tTexel cDSA::GetTexel( int m, int x, int y ) const
966 {
967  //VAR( dbg, m );
968  //VAR( dbg, sensor_info.nb_matrices );
969  assert( 0 <= m && m < (int) sensor_info.nb_matrices );
970  assert( x >= 0 && x < (int) matrix_info[m].cells_x );
971  assert( y >= 0 && y < (int) matrix_info[m].cells_y );
972 
973  return frame.texel[ texel_offset[m] + y * matrix_info[m].cells_x + x ];
974 }
975 
976 
977 //-----------------------------------------------------------------
978 
982 double cDSA::GetContactArea( int m )
983 {
984  double apc = matrix_info[m].texel_width * matrix_info[m].texel_height; // area per cell
985  double area = 0.0;
986 
987  for ( int y=0; y < matrix_info[m].cells_y; y++ )
988  {
989  for ( int x=0; x < matrix_info[m].cells_x; x++ )
990  {
991  if ( GetTexel( m, x, y ) > contact_area_cell_threshold )
992  {
993  area += apc;
994  }
995  }
996  }
997  return area;
998 }
999 
1000 //-----------------------------------------------------------------
1005 double cDSA::VoltageToPressure( double voltage )
1006 {
1007  // !!! for now use linear scale anyway
1008 
1009  /*
1010  # N/(mm*mm) <-> Pascal (from units.exe):
1011  # You have: N/(mm*mm)
1012  # You want: pascal
1013  # * 1000000
1014  # / 1e-06
1015  # => 1 N/(mm*mm) = 1e6 Pascal
1016  */
1017  return voltage * calib_pressure / calib_voltage;
1018 }
1019 //-----------------------------------------------------------------
1020 
1021 
1027 {
1028  sContactInfo result;
1029  double sum_pressures = 0.0;
1030  double sum_x = 0.0;
1031  double sum_y = 0.0;
1032  int nbcells = 0;
1033 
1034  for ( int y=0; y < matrix_info[m].cells_y; y++ )
1035  {
1036  for ( int x=0; x < matrix_info[m].cells_x; x++ )
1037  {
1038  double v = GetTexel( m, x, y );
1039 
1040  if ( v > contact_force_cell_threshold )
1041  {
1042  // \attention we cannot just sum up the voltages delivered by the tactile sensor since the
1043  // correlation between voltage and pressure might be non linear
1044  // so let calibration_data.VoltageToPressure() handle that
1045  double p = VoltageToPressure( v );
1046  sum_pressures += p;
1047  sum_x += double(x) * p;
1048  sum_y += double(y) * p;
1049  nbcells += 1;
1050  }
1051  }
1052  }
1053 
1054  result.area = matrix_info[m].texel_width * matrix_info[m].texel_height * (double) nbcells;
1055 
1056  result.force = force_factor * sum_pressures * result.area;
1057  if ( sum_pressures != 0.0 )
1058  {
1059  result.cog_x = matrix_info[m].texel_width * sum_x / sum_pressures;
1060  result.cog_y = matrix_info[m].texel_height * sum_y / sum_pressures;
1061  }
1062  else
1063  {
1064  result.cog_x = 0.0;
1065  result.cog_y = 0.0;
1066  }
1067 
1068  return result;
1069 }
1070 //-----------------------------------------------------------------
1071 
1072 
1074 {
1075  switch (error_code)
1076  {
1105  default:
1106  return "unknown error_code";
1107  }
1108 }
1109 //-----------------------------------------------------------------
1110 
1111 
1112 #define PRINT_MEMBER( _s, _var, _member ) \
1113  (_s) << " " << #_member << "=" << _var._member << "\n"
1114 
1115 #define PRINT_MEMBER_HEX( _s, _var, _member ) \
1116  (_s) << " " << #_member << "=0x" << std::hex << int(_var._member) << std::dec << "\n"
1117 
1118 
1119 // if the namespace is used then the overloaded operator<< must be explicitly defined in that namespace
1120 
1121 std::ostream & NS_SDH operator<<( std::ostream &stream, cDSA::sControllerInfo const &controller_info )
1122 {
1123  stream << "sControllerInfo:\n";
1124  stream << " " << "error_code=" << controller_info.error_code << " (" << cDSA::ErrorCodeToString( controller_info.error_code ) << ")\n";
1125  PRINT_MEMBER( stream, controller_info, serial_no );
1126  PRINT_MEMBER_HEX( stream, controller_info, hw_version );
1127  PRINT_MEMBER( stream, controller_info, sw_version );
1128  PRINT_MEMBER_HEX( stream, controller_info, status_flags );
1129  PRINT_MEMBER_HEX( stream, controller_info, feature_flags );
1130  PRINT_MEMBER_HEX( stream, controller_info, senscon_type );
1131  PRINT_MEMBER_HEX( stream, controller_info, active_interface );
1132  PRINT_MEMBER( stream, controller_info, can_baudrate );
1133  return PRINT_MEMBER( stream, controller_info, can_id );
1134 }
1135 //----------------------------------------------------------------------
1136 
1137 
1138 std::ostream & NS_SDH operator<<( std::ostream &stream, cDSA::sSensorInfo const &sensor_info )
1139 {
1140  stream << "sSensorInfo:\n";
1141  stream << " " << "error_code=" << sensor_info.error_code << " (" << cDSA::ErrorCodeToString( sensor_info.error_code ) << ")\n";
1142  PRINT_MEMBER( stream, sensor_info, nb_matrices );
1143  PRINT_MEMBER( stream, sensor_info, generated_by );
1144  PRINT_MEMBER_HEX( stream, sensor_info, hw_revision );
1145  PRINT_MEMBER( stream, sensor_info, serial_no );
1146  return PRINT_MEMBER_HEX( stream, sensor_info, feature_flags );
1147 }
1148 //----------------------------------------------------------------------
1149 
1150 
1151 std::ostream & NS_SDH operator<<( std::ostream &stream, cDSA::sMatrixInfo const &matrix_info )
1152 {
1153  stream << "sMatrixInfo:\n";
1154  stream << " " << "error_code=" << matrix_info.error_code << " (" << cDSA::ErrorCodeToString( matrix_info.error_code ) << ")\n";
1155  PRINT_MEMBER( stream, matrix_info, texel_width );
1156  PRINT_MEMBER( stream, matrix_info, texel_height );
1157  PRINT_MEMBER( stream, matrix_info, cells_x );
1158  PRINT_MEMBER( stream, matrix_info, cells_y );
1159  stream << " " << "uid" << "={";
1160  unsigned int i;
1161  for ( i=0; i<(sizeof(matrix_info.uid)/sizeof(matrix_info.uid[0])); i++ )
1162  stream << " 0x" << std::hex << std::setfill('0') << std::setw(2) << int(matrix_info.uid[i]);
1163  stream << "}\n";
1164  stream << " " << "reserved" << "={";
1165  for ( i=0; i<(sizeof(matrix_info.reserved)/sizeof(matrix_info.reserved[0])); i++ )
1166  stream << " 0x" << std::hex << std::setfill('0') << std::setw(2) << int(matrix_info.reserved[i]);
1167  stream << "}\n" << std::dec << std::setfill(' ');
1168  PRINT_MEMBER_HEX( stream, matrix_info, hw_revision );
1169 
1170  PRINT_MEMBER( stream, matrix_info, matrix_center_x );
1171  PRINT_MEMBER( stream, matrix_info, matrix_center_y );
1172  PRINT_MEMBER( stream, matrix_info, matrix_center_z );
1173 
1174  PRINT_MEMBER( stream, matrix_info, matrix_theta_x );
1175  PRINT_MEMBER( stream, matrix_info, matrix_theta_y );
1176  PRINT_MEMBER( stream, matrix_info, matrix_theta_z );
1177  PRINT_MEMBER( stream, matrix_info, fullscale );
1178  PRINT_MEMBER_HEX( stream, matrix_info, feature_flags );
1179  return stream;
1180 }
1181 //----------------------------------------------------------------------
1182 
1184 
1185 std::ostream & operator<<( std::ostream &stream, cDSA::sResponse const &response )
1186 {
1187  stream << "sResponse:\n";
1188  PRINT_MEMBER_HEX( stream, response, packet_id );
1189  PRINT_MEMBER( stream, response, size );
1190  PRINT_MEMBER( stream, response, max_payload_size );
1191 
1192  stream << " payload=";
1193  if ( response.payload )
1194  {
1195  UInt16 i;
1196  for ( i=0; i< response.size && i < response.max_payload_size; i+=8 )
1197  {
1198  cHexByteString hbs( (const char*)&response.payload[i], std::min( 8, response.size-i ) );
1199  stream << "\n " << std::setw(3) << i << ": " << hbs;
1200  }
1201  stream << std::dec;
1202  }
1203  else
1204  stream << "NULL\n";
1205 
1206  return stream;
1207 }
1208 
1210 //----------------------------------------------------------------------
1211 
1212 
1213 std::ostream & NS_SDH operator<<( std::ostream &stream, cDSA const &dsa )
1214 {
1215  stream << "cDSA.frame:";
1216  PRINT_MEMBER( stream, dsa.GetFrame(), timestamp );
1217  PRINT_MEMBER_HEX( stream, dsa.GetFrame(), flags );
1218 
1219  unsigned int m, x, y;
1220  for ( m = 0; m < dsa.GetSensorInfo().nb_matrices; m++ )
1221  {
1222  stream << " matrix " << m << ":\n";
1223 
1224  for ( y = 0; y < dsa.GetMatrixInfo( m ).cells_y; y++ )
1225  {
1226  stream << std::setw( 2 ) << y << "| ";
1227  for ( x = 0; x < dsa.GetMatrixInfo( m ).cells_x; x++ )
1228  {
1229  stream << std::setw( 4 ) << dsa.GetTexel( m, x, y ) << " ";
1230  }
1231  stream << "\n";
1232  }
1233  stream << "\n";
1234  }
1235  return stream;
1236 }
1237 //----------------------------------------------------------------------
1238 
1239 
1240 //======================================================================
1241 /*
1242  {
1243  Here are some settings for the emacs/xemacs editor (and can be safely ignored):
1244  (e.g. to explicitely set C++ mode for *.h header files)
1245 
1246  Local Variables:
1247  mode:C
1248  mode:ELSE
1249  End:
1250  }
1251 */
1252 //======================================================================}
Structure to hold info about the contact of one sensor patch.
Definition: dsa.h:249
cDBG dbg
A stream object to print coloured debug messages.
Definition: dsa.h:295
UInt16 sw_version
Definition: dsa.h:119
UInt16 nb_matrices
Definition: dsa.h:117
double calib_voltage
see calib_pressure
Definition: dsa.h:342
UInt16 cells_y
Definition: dsa.h:120
void WriteCommandWithPayload(UInt8 command, UInt8 *payload, UInt16 payload_len)
Definition: dsa.cpp:101
double force_factor
additional calibration factor for forces in GetContactForce
Definition: dsa.h:334
float matrix_center_y
Definition: dsa.h:126
void StoreNow(void)
Store current time internally.
Definition: simpletime.h:103
UInt8 senscon_type
Definition: dsa.h:122
UInt32 timestamp
the timestamp of the frame. Use GetAgeOfFrame() to set this into relation with the time of the PC...
Definition: dsa.h:237
eDSAPacketID
Command ID for the DSACON32m tactile sensor controller according to DSACON32_Command_Set_Reference_Ma...
Definition: dsa.cpp:60
sMatrixInfo const & GetMatrixInfo(int m) const
Return a reference to the sMatrixInfo of matrix m read from the remote DSACON32m controller.
Definition: dsa.h:485
UInt16 cells_x
Definition: dsa.h:186
uint8_t UInt8
unsigned integer, size 1 Byte (8 Bit)
Definition: basisdef.h:61
UInt8 feature_flags
Definition: dsa.h:121
UInt8 reserved[2]
Definition: dsa.h:189
void ParseFrame(sResponse *response, sTactileSensorFrame *frame_p)
Definition: dsa.cpp:495
#define PRINT_MEMBER_HEX(_s, _var, _member)
Definition: dsa.cpp:1115
cSerialBase * com
the communication interface to use
Definition: dsa.h:298
void Open(void)
(Re-)open connection to DSACON32m controller, this is called by the constructor automatically, but is still usefull to call after a call to Close()
Definition: dsa.cpp:671
UInt16 cells_y
Definition: dsa.h:187
helper class to set value on construction and reset to previous value on destruction. (RAII-idiom)
Definition: util.h:334
#define NULL
Definition: getopt1.c:56
UInt16 generated_by
Definition: dsa.h:118
void ReadMatrixInfo(sMatrixInfo *_matrix_info)
Definition: dsa.cpp:341
void SetFlag(bool flag)
Definition: dbg.h:149
Interface of class #SDH::cTCPSerial, class to access TCP port cygwin/linux.
tTexel contact_force_cell_threshold
threshold of texel cell value for detecting forces with GetContactForce
Definition: dsa.h:331
sTactileSensorFrame frame
the latest frame received from the remote DSACON32m controller
Definition: dsa.h:313
UInt8 packet_id
Definition: dsa.h:276
Derived exception class for low-level DSA related exceptions.
Definition: dsa.h:88
long read_timeout_us
default timeout used for reading in us
Definition: dsa.h:322
UInt16 error_code
Definition: dsa.h:183
float texel_height
Definition: dsa.h:118
double Elapsed(void) const
Return time in seconds elapsed between the time stored in the object and now.
Definition: simpletime.h:115
UInt16 error_code
0000h, if successful, otherwise error code
Definition: dsa.h:116
void Close(void)
Set the framerate of the remote DSACON32m controller to 0 and close connection to it...
Definition: dsa.cpp:739
cDSA(int debug_level=0, int port=1, char const *device_format_string="/dev/ttyS%d")
Definition: dsa.cpp:596
void ReadResponse(sResponse *response, UInt8 command_id)
Definition: dsa.cpp:169
dummy class for (debug) stream output of bytes as list of hex values
Definition: dbg.h:329
void ReadAndCheckErrorResponse(char const *msg, UInt8 command_id)
Definition: dsa.cpp:748
friend VCC_EXPORT std::ostream & operator<<(std::ostream &stream, cDSA::sResponse const &response)
Definition: dsa.cpp:1185
double GetContactArea(int m)
Definition: dsa.cpp:982
UInt16 can_id
Definition: dsa.h:125
UInt16 tTexel
data type for a single &#39;texel&#39; (tactile sensor element)
Definition: dsa.h:115
double force
accumulated force in N
Definition: dsa.h:251
eDSAErrorCode
error codes returned by the remote DSACON32m tactile sensor controller
Definition: dsa.h:118
UInt16 error_code
Definition: dsa.h:157
void SetFramerate(UInt16 framerate, bool do_RLE=true, bool do_data_acquisition=true)
Definition: dsa.cpp:766
UInt8 flags
internal data
Definition: dsa.h:238
UInt32 start_dsa
Definition: dsa.h:325
UInt8 status_flags
Definition: dsa.h:120
UInt8 * payload
Definition: dsa.h:270
void SetMatrixSensitivity(int matrix_no, double sensitivity, bool do_all_matrices=false, bool do_reset=false, bool do_persistent=false)
Definition: dsa.cpp:836
uint32_t UInt32
unsigned integer, size 4 Byte (32 Bit)
Definition: basisdef.h:65
cSimpleTime start_pc
Definition: dsa.h:324
#define NAMESPACE_SDH_START
UInt32 serial_no
Definition: dsa.h:117
UInt16 error_code
Definition: dsa.h:172
void Init(int debug_level)
Definition: dsa.cpp:577
UInt8 uid[6]
Definition: dsa.h:188
float matrix_center_z
Definition: dsa.h:127
#define VAR(_d, _var)
Definition: dbg.h:309
SDH::cDSA is the end user interface class to access the DSACON32m, the tactile sensor controller of t...
Definition: dsa.h:111
float fullscale
Definition: dsa.h:132
float texel_width
Definition: dsa.h:117
Int32 max_payload_size
Definition: dsa.h:271
UInt16 cells_x
Definition: dsa.h:119
float texel_width
Definition: dsa.h:184
tTexel contact_area_cell_threshold
threshold of texel cell value for detecting contacts with GetContactArea
Definition: dsa.h:328
#define NS_SDH
data structure for storing responses from the remote DSACON32m controller
Definition: dsa.h:275
#define PRINT_MEMBER(_s, _var, _member)
Definition: dsa.cpp:1112
Interface of auxilliary utility functions for SDHLibrary-CPP.
void FlushInput(long timeout_us_first, long timeout_us_subsequent)
Definition: dsa.cpp:647
virtual const char * what() const
UInt8 GetCRC_HB()
return the high byte of the current CRC value
Definition: crc.h:131
static char const * ErrorCodeToString(eDSAErrorCode error_code)
Definition: dsa.cpp:1073
void QuerySensorInfo(sSensorInfo *_sensor_info)
Definition: dsa.cpp:442
UInt16 error_code
0000h, if successful, otherwise error code
Definition: dsa.h:206
This file contains interface to #SDH::cDSA, a class to communicate with the tactile sensors of the SD...
Int32 max_payload_size
Definition: dsa.h:279
Low-level communication class to access a serial port on Cygwin and Linux.
Definition: rs232-cygwin.h:84
Low-level communication class to access a CAN port.
Definition: tcpserial.h:88
A data structure describing the sensor info about the remote DSACON32m controller.
Definition: dsa.h:170
sSensorInfo sensor_info
the sensor info read from the remote DSACON32m controller
Definition: dsa.h:307
int * texel_offset
an array with the offsets of the first texel of all matrices into the whole frame ...
Definition: dsa.h:319
UInt16 nb_matrices
Definition: dsa.h:173
bool acquiring_single_frame
flag, true if user requested acquiring of a single frame. Needed for DSACON32m firmware-bug workaroun...
Definition: dsa.h:687
Interface of class #SDH::cSDHBase.
#define USING_NAMESPACE_SDH
UInt16 size
Definition: dsa.h:269
virtual int write(char const *ptr, int len=0)=0
Write data to a previously opened port.
float matrix_theta_x
Definition: dsa.h:129
double calib_pressure
Definition: dsa.h:340
sContactInfo GetContactInfo(int m)
Definition: dsa.cpp:1026
tTexel GetTexel(int m, int x, int y) const
Definition: dsa.cpp:965
tTexel * texel
an 2D array of tTexel elements. Use GetTexel() for easy access to specific individual elements...
Definition: dsa.h:239
float texel_height
Definition: dsa.h:185
void QueryControllerInfo(sControllerInfo *_controller_info)
Definition: dsa.cpp:434
UInt16 sw_version
Definition: dsa.h:160
UInt8 active_interface
Definition: dsa.h:123
bool m_read_another
Definition: dsa.h:267
UInt8 packet_id
Definition: dsa.h:268
sTactileSensorFrame const & GetFrame() const
return a reference to the latest tactile sensor frame without reading from remote DSACON32m ...
Definition: dsa.h:493
UInt8 * payload
Definition: dsa.h:278
double VoltageToPressure(double voltage)
Definition: dsa.cpp:1005
float matrix_theta_z
Definition: dsa.h:131
Structure to hold info about the sensitivity settings of one sensor patch.
Definition: dsa.h:204
void QueryMatrixInfos(void)
Definition: dsa.cpp:458
#define NAMESPACE_SDH_END
bool do_RLE
flag, true if data should be sent Run Length Encoded by the remote DSACON32m controller ...
Definition: dsa.h:301
This file contains settings to make the SDHLibrary compile on differen systems:
A derived CRC class that uses a CRC table and initial value suitable for the Weiss Robotics DSACON32m...
Definition: crc.h:147
sControllerInfo controller_info
the controller info read from the remote DSACON32m controller
Definition: dsa.h:304
virtual void Open(void)=0
Open rs232 port port.
tCRCValue GetCRC()
return the current CRC value
Definition: crc.h:119
A data structure describing a full tactile sensor frame read from the remote DSACON32m controller...
Definition: dsa.h:235
void ReadFrame(sTactileSensorFrame *frame_p)
Definition: dsa.cpp:353
void SetMatrixThreshold(int matrix_no, UInt16 threshold, bool do_all_matrices=false, bool do_reset=false, bool do_persistent=false)
Definition: dsa.cpp:902
Derived exception class for low-level serial communication related exceptions.
Definition: serialbase.h:86
#define DSA_MAX_PREAMBLE_SEARCH
Definition: dsa.h:61
double cog_y
center of gravity of contact in y direction of sensor patch in mm
Definition: dsa.h:254
sMatrixInfo * matrix_info
the matrix infos read from the remote DSACON32m controller
Definition: dsa.h:310
virtual void Close(void)=0
Close the previously opened communication channel.
sSensorInfo const & GetSensorInfo(void) const
Return a reference to the sSensorInfo read from the remote DSACON32m controller.
Definition: dsa.h:478
float matrix_theta_y
Definition: dsa.h:130
USING_NAMESPACE_SDH NAMESPACE_SDH_START std::ostream * g_sdh_debug_log
Definition: sdhbase.cpp:55
Class for short, fixed maximum length text messages.
Definition: sdhexception.h:77
void ReadSensorInfo(sSensorInfo *_sensor_info)
Definition: dsa.cpp:329
tCRCValue AddByte(unsigned char byte)
insert byte into CRC calculation and return the new current CRC checksum
Definition: crc.h:104
virtual ssize_t Read(void *data, ssize_t size, long timeout_us, bool return_on_less_data)=0
double area
area of contact in mm*mm.
Definition: dsa.h:252
bool GetFlag(void) const
Definition: dbg.h:158
#define DEFINE_TO_CASECOMMAND(_c)
Definition: util.h:103
UInt8 hw_version
Definition: dsa.h:118
~cDSA()
Destructur: clean up and delete dynamically allocated memory.
Definition: dsa.cpp:724
void QueryMatrixInfo(sMatrixInfo *_matrix_info, int matrix_no)
Definition: dsa.cpp:450
struct VCC_EXPORT cDSA::sTactileSensorFrame SDH__attribute__
void PDM(char const *fmt,...) SDH__attribute__((format(printf
unsigned long GetAgeOfFrame(sTactileSensorFrame *frame_p)
Definition: dsa.h:651
void WriteCommand(UInt8 command)
Definition: dsa.h:347
cDBG dbg
A stream object to print colored debug messages.
Definition: serialbase.h:227
UInt16 GetMatrixThreshold(int matrix_no)
Definition: dsa.cpp:934
sSensitivityInfo GetMatrixSensitivity(int matrix_no)
Definition: dsa.cpp:879
UInt8 GetCRC_LB()
return the low byte of the current CRC value
Definition: crc.h:125
void ReadControllerInfo(sControllerInfo *_controller_info)
Definition: dsa.cpp:314
UInt16 size
Definition: dsa.h:277
A data structure describing a single sensor matrix connected to the remote DSACON32m controller...
Definition: dsa.h:181
float matrix_center_x
Definition: dsa.h:125
uint16_t UInt16
unsigned integer, size 2 Byte (16 Bit)
Definition: basisdef.h:63
double cog_x
center of gravity of contact in x direction of sensor patch in mm
Definition: dsa.h:253
int nb_cells
The total number of sensor cells.
Definition: dsa.h:316
UInt32 can_baudrate
Definition: dsa.h:124
A data structure describing the controller info about the remote DSACON32m controller.
Definition: dsa.h:155
UInt8 hw_revision
Definition: dsa.h:119
void SetFramerateRetries(UInt16 framerate, bool do_RLE=true, bool do_data_acquisition=true, unsigned int retries=0, bool ignore_exceptions=false)
Definition: dsa.cpp:810


sdhlibrary_cpp
Author(s): Dirk Osswald
autogenerated on Sun Aug 18 2019 03:42:20