tCanMatrixParser.cpp
Go to the documentation of this file.
00001 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00002 // This file is part of FZIs ic_workspace.
00003 //
00004 // This program is free software licensed under the LGPL
00005 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00006 // You can find a copy of this license in LICENSE folder in the top
00007 // directory of the source code.
00008 //
00009 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00010 //
00011 // -- END LICENSE BLOCK ------------------------------------------------
00012 
00013 // ----------------------------------------------------------
00014 /*
00015  * tCanMatrixParser.cpp
00016  * <section>
00017  *
00018  * Created by Hugo Ritzkowski on 2011-04-14.
00019  * Copyright 2011
00020  * Company Forschungszentrum Informatik (FZI), Abteilung IDS.
00021  * All rights reserved.
00022  *
00023  */
00024 // ----------------------------------------------------------
00033 // ----------------------------------------------------------
00034 
00035 #include "tCanMatrixParser.h"
00036 
00037 #include "icl_hardware_can/Logging.h"
00038 #include "icl_core_config/Config.h"
00039 
00040 #include <boost/filesystem.hpp>
00041 #include <map>
00042 #include <tinyxml.h>
00043 
00044 #ifdef _IC_BUILDER_CANTOOLS_
00045 extern "C" {
00046 #include <dbcModel.h>
00047 #include <dbcReader.h>
00048 }
00049 #endif
00050 
00051 namespace icl_hardware {
00052 namespace can {
00053 
00054 tCanMatrixParser::tCanMatrixParser(const std::string identifier)
00055   : m_data_file_name(NULL),
00056     is_initialized(false)
00057 {
00058 
00059   //get the filename of the xml-file
00060   if (identifier != "")
00061   {
00062     setDataFileName(boost::filesystem::path(identifier));
00063   }
00064   else
00065   {
00066     throw std::runtime_error("No CAN matrix provided!");
00067     return;
00068   }
00069 
00070   LOGGING_DEBUG(icl_hardware::can::CAN, "Opening CanMatrixParser with interpreter data from file: " << getDataFileName().string() << icl_core::logging::endl);
00071 
00072   int ret = 0;
00073 #if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2
00074   std::string extension = getDataFileName().extension();
00075 #else
00076   std::string extension = getDataFileName().extension().string();
00077 #endif
00078 
00079   if (extension == ".xml" || extension == ".canxml")
00080   {
00081     // open and check xml-file
00082     TiXmlHandle doc_handle(NULL);
00083     TiXmlDocument default_header_file(getDataFileName().string());
00084 
00085     if (default_header_file.LoadFile())
00086     {
00087       doc_handle = TiXmlHandle(&default_header_file);
00088       if (!doc_handle.FirstChildElement().ToElement())
00089       {
00090         // No valid root tag
00091         throw std::runtime_error("Found no root tag in " + getDataFileName().string());
00092         return;
00093       }
00094     }
00095     else
00096     {
00097       throw std::runtime_error("File " + getDataFileName().string() + " is not well-formed XML");
00098       return;
00099     }
00100     //get content of xml-file in std::map
00101     ret = mapContentOfFile(doc_handle);
00102   }
00103   else if (extension == ".dbc")
00104   {
00105 #ifdef _IC_BUILDER_CANTOOLS_
00106     dbc_t* dbc;
00107 
00108     if (boost::filesystem::exists(getDataFileName()))
00109     {
00110       dbc = dbc_read_file(getDataFileName().string().c_str());
00111       if (!dbc->filename)
00112       {
00113         throw std::runtime_error("File " + getDataFileName().string() + " is not a valid DBC file");
00114         return;
00115       }
00116       ret = mapContentOfFile(dbc);
00117       dbc_free(dbc);
00118     }
00119     else
00120     {
00121       throw std::runtime_error("File " + getDataFileName().string() + " is not a valid file");
00122       return;
00123     }
00124 #else
00125     throw std::runtime_error("Missing dbc support, please compile with cantools library.");
00126     return;
00127 #endif
00128   }
00129 
00130   if(ret != 0)
00131   {
00132     throw std::runtime_error("CanMatrix could not be read.");
00133     return;
00134   }
00135 
00136   is_initialized = true;
00137 }
00138 
00139 tCanMatrixParser::~tCanMatrixParser()
00140 {
00141   if (m_data_file_name != NULL)
00142   {
00143     delete m_data_file_name;
00144     m_data_file_name = NULL;
00145   }
00146 }
00147 
00148 const CanMatrix& tCanMatrixParser::getCanMatrix() const
00149 {
00150   return m_canmatrix;
00151 }
00152 
00153 int tCanMatrixParser::mapContentOfFile(TiXmlHandle &doc_handle)
00154 {
00155   //    <icl_hardware_can>
00156   //      <can_matrix>
00157   //        <message>
00158   //          <canid>32</canid>
00159   //          <conversion>0.001</conversion>
00160   //          <description>The velocity of the left wheel</description>
00161   //          <unit>1/s</unit>
00162   //          <data_start_bit> 2 </data_start_bit>  (index 0..63)
00163   //          <signal_length> 2 </signal_length>
00164   //          <offset> 10. </offset>
00165   //          <lower_bound> 0. </lower_bound>
00166   //          <upper_bound> 1. </upper_bound>
00167   //          <little_endian> 1 </little_endian>
00168   //          <signedness> 0 </signedness>
00169   //        </message>
00170   //        ...
00171   //      </can_matrix>
00172   //    </icl_hardware_can>
00173 
00174   TiXmlElement * element = doc_handle.FirstChildElement().ToElement();
00175   if (std::string(element->Value()) != "icl_hardware_can")
00176   {
00177     LOGGING_ERROR(icl_hardware::can::CAN, "Found no <icl_hardware_can> root tag in " << getDataFileName().string() << icl_core::logging::endl);
00178     return -1;
00179   }
00180 
00181   TiXmlElement* message_data = doc_handle.FirstChildElement().FirstChildElement().FirstChildElement().ToElement();
00182   if (std::string(message_data->Value()) == "message")
00183   {
00184     unsigned int id = 0;
00185 
00186     struct CanMatrixElement can_matrix_data = {"", 0., "", 0 , 0 , 0., 0., 0., false, false};
00187 
00188     if (checkXmlFile(message_data) == 0)
00189     {
00190       do
00191       {
00192         id = atoi(message_data->FirstChild("canid")->ToElement()->GetText());
00193         can_matrix_data.conversion = atof(message_data->FirstChild("conversion")->ToElement()->GetText());
00194         can_matrix_data.description = message_data->FirstChild("description")->ToElement()->GetText();
00195         can_matrix_data.unit = message_data->FirstChild("unit")->ToElement()->GetText();
00196         can_matrix_data.start_bit = atoi(message_data->FirstChild("data_start_bit")->ToElement()->GetText());
00197         can_matrix_data.signal_length = atoi(message_data->FirstChild("signal_length")->ToElement()->GetText());
00198         can_matrix_data.offset = atof(message_data->FirstChild("offset")->ToElement()->GetText());
00199         can_matrix_data.lower_border = atof(message_data->FirstChild("lower_border")->ToElement()->GetText());
00200         can_matrix_data.upper_border = atof(message_data->FirstChild("upper_border")->ToElement()->GetText());
00201         can_matrix_data.little_endian = bool(atoi(message_data->FirstChild("little_endian")->ToElement()->GetText()));
00202         can_matrix_data.signedness = bool(atoi(message_data->FirstChild("signedness")->ToElement()->GetText()));
00203 
00204         CanMatrix::iterator iter = m_canmatrix.find(id);
00205 
00206         if (iter != m_canmatrix.end())
00207         {
00209           iter->second.insert(iter->second.end(), can_matrix_data);
00210         }
00211         else
00212         {
00214           m_canmatrix.insert(std::pair<unsigned int, std::vector<CanMatrixElement> >(id, std::vector<CanMatrixElement>(1, can_matrix_data)));
00215         }
00216 
00217       }
00218       while ((message_data = message_data->NextSiblingElement()));
00219       message_data = NULL;
00220     }
00221     else
00222     {
00223       LOGGING_ERROR(icl_hardware::can::CAN, "Structure of xml-file is not compatible."  << icl_core::logging::endl);
00224       LOGGING_ERROR(icl_hardware::can::CAN, "Missing child element!" << icl_core::logging::endl);
00225       return -1;
00226     }
00227   }
00228   else
00229   {
00230     LOGGING_ERROR(icl_hardware::can::CAN, "Structure of xml-file is not compatible " << getDataFileName().string() << icl_core::logging::endl);
00231     return -1;
00232   }
00233   element = NULL;
00234 
00235   return 0;
00236 }
00237 
00238 const int tCanMatrixParser::checkXmlFile(TiXmlElement *element) const
00239 {
00240 
00241   if (element->FirstChild("canid") && element->FirstChild("conversion") && element->FirstChild("description")
00242       && element->FirstChild("unit") && element->FirstChild("data_start_bit") && element->FirstChild("signal_length")
00243       && element->FirstChild("offset") && element->FirstChild("lower_border") && element->FirstChild("upper_border")
00244       && element->FirstChild("little_endian") && element->FirstChild("signedness") )
00245   {
00246     return 0;
00247   }
00248   else
00249   {
00250     return -1;
00251   }
00252 }
00253 
00254 int tCanMatrixParser::mapContentOfFile(void *dbc_)
00255 {
00256 #ifndef _IC_BUILDER_CANTOOLS_
00257   return -1;
00258 #else
00259   dbc_t *dbc = reinterpret_cast<dbc_t*>(dbc_);
00260 
00261   if (!dbc)
00262   {
00263     return -1;
00264   }
00265 
00266   message_list_t *ml;
00267   signal_list_t *sl;
00268 
00269   for(ml = dbc->message_list; ml != NULL; ml = ml->next) {
00270     unsigned int id = ml->message->id;
00271 
00272     for(sl = ml->message->signal_list; sl != NULL; sl = sl->next) {
00273       struct CanMatrixElement can_matrix_data = {"", 0., "", 0 , 0 , 0., 0., 0., false, false};
00274 
00275       can_matrix_data.conversion = sl->signal->scale;
00276       can_matrix_data.description = sl->signal->name;
00277       can_matrix_data.unit = sl->signal->unit?sl->signal->unit:"";
00278       can_matrix_data.start_bit = sl->signal->bit_start + 1;
00279       can_matrix_data.signal_length = sl->signal->bit_len;
00280       can_matrix_data.offset = sl->signal->offset;
00281       can_matrix_data.lower_border = sl->signal->min;
00282       can_matrix_data.upper_border = sl->signal->max;
00283       can_matrix_data.little_endian = sl->signal->endianess;
00284       can_matrix_data.signedness = sl->signal->signedness;
00285 
00286       CanMatrix::iterator iter = m_canmatrix.find(id);
00287 
00288       if (iter != m_canmatrix.end())
00289       {
00291         iter->second.insert(iter->second.end(), can_matrix_data);
00292       }
00293       else
00294       {
00296         m_canmatrix.insert(std::pair<unsigned int, std::vector<CanMatrixElement> >(id, std::vector<CanMatrixElement>(1, can_matrix_data)));
00297       }
00298     }
00299   }
00300 
00301 #endif
00302   return 0;
00303 }
00304 
00305 void tCanMatrixParser::setDataFileName(const boost::filesystem::path &file_name)
00306 {
00307   if (m_data_file_name)
00308   {
00309     delete m_data_file_name;
00310   }
00311   m_data_file_name = new boost::filesystem::path(file_name);
00312 }
00313 
00314 const boost::filesystem::path & tCanMatrixParser::getDataFileName() const
00315 {
00316   return *m_data_file_name;
00317 }
00318 
00319 const bool tCanMatrixParser::isActive() const
00320 {
00321   return is_initialized;
00322 }
00323 
00324 std::ostream &operator<<(std::ostream &stream, const CanMatrix& can_matrix)
00325 {
00326 //  icl_graphics::tCameraParameterIO::WriteDeviceTag(&camera_parameter_provider, stream);
00327   stream << can_matrix.size();
00328   return stream;
00329 }
00330 
00331 }
00332 }


fzi_icl_can
Author(s):
autogenerated on Thu Jun 6 2019 20:26:01