cola_parser.cpp
Go to the documentation of this file.
1 /*
2  * @brief sim_loc_cola_parser parses and converts binary Cola telegrams to ros messages SickLocColaTelegramMsg
3  * and vice versa.
4  *
5  * See Operation-Instruction-v1.1.0.241R.pdf, chapter 5.8 "About CoLa-A telegrams", page 46-48,
6  * Telegram-Listing-v1.1.0.241R.pdf, chapter 2.3.9 "Command: LocRequestTimestamp", page 21, and
7  * Technical_information_Telegram_Listing_NAV_LOC_en_IM0076556.PDF for further details about
8  * Cola telegrams.
9  *
10  * Copyright (C) 2019 Ing.-Buero Dr. Michael Lehning, Hildesheim
11  * Copyright (C) 2019 SICK AG, Waldkirch
12  *
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  *
25  * All rights reserved.
26  *
27  * Redistribution and use in source and binary forms, with or without
28  * modification, are permitted provided that the following conditions are met:
29  *
30  * * Redistributions of source code must retain the above copyright
31  * notice, this list of conditions and the following disclaimer.
32  * * Redistributions in binary form must reproduce the above copyright
33  * notice, this list of conditions and the following disclaimer in the
34  * documentation and/or other materials provided with the distribution.
35  * * Neither the name of SICK AG nor the names of its
36  * contributors may be used to endorse or promote products derived from
37  * this software without specific prior written permission
38  * * Neither the name of Ing.-Buero Dr. Michael Lehning nor the names of its
39  * contributors may be used to endorse or promote products derived from
40  * this software without specific prior written permission
41  *
42  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
46  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
47  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
48  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52  * POSSIBILITY OF SUCH DAMAGE.
53  *
54  * Authors:
55  * Michael Lehning <michael.lehning@lehning.de>
56  *
57  * Copyright 2019 SICK AG
58  * Copyright 2019 Ing.-Buero Dr. Michael Lehning
59  *
60  */
61 #include "sick_scan/ros_wrapper.h"
62 #include <cassert>
63 #include "sick_scan/cola_parser.h"
64 #include "sick_scan/utils.h"
65 
69 const std::string sick_scan_xd::ColaParser::s_command_type_string[MAX_COLA_COMMAND_NUMBER] =
70  {
71  "sINVALID", "sRN", "sRA", "sMN", "sAN", "sMA", "sWN", "sWA", "sEN", "sEA", "sSN", "sFA"
72  };
73 
77 const std::map<std::string, sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND> sick_scan_xd::ColaParser::s_command_type_map =
78  {
79  {"", sINVALID}, {"sINVALID", sINVALID}, {"sRN", sRN}, {"sRA", sRA}, {"sMN", sMN}, {"sAN", sAN}, {"sMA", sMA}, {"sWN", sWN}, {"sWA", sWA}, {"sEN", sEN}, {"sEA", sEA}, {"sSN", sSN}, {"sFA", sFA}
80  };
81 
85 const std::string sick_scan_xd::ColaParser::s_cola_ascii_start_tag = "<STX>";
86 
90 const std::string sick_scan_xd::ColaParser::s_cola_ascii_end_tag = "<ETX>";
91 
100  const std::string & command_name, const std::vector<std::string> & parameter)
101 {
103  cola_telegram.header.stamp = ROS::now();
104  cola_telegram.command_type = command_type;
105  cola_telegram.command_name = command_name;
106  cola_telegram.parameter = parameter;
107  return cola_telegram;
108 }
109 
119 {
121  return decodeColaTelegram(cola_ascii);
122 }
123 
130 {
131  // Check and remove start and end tags ("<STX>" and "<ETX>")
132  std::string cola_ascii_cmd;
133  if (cola_ascii.size() > s_cola_ascii_start_tag.size() + s_cola_ascii_end_tag.size()
134  && cola_ascii.substr(0, s_cola_ascii_start_tag.size()) == s_cola_ascii_start_tag
135  && cola_ascii.substr(cola_ascii.size() - s_cola_ascii_end_tag.size()) == s_cola_ascii_end_tag)
136  {
137  cola_ascii_cmd = cola_ascii.substr(s_cola_ascii_start_tag.size(), cola_ascii.size() - s_cola_ascii_start_tag.size() - s_cola_ascii_end_tag.size());
138  }
139  else
140  {
141  cola_ascii_cmd = cola_ascii;
142  }
143  // Split in command_type, command_name and optional parameter by spaces
144  std::vector<std::string> cola_parts = sick_scan_xd::Utils::splitSpaces(cola_ascii_cmd);
145  if(cola_parts.size() < 2) // at least command_type and command_name required
146  {
147  ROS_WARN_STREAM("## ERROR Parse error in ColaParser::decodeColaTelegram(\"" << cola_ascii_cmd << "\"): to few arguments, at least command_type and command_name required");
148  return createColaTelegram(sINVALID, "");
149  }
150  // Convert command_type from string to COLA_SOPAS_COMMAND
151  sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND command_type = convertSopasCommand(cola_parts[0]);
152  if(command_type == sINVALID)
153  {
154  ROS_WARN_STREAM("## ERROR Parse error in ColaParser::decodeColaTelegram(\"" << cola_ascii_cmd << "\"): invalid command_type \"" << cola_parts[0] << "\"");
155  return createColaTelegram(sINVALID, "");
156  }
157  // Check command_name
158  if(cola_parts[1].empty())
159  {
160  ROS_WARN_STREAM("## ERROR Parse error in ColaParser::decodeColaTelegram(\"" << cola_ascii_cmd << "\"): invalid command_name \"" << cola_parts[1] << "\"");
161  return createColaTelegram(sINVALID, "");
162  }
163  // Append command parameter
164  sick_scan_xd::SickLocColaTelegramMsg cola_telegram = createColaTelegram(command_type, cola_parts[1]);
165  if(cola_parts.size() > 2)
166  {
167  cola_telegram.parameter.reserve(cola_parts.size() - 2);
168  for(size_t n = 2; n < cola_parts.size(); n++)
169  cola_telegram.parameter.push_back(cola_parts[n]);
170  }
171  return cola_telegram;
172 }
173 
180 std::vector<uint8_t> sick_scan_xd::ColaParser::encodeColaTelegram(const sick_scan_xd::SickLocColaTelegramMsg & cola_telegram, bool parameter_is_ascii)
181 {
182  assert(cola_telegram.command_type > sINVALID && cola_telegram.command_type < MAX_COLA_COMMAND_NUMBER);
183  std::string cola_ascii;
184  cola_ascii.reserve(64*1024);
185  cola_ascii += s_cola_ascii_start_tag;
186  cola_ascii += convertSopasCommand((COLA_SOPAS_COMMAND)cola_telegram.command_type);
187  cola_ascii += " ";
188  cola_ascii += cola_telegram.command_name;
189  for(size_t n = 0; n < cola_telegram.parameter.size(); n++)
190  {
191  if( n == 0 || parameter_is_ascii)
192  cola_ascii += " ";
193  cola_ascii += cola_telegram.parameter[n];
194  }
195  cola_ascii += s_cola_ascii_end_tag;
197 }
198 
206 std::vector<uint8_t> sick_scan_xd::ColaParser::encodeColaTelegram(const COLA_SOPAS_COMMAND & command_type, const std::string & command_name,
207  const std::vector<std::string> & parameter, bool parameter_is_ascii)
208 {
209  return encodeColaTelegram(createColaTelegram(command_type, command_name, parameter), parameter_is_ascii);
210 }
211 
219 {
220  return s_command_type_string[command_type];
221 }
222 
230 {
231  std::map<std::string, sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND>::const_iterator iter_command_type = s_command_type_map.find(sopas_command);
232  sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND command_type = (iter_command_type != s_command_type_map.cend()) ? (iter_command_type->second) : sINVALID;
233  return command_type;
234 }
235 
243 int32_t sick_scan_xd::ColaParser::convertColaArg(const std::string & cola_arg, int base, int32_t default_value)
244 {
245  try
246  {
247  if(base < 0)
248  base = ((cola_arg.find_first_of("+-") != std::string::npos) ? 10 : 16); // base 10 if +/-sign in cola_arg, otherwise hex
249  return std::stoi(cola_arg, 0, base);
250  }
251  catch(const std::exception & exc)
252  {
253  ROS_WARN_STREAM("## ERROR ColaParser::convertColaArg(" << cola_arg << ") failed, exception " << exc.what());
254  }
255  return default_value;
256 }
257 
265 uint32_t sick_scan_xd::ColaParser::convertColaArg(const std::string & cola_arg, int base, uint32_t default_value)
266 {
267  try
268  {
269  if(base < 0)
270  base = ((cola_arg.find_first_of("+-") != std::string::npos) ? 10 : 16); // base 10 if +/-sign in cola_arg, otherwise hex
271  return (uint32_t)std::stoul(cola_arg, 0, base);
272  }
273  catch(const std::exception & exc)
274  {
275  ROS_WARN_STREAM("## ERROR ColaParser::convertColaArg(" << cola_arg << ") failed, exception " << exc.what());
276  }
277  return default_value;
278 }
279 
286 bool sick_scan_xd::ColaParser::convertColaResponseBool(const std::string & cola_response_arg, bool default_value)
287 {
288  return ((sick_scan_xd::ColaParser::convertColaArg(cola_response_arg, 10, (default_value ? 1 : 0)) > 0) ? true : false);
289 }
std_msgs::Header_::stamp
_stamp_type stamp
Definition: Header.h:45
pcap_json_converter.cola_ascii
bool cola_ascii
Definition: pcap_json_converter.py:132
sick_scan_xd::ColaParser::createColaTelegram
static sick_scan_xd::SickLocColaTelegramMsg createColaTelegram(const COLA_SOPAS_COMMAND &command_type, const std::string &command_name, const std::vector< std::string > &parameter=std::vector< std::string >())
Creates and returns a Cola telegram (type SickLocColaTelegramMsg).
Definition: cola_parser.cpp:99
sick_scan_xd::ColaParser::s_command_type_string
static const std::string s_command_type_string[MAX_COLA_COMMAND_NUMBER]
static table to convert COLA_SOPAS_COMMAND to string, f.e. s_command_type_string[sRN]:="sRN",...
Definition: cola_parser.h:223
utils.h
sick_scan_xd::SickLocColaTelegramMsg_
Definition: SickLocColaTelegramMsg.h:24
sick_scan_xd::ColaParser::encodeColaTelegram
static std::vector< uint8_t > encodeColaTelegram(const sick_scan_xd::SickLocColaTelegramMsg &cola_telegram, bool parameter_is_ascii=true)
Encodes and returns a Cola Binary telegram from ros message SickLocColaTelegramMsg.
Definition: cola_parser.cpp:180
sick_scan_xd::SickLocColaTelegramMsg_::command_name
_command_name_type command_name
Definition: SickLocColaTelegramMsg.h:51
sick_scan_xd::ColaParser::s_command_type_map
static const std::map< std::string, COLA_SOPAS_COMMAND > s_command_type_map
static map to convert COLA_SOPAS_COMMANDs from string to enum, f.e. s_command_type_map["sRN"]:=sRN,...
Definition: cola_parser.h:224
sick_scan_xd::Utils::splitSpaces
static std::vector< std::string > splitSpaces(const std::string &s)
Definition: utils.cpp:139
default_value
string default_value
sick_scan_xd::ColaParser::convertColaResponseBool
static bool convertColaResponseBool(const std::string &cola_response_arg, bool default_value)
Definition: cola_parser.cpp:286
sick_scan_xd::ColaParser::decodeColaTelegram
static sick_scan_xd::SickLocColaTelegramMsg decodeColaTelegram(const std::vector< uint8_t > &cola_binary)
Decodes and returns a Cola message of type SickLocColaTelegramMsg from a Cola-Binary telegram....
Definition: cola_parser.cpp:118
sick_scan_xd::ColaParser::convertColaArg
static int32_t convertColaArg(const std::string &cola_arg, int base=10, int32_t default_value=0)
Definition: cola_parser.cpp:243
ROS::now
ROS::Time now(void)
Definition: ros_wrapper.cpp:116
encodeColaTelegram
static std::vector< uint8_t > encodeColaTelegram(const std::vector< uint8_t > &payload, bool is_binary)
Definition: test_server_cola_msg.cpp:75
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
Definition: sick_scan_logging.h:123
multiscan_sopas_test_server.cola_binary
int cola_binary
Definition: multiscan_sopas_test_server.py:173
sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND
enum sick_scan_xd::ColaParser::COLA_SOPAS_COMMAND_ENUM COLA_SOPAS_COMMAND
Enumeration of SOPAS commands in cola telegrams: The command_type in SickLocColaTelegramMsg is one of...
sick_scan_xd::SickLocColaTelegramMsg_::command_type
_command_type_type command_type
Definition: SickLocColaTelegramMsg.h:48
sick_scan_xd::ColaParser::convertSopasCommand
static std::string convertSopasCommand(COLA_SOPAS_COMMAND command_type)
Converts and returns a COLA_SOPAS_COMMAND to string. Example: convertSopasCommand(sMN) returns "sMN".
Definition: cola_parser.cpp:218
sick_scan_xd::ColaAsciiBinaryConverter::ConvertColaAscii
static std::string ConvertColaAscii(const std::vector< uint8_t > &cola_telegram)
Converts and returns a Cola-ASCII telegram to string.
Definition: cola_converter.cpp:105
sick_scan_xd::ColaParser::s_cola_ascii_end_tag
static const std::string s_cola_ascii_end_tag
All Cola-ACSII telegrams start with s_cola_ascii_start_tag := "<ETX>" ("End of TeXt")
Definition: cola_parser.h:226
sick_scan_xd::ColaParser::s_cola_ascii_start_tag
static const std::string s_cola_ascii_start_tag
All Cola-ACSII telegrams start with s_cola_ascii_start_tag := "<STX>" ("Start of TeXt")
Definition: cola_parser.h:225
sick_scan_xd::SickLocColaTelegramMsg_::parameter
_parameter_type parameter
Definition: SickLocColaTelegramMsg.h:54
ros_wrapper.h
cola_parser.h
sick_scan_xd::SickLocColaTelegramMsg_::header
_header_type header
Definition: SickLocColaTelegramMsg.h:45


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:07