SVHSerialInterface.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of the SCHUNK SVH Driver suite.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2014 SCHUNK Mobile Greifsysteme GmbH, Lauffen/Neckar Germany
12 // © Copyright 2014 FZI Forschungszentrum Informatik, Karlsruhe, Germany
13 //
14 // -- END LICENSE BLOCK ------------------------------------------------
15 
16 //----------------------------------------------------------------------
29 //----------------------------------------------------------------------
31 #include "driver_svh/Logging.h"
32 
33 #include <icl_comm/ByteOrderConversion.h>
34 #include <boost/bind/bind.hpp>
35 
36 using icl_core::TimeSpan;
37 using icl_comm::serial::SerialFlags;
38 
39 namespace driver_svh {
40 
42  m_connected(false),
43  m_received_packet_callback(received_packet_callback),
44  m_packets_transmitted(0)
45 {
46 }
47 
49 {
50  //close();
51 }
52 
53 bool SVHSerialInterface::connect(const std::string &dev_name)
54 {
55  // close device if already opened
56  close();
57 
58  // create serial device
59  m_serial_device.reset(new Serial(dev_name.c_str(), SerialFlags(SerialFlags::eBR_921600, SerialFlags::eDB_8)));
60 
61  if (m_serial_device)
62  {
63  // open serial device
64  if (!m_serial_device->Open())
65  {
66  LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not open serial device: " << dev_name.c_str() << endl);
67  return false;
68  }
69  }
70  else
71  {
72  LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not create serial device handle: " << dev_name.c_str() << endl);
73  return false;
74  }
75 
76  // create receive thread
78 
79  if (m_receive_thread)
80  {
81  // start receive thread
82  if (!m_receive_thread->start())
83  {
84  LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not start the receive thread for the serial device!" << endl);
85  return false;
86  }
87  }
88  else
89  {
90  LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not create the receive thread for the serial device!" << endl);
91  return false;
92  }
93 
94  m_connected = true;
95  LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device " << dev_name.c_str() << " opened and receive thread started. Communication can now begin." << endl);
96 
97  return true;
98 }
99 
101 {
102  m_connected = false;
103 
104  // cancel and delete receive packet thread
105  if (m_receive_thread)
106  {
107  // cancel thread
108  m_receive_thread->cancel();
109 
110  m_receive_thread.reset();
111 
112  LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device receive thread was terminated." << endl);
113  }
114 
115  // close and delete serial device handler
116  if (m_serial_device)
117  {
118  m_serial_device->Close();
119 
120  m_serial_device.reset();
121  LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device handle was closed and terminated." << endl);
122  }
123 }
124 
126 {
127  if (m_serial_device != NULL)
128  {
129  // For alignment: Always 64Byte data, padded with zeros
130  packet.data.resize(64,0);
131  uint8_t check_sum1 = 0;
132  uint8_t check_sum2 = 0;
133 
134  // Calculate Checksum for the packet
135  for (size_t i = 0; i < packet.data.size(); i++)
136  {
137  check_sum1 += packet.data[i];
138  check_sum2 ^= packet.data[i];
139  }
140 
141  // set packet counter
142  packet.index = static_cast<uint8_t>(m_packets_transmitted % uint8_t(-1));
143 
144  if (m_serial_device->IsOpen())
145  {
146  // Prepare arraybuilder
147  size_t size = packet.data.size() + cPACKET_APPENDIX_SIZE;
148  icl_comm::ArrayBuilder send_array(size);
149  // Write header and packet information and checksum
150  send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
151 
152  // actual hardware call to send the packet
153  size_t bytes_send = 0;
154  while (bytes_send < size)
155  {
156  bytes_send += m_serial_device->Write(send_array.array.data() + bytes_send, size - bytes_send);
157  }
158 
159  // Small delay -> THIS SHOULD NOT BE NECESSARY as the communication speed should be handable by the HW. However, it will die if this sleep is
160  // not used and this may also depend on your computer speed -> This issue might stem also from the hardware and will hopefully be fixed soon.
161  // 782µs are needed to send 72bytes via a baudrate of 921600
163  // Instead you could wait for the response of the packet (or on of the previous n packets). This slows down the speed to the 2-way latency, which is platform dependent
164  /*icl_core::TimeStamp start_time = icl_core::TimeStamp::now();
165  bool timeout = false;
166  while(!timeout){
167  if(uint8_t(packet.index-last_index)<8)break;
168  if ((icl_core::TimeStamp::now() - start_time).tsSec() > 1)
169  {
170  timeout = true;
171  }
172  }//*/
173 
174  }
175  else
176  {
177  LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "sendPacket failed, serial device was not properly initialized." << endl);
178  return false;
179  }
180 
182  }
183 
184  return true;
185 }
186 
188 {
190  // Only the receive thread knows abotu the accurate number it has received
191  m_receive_thread->resetReceivedPackageCount();
192 }
193 
195 {
196 
197  uint8_t check_sum1 = 0;
198  uint8_t check_sum2 = 0;
199 
200  // Calculate Checksum for the packet
201  for (size_t i = 0; i < packet.data.size(); i++)
202  {
203  check_sum1 += packet.data[i];
204  check_sum2 ^= packet.data[i];
205  }
206 
207  // set packet counter
208  packet.index = static_cast<uint8_t>(m_dummy_packets_printed % uint8_t(-1));
209 
210 
211  // Prepare arraybuilder
212  size_t size = packet.data.size() + cPACKET_APPENDIX_SIZE;
213  icl_comm::ArrayBuilder send_array(size);
214  // Write header and packet information and checksum
215  send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
216 
217  std::cout << send_array << std::endl;
218 
220 }
221 
222 void SVHSerialInterface::receivedPacketCallback(const SVHSerialPacket &packet, unsigned int packet_count)
223 {
224  last_index=packet.index;
225  m_received_packet_callback(packet,packet_count);
226 }
227 
228 }
const uint8_t PACKET_HEADER1
Header sync byte 1.
ReceivedPacketCallback m_received_packet_callback
Callback function for received packets.
boost::function< void(const SVHSerialPacket &packet, unsigned int packet_count)> ReceivedPacketCallback
definition of boost function callback for received packages
const uint8_t PACKET_HEADER2
Header sync byte 2.
void printPacketOnConsole(SVHSerialPacket &packet)
printPacketOnConsole is a pure helper function to show what raw data is actually sent. This is not meant for any productive use other than understand whats going on.
void receivedPacketCallback(const SVHSerialPacket &packet, unsigned int packet_count)
called on received packets, calls m_received_packet_callback
void close()
canceling receive thread and closing connection to serial port
unsigned int m_dummy_packets_printed
packet counter simulation for pure showing purposes
int usleep(unsigned long useconds)
bool sendPacket(SVHSerialPacket &packet)
function for sending packets via serial device to the SVH
std::vector< uint8_t > data
Payload of the package.
Thread for receiving messages from the serial device.
unsigned char uint8_t
bool connect(const std::string &dev_name)
connecting to serial device and starting receive thread
ThreadStream & endl(ThreadStream &stream)
const size_t cPACKET_APPENDIX_SIZE
The packet overhead size in bytes.
uint8_t index
Continuosly incremented counter per package.
unsigned int m_packets_transmitted
packet counters
boost::shared_ptr< SVHReceiveThread > m_receive_thread
thread for receiving serial packets
bool m_connected
serial device connected state
boost::shared_ptr< Serial > m_serial_device
pointer to serial interface object
SVHSerialInterface(const ReceivedPacketCallback &received_packet_callback)
Constructs a serial interface class for basic communication with the SCHUNK five finger hand...
uint8_t last_index
used to wait to the response of the sending packet
Basic communication handler for the SCHUNK five finger hand.
void resetTransmitPackageCount()
resetTransmitPackageCount Resets the transmitpackage count to zero
#define LOGGING_TRACE_C(streamname, classname, arg)
#define LOGGING_ERROR_C(streamname, classname, arg)
The SerialPacket holds the (non generated) header and data of one message to the SVH-Hardware.


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Mon Jun 10 2019 15:04:59