PDO.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 Canopen 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 2016 SCHUNK GmbH, Lauffen/Neckar Germany
00012 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00023 //----------------------------------------------------------------------
00024 
00025 #include "ds301.h"
00026 #include "PDO.h"
00027 
00028 #include "Logging.h"
00029 #include "exceptions.h"
00030 
00031 #include <string.h>
00032 
00033 namespace icl_hardware {
00034 namespace canopen_schunk {
00035 
00036 PDO::PDO(const uint8_t node_id,
00037          const uint8_t pdo_nr,
00038          const icl_hardware::canopen_schunk::CanDevPtr& can_device)
00039   : m_node_id(node_id),
00040     m_pdo_nr(pdo_nr),
00041     m_can_device(can_device)
00042 {
00043 }
00044 
00045 PDO::PDOStringMatchVec PDO::remap (SDO& sdo,
00046                                    const MappingConfigurationList& mappings,
00047                                    const eTransmissionType& transmission_type,
00048                                    const uint16_t pdo_cob_id,
00049                                    const uint16_t pdo_communication_parameter,
00050                                    const uint16_t pdo_mapping_parameter,
00051                                    const bool dummy_mapping,
00052                                    const uint8_t cyclic_timeout_cycles
00053                                   )
00054 {
00055   m_mapping_list.clear();
00056   PDO::PDOStringMatchVec ret_vec;
00057 
00058   // if no mapping is given, we leave the mapping as is.
00059   if (mappings.size() == 0)
00060   {
00061     LOGGING_INFO_C (CanOpen, PDO, "Remapping called with empty mapping. Not doing anything." << endl);
00062     return PDO::PDOStringMatchVec();
00063   }
00064 
00065   // A maximum of 64 mappings are supported.
00066   // See DS301 Specification Section 7.5.2.36 (Object 0x1600 to 0x17FF). Sub Index ranges to 0x40 resulting in 64 maximum mappable values
00067   if (mappings.size() > 64)
00068   {
00069     std::stringstream ss;
00070     ss << "Illegal number of mappings given. A maximum of 64 mappings is allowed. " <<
00071           "However, " << mappings.size() << " mappings were given.";
00072     throw PDOException (ss.str());
00073   }
00074 
00075   // set the full transmission type
00076   uint8_t transmission_type_int = static_cast<uint8_t>(transmission_type);
00077   if (transmission_type == SYNCHRONOUS_CYCLIC)
00078   {
00079     transmission_type_int += cyclic_timeout_cycles;
00080   }
00081 
00082   // establish rpdo communication in index 0x1400 / 0x01
00083   uint16_t index = pdo_communication_parameter;
00084   uint8_t subindex = 0x01;
00085   std::vector<uint8_t> data(4, 0);
00086 
00087   // disable this PDO
00088   data[0] = pdo_cob_id & 0xff;
00089   data[1] = pdo_cob_id >> 8;
00090   data[2] = 0x00;
00091   data[3] = 0x80;
00092 
00093   if (!dummy_mapping)
00094   {
00095     try
00096     {
00097       sdo.download(false, index, subindex, data);
00098     }
00099     catch (const std::exception& e)
00100     {
00101       std::stringstream ss;
00102       ss << "Downloading PDO communication object failed! ";
00103       ss << e.what();
00104       throw PDOException (ss.str());
00105     }
00106   }
00107 
00108   // clear PDO
00109   index = pdo_mapping_parameter;
00110   subindex = 0x00;
00111   uint8_t clear_data = 0;
00112 
00113   if (!dummy_mapping)
00114   {
00115     try
00116     {
00117       sdo.download(false, index, subindex, clear_data);
00118     }
00119     catch (const std::exception& e)
00120     {
00121       std::stringstream ss;
00122       ss << "Clearing PDO mapping failed! ";
00123       ss << e.what();
00124       throw PDOException (ss.str());
00125     }
00126   }
00127 
00128 
00129   // perform mapping
00130   index = pdo_mapping_parameter;
00131   subindex = 0;
00132   uint8_t cumul_length = 0;
00133   for (size_t i = 0; i < mappings.size(); ++i)
00134   {
00135     ++subindex;
00136     data[0] = mappings[i].length;
00137     data[1] = mappings[i].subindex;
00138     data[2] = mappings[i].index & 0xff;
00139     data[3] = mappings[i].index >> 8;
00140     cumul_length += mappings[i].length;
00141 
00142     PDOStringMatch match;
00143     match.name = mappings[i].name;
00144     match.pdo_mapping_index = i;
00145     ret_vec.push_back(match);
00146 
00147     if (cumul_length > 64)
00148     {
00149       throw PDOException ("The configured length of the PDO mapping is too big. To send a PDO in one CAN frame its size cannot be larger than 64 bit");
00150 
00151       //TODO: Currently this will leave a disabled PDO. We could as well use the PDO with the mappings so far and just drop a warning...
00152     }
00153 
00154     LOGGING_DEBUG (CanOpen, "Mapping " << hexToString(mappings[i].index) << " / " << static_cast<int>(mappings[i].subindex) << endl );
00155     if (!dummy_mapping)
00156     {
00157       sdo.download(false, index, subindex, data);
00158     }
00159 
00160     m_mapping_list.push_back(Mapping(mappings[i]));
00161   }
00162 
00163   index = pdo_mapping_parameter;
00164   subindex = 0x00;
00165   uint8_t num_mappings = mappings.size();
00166 
00167   if (!dummy_mapping)
00168   {
00169     try
00170     {
00171       sdo.download(false, index, subindex, num_mappings);
00172     }
00173     catch (const std::exception& e)
00174     {
00175       std::stringstream ss;
00176       ss << "Setting number of mappings failed! ";
00177       ss << e.what();
00178       throw PDOException (ss.str());
00179     }
00180   }
00181 
00182   // set PDO's transmission type
00183   index = pdo_communication_parameter;
00184   subindex = 0x02;
00185   if (!dummy_mapping)
00186   {
00187     try
00188     {
00189       sdo.download(false, index, subindex, transmission_type_int);
00190     }
00191     catch (const std::exception& e)
00192     {
00193       std::stringstream ss;
00194       ss << "Downloading PDO communication object failed! ";
00195       ss << e.what();
00196       throw PDOException (ss.str());
00197     }
00198   }
00199 
00200   // enable this PDO
00201   index = pdo_communication_parameter;
00202   subindex = 0x01;
00203   data[0] = pdo_cob_id & 0xff;
00204   data[1] = pdo_cob_id >> 8;
00205   data[2] = 0x00;
00206   data[3] = 0x00;
00207 
00208   if (!dummy_mapping)
00209   {
00210     try
00211     {
00212       sdo.download(false, index, subindex, data);
00213     }
00214     catch (const std::exception& e)
00215     {
00216       std::stringstream ss;
00217       ss << "Enabling PDO object failed! ";
00218       ss << e.what();
00219       throw PDOException (ss.str());
00220     }
00221   }
00222 
00223   LOGGING_DEBUG (CanOpen, "Remapping for node " << static_cast<int>(m_node_id) << " finished!" << endl);
00224 
00225   return ret_vec;
00226 }
00227 
00228 
00229 PDO::PDOStringMatchVec PDO::appendMapping (SDO& sdo,
00230                                    const MappingConfigurationList& mappings,
00231                                    const eTransmissionType& transmission_type,
00232                                    const uint16_t pdo_cob_id,
00233                                    const uint16_t pdo_communication_parameter,
00234                                    const uint16_t pdo_mapping_parameter,
00235                                    const bool dummy_mapping,
00236                                    const uint8_t cyclic_timeout_cycles)
00237 {
00238   // Create MappingConfiguration from m_mapping_list
00239   MappingConfigurationList new_configuration;
00240   uint8_t cum_length = 0;
00241   for (MappingList::iterator it = m_mapping_list.begin(); it != m_mapping_list.end(); ++it)
00242   {
00243     new_configuration.push_back(it->getConfiguration());
00244     cum_length += it->getConfiguration().length;
00245   }
00246 
00247   // append new mapping to old mappingConfiguration
00248   uint8_t new_cum_length = 0;
00249   for (MappingConfigurationList::const_iterator it = mappings.begin(); it != mappings.end(); ++it)
00250   {
00251     new_cum_length += it->length;
00252     new_configuration.push_back(*it);
00253   }
00254 
00255   // Check, if there's enough space left in the PDO
00256   if (cum_length + new_cum_length > 64)
00257   {
00258     std::stringstream ss;
00259     ss <<  "The requested length of the PDO mapping is too big. "<<
00260            "To send a PDO in one CAN frame its size cannot be larger than 64 bit." <<
00261            "Please append this configuration to another PDO.";
00262     throw PDOException (ss.str());
00263   }
00264 
00265   // call remap
00266   return remap(sdo,
00267                new_configuration,
00268                transmission_type,
00269                pdo_cob_id,
00270                pdo_communication_parameter,
00271                pdo_mapping_parameter,
00272                cyclic_timeout_cycles);
00273 }
00274 
00275 
00276 
00277 }}//end of NS


schunk_canopen_driver
Author(s): Felix Mauch , Georg Heppner
autogenerated on Sun May 22 2016 03:30:56