SVHSerialInterface.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of the SCHUNK SVH Driver suite.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2014 SCHUNK Mobile Greifsysteme GmbH, Lauffen/Neckar Germany
00012 // © Copyright 2014 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00013 //
00014 // -- END LICENSE BLOCK ------------------------------------------------
00015 
00016 //----------------------------------------------------------------------
00029 //----------------------------------------------------------------------
00030 #include "driver_svh/SVHSerialInterface.h"
00031 #include "driver_svh/Logging.h"
00032 
00033 #include <icl_comm/ByteOrderConversion.h>
00034 #include <boost/bind/bind.hpp>
00035 
00036 using icl_core::TimeSpan;
00037 using icl_comm::serial::SerialFlags;
00038 
00039 namespace driver_svh {
00040 
00041 SVHSerialInterface::SVHSerialInterface(ReceivedPacketCallback const & received_packet_callback) :
00042   m_connected(false),
00043   m_received_packet_callback(received_packet_callback),
00044   m_packets_transmitted(0)
00045 {
00046 }
00047 
00048 SVHSerialInterface::~SVHSerialInterface()
00049 {
00050   //close();
00051 }
00052 
00053 bool SVHSerialInterface::connect(const std::string &dev_name)
00054 {
00055   // close device if already opened
00056   close();
00057 
00058   // create serial device
00059   m_serial_device.reset(new Serial(dev_name.c_str(), SerialFlags(SerialFlags::eBR_921600, SerialFlags::eDB_8)));
00060 
00061   if (m_serial_device)
00062   {
00063     // open serial device
00064     if (!m_serial_device->Open())
00065     {
00066       LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not open serial device: " << dev_name.c_str() << endl);
00067       return false;
00068     }
00069   }
00070   else
00071   {
00072     LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not create serial device handle: " << dev_name.c_str() << endl);
00073     return false;
00074   }
00075 
00076   // create receive thread
00077   m_receive_thread.reset(new SVHReceiveThread(TimeSpan(0, 500000), m_serial_device, boost::bind(&SVHSerialInterface::receivedPacketCallback,this,_1,_2)));
00078 
00079   if (m_receive_thread)
00080   {
00081     // start receive thread
00082     if (!m_receive_thread->start())
00083     {
00084       LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not start the receive thread for the serial device!" << endl);
00085       return false;
00086     }
00087   }
00088   else
00089   {
00090     LOGGING_ERROR_C(DriverSVH, SVHSerialInterface, "Could not create the receive thread for the serial device!" << endl);
00091     return false;
00092   }
00093 
00094   m_connected = true;
00095   LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device  " << dev_name.c_str()  << " opened and receive thread started. Communication can now begin." << endl);
00096 
00097   return true;
00098 }
00099 
00100 void SVHSerialInterface::close()
00101 {
00102   m_connected = false;
00103 
00104   // cancel and delete receive packet thread
00105   if (m_receive_thread)
00106   {
00107     // cancel thread
00108     m_receive_thread->cancel();
00109 
00110     m_receive_thread.reset();
00111 
00112     LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device receive thread was terminated." << endl);
00113   }
00114 
00115   // close and delete serial device handler
00116   if (m_serial_device)
00117   {
00118     m_serial_device->Close();
00119 
00120     m_serial_device.reset();
00121     LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "Serial device handle was closed and terminated." << endl);
00122   }
00123 }
00124 
00125 bool SVHSerialInterface::sendPacket(SVHSerialPacket& packet)
00126 {
00127   if (m_serial_device != NULL)
00128   {
00129     // For alignment: Always 64Byte data, padded with zeros
00130     packet.data.resize(64,0);
00131     uint8_t check_sum1 = 0;
00132     uint8_t check_sum2 = 0;
00133 
00134     // Calculate Checksum for the packet
00135     for (size_t i = 0; i < packet.data.size(); i++)
00136     {
00137       check_sum1 += packet.data[i];
00138       check_sum2 ^= packet.data[i];
00139     }
00140 
00141     // set packet counter
00142     packet.index = static_cast<uint8_t>(m_packets_transmitted % uint8_t(-1));
00143 
00144     if (m_serial_device->IsOpen())
00145     {
00146       // Prepare arraybuilder
00147       size_t size = packet.data.size() + cPACKET_APPENDIX_SIZE;
00148       icl_comm::ArrayBuilder send_array(size);
00149       // Write header and packet information and checksum
00150       send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
00151 
00152       // actual hardware call to send the packet
00153       size_t bytes_send = 0;
00154       while (bytes_send < size)
00155       {
00156         bytes_send += m_serial_device->Write(send_array.array.data() + bytes_send, size - bytes_send);
00157       }
00158 
00159       // 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
00160       // 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.
00161       // 782µs are needed to send 72bytes via a baudrate of 921600
00162       icl_core::os::usleep(782);
00163       // 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
00164       /*icl_core::TimeStamp start_time = icl_core::TimeStamp::now();
00165       bool timeout = false;
00166       while(!timeout){
00167         if(uint8_t(packet.index-last_index)<8)break;
00168         if ((icl_core::TimeStamp::now() - start_time).tsSec() > 1)
00169         {
00170             timeout = true;
00171         }
00172       }//*/
00173 
00174     }
00175     else
00176     {
00177       LOGGING_TRACE_C(DriverSVH, SVHSerialInterface, "sendPacket failed, serial device was not properly initialized." << endl);
00178       return false;
00179     }
00180 
00181     m_packets_transmitted++;
00182   }
00183 
00184   return true;
00185 }
00186 
00187 void SVHSerialInterface::resetTransmitPackageCount()
00188 {
00189   m_packets_transmitted = 0;
00190   // Only the receive thread knows abotu the accurate number it has received
00191   m_receive_thread->resetReceivedPackageCount();
00192 }
00193 
00194 void SVHSerialInterface::printPacketOnConsole(SVHSerialPacket &packet)
00195 {
00196 
00197   uint8_t check_sum1 = 0;
00198   uint8_t check_sum2 = 0;
00199 
00200   // Calculate Checksum for the packet
00201   for (size_t i = 0; i < packet.data.size(); i++)
00202   {
00203     check_sum1 += packet.data[i];
00204     check_sum2 ^= packet.data[i];
00205   }
00206 
00207   // set packet counter
00208   packet.index = static_cast<uint8_t>(m_dummy_packets_printed % uint8_t(-1));
00209 
00210 
00211   // Prepare arraybuilder
00212   size_t size = packet.data.size() + cPACKET_APPENDIX_SIZE;
00213   icl_comm::ArrayBuilder send_array(size);
00214   // Write header and packet information and checksum
00215   send_array << PACKET_HEADER1 << PACKET_HEADER2 << packet << check_sum1 << check_sum2;
00216 
00217   std::cout << send_array << std::endl;
00218 
00219   m_dummy_packets_printed++;
00220 }
00221 
00222 void SVHSerialInterface::receivedPacketCallback(const SVHSerialPacket &packet, unsigned int packet_count)
00223 {
00224   last_index=packet.index;
00225   m_received_packet_callback(packet,packet_count);
00226 }
00227 
00228 }


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Thu Jun 6 2019 18:29:08