modbus_api_spec.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Pilz GmbH & Co. KG
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13 
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef MODBUS_API_SPEC_H
19 #define MODBUS_API_SPEC_H
20 
21 #include <algorithm>
22 #include <initializer_list>
23 #include <map>
24 #include <string>
25 #include <utility>
26 
27 #include <ros/ros.h>
28 #include <xmlrpcpp/XmlRpc.h>
29 
30 namespace prbt_hardware_support
31 {
32 static const std::string READ_API_SPEC_PARAM_NAME{ "read_api_spec/" };
33 
34 namespace modbus_api_spec
35 {
36 static const std::string RUN_PERMITTED{ "RUN_PERMITTED" };
37 static const std::string VERSION{ "VERSION" };
38 static const std::string BRAKETEST_REQUEST{ "BRAKETEST_REQUEST" };
39 static const std::string OPERATION_MODE{ "OPERATION_MODE" };
40 static const std::string BRAKETEST_PERFORMED{ "BRAKETEST_PERFORMED" };
41 static const std::string BRAKETEST_RESULT{ "BRAKETEST_RESULT" };
42 } // namespace modbus_api_spec
43 
47 class ModbusApiSpecException : public std::runtime_error
48 {
49 public:
50  ModbusApiSpecException(const std::string& what_arg) : std::runtime_error(what_arg)
51  {
52  }
53 };
54 
61 template <class T = ros::NodeHandle>
63 {
64 public:
65  ModbusApiSpecTemplated(std::initializer_list<std::pair<std::string, unsigned short> > reg_list)
66  {
67  for (auto entry : reg_list)
68  {
69  setRegisterDefinition(entry.first, entry.second);
70  }
71  }
72 
87  {
88  }
89 
104  ModbusApiSpecTemplated(T& nh, const std::string& param_name)
105  {
107  if (!nh.getParam(param_name, rpc))
108  {
109  throw ModbusApiSpecException("No api specified. (Expected at " + nh.getNamespace() + "/" + param_name + ")");
110  }
111 
112  for (auto rpci = rpc.begin(); rpci != rpc.end(); ++rpci)
113  {
114  int value = rpci->second;
115  setRegisterDefinition(rpci->first.c_str(), static_cast<unsigned short>(value));
116  }
117  }
118 
119  inline bool hasRegisterDefinition(const std::string& key) const
120  {
121  return register_mapping_.find(key) != register_mapping_.end();
122  }
123 
124  inline void setRegisterDefinition(const std::string& key, unsigned short value)
125  {
126  register_mapping_[key] = value;
127  }
128 
129  inline unsigned short getRegisterDefinition(const std::string& key) const
130  {
131  try
132  {
133  return register_mapping_.at(key);
134  }
135  catch (const std::out_of_range& e)
136  {
137  throw ModbusApiSpecException(e.what());
138  }
139  }
140  inline unsigned short getMinRegisterDefinition() const
141  {
142  if (register_mapping_.empty())
143  {
144  throw ModbusApiSpecException("Cannot read values. Api spec is empty.");
145  }
146 
147  typedef std::pair<std::string, unsigned short> RegisterMappingEntry;
148  // The following is excluded because lambda functions are not marked properly with gcc-7
149  // see https://github.com/gcc-mirror/gcc/commit/7de708f
150  // LCOV_EXCL_START
151  auto it = std::min_element(
152  register_mapping_.begin(), register_mapping_.end(),
153  [](const RegisterMappingEntry& a, const RegisterMappingEntry& b) { return a.second < b.second; });
154  // LCOV_EXCL_STOP
155  return it->second;
156  }
157 
158  inline unsigned short getMaxRegisterDefinition() const
159  {
160  if (register_mapping_.empty())
161  {
162  throw ModbusApiSpecException("Cannot read values. Api spec is empty.");
163  }
164 
165  typedef std::pair<std::string, unsigned short> RegisterMappingEntry;
166  // The following is excluded because lambda functions are not marked properly with gcc-7
167  // see https://github.com/gcc-mirror/gcc/commit/7de708f
168  // LCOV_EXCL_START
169  auto it = std::max_element(
170  register_mapping_.begin(), register_mapping_.end(),
171  [](const RegisterMappingEntry& a, const RegisterMappingEntry& b) { return a.second < b.second; });
172  // LCOV_EXCL_STOP
173  return it->second;
174  }
175 
176  inline void getAllDefinedRegisters(std::vector<unsigned short>& registers)
177  {
178  for (auto it = register_mapping_.begin(); it != register_mapping_.end(); ++it)
179  {
180  registers.push_back(it->second);
181  std::sort(registers.begin(), registers.end());
182  }
183  }
184 
185  inline std::map<std::string, unsigned short>::size_type size() const
186  {
187  return register_mapping_.size();
188  }
189 
190 private:
191  std::map<std::string, unsigned short> register_mapping_;
192 };
193 
196 
197 } // namespace prbt_hardware_support
198 #endif // MODBUS_API_SPEC_H
static const std::string BRAKETEST_PERFORMED
static const std::string BRAKETEST_REQUEST
Expection thrown by prbt_hardware_support::ModbusApiSpec.
unsigned short getRegisterDefinition(const std::string &key) const
void getAllDefinedRegisters(std::vector< unsigned short > &registers)
static const std::string BRAKETEST_RESULT
ModbusApiSpecTemplated ModbusApiSpec
Simple typedef for class like usage.
ModbusApiSpecTemplated(std::initializer_list< std::pair< std::string, unsigned short > > reg_list)
ModbusApiSpecTemplated(T &nh, const std::string &param_name)
Construct a new Modbus Api Spec Templated object.
static const std::string OPERATION_MODE
static const std::string READ_API_SPEC_PARAM_NAME
static const std::string RUN_PERMITTED
ModbusApiSpecException(const std::string &what_arg)
void setRegisterDefinition(const std::string &key, unsigned short value)
std::map< std::string, unsigned short >::size_type size() const
std::map< std::string, unsigned short > register_mapping_
bool hasRegisterDefinition(const std::string &key) const
Specifies the meaning of the holding registers.
ModbusApiSpecTemplated(T &nh)
Construct a new Modbus Api Spec Templated object.


prbt_hardware_support
Author(s):
autogenerated on Mon Feb 28 2022 23:14:34