stream.h
Go to the documentation of this file.
1 /*
2  * Copyright 2018 The urg_stamped Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SCIP2_RESPONSE_STREAM_H
18 #define SCIP2_RESPONSE_STREAM_H
19 
20 #include <boost/asio.hpp>
21 
22 #include <cstdint>
23 #include <map>
24 #include <string>
25 #include <vector>
26 
27 #include <scip2/decode.h>
29 #include <scip2/logger.h>
30 
31 namespace scip2
32 {
33 class ScanData
34 {
35 public:
36  uint32_t timestamp_;
37  std::vector<int32_t> ranges_;
38  std::vector<int32_t> intensities_;
39 };
40 
41 class ResponseStream : public Response
42 {
43 public:
44  using Callback = boost::function<void(
45  const boost::posix_time::ptime&,
46  const std::string&,
47  const std::string&,
48  const ScanData&)>;
49 
50 protected:
52 
53 public:
54  virtual std::string getCommandCode() const = 0;
55  virtual void operator()(
56  const boost::posix_time::ptime&,
57  const std::string&,
58  const std::string&,
59  std::istream&) = 0;
60 
62  const boost::posix_time::ptime& time_read,
63  const std::string& echo_back,
64  const std::string& status,
65  std::istream& stream,
66  ScanData& scan)
67  {
68  if (status != "99")
69  {
70  return false;
71  }
72  std::string stamp;
73  if (!std::getline(stream, stamp))
74  {
75  logger::error() << "Failed to get timestamp" << std::endl;
76  return false;
77  }
78  const uint8_t checksum = stamp.back();
79  stamp.pop_back(); // remove checksum
80  if (stamp.size() < 4)
81  {
82  logger::error() << "Wrong timestamp format" << std::endl;
83  return false;
84  }
85 
86  auto dec = Decoder<4>(stamp);
87  auto it = dec.begin();
88  scan.timestamp_ = *it;
89  if ((dec.getChecksum() & 0x3F) + 0x30 != checksum)
90  {
91  logger::error() << "Checksum mismatch" << std::endl;
92  return false;
93  }
94  return true;
95  }
97  {
98  cb_ = cb;
99  }
100 };
101 
103 {
104 public:
105  std::string getCommandCode() const
106  {
107  return std::string("MD");
108  }
110  const boost::posix_time::ptime& time_read,
111  const std::string& echo_back,
112  const std::string& status,
113  std::istream& stream) override
114  {
115  ScanData scan;
116  if (!readTimestamp(time_read, echo_back, status, stream, scan))
117  {
118  if (cb_)
119  {
120  cb_(time_read, echo_back, status, scan);
121  }
122  readUntilEnd(stream);
123  return;
124  }
125  scan.ranges_.reserve(512);
126 
127  std::string line;
128  scip2::DecoderRemain remain;
129  while (std::getline(stream, line))
130  {
131  if (line.size() == 0)
132  break;
133 
134  const uint8_t checksum = line.back();
135  line.pop_back(); // remove checksum
136  if (line.size() < 3)
137  {
138  logger::error() << "Wrong stream format" << std::endl;
139  return;
140  }
141  auto dec = Decoder<3>(line, remain);
142  auto it = dec.begin();
143  for (; it != dec.end(); ++it)
144  {
145  scan.ranges_.push_back(*it);
146  }
147  remain = it.getRemain();
148  if ((dec.getChecksum() & 0x3F) + 0x30 != checksum)
149  {
150  logger::error() << "Checksum mismatch; scan dropped" << std::endl
151  << line << std::endl;
152  return;
153  }
154  }
155  if (cb_)
156  {
157  cb_(time_read, echo_back, status, scan);
158  }
159  }
160 };
161 
163 {
164 public:
165  std::string getCommandCode() const
166  {
167  return std::string("ME");
168  }
170  const boost::posix_time::ptime& time_read,
171  const std::string& echo_back,
172  const std::string& status,
173  std::istream& stream) override
174  {
175  ScanData scan;
176  if (!readTimestamp(time_read, echo_back, status, stream, scan))
177  {
178  if (cb_)
179  cb_(time_read, echo_back, status, scan);
180  return;
181  }
182  scan.ranges_.reserve(512);
183  scan.intensities_.reserve(512);
184 
185  std::string line;
186  scip2::DecoderRemain remain;
187  while (std::getline(stream, line))
188  {
189  if (line.size() == 0)
190  break;
191 
192  const uint8_t checksum = line.back();
193  line.pop_back(); // remove checksum
194  if (line.size() < 3)
195  {
196  logger::error() << "Wrong stream format" << std::endl;
197  return;
198  }
199  auto dec = Decoder<6>(line, remain);
200  auto it = dec.begin();
201  for (; it != dec.end(); ++it)
202  {
203  scan.ranges_.push_back((*it) >> 18);
204  scan.intensities_.push_back((*it) & 0x3FFFF);
205  }
206  remain = it.getRemain();
207  if ((dec.getChecksum() & 0x3F) + 0x30 != checksum)
208  {
209  logger::error() << "Checksum mismatch; scan dropped" << std::endl
210  << line << std::endl;
211  return;
212  }
213  }
214  if (cb_)
215  {
216  cb_(time_read, echo_back, status, scan);
217  }
218  }
219 };
220 
221 } // namespace scip2
222 
223 #endif // SCIP2_RESPONSE_STREAM_H
scip2::ScanData
Definition: stream.h:33
scip2::ResponseStream::getCommandCode
virtual std::string getCommandCode() const =0
scip2::Response
Definition: abstract.h:27
scip2::ResponseMD::getCommandCode
std::string getCommandCode() const
Definition: stream.h:105
logger.h
scip2::ResponseME
Definition: stream.h:162
scip2::ResponseStream::readTimestamp
bool readTimestamp(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, std::istream &stream, ScanData &scan)
Definition: stream.h:61
scip2::ResponseStream::registerCallback
void registerCallback(Callback cb)
Definition: stream.h:96
urg_sim::encode::checksum
std::string checksum(const std::string &a)
Definition: encode.cpp:28
scip2::readUntilEnd
void readUntilEnd(std::istream &stream)
Definition: abstract.h:39
scip2::ResponseStream::Callback
boost::function< void(const boost::posix_time::ptime &, const std::string &, const std::string &, const ScanData &)> Callback
Definition: stream.h:48
scip2::ResponseMD
Definition: stream.h:102
scip2::ResponseME::getCommandCode
std::string getCommandCode() const
Definition: stream.h:165
decode.h
scip2
Definition: connection.h:30
scip2::DecoderRemain
Definition: decode.h:25
scip2::ScanData::ranges_
std::vector< int32_t > ranges_
Definition: stream.h:37
scip2::Decoder
Definition: decode.h:44
scip2::ResponseStream
Definition: stream.h:41
scip2::ResponseStream::operator()
virtual void operator()(const boost::posix_time::ptime &, const std::string &, const std::string &, std::istream &)=0
scip2::ScanData::intensities_
std::vector< int32_t > intensities_
Definition: stream.h:38
abstract.h
scip2::ResponseStream::cb_
Callback cb_
Definition: stream.h:51
scip2::ScanData::timestamp_
uint32_t timestamp_
Definition: stream.h:36
scip2::ResponseMD::operator()
void operator()(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, std::istream &stream) override
Definition: stream.h:109
scip2::logger::error
std::ostream & error()
Definition: logger.cpp:105
scip2::ResponseME::operator()
void operator()(const boost::posix_time::ptime &time_read, const std::string &echo_back, const std::string &status, std::istream &stream) override
Definition: stream.h:169


urg_stamped
Author(s): Atsushi Watanabe
autogenerated on Wed Dec 18 2024 03:10:57