104 int bytes_written = 0;
109 char* buffer =
new char[ payload_len+8 ];
114 char buffer[ payload_len + 8 ];
116 buffer[0] = (
UInt8) 0xaa;
117 buffer[1] = (
UInt8) 0xaa;
118 buffer[2] = (
UInt8) 0xaa;
120 buffer[4] = ((
UInt8*) &payload_len)[0];
121 buffer[5] = ((
UInt8*) &payload_len)[1];
123 if ( payload_len > 0)
131 for ( i=0; i < payload_len; i++)
133 checksum.
AddByte( payload[ i ] );
134 buffer[ 6+i ] = payload[i];
137 if ( payload_len > 0)
140 len = payload_len + 8;
150 bytes_written =
com->
write( buffer, len );
164 if ( bytes_written != len )
165 throw new cDSAException(
cMsg(
"Could only write %d/%d bytes to DSACON32m", bytes_written, len ) );
171 assert( response !=
NULL );
173 int retries_frames = 0;
174 while ( retries_frames++ < 5 )
180 int nb_preamble_bytes = 0;
181 ssize_t bytes_read = 0;
191 dbg <<
"Caught cSerialBaseException " << e->
what() <<
", rethrowing as cDSAException timeout\n";
195 if ( bytes_read == 0 )
196 throw new cDSAException(
cMsg(
"Timeout while reading preamble from remote DSACON32m controller" ) );
202 dbg <<
"found valid preamble byte no " << nb_preamble_bytes <<
"\n";
206 nb_preamble_bytes = 0;
207 dbg <<
"ignoring invalid preamble byte " << int(byte) <<
"\n";
210 found = nb_preamble_bytes == 3;
214 throw new cDSAException(
cMsg(
"Could not find valid preamble in %ld data bytes from remote DSACON32m controller", bytes_read ) );
220 if ( bytes_read != 3 )
222 throw new cDSAException(
cMsg(
"Could only read %ld/3 header bytes from remote DSACON32m controller", bytes_read ) );
233 char* buffer =
new char[ response->
size+2 ];
238 char buffer[ response->
size+2 ];
242 dbg <<
"Read and ignored " << nb_bytes_ignored <<
" bytes of response " << *response <<
"\n";
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 ) );
271 if ( bytes_read != response->
size )
273 throw new cDSAException(
cMsg(
"Could only read %ld/%d payload bytes from remote DSACON32m controller", bytes_read, response->
size ) );
279 if ( response->
size > 0 )
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 ) );
291 for ( i=0; i < response->
size; i++ )
294 if ( checksum_received != checksum_calculated.
GetCRC() )
296 dbg <<
"Checksum Error, got 0x" << std::hex << checksum_received <<
" but expected 0x" << std::hex << checksum_calculated.
GetCRC() <<
"\n";
297 dbg <<
"response = " << *response <<
"\n";
300 throw new cDSAException(
cMsg(
"Checksum Error, got 0x%x but expected 0x%x", checksum_received, checksum_calculated.
GetCRC() ) );
303 dbg <<
"Checksum OK\n";
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 ) );
316 sResponse response( (
UInt8*) _controller_info,
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 ) );
331 sResponse response( (
UInt8*) _sensor_info,
sizeof( *_sensor_info ) );
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) ) );
343 sResponse response( (
UInt8*) _matrix_info,
sizeof( *_matrix_info ) );
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) ) );
365 UInt8 buffer[ buffersize ];
367 sResponse response( buffer, buffersize );
380 while ( read_another )
392 read_another =
false;
426 dbg <<
"switching off acquiring single frames\n";
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) );
541 while (i+1 < response->
size)
544 v = rle_unit & 0x0fff;
551 frame_p->
texel[ j ] = v;
556 i +=
sizeof( rle_unit );
579 dbg <<
"Debug messages of class cDSA are printed like this.\n";
586 assert(
sizeof(
sResponse ) == 7 +
sizeof(
char* ) );
596 cDSA::cDSA(
int debug_level,
int port,
char const* device_format_string )
617 com =
new cRS232( port, 115200, 1.0, device_format_string );
622 cDSA::cDSA(
int debug_level,
char const* _tcp_adr,
int _tcp_port,
double _timeout )
649 int bytes_read, bytes_read_total = 0;
650 long timeout_us = timeout_us_first;
654 bytes_read =
com->
Read( &byte, 4096, timeout_us,
true );
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";
754 if ( response.
size != 2 )
756 throw new cDSAException(
cMsg(
"Invalid response from DSACON32m for %s, expected 2 bytes but got %d", msg, response.
size ) );
768 dbg <<
"cDSA::SetFramerate, setting framerate to " << framerate <<
" do_data_acquisition= " << do_data_acquisition <<
"\n";
771 if ( do_data_acquisition )
795 buffer[1] = ((
UInt8*) &framerate)[0];
796 buffer[2] = ((
UInt8*) &framerate)[1];
800 dbg <<
"acknowledge ok\n";
802 if ( framerate==0 && do_data_acquisition )
822 if ( retries-- == 0 && !ignore_exceptions )
825 dbg <<
"ignoring Caught exception: " << e->
what() <<
"\n";
831 }
while ( retries>0 );
838 bool do_all_matrices,
843 #pragma pack(push,1) // for VCC (MS Visual Studio) we have to set the necessary 1 byte packing with this pragma 845 struct sSetSensitivity
852 #pragma pack(pop) // for VCC (MS Visual Studio) restore normal packing 855 sSetSensitivity set_sensitivity;
857 set_sensitivity.flags = 0;
859 set_sensitivity.flags |= (1<<7);
860 if ( do_all_matrices )
861 set_sensitivity.flags |= (1<<1);
863 set_sensitivity.flags |= (1<<0);
865 set_sensitivity.matrix_no = (
UInt8) matrix_no;
866 set_sensitivity.sensitivity = (float) sensitivity;
871 if ( ! do_persistent )
874 dbg <<
"SetMatrixSensitivity ok\n";
885 sResponse response( (
UInt8*) &sensitivity_info,
sizeof( sensitivity_info ) );
888 if ( response.
size !=
sizeof( sensitivity_info ) )
890 throw new cDSAException(
cMsg(
"Invalid response from DSACON32m for cDSA::GetMatrixSensitivity(), expected %ld bytes but got %d",
sizeof( sensitivity_info ), response.
size ) );
894 throw new cDSAException(
cMsg(
"Error response from DSACON32m for cDSA::GetMatrixSensitivity(), errorcode = %d (%s)", sensitivity_info.error_code,
ErrorCodeToString( sensitivity_info.error_code ) ) );
896 dbg <<
"GetMatrixSensitivity ok\n";
898 return sensitivity_info;
904 bool do_all_matrices,
914 if ( do_all_matrices )
921 buffer[1] = matrix_no & 0xff;
922 memcpy( &(buffer[2]), &threshold,
sizeof( threshold ) );
926 if ( ! do_persistent )
929 dbg <<
"SetMatrixThreshold ok\n";
942 sResponse response( buffer,
sizeof(buffer) );
946 if ( response.
size !=
sizeof( buffer ) )
948 throw new cDSAException(
cMsg(
"cDSA::GetMatrixThreshold() Invalid response from DSACON32m, expected %ld bytes but got %d",
sizeof( buffer ), response.
size ) );
953 memcpy( (
void*) &error_code, (
void*) &(buffer[0]),
sizeof( error_code ) );
956 dbg <<
"GetMatrixThreshold ok\n";
959 memcpy( (
void*) &threshold, (
void*) &(buffer[2]),
sizeof( threshold ) );
1029 double sum_pressures = 0.0;
1047 sum_x += double(x) * p;
1048 sum_y += double(y) * p;
1057 if ( sum_pressures != 0.0 )
1106 return "unknown error_code";
1112 #define PRINT_MEMBER( _s, _var, _member ) \ 1113 (_s) << " " << #_member << "=" << _var._member << "\n" 1115 #define PRINT_MEMBER_HEX( _s, _var, _member ) \ 1116 (_s) << " " << #_member << "=0x" << std::hex << int(_var._member) << std::dec << "\n" 1123 stream <<
"sControllerInfo:\n";
1140 stream <<
"sSensorInfo:\n";
1153 stream <<
"sMatrixInfo:\n";
1159 stream <<
" " <<
"uid" <<
"={";
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]);
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(
' ');
1187 stream <<
"sResponse:\n";
1192 stream <<
" payload=";
1199 stream <<
"\n " << std::setw(3) << i <<
": " << hbs;
1215 stream <<
"cDSA.frame:";
1219 unsigned int m, x, y;
1222 stream <<
" matrix " << m <<
":\n";
1226 stream << std::setw( 2 ) << y <<
"| ";
1229 stream << std::setw( 4 ) << dsa.
GetTexel( m, x, y ) <<
" ";
cDBG dbg
A stream object to print coloured debug messages.
double calib_voltage
see calib_pressure
sTactileSensorFrame const & GetFrame() const
return a reference to the latest tactile sensor frame without reading from remote DSACON32m ...
void WriteCommandWithPayload(UInt8 command, UInt8 *payload, UInt16 payload_len)
double force_factor
additional calibration factor for forces in GetContactForce
void StoreNow(void)
Store current time internally.
UInt32 timestamp
the timestamp of the frame. Use GetAgeOfFrame() to set this into relation with the time of the PC...
eDSAPacketID
Command ID for the DSACON32m tactile sensor controller according to DSACON32_Command_Set_Reference_Ma...
double Elapsed(void) const
Return time in seconds elapsed between the time stored in the object and now.
uint8_t UInt8
unsigned integer, size 1 Byte (8 Bit)
void ParseFrame(sResponse *response, sTactileSensorFrame *frame_p)
#define PRINT_MEMBER_HEX(_s, _var, _member)
cSerialBase * com
the communication interface to use
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()
helper class to set value on construction and reset to previous value on destruction. (RAII-idiom)
void ReadMatrixInfo(sMatrixInfo *_matrix_info)
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
sTactileSensorFrame frame
the latest frame received from the remote DSACON32m controller
Derived exception class for low-level DSA related exceptions.
long read_timeout_us
default timeout used for reading in us
UInt16 error_code
0000h, if successful, otherwise error code
virtual const char * what() const
void Close(void)
Set the framerate of the remote DSACON32m controller to 0 and close connection to it...
cDSA(int debug_level=0, int port=1, char const *device_format_string="/dev/ttyS%d")
void ReadResponse(sResponse *response, UInt8 command_id)
dummy class for (debug) stream output of bytes as list of hex values
void ReadAndCheckErrorResponse(char const *msg, UInt8 command_id)
friend VCC_EXPORT std::ostream & operator<<(std::ostream &stream, cDSA::sResponse const &response)
double GetContactArea(int m)
UInt16 tTexel
data type for a single 'texel' (tactile sensor element)
sSensorInfo const & GetSensorInfo(void) const
Return a reference to the sSensorInfo read from the remote DSACON32m controller.
eDSAErrorCode
error codes returned by the remote DSACON32m tactile sensor controller
void SetFramerate(UInt16 framerate, bool do_RLE=true, bool do_data_acquisition=true)
void SetMatrixSensitivity(int matrix_no, double sensitivity, bool do_all_matrices=false, bool do_reset=false, bool do_persistent=false)
uint32_t UInt32
unsigned integer, size 4 Byte (32 Bit)
#define NAMESPACE_SDH_START
void Init(int debug_level)
SDH::cDSA is the end user interface class to access the DSACON32m, the tactile sensor controller of t...
tTexel contact_area_cell_threshold
threshold of texel cell value for detecting contacts with GetContactArea
data structure for storing responses from the remote DSACON32m controller
#define PRINT_MEMBER(_s, _var, _member)
Interface of auxilliary utility functions for SDHLibrary-CPP.
void FlushInput(long timeout_us_first, long timeout_us_subsequent)
UInt8 GetCRC_HB()
return the high byte of the current CRC value
void QuerySensorInfo(sSensorInfo *_sensor_info)
tTexel GetTexel(int m, int x, int y) const
This file contains interface to #SDH::cDSA, a class to communicate with the tactile sensors of the SD...
Low-level communication class to access a serial port on Cygwin and Linux.
Low-level communication class to access a CAN port.
A data structure describing the sensor info about the remote DSACON32m controller.
sSensorInfo sensor_info
the sensor info read from the remote DSACON32m controller
int * texel_offset
an array with the offsets of the first texel of all matrices into the whole frame ...
bool acquiring_single_frame
flag, true if user requested acquiring of a single frame. Needed for DSACON32m firmware-bug workaroun...
Interface of class #SDH::cSDHBase.
#define USING_NAMESPACE_SDH
virtual int write(char const *ptr, int len=0)=0
Write data to a previously opened port.
sContactInfo GetContactInfo(int m)
tTexel * texel
an 2D array of tTexel elements. Use GetTexel() for easy access to specific individual elements...
void QueryControllerInfo(sControllerInfo *_controller_info)
double VoltageToPressure(double voltage)
Structure to hold info about the sensitivity settings of one sensor patch.
void QueryMatrixInfos(void)
#define NAMESPACE_SDH_END
bool do_RLE
flag, true if data should be sent Run Length Encoded by the remote DSACON32m controller ...
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...
sControllerInfo controller_info
the controller info read from the remote DSACON32m controller
virtual void Open(void)=0
Open rs232 port port.
tCRCValue GetCRC()
return the current CRC value
A data structure describing a full tactile sensor frame read from the remote DSACON32m controller...
void ReadFrame(sTactileSensorFrame *frame_p)
void SetMatrixThreshold(int matrix_no, UInt16 threshold, bool do_all_matrices=false, bool do_reset=false, bool do_persistent=false)
Derived exception class for low-level serial communication related exceptions.
#define DSA_MAX_PREAMBLE_SEARCH
sMatrixInfo * matrix_info
the matrix infos read from the remote DSACON32m controller
virtual void Close(void)=0
Close the previously opened communication channel.
USING_NAMESPACE_SDH NAMESPACE_SDH_START std::ostream * g_sdh_debug_log
Class for short, fixed maximum length text messages.
void ReadSensorInfo(sSensorInfo *_sensor_info)
tCRCValue AddByte(unsigned char byte)
insert byte into CRC calculation and return the new current CRC checksum
virtual ssize_t Read(void *data, ssize_t size, long timeout_us, bool return_on_less_data)=0
#define DEFINE_TO_CASECOMMAND(_c)
~cDSA()
Destructur: clean up and delete dynamically allocated memory.
void QueryMatrixInfo(sMatrixInfo *_matrix_info, int matrix_no)
struct VCC_EXPORT cDSA::sTactileSensorFrame SDH__attribute__
void PDM(char const *fmt,...) SDH__attribute__((format(printf
unsigned long GetAgeOfFrame(sTactileSensorFrame *frame_p)
sMatrixInfo const & GetMatrixInfo(int m) const
Return a reference to the sMatrixInfo of matrix m read from the remote DSACON32m controller.
void WriteCommand(UInt8 command)
cDBG dbg
A stream object to print colored debug messages.
UInt16 GetMatrixThreshold(int matrix_no)
sSensitivityInfo GetMatrixSensitivity(int matrix_no)
UInt8 GetCRC_LB()
return the low byte of the current CRC value
void ReadControllerInfo(sControllerInfo *_controller_info)
A data structure describing a single sensor matrix connected to the remote DSACON32m controller...
uint16_t UInt16
unsigned integer, size 2 Byte (16 Bit)
static char const * ErrorCodeToString(eDSAErrorCode error_code)
int nb_cells
The total number of sensor cells.
A data structure describing the controller info about the remote DSACON32m controller.
void SetFramerateRetries(UInt16 framerate, bool do_RLE=true, bool do_data_acquisition=true, unsigned int retries=0, bool ignore_exceptions=false)