DbcUtilities.h
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018 New Eagle
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of New Eagle nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *********************************************************************/
34 
35 #ifndef _NEW_EAGLE_DBC_UTILITIES_H
36 #define _NEW_EAGLE_DBC_UTILITIES_H
37 
38 #include <ros/ros.h>
39 #include <map>
40 #include <sstream> // std::istringstream
41 #include <string>
42 
43 #include <dbc/DbcSignal.h>
44 #include <dbc/DbcMessage.h>
45 
46 namespace NewEagle
47 {
48  static int32_t ConvertToMTBitOrdering(uint32_t bit, uint32_t dlc)
49  {
50  if (bit < 0 || bit >- dlc * 8)
51  {
52  return -1;
53  }
54 
55  int32_t msgBitLength = (int32_t)dlc * 8;
56 
57  int32_t row = (int32_t) bit / 8;
58  int32_t offset = (int32_t)bit % 8;
59 
60  return (msgBitLength - (row + 1) * 8) + offset;
61  }
62 
63  static int32_t ConvertToMTBitOrdering(uint32_t bit)
64  {
65  return ConvertToMTBitOrdering(bit, 8);
66 
67  }
68 
69  static double Unpack(uint8_t* data, const NewEagle::DbcSignal &signal)
70  {
71  int32_t wordSize = sizeof(data);
72  int32_t startBit = (int32_t)signal.GetStartBit();
73 
74  if (signal.GetEndianness() == NewEagle::LITTLE_END)
75  {
76  startBit = ConvertToMTBitOrdering(signal.GetStartBit(), signal.GetDlc());
77  }
78  else
79  {
80  startBit = ConvertToMTBitOrdering(signal.GetStartBit(), signal.GetDlc()) - ((int32_t)signal.GetLength() - 1);
81  }
82 
83  int32_t bit = (int32_t)(startBit % 8);
84 
85  bool isExactlyByte = ((bit + signal.GetLength()) % 8 == 0);
86  uint32_t numBytes = (isExactlyByte ? 0 : 1) + ((bit + (int32_t)signal.GetLength()) / 8);
87 
88  int32_t b = (int32_t)wordSize - ((int)startBit / 8) - 1;
89  int32_t w = (int)signal.GetLength();
90  int32_t maskShift = bit;
91  int32_t rightShift = 0;
92 
93  uint32_t unsignedResult = 0;
94  for(int32_t i = 0; i < numBytes; i++)
95  {
96  if ((b < 0) || (b >= sizeof(data)))
97  {
98  return std::numeric_limits<int>::quiet_NaN();
99  }
100 
101  int32_t mask = 0xFF;
102  if (w < 8)
103  {
104  mask >>= (8 - w);
105  }
106  mask <<= maskShift;
107 
108  int32_t extractedByte = (data[b] & mask) >> maskShift;
109  unsignedResult |= (uint32_t)extractedByte << (8 * i - rightShift);
110 
111  if (signal.GetEndianness() == NewEagle::BIG_END)
112  {
113  if ((b % wordSize) == 0)
114  {
115  b += 2 * wordSize - 1;
116  }
117  else
118  {
119  b--;
120  }
121  }
122  else
123  {
124  b++;
125  }
126 
127  w -= ( 8 - maskShift);
128  rightShift += maskShift;
129  maskShift = 0;
130 
131  }
132 
133  double result = 0;
134  if (signal.GetSign() == NewEagle::SIGNED)
135  {
136  if ((unsignedResult & (1 << (int32_t)signal.GetLength() - 1)) != 0)
137  {
138  if (signal.GetLength() < 32)
139  {
140  uint32_t signExtension = (0xFFFFFFFF << (int32_t)signal.GetLength());
141  unsignedResult |= signExtension;
142  }
143  }
144 
145  result = (double)((int32_t)unsignedResult);
146 
147  }
148  else if (signal.GetSign() == NewEagle::UNSIGNED)
149  {
150  result = (double)(unsignedResult);
151  }
152 
153  if ((signal.GetGain() != 1) || (signal.GetOffset() != 0))
154  {
155  result *= signal.GetGain();
156  result += signal.GetOffset();
157  }
158 
159  return result;
160  }
161 
162  static void Pack(uint8_t * data, const NewEagle::DbcSignal &signal)
163  {
164  uint32_t result = 0;
165 
166  double tmp = signal.GetResult();
167 
168  if ((signal.GetGain() != 1) || (signal.GetOffset() != 0))
169  {
170  tmp -= signal.GetOffset();
171  tmp /= signal.GetGain();
172  }
173 
174  if (signal.GetSign() == NewEagle::SIGNED)
175  {
176  int32_t i = (int32_t)tmp;
177  uint32_t u = (uint)i;
178 
179  result = u;
180  }
181  else
182  {
183  result = (uint)tmp;
184  }
185 
186  int8_t wordSize = sizeof(data);
187  int8_t startBit = (int)signal.GetStartBit();
188 
189  if (signal.GetEndianness() == NewEagle::LITTLE_END)
190  {
191  startBit = ConvertToMTBitOrdering(signal.GetStartBit(), signal.GetDlc());
192  }
193  else
194  {
195  startBit = ConvertToMTBitOrdering(signal.GetStartBit(), signal.GetDlc()) - ((int32_t)signal.GetLength() - 1);
196  }
197 
198  int32_t bit = (int32_t)(startBit % 8);
199 
200  bool isExactlyByte = ((bit + signal.GetLength()) % 8 == 0);
201  uint32_t numBytes = (isExactlyByte ? 0 : 1) + ((bit + (int32_t)signal.GetLength()) / 8);
202 
203  int32_t b = (int32_t)wordSize - ((int)startBit / 8) - 1;
204  int32_t w = (int)signal.GetLength();
205  int32_t maskShift = bit;
206  int32_t rightShift = 0;
207 
208  uint8_t mask = 0xFF;
209  uint32_t extractedByte;
210 
211  for(int i = 0; i < numBytes; i++)
212  {
213  if ((b < 0 || (b >= sizeof(data))))
214  {
215  return;
216  }
217 
218  mask = 0xFF;
219 
220  if (w < 8)
221  {
222  mask >>= (8 - w);
223  }
224 
225  mask <<= maskShift;
226 
227  extractedByte = (result >> (8 * i - rightShift)) & 0xFF;
228 
229  data[b] = (uint32_t)(data[b] & ~mask);
230  data[b] |= (uint8_t)((extractedByte << maskShift) & mask);
231 
232  if (signal.GetEndianness() == NewEagle::BIG_END)
233  {
234  if ((b % wordSize) == 0)
235  {
236  b += 2 * wordSize - 1;
237  }
238  else
239  {
240  b--;
241  }
242  }
243  else
244  {
245  b++;
246  }
247 
248  w -= ( 8 - maskShift);
249  rightShift += maskShift;
250  maskShift = 0;
251  }
252 
253  }
254 
255 }
256 
257 #endif // _NEW_EAGLE_DBC_UTILITIES_H
static double Unpack(uint8_t *data, const NewEagle::DbcSignal &signal)
Definition: DbcUtilities.h:69
uint8_t GetLength() const
Definition: DbcSignal.cpp:119
Definition: Dbc.h:45
double GetOffset() const
Definition: DbcSignal.cpp:104
ByteOrder GetEndianness() const
Definition: DbcSignal.cpp:114
uint8_t GetStartBit() const
Definition: DbcSignal.cpp:109
double GetResult() const
Definition: DbcSignal.cpp:94
static int32_t ConvertToMTBitOrdering(uint32_t bit, uint32_t dlc)
Definition: DbcUtilities.h:48
SignType GetSign() const
Definition: DbcSignal.cpp:124
static void Pack(uint8_t *data, const NewEagle::DbcSignal &signal)
Definition: DbcUtilities.h:162
uint8_t GetDlc() const
Definition: DbcSignal.cpp:89
double GetGain() const
Definition: DbcSignal.cpp:99


dbc
Author(s): Ryan Borchert
autogenerated on Fri Mar 20 2020 03:31:33