SVHSerialInterface.cpp
Go to the documentation of this file.
1 //
3 // © Copyright 2022 SCHUNK Mobile Greifsysteme GmbH, Lauffen/Neckar Germany
4 // © Copyright 2022 FZI Forschungszentrum Informatik, Karlsruhe, Germany
5 //
6 // This file is part of the Schunk SVH Library.
7 //
8 // The Schunk SVH Library is free software: you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or (at your
11 // option) any later version.
12 //
13 // The Schunk SVH Library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 // Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // the Schunk SVH Library. If not, see <https://www.gnu.org/licenses/>.
20 //
22 
23 //----------------------------------------------------------------------
36 //----------------------------------------------------------------------
39 
40 #include <chrono>
41 #include <functional>
42 #include <memory>
44 #include <thread>
45 
46 
48 
49 namespace driver_svh {
50 
52  : m_connected(false)
53  , m_received_packet_callback(received_packet_callback)
54  , m_packets_transmitted(0)
55 {
56 }
57 
59 {
60  // close();
61 }
62 
63 bool SVHSerialInterface::connect(const std::string& dev_name)
64 {
65  // close device if already opened
66  close();
67 
68  // create serial device
69  m_serial_device.reset(
70  new Serial(dev_name.c_str(), SerialFlags(SerialFlags::BR_921600, SerialFlags::DB_8)));
71 
72  if (m_serial_device)
73  {
74  // open serial device
75  if (!m_serial_device->open())
76  {
77  SVH_LOG_ERROR_STREAM("SVHSerialInterface",
78  "Could not open serial device: " << dev_name.c_str());
79  return false;
80  }
81  }
82  else
83  {
84  SVH_LOG_ERROR_STREAM("SVHSerialInterface",
85  "Could not create serial device handle: " << dev_name.c_str());
86  return false;
87  }
88 
90  std::make_unique<SVHReceiveThread>(std::chrono::microseconds(500),
93  this,
94  std::placeholders::_1,
95  std::placeholders::_2));
96 
97  // create receive thread
98  m_receive_thread = std::thread([this] { m_svh_receiver->run(); });
99 
100  m_connected = true;
101  SVH_LOG_DEBUG_STREAM("SVHSerialInterface",
102  "Serial device "
103  << dev_name.c_str()
104  << " opened and receive thread started. Communication can now begin.");
105 
106  return true;
107 }
108 
110 {
111  m_connected = false;
112 
113  // cancel and delete receive packet thread
114  if (m_svh_receiver)
115  {
116  m_svh_receiver->stop();
117  }
118  if (m_receive_thread.joinable())
119  {
120  m_receive_thread.join();
121  SVH_LOG_DEBUG_STREAM("SVHSerialInterface", "Serial device receive thread was terminated.");
122  }
123 
124  // close and delete serial device handler
125  if (m_serial_device)
126  {
127  m_serial_device->close();
128 
129  m_serial_device.reset();
130  SVH_LOG_DEBUG_STREAM("SVHSerialInterface", "Serial device handle was closed and terminated.");
131  }
132 }
133 
135 {
136  if (m_serial_device != NULL)
137  {
138  // For alignment: Always 64Byte data, padded with zeros
139  packet.data.resize(64, 0);
140 
141  uint8_t check_sum1 = 0;
142  uint8_t check_sum2 = 0;
143 
144  // Calculate Checksum for the packet
145  for (size_t i = 0; i < packet.data.size(); i++)
146  {
147  check_sum1 += packet.data[i];
148  check_sum2 ^= packet.data[i];
149  }
150 
151  // set packet counter
152  packet.index = static_cast<uint8_t>(m_packets_transmitted % uint8_t(-1));
153 
154  if (m_serial_device->isOpen())
155  {
156  // Prepare arraybuilder
157  ssize_t size = static_cast<ssize_t>(packet.data.size() + C_PACKET_APPENDIX_SIZE);
158  driver_svh::ArrayBuilder send_array(size);
159  // Write header and packet information and checksum
160  send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
161 
162  // actual hardware call to send the packet
163  ssize_t bytes_send = 0;
164  while (bytes_send < size)
165  {
166  bytes_send +=
167  m_serial_device->write(send_array.array.data() + bytes_send, size - bytes_send);
168  }
169 
170  // Small delay -> THIS SHOULD NOT BE NECESSARY as the communication speed should be handable
171  // by the HW. However, it will die if this sleep is not used and this may also depend on your
172  // computer speed -> This issue might stem also from the hardware and will hopefully be fixed
173  // soon. 782µs are needed to send 72bytes via a baudrate of 921600
174  std::this_thread::sleep_for(std::chrono::microseconds(782));
175  // Instead you could wait for the response of the packet (or on of the previous n packets).
176  // This slows down the speed to the 2-way latency, which is platform dependent
177  }
178  else
179  {
180  SVH_LOG_DEBUG_STREAM("SVHSerialInterface",
181  "sendPacket failed, serial device was not properly initialized.");
182  return false;
183  }
184 
186  }
187 
188  return true;
189 }
190 
192 {
194  // Only the receive thread knows abotu the accurate number it has received
195  m_svh_receiver->resetReceivedPackageCount();
196 }
197 
199 {
200  uint8_t check_sum1 = 0;
201  uint8_t check_sum2 = 0;
202 
203  // Calculate Checksum for the packet
204  for (size_t i = 0; i < packet.data.size(); i++)
205  {
206  check_sum1 += packet.data[i];
207  check_sum2 ^= packet.data[i];
208  }
209 
210  // set packet counter
211  packet.index = static_cast<uint8_t>(m_dummy_packets_printed % uint8_t(-1));
212 
213 
214  // Prepare arraybuilder
215  size_t size = packet.data.size() + C_PACKET_APPENDIX_SIZE;
216  driver_svh::ArrayBuilder send_array(size);
217  // Write header and packet information and checksum
218  send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
219 
220  std::cout << send_array << std::endl;
221 
223 }
224 
226  unsigned int packet_count)
227 {
228  m_last_index = packet.index;
229  m_received_packet_callback(packet, packet_count);
230 }
231 
232 } // namespace driver_svh
std::unique_ptr< SVHReceiveThread > m_svh_receiver
handle to manage the actual receiving of data
const uint8_t PACKET_HEADER1
Header sync byte 1.
ReceivedPacketCallback m_received_packet_callback
Callback function for received packets.
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.
std::shared_ptr< Serial > m_serial_device
pointer to serial interface object
void receivedPacketCallback(const SVHSerialPacket &packet, unsigned int packet_count)
void close()
canceling receive thread and closing connection to serial port
std::vector< uint8_t > array
array of template type TArray
unsigned int m_dummy_packets_printed
packet counter simulation for pure showing purposes
std::function< void(const SVHSerialPacket &packet, unsigned int packet_count)> ReceivedPacketCallback
definition of function callback for received packages
bool sendPacket(SVHSerialPacket &packet)
function for sending packets via serial device to the SVH
std::vector< uint8_t > data
Payload of the package.
bool connect(const std::string &dev_name)
connecting to serial device and starting receive thread
const size_t C_PACKET_APPENDIX_SIZE
The packet overhead size in bytes.
#define SVH_LOG_DEBUG_STREAM(NAME, M)
Definition: Logger.h:39
#define SVH_LOG_ERROR_STREAM(NAME, M)
Definition: Logger.h:60
uint8_t index
Continuosly incremented counter per package.
unsigned int m_packets_transmitted
packet counters
bool m_connected
serial device connected state
SVHSerialInterface(const ReceivedPacketCallback &received_packet_callback)
Constructs a serial interface class for basic communication with the SCHUNK five finger hand...
std::thread m_receive_thread
thread for receiving serial packets
Enables acces to serial devices.
Definition: Serial.h:68
void resetTransmitPackageCount()
resetTransmitPackageCount Resets the transmitpackage count to zero
The SerialPacket holds the (non generated) header and data of one message to the SVH-Hardware.
Short description of tSerialFlags.
Definition: SerialFlags.h:52


schunk_svh_library
Author(s): Georg Heppner, Lars Pfotzer, Felix Exner, Johannes Mangler, Stefan Scherzinger, Pascal Becker
autogenerated on Fri Apr 14 2023 02:26:23