33 #include <boost/asio.hpp> 34 #include <boost/array.hpp> 35 #include <boost/format.hpp> 36 #include <boost/bind.hpp> 37 #include <boost/serialization/access.hpp> 38 #include <boost/archive/binary_iarchive.hpp> 39 #include <boost/shared_array.hpp> 40 #include <boost/algorithm/string.hpp> 41 #include <boost/chrono.hpp> 71 const boost::posix_time::ptime &)>
cb_aux_;
81 std::vector<boost::shared_array<const TableSincos>>
tbl_v_;
87 boost::asio::streambuf
buf_;
91 : socket_(io_service_)
98 , tbl_h_loaded_(false)
99 , tbl_v_loaded_(false)
107 void connect(
const char *ip,
const unsigned int port, decltype(cb_connect_) cb)
110 boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(ip), port);
111 timer_.expires_from_now(boost::posix_time::seconds(timeout_));
134 send(std::string(
"SET:_ars=1\n"));
136 send(std::string(
"SET:_ars=0\n"));
138 [[deprecated(
"use setHorizontalInterlace() instead of setInterlace()")]]
145 send((boost::format(
"SET:_itl=0,%02d\n") % itl).str());
149 send((boost::format(
"SET:_itv=0,%02d\n") % itl).str());
154 tbl_vn_loaded_.resize(itl);
157 send(std::string(
"GET:tblv\n"));
161 for (
int i = 0; i < itl; ++i)
163 send((boost::format(
"GET:tv%02d\n") % i).str());
164 tbl_vn_loaded_[i] =
false;
170 send(std::string(
"GET:tblh\n"));
174 send(std::string(
"PNG\n"));
178 send((boost::format(
"DAT:ax=%d\n") % static_cast<int>(
start)).str());
184 send((boost::format(
"DAT:ri=%d\n") % static_cast<int>(
start)).str());
188 send((boost::format(
"DAT:ro=%d\n") % static_cast<int>(
start)).str());
194 timer_.expires_from_now(boost::posix_time::seconds(timeout_));
198 boost::asio::async_read(socket_, buf_, boost::asio::transfer_at_least(4),
203 boost::system::error_code ec;
204 io_service_.poll(ec);
223 void send(
const std::string cmd)
226 boost::asio::async_write(socket_, boost::asio::buffer(*data),
264 template <
class DATA_TYPE>
278 const DATA_TYPE *data = boost::asio::buffer_cast<
const DATA_TYPE *>(buf_.data());
280 for (
int s = 0;
s < range_index.
nspots;
s++)
282 const double spot =
s + range_header.
spot;
283 const double h_rad = h_head + (h_tail - h_head) * tbl_h_[spot];
284 const double h_cos = cos(h_rad);
285 const double h_sin = sin(h_rad);
286 const vssp::XYZI dir(tbl_v_[tv][spot].
s, tbl_v_[tv][spot].c, h_sin, h_cos);
287 for (
int e = index[s]; e < index[s + 1]; e++)
288 points[i++] = dir * data[e];
292 void onRead(
const boost::system::error_code &error)
294 const auto time_read = boost::posix_time::microsec_clock::universal_time();
295 const auto length_total = buf_.size();
296 if (error == boost::asio::error::eof)
321 const uint8_t *data = boost::asio::buffer_cast<
const uint8_t *>(buf_.data());
322 for (
size_t i = 1; i < buf_.size() -
sizeof(uint32_t); i++)
324 const uint32_t *mark =
reinterpret_cast<const uint32_t *
>(data + i);
333 if (buf_.size() < header.
length)
347 const std::string data(boost::asio::buffer_cast<const char *>(buf_.data()));
364 const std::string data(boost::asio::buffer_cast<const char *>(buf_.data()));
365 std::vector<std::string> lines;
366 boost::algorithm::split(lines, data, boost::algorithm::is_any_of(
"\n\r"));
367 if (lines.size() == 0)
370 if (lines[0].compare(0, 7,
"GET:tbl") == 0 ||
371 lines[0].compare(0, 6,
"GET:tv") == 0)
373 if (lines.size() < 2)
375 std::vector<std::string> cells;
376 boost::algorithm::split(cells, lines[1], boost::algorithm::is_any_of(
","));
378 if (lines[0].compare(
"GET:tblv") == 0 ||
379 lines[0].compare(0, 6,
"GET:tv") == 0)
382 if (lines[0].compare(0, 6,
"GET:tv") == 0)
383 tv = std::stoi(lines[0].substr(6));
385 if (tv >= static_cast<int>(tbl_v_.size()))
390 for (
auto &cell : cells)
392 const double rad(std::strtol(cell.c_str(),
nullptr, 16) * 2.0 * M_PI / 65535.0);
393 sincos(rad, &tbl_v[i].
s, &tbl_v[i].c);
397 tbl_vn_loaded_[tv] =
true;
399 bool load_finished =
true;
400 for (
auto loaded : tbl_vn_loaded_)
403 load_finished =
false;
405 tbl_v_loaded_ = load_finished;
407 else if (lines[0].compare(
"GET:tblh") == 0)
411 for (
auto &cell : cells)
413 tbl_h[i] = std::strtol(cell.c_str(),
nullptr, 16) / 65535.0;
417 tbl_h_loaded_ =
true;
439 if (!tbl_h_loaded_ || !tbl_v_loaded_ || !cb_point_)
465 std::memcpy(index.get(), boost::asio::buffer_cast<
const vssp::RangeIndex *>(buf_.data()),
466 sizeof(uint16_t) * (range_index.
nspots + 1));
467 buf_.consume(index_length);
468 length -= index_length;
477 success = rangeToXYZ<vssp::DataRangeIntensity>(
478 range_header, range_header_v2r1, range_index, index, points);
482 success = rangeToXYZ<vssp::DataRangeOnly>(
483 range_header, range_header_v2r1, range_index, index, points);
491 cb_point_(header, range_header, range_index, index, points, time_read);
504 for (
int i = 0; i < aux_header.
data_count; i++)
511 auxs[i][b] = aux_factor_[b] * data[offset++].
val;
513 buf_.consume(
sizeof(int32_t) * offset);
514 length -=
sizeof(int32_t) * offset;
517 cb_aux_(header, aux_header, auxs, time_read);
525 buf_.consume(length);
static const uint32_t TYPE_PNG
void setAutoReset(const bool enable)
static const uint32_t TYPE_SET
void onTimeout(const boost::system::error_code &error)
boost::asio::io_service & getIoService()
void onRead(const boost::system::error_code &error)
bool rangeToXYZ(const vssp::RangeHeader &range_header, const vssp::RangeHeaderV2R1 &range_header_v2r1, const vssp::RangeIndex &range_index, const boost::shared_array< const uint16_t > &index, const boost::shared_array< vssp::XYZI > &points)
void requestData(const bool intensity=1, const bool start=1)
void registerAuxCallback(decltype(cb_aux_) cb)
boost::asio::io_service io_service_
void requestVerticalTable(const int itl=1)
void setHorizontalInterlace(const int itl)
void setTimeout(const double to)
void setVerticalInterlace(const int itl)
boost::function< void(bool)> cb_connect_
static const uint32_t TYPE_AX
void registerCallback(decltype(cb_point_) cb)
void registerErrorCallback(decltype(cb_error_) cb)
boost::asio::ip::tcp::socket socket_
static const AuxFactorArray AUX_FACTOR_DEFAULT
void requestAuxData(const bool start=1)
boost::asio::deadline_timer timer_
AuxFactorArray aux_factor_
static const uint32_t TYPE_RI
void registerPingCallback(decltype(cb_ping_) cb)
void requestHorizontalTable()
boost::asio::streambuf buf_
void onTimeoutConnect(const boost::system::error_code &error)
static const uint32_t TYPE_ERR
static const uint32_t TYPE_DAT
void setInterlace(const int itl)
std::vector< bool > tbl_vn_loaded_
void onConnect(const boost::system::error_code &error)
static const uint32_t TYPE_RO
void onSend(const boost::system::error_code &error, boost::shared_ptr< std::string > data)
static const uint32_t TYPE_ER
const RangeHeaderV2R1 RANGE_HEADER_V2R1_DEFAULT
void connect(const char *ip, const unsigned int port, decltype(cb_connect_) cb)
boost::function< void(const vssp::Header &, const vssp::RangeHeader &, const vssp::RangeIndex &, const boost::shared_array< uint16_t > &, const boost::shared_array< vssp::XYZI > &, const boost::posix_time::ptime &)> cb_point_
boost::function< void(const vssp::Header &, const boost::posix_time::ptime &)> cb_ping_
static const uint32_t STATUS_OK
boost::function< void(const vssp::Header &, const std::string &, const boost::posix_time::ptime &)> cb_error_
static const uint32_t VSSP_MARK
static const uint32_t TYPE_VER
std::vector< boost::shared_array< const TableSincos > > tbl_v_
boost::shared_array< const double > tbl_h_
static const uint32_t TYPE_GET
boost::function< void(const vssp::Header &, const vssp::AuxHeader &, const boost::shared_array< vssp::Aux > &, const boost::posix_time::ptime &)> cb_aux_
void send(const std::string cmd)