tCanFilterMessages.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 FZIs ic_workspace.
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 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
22 //----------------------------------------------------------------------
23 #include "tCanFilterMessages.h"
24 
25 #include <map>
26 #include <boost/filesystem.hpp>
27 
29 
30 namespace icl_hardware {
31 namespace can {
32 
34  : m_data_file_name(NULL),
35  is_initialized(false)
36 {
37 }
38 
40 {
41  if (m_data_file_name != NULL)
42  {
43  delete m_data_file_name;
44  m_data_file_name = NULL;
45  }
46 }
47 
48 void tCanFilterMessages::Open(const std::string identifier)
49 {
50  //get the filename of the can-message-file
51  if (identifier != "")
52  {
53  setDataFileName(boost::filesystem::path(identifier));
54  }
55  else
56  {
57  LOGGING_ERROR(icl_hardware::can::CAN, "No data file provided!" << icl_core::logging::endl);
58  return;
59  }
60 
61  LOGGING_DEBUG(icl_hardware::can::CAN, "Opening canmatrixParser with data from file: " << getDataFileName().string() << icl_core::logging::endl);
62 
63  // open and check can-file
64  int ret=PrepareFiles();
65 
66  if (ret!=0)
67  {
68  LOGGING_ERROR(icl_hardware::can::CAN, "No such file as: " << identifier << icl_core::logging::endl);
69  return;
70  }
71 
73 
74  is_initialized = true;
75 }
76 
78 {
79  std::map<unsigned int, DataWrapper>::const_iterator iter = m_table_id_to_data.find(message.id);
80 
81  if (iter != m_table_id_to_data.end())
82  {
83  for (unsigned int i=0; i < 8; i++)
84  {
86  if (message.data[i] != iter->second.data[i] && !byteIsChangingConstantly(i, message.id))
87  {
88  return true;
89  }
90  }
91  }
92  else
93  {
94  return true;
95  }
96 
97  return false;
98 }
99 
100 bool tCanFilterMessages::byteIsChangingConstantly(unsigned int i, unsigned int id) const
101 {
102  std::multimap<unsigned int, unsigned int>::const_iterator iter_multi = m_table_id_to_changing_bytes.find(id);
103  if (iter_multi != m_table_id_to_changing_bytes.end())
104  {
105  while (id == iter_multi->first)
106  {
107  if (iter_multi->second == i)
108  {
109  return true;
110  }
111  iter_multi++;
112  }
113  }
114  return false;
115 }
116 
118 {
119  std::string line;
121 
122  while (m_data_file.good())
123  {
124  getline(m_data_file, line);
125  if (line.length() == 0)
126  {
127  //lines with no value are ignored
128  continue;
129  }
130 
131  //copy of line has to be used, because in the actuell version, the string is cut in pieces
132  StringToCanMsg(message, line);
133 
134  //if a comment or an empty line was read, message.empty()
135  if (message.id != 0 || message.dlc != 0 || message.rtr != 0)
136  {
137  std::map<unsigned int, DataWrapper>::iterator iter = m_table_id_to_data.find(message.id);
138 
139  if (iter == m_table_id_to_data.end())
140  {
141  LOGGING_TRACE(icl_hardware::can::CAN, "id: " << message.id << " is newly registered" << icl_core::logging::endl);
142  memcpy(m_message_data.data, message.data, sizeof(message.data));
143  m_table_id_to_data.insert(std::pair<unsigned int, DataWrapper>(message.id, m_message_data));
144  }
145  else
146  {
148  for (unsigned int i=0; i < 8; i++)
149  {
150  if (iter->second.data[i] != message.data[i])
151  {
152  std::multimap<unsigned int, unsigned int>::iterator iter_multi = m_table_id_to_changing_bytes.find(iter->first);
153  bool known_byte = false;
154 
155  if (iter_multi != m_table_id_to_changing_bytes.end())
156  {
158  while(iter_multi->first == message.id && !known_byte)
159  {
160  if (iter_multi->second == i)
161  {
162  known_byte = true;
163  }
164  iter_multi++;
165  }
166  }
167  if (!known_byte)
168  {
169  LOGGING_TRACE(icl_hardware::can::CAN, "id: " << message.id << " - add byte: " << i << icl_core::logging::endl);
170  m_table_id_to_changing_bytes.insert(std::pair <unsigned int, unsigned int> (message.id, i));
171  }
172  }
173  }
174  }
175  }
176  }
177 }
178 
180 {
181  unsigned int pos = 0;
182  int word_length = 0;
183 
184  if (str.substr(0,1) == "#")
185  {
186  // skip lines beginning with a comment
187  return;
188  }
189 
190  //FZI-CAN FILE V1.0 has 11 values
191  for (int i=0; i < 11; i++)
192  {
193  size_t position = str.find(' ', pos);
194  if (position == std::string::npos)
195  {
196  word_length = str.size() - pos;
197  }
198  else
199  {
200  word_length = position - pos;
201  }
202 
203  switch(i)
204  {
205  case 0:
206  {
207  // message.gmtime = atof((str.substr(pos, word_length)).data());
208  break;
209  }
210  case 1:
211  {
212  message.id = atoi((str.substr(pos, word_length)).data());
213  break;
214  }
215  case 2:
216  {
217  message.dlc = atoi((str.substr(pos, word_length)).data());
218  break;
219  }
220  default:
221  {
222 
223  message.data[i-3] = (unsigned char)(strtol((str.substr(pos, word_length)).data(), NULL, 16));
224  break;
225  }
226  }
227 
228  pos += word_length+1;
229  }
230 }
231 
233 {
234  //open files
235  m_data_file.open(getDataFileName().string().c_str(), std::ios::in);
236 
237  //check all files are open
238  if (!m_data_file.is_open())
239  {
240  return -1;
241  }
242 
243  return 0;
244 }
245 
246 void tCanFilterMessages::setDataFileName(const boost::filesystem::path &file_name)
247 {
248  if (m_data_file_name)
249  {
250  delete m_data_file_name;
251  }
252  m_data_file_name = new boost::filesystem::path(file_name);
253 }
254 
255 const boost::filesystem::path& tCanFilterMessages::getDataFileName() const
256 {
257  return *m_data_file_name;
258 }
259 
261 {
262  return is_initialized;
263 }
264 
265 }
266 }
boost::filesystem::path * m_data_file_name
Implements a struct representing a can message.
Definition: tCanMessage.h:43
void * memcpy(void *dest, void *src, size_t count)
#define LOGGING_DEBUG(streamname, arg)
std::multimap< unsigned int, unsigned int > m_table_id_to_changing_bytes
std::map< unsigned int, DataWrapper > m_table_id_to_data
#define LOGGING_ERROR(streamname, arg)
bool getStatus() const
function returns true if message data changed because of human interaction
void setDataFileName(const boost::filesystem::path &file_name)
ThreadStream & endl(ThreadStream &stream)
bool byteIsChangingConstantly(unsigned int i, unsigned int id) const
void StringToCanMsg(icl_hardware::can::tCanMessage &msg, std::string str)
void Open(const std::string identifer)
std::ifstream m_data_file
File handler for data file.
#define LOGGING_TRACE(streamname, arg)
const boost::filesystem::path & getDataFileName() const
bool checkMessage(const tCanMessage &msg) const


fzi_icl_can
Author(s):
autogenerated on Mon Jun 10 2019 13:17:02