Autoware.Auto
xsens_base_translator.hpp
Go to the documentation of this file.
1 // Copyright 2019 the Autoware Foundation
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // Co-developed by Tier IV, Inc. and Apex.AI, Inc.
16 
18 
19 #ifndef XSENS_DRIVER__XSENS_BASE_TRANSLATOR_HPP_
20 #define XSENS_DRIVER__XSENS_BASE_TRANSLATOR_HPP_
21 
22 #include <common/types.hpp>
25 #include <cstdint>
26 #include <mutex>
27 #include <numeric>
28 #include <vector>
29 
31 
33 
34 namespace autoware
35 {
38 namespace drivers
39 {
40 namespace xsens_driver
41 {
42 
43 template<typename Derived, typename MessageT>
44 class XSENS_DRIVER_PUBLIC XsensBaseTranslator
46 {
47 public:
48  struct Packet
49  {
50  uint8_t data;
51  };
52 
53 protected:
54  enum class State
55  {
56  START,
57  PREAMBLE_READ,
58  BID_READ,
59  MID_READ,
60  LENGTH_READ,
61  };
62 
63  std::vector<uint8_t> raw_message_;
64 
66 
68 
69  std::size_t current_length_;
70 
71 public:
73  : current_state_(State::START) {}
74 
75  bool8_t use_double_precision(int32_t data_id)
76  {
77  if ((data_id & 0x0003) == 0x3) {
78  return true;
79  } else if ((data_id & 0x0003) == 0x0) {
80  return false;
81  } else {
82  throw std::runtime_error("fixed point precision not supported.");
83  }
84  }
85 
94  bool8_t convert(const Packet & pkt, MessageT & output)
95  {
96  switch (current_state_) {
97  case State::START:
98  if (pkt.data == 0xFA) {
99  current_state_ = State::PREAMBLE_READ;
100  } else {
101  current_state_ = State::START;
102  }
103  return false;
104  case State::PREAMBLE_READ:
105  if (pkt.data == 0xFF) {
106  current_state_ = State::BID_READ;
107  } else {
108  current_state_ = State::START;
109  }
110  return false;
111  case State::BID_READ:
112  current_mid_ = MID_from_int(pkt.data);
113  current_state_ = State::MID_READ;
114  return false;
115  case State::MID_READ:
116  current_length_ = pkt.data;
117  current_state_ = State::LENGTH_READ;
118  return false;
119  case State::LENGTH_READ:
120  if (raw_message_.size() == current_length_) {
121  std::size_t checksum = 0xFF;
122  // NOTE(esteve): workaround for uncrustify. The standard ROS 2 configuration does not
123  // understand nested < > in templates
124  using MID_underlying_type = std::underlying_type_t<decltype(current_mid_)>;
125  checksum += static_cast<MID_underlying_type>(current_mid_);
126  checksum += current_length_;
127  checksum += pkt.data;
128  std::size_t sum =
129  std::accumulate(std::begin(raw_message_), std::end(raw_message_), checksum);
130  if (0xFF & sum) {
131  // Checksum error, start over
132  current_state_ = State::START;
133  current_length_ = 0;
134  raw_message_.clear();
135  return false;
136  } else {
137  if (current_mid_ == MID::MT_DATA) {
138  // TODO(esteve): parse legacy data
139  throw std::runtime_error("Legacy data not supported yet");
140  } else if (current_mid_ == MID::MT_DATA2) {
141  parse_mtdata2(output);
142  }
143  current_state_ = State::START;
144  current_length_ = 0;
145  raw_message_.clear();
146  }
147  return true;
148  } else {
149  raw_message_.push_back(pkt.data);
150  return false;
151  }
152  return false;
153  }
154  return false;
155  }
156 
157  void parse_mtdata2(MessageT & output)
158  {
159  auto data = raw_message_;
160 
161  // Read bytes from the byte vector until there are no more messages left
162  while (!data.empty()) {
163  const int32_t data_id = data[1] | data[0] << 8;
164  const int32_t message_size = data[2];
165 
166  // Create a slice from the byte vector, skipping the first three bytes (data_id and
167  // message_size)
168  auto content = decltype(data)(
169  std::begin(data) + 3,
170  std::begin(data) + 3 + message_size);
171 
172  // Overwrite data with the bytes after the slice
173  data = decltype(data)(
174  std::begin(data) + 3 + message_size,
175  std::end(data));
176 
177  int32_t group = data_id & 0xF800;
178  XDIGroup xdigroup = XDIGroup_from_int(static_cast<uint16_t>(group));
179  // Dispatch the rest of the parsing to the translator specialization via CRTP
180  this->impl().parse_xdigroup_mtdata2(xdigroup, output, data_id, content);
181  }
182  }
183 };
184 
185 } // namespace xsens_driver
186 } // namespace drivers
187 } // namespace autoware
188 
189 #endif // XSENS_DRIVER__XSENS_BASE_TRANSLATOR_HPP_
Definition: output_type_trait.hpp:30
std::vector< uint8_t > raw_message_
Definition: xsens_base_translator.hpp:63
Definition: xsens_base_translator.hpp:48
void parse_mtdata2(MessageT &output)
Definition: xsens_base_translator.hpp:157
MID current_mid_
Definition: xsens_base_translator.hpp:67
bool bool8_t
Definition: types.hpp:33
std::size_t current_length_
Definition: xsens_base_translator.hpp:69
XSENS_DRIVER_PUBLIC XDIGroup XDIGroup_from_int(uint16_t value)
Definition: xsens_common.cpp:130
This file includes common type definition.
uint8_t data
Definition: xsens_base_translator.hpp:50
Definition: xsens_base_translator.hpp:44
XDIGroup
Definition: xsens_common.hpp:152
This file includes common helper functions.
MID
Definition: xsens_common.hpp:37
State current_state_
Definition: xsens_base_translator.hpp:65
end
Definition: scripts/get_open_port.py:23
bool8_t convert(const Packet &pkt, MessageT &output)
Convert Xsens frames into ROS messages. An Xsens frame is composed of the following bytes: ...
Definition: xsens_base_translator.hpp:94
bool8_t use_double_precision(int32_t data_id)
Definition: xsens_base_translator.hpp:75
XSENS_DRIVER_PUBLIC MID MID_from_int(uint16_t value)
Definition: xsens_common.cpp:36
XsensBaseTranslator()
Definition: xsens_base_translator.hpp:72
This file defines the lanelet2_map_provider_node class.
Definition: quick_sort.hpp:24