node.cpp
Go to the documentation of this file.
1 #include <industrial_modbus_tcp/Configure.h>
3 #include <ros/ros.h>
4 
5 using namespace industrial_modbus_tcp;
6 
7 std::shared_ptr<ros::NodeHandle> nh;
8 std::vector<std::shared_ptr<Handler>> modbus_handlers;
9 std::string base_topic;
10 std::shared_ptr<ros::Publisher> error_pub;
11 
12 bool configureModbusCallback(industrial_modbus_tcp::ConfigureRequest &req,
13  industrial_modbus_tcp::ConfigureResponse &res)
14 {
15  res.error.clear();
16 
17  if (req.handlers.empty())
18  {
19  res.error = "Zero handler provided";
20  return true;
21  }
22 
23  for (auto &handler : req.handlers)
24  {
25  if (handler.name.empty())
26  {
27  res.error = "Handler name cannot be empty";
28  return true;
29  }
30 
31  if (handler.ip_address.empty())
32  {
33  res.error = "Handler '" + handler.name + "' IP address cannot be empty";
34  return true;
35  }
36 
37  if (handler.d_bool.empty() && handler.d_float32.empty() && handler.d_float64.empty() &&
38  handler.d_int16.empty() && handler.d_int32.empty() && handler.d_int64.empty() && handler.d_int8.empty() &&
39  handler.d_uint16.empty() && handler.d_uint32.empty() && handler.d_uint64.empty() && handler.d_uint8.empty())
40  {
41  res.error = "Handler '" + handler.name + "' contains zero data to be fetched";
42  return true;
43  }
44  }
45 
46  modbus_handlers.clear();
47  for (auto &handler_config : req.handlers)
48  {
49  modbus_error_recovery_mode recovery_mode;
50  switch (handler_config.modbus_error_recovery_mode)
51  {
52  case 0:
53  recovery_mode = MODBUS_ERROR_RECOVERY_NONE;
54  break;
55  case 1:
56  recovery_mode = MODBUS_ERROR_RECOVERY_LINK;
57  break;
58  case 2:
59  recovery_mode = MODBUS_ERROR_RECOVERY_PROTOCOL;
60  break;
61  default:
62  recovery_mode = (modbus_error_recovery_mode)(MODBUS_ERROR_RECOVERY_LINK | MODBUS_ERROR_RECOVERY_PROTOCOL);
63  break;
64  }
65 
66  std::shared_ptr<Handler> handler;
67  try
68  {
69  if (handler_config.port == 0)
70  {
71  handler.reset(new Handler(nh,
72  handler_config.name,
73  error_pub,
74  handler_config.ip_address,
75  recovery_mode));
76  }
77  else
78  {
79  handler.reset(new Handler(nh,
80  handler_config.name,
81  error_pub,
82  handler_config.ip_address,
83  recovery_mode,
84  handler_config.port));
85  }
86  }
87  catch (std::runtime_error &e)
88  {
89  std_msgs::String error;
90  error.data = "Handler '" + handler_config.name + "' error: " + e.what();
91  error_pub->publish(error);
92  res.error = error.data;
93  return true;
94  }
95 
96  // Add data into the handler
97  std::vector<std::shared_ptr<DataType>> data;
98 
99  for (auto v : handler_config.d_bool)
100  {
101  std::shared_ptr<DataType> d = std::make_shared<BoolType>(nh,
102  v.reg.address,
103  std::chrono::microseconds(v.reg.poll_rate_usec),
104  v.reg.topic_name);
105  std::dynamic_pointer_cast<BoolType>(d)->mask_ = v.mask;
106  data.emplace_back(d);
107  }
108 
109  for (auto v : handler_config.d_int8)
110  {
111  std::shared_ptr<DataType> d = std::make_shared<Int8Type>(nh,
112  v.reg.address,
113  std::chrono::microseconds(v.reg.poll_rate_usec),
114  v.reg.topic_name);
115  std::dynamic_pointer_cast<Int8Type>(d)->bit_shift = v.bit_shift;
116  data.emplace_back(d);
117  }
118 
119  for (auto v : handler_config.d_uint8)
120  {
121  std::shared_ptr<DataType> d = std::make_shared<UInt8Type>(nh,
122  v.reg.address,
123  std::chrono::microseconds(v.reg.poll_rate_usec),
124  v.reg.topic_name);
125  std::dynamic_pointer_cast<UInt8Type>(d)->bit_shift = v.bit_shift;
126  data.emplace_back(d);
127  }
128 
129  for (auto v : handler_config.d_int16)
130  {
131  std::shared_ptr<DataType> d = std::make_shared<Int16Type>(nh,
132  v.reg.address,
133  std::chrono::microseconds(v.reg.poll_rate_usec),
134  v.reg.topic_name);
135  data.emplace_back(d);
136  }
137 
138  for (auto v : handler_config.d_uint16)
139  {
140  std::shared_ptr<DataType> d = std::make_shared<UInt16Type>(nh,
141  v.reg.address,
142  std::chrono::microseconds(v.reg.poll_rate_usec),
143  v.reg.topic_name);
144  data.emplace_back(d);
145  }
146 
147  for (auto v : handler_config.d_int32)
148  {
149  std::shared_ptr<DataType> d = std::make_shared<Int32Type>(nh,
150  v.reg.address,
151  std::chrono::microseconds(v.reg.poll_rate_usec),
152  v.reg.topic_name);
153  std::dynamic_pointer_cast<Int32Type>(d)->big_endian = v.big_endian;
154  data.emplace_back(d);
155  }
156 
157  for (auto v : handler_config.d_uint32)
158  {
159  std::shared_ptr<DataType> d = std::make_shared<UInt32Type>(nh,
160  v.reg.address,
161  std::chrono::microseconds(v.reg.poll_rate_usec),
162  v.reg.topic_name);
163  std::dynamic_pointer_cast<UInt32Type>(d)->big_endian = v.big_endian;
164  data.emplace_back(d);
165  }
166 
167  for (auto v : handler_config.d_int64)
168  {
169  std::shared_ptr<DataType> d = std::make_shared<Int64Type>(nh,
170  v.reg.address,
171  std::chrono::microseconds(v.reg.poll_rate_usec),
172  v.reg.topic_name);
173  std::dynamic_pointer_cast<Int64Type>(d)->big_endian = v.big_endian;
174  data.emplace_back(d);
175  }
176 
177  for (auto v : handler_config.d_uint64)
178  {
179  std::shared_ptr<DataType> d = std::make_shared<UInt64Type>(nh,
180  v.reg.address,
181  std::chrono::microseconds(v.reg.poll_rate_usec),
182  v.reg.topic_name);
183  std::dynamic_pointer_cast<UInt64Type>(d)->big_endian = v.big_endian;
184  data.emplace_back(d);
185  }
186 
187  for (auto v : handler_config.d_float32)
188  {
189  std::shared_ptr<DataType> d = std::make_shared<Float32Type>(nh,
190  v.reg.address,
191  std::chrono::microseconds(v.reg.poll_rate_usec),
192  v.reg.topic_name);
193  std::dynamic_pointer_cast<Float32Type>(d)->big_endian = v.big_endian;
194  data.emplace_back(d);
195  }
196 
197  for (auto v : handler_config.d_float64)
198  {
199  std::shared_ptr<DataType> d = std::make_shared<Float64Type>(nh,
200  v.reg.address,
201  std::chrono::microseconds(v.reg.poll_rate_usec),
202  v.reg.topic_name);
203  std::dynamic_pointer_cast<Float64Type>(d)->big_endian = v.big_endian;
204  data.emplace_back(d);
205  }
206 
207  handler->setData(data);
208  modbus_handlers.emplace_back(handler);
209  }
210 
211  return true;
212 }
213 
214 int main(int argc,
215  char *argv[])
216 {
217  ros::init(argc, argv, "modbus_tcp");
218  nh = std::make_shared<ros::NodeHandle>("~");
219 
220  nh->param<std::string>("base_topic", base_topic, base_topic);
221  error_pub = std::make_shared<ros::Publisher>();
222  *error_pub = nh->advertise<std_msgs::String>(base_topic + "errors", 5);
223  ros::ServiceServer service = nh->advertiseService(base_topic + "configure", configureModbusCallback);
224 
226  spinner.start();
228  return 0;
229 }
std::string base_topic
Definition: node.cpp:9
d
int main(int argc, char *argv[])
Definition: node.cpp:214
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
void spinner()
std::shared_ptr< ros::Publisher > error_pub
Definition: node.cpp:10
std::shared_ptr< ros::NodeHandle > nh
Definition: node.cpp:7
bool configureModbusCallback(industrial_modbus_tcp::ConfigureRequest &req, industrial_modbus_tcp::ConfigureResponse &res)
Definition: node.cpp:12
std::vector< std::shared_ptr< Handler > > modbus_handlers
Definition: node.cpp:8
ROSCPP_DECL void waitForShutdown()


industrial_modbus_tcp
Author(s): Victor Lamoine - Institut Maupertuis
autogenerated on Mon Feb 28 2022 22:33:12