start_request_serialization.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-2021 Pilz GmbH & Co. KG
2 //
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU Lesser General Public License as published by
5 // the Free Software Foundation, either version 3 of the License, or
6 // (at your option) any later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public License
14 // along with this program. If not, see <https://www.gnu.org/licenses/>.
15 
16 #include <string>
17 #include <cassert>
18 #include <iostream>
19 
20 #ifdef _WIN32
21 #include <Windows.h>
22 #endif
23 
24 #include <boost/crc.hpp>
25 
31 
32 using namespace std;
33 
35 {
36 namespace data_conversion_layer
37 {
38 namespace start_request
39 {
40 static constexpr uint64_t RESERVED{ 0 };
41 
42 static const uint32_t OPCODE{ 0x35 };
43 } // namespace start_request
44 
46 {
47  boost::crc_32_type crc;
48  crc.process_bytes(&data.at(0), data.size());
49  return static_cast<uint32_t>(crc.checksum());
50 }
51 
53  const uint32_t& seq_number)
54 {
55  std::ostringstream os;
56 
57  raw_processing::write(os, seq_number);
60 
62 #ifdef __linux__
63  const uint32_t host_ip_big_endian = htobe32(msg.host_ip_);
64 #endif
65 
66 #ifdef _WIN32
67  const uint32_t host_ip_big_endian = _byteswap_ulong(msg.host_ip_);
68 #endif
69 
70  raw_processing::write(os, host_ip_big_endian);
71 
74 
81  const uint8_t device_enabled{ 0b00001000 };
82  const uint8_t intensity_enabled{ static_cast<uint8_t>(
83  msg.master_device_settings_.intensitiesEnabled() ? 0b00001000 : 0b00000000) };
84  const uint8_t point_in_safety_enabled{ 0 };
85  const uint8_t active_zone_set_enabled{ 0b00001000 };
86  const uint8_t io_pin_data_enabled{ 0b00001000 };
87  const uint8_t scan_counter_enabled{ 0b00001000 };
88  const uint8_t speed_encoder_enabled{ 0 };
89  const uint8_t diagnostics_enabled{ static_cast<uint8_t>(
90  msg.master_device_settings_.diagnosticsEnabled() ? 0b00001000 : 0b00000000) };
91 
92  raw_processing::write(os, device_enabled);
93  raw_processing::write(os, intensity_enabled);
94  raw_processing::write(os, point_in_safety_enabled);
95  raw_processing::write(os, active_zone_set_enabled);
96  raw_processing::write(os, io_pin_data_enabled);
97  raw_processing::write(os, scan_counter_enabled);
98  raw_processing::write(os, speed_encoder_enabled);
99  raw_processing::write(os, diagnostics_enabled);
100 
101  const auto start = msg.master_.scanRange().start().value();
102  auto end = msg.master_.scanRange().end().value();
103  const auto resolution = msg.master_.resolution().value();
104 
105  /* In order to get all the data points we want, the scanner needs a value
106  that is strictly greater than the end point */
107  if ((end - start) % resolution == 0)
108  {
109  end++;
110  }
112  raw_processing::write(os, end);
113  raw_processing::write(os, resolution);
114 
115  PSENSCAN_DEBUG("StartRequestSerialization",
116  "Serializing start request with angle_start={} angle_end={} resolution={} tenths of degree.",
117  start,
118  end,
119  resolution);
120 
121  for (const auto& subscriber :
122  msg.subscribers_) // Note: This refers to the scanner type subscriber, *not* a ros subscriber
123  {
124  raw_processing::write(os, subscriber.scanRange().start().value());
125  raw_processing::write(os, subscriber.scanRange().end().value());
126  raw_processing::write(os, subscriber.resolution().value());
127  }
128 
129  const std::string raw_data_as_str{ os.str() };
130  const data_conversion_layer::RawData raw_data(raw_data_as_str.cbegin(), raw_data_as_str.cend());
131 
132  std::ostringstream os_crc;
133  raw_processing::write(os_crc, calculateCRC(raw_data));
134 
135  std::string raw_data_with_crc_str(os_crc.str() + os.str());
136  data_conversion_layer::RawData raw_data_with_crc{ raw_data_with_crc_str.cbegin(), raw_data_with_crc_str.cend() };
137 
138  assert(raw_data_with_crc.size() == 58 && "Message data of start request has not the size expceted by protocol");
139 
140  return raw_data_with_crc;
141 }
142 
143 } // namespace data_conversion_layer
144 } // namespace psen_scan_v2_standalone
ROSCPP_DECL void start()
const uint32_t host_ip_
network byte order = big endian
Definition: start_request.h:92
const util::TenthOfDegree & end() const
Definition: scan_range.h:100
void write(std::ostringstream &os, const T &data)
#define PSENSCAN_DEBUG(name,...)
Definition: logging.h:63
Root namespace in which the software components to communicate with the scanner (firmware-version: 2)...
Definition: udp_client.h:41
uint32_t calculateCRC(const data_conversion_layer::RawData &data)
const util::TenthOfDegree & start() const
Definition: scan_range.h:94
Higher level data type representing a scanner start request.
Definition: start_request.h:42
const std::array< LaserScanSettings, NUM_SUBSCRIBERS > subscribers_
Definition: start_request.h:97


psen_scan_v2
Author(s): Pilz GmbH + Co. KG
autogenerated on Sat Nov 5 2022 02:13:36