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
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::LaserScanSettings::scanRange
constexpr const ScanRange & scanRange() const
Definition: start_request.h:107
psen_scan_v2_standalone::data_conversion_layer::start_request::OPCODE
static const uint32_t OPCODE
Definition: start_request_serialization.cpp:42
start_request_serialization.h
start_request.h
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::master_device_settings_
const DeviceSettings master_device_settings_
Definition: start_request.h:95
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::DeviceSettings::diagnosticsEnabled
constexpr bool diagnosticsEnabled() const
Definition: start_request.h:122
psen_scan_v2_standalone::ScanRangeTemplated::start
const util::TenthOfDegree & start() const
Definition: scan_range.h:94
PSENSCAN_DEBUG
#define PSENSCAN_DEBUG(name,...)
Definition: logging.h:63
psen_scan_v2_standalone::data_conversion_layer::raw_processing::write
void write(std::ostringstream &os, const T &data)
Definition: raw_processing.h:47
psen_scan_v2_standalone::data_conversion_layer::calculateCRC
uint32_t calculateCRC(const data_conversion_layer::RawData &data)
Definition: start_request_serialization.cpp:45
psen_scan_v2_standalone::util::TenthOfDegree::value
constexpr int16_t value() const
Definition: tenth_of_degree.h:49
psen_scan_v2_standalone::ScanRangeTemplated::end
const util::TenthOfDegree & end() const
Definition: scan_range.h:100
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::subscribers_
const std::array< LaserScanSettings, NUM_SUBSCRIBERS > subscribers_
Definition: start_request.h:97
psen_scan_v2_standalone::data_conversion_layer::start_request::RESERVED
static constexpr uint64_t RESERVED
Definition: start_request_serialization.cpp:40
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::host_udp_port_data_
const uint16_t host_udp_port_data_
Definition: start_request.h:93
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::DeviceSettings::intensitiesEnabled
constexpr bool intensitiesEnabled() const
Definition: start_request.h:127
raw_scanner_data.h
psen_scan_v2_standalone::data_conversion_layer::scanner_reply::serialize
RawData serialize(const Message &reply)
Definition: scanner_reply_serialization_deserialization.cpp:55
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::host_ip_
const uint32_t host_ip_
network byte order = big endian
Definition: start_request.h:92
raw_processing.h
start
ROSCPP_DECL void start()
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::master_
const LaserScanSettings master_
Definition: start_request.h:96
psen_scan_v2_standalone::data_conversion_layer::start_request::Message::LaserScanSettings::resolution
constexpr util::TenthOfDegree resolution() const
Definition: start_request.h:112
std
logging.h
psen_scan_v2_standalone
Root namespace in which the software components to communicate with the scanner (firmware-version: 2)...
Definition: udp_client.h:41
psen_scan_v2_standalone::data_conversion_layer::RawData
std::vector< char > RawData
Definition: raw_scanner_data.h:25
psen_scan_v2_standalone::data_conversion_layer::start_request::Message
Higher level data type representing a scanner start request.
Definition: start_request.h:42


psen_scan_v2
Author(s): Pilz GmbH + Co. KG
autogenerated on Sat Nov 25 2023 03:46:26