swarmros/src/swarmros/bridge/main.cpp
Go to the documentation of this file.
2 #include <swarmio/data/discovery/Schema.pb.h>
3 #include <swarmio/data/Variant.pb.h>
4 #include <swarmio/Exception.h>
5 #include <swarmros/bridge/Node.h>
7 #include <g3log/g3log.hpp>
8 #include <g3log/logworker.hpp>
9 #include <libconfig.h++>
10 #include <ros/ros.h>
11 #include <czmq.h>
12 #include <map>
13 
14 using namespace swarmros;
15 
19 int main(int argc, const char *argv[])
20 {
21  // Initialize ROS
22  ros::init(argc, (char **)argv, "bridge");
23 
24  // Initialize logging
25  auto worker = g3::LogWorker::createLogWorker();
26  worker->addSink(std::make_unique<bridge::DebugSink>(), &bridge::DebugSink::ReceiveLogMessage);
27  initializeLogging(worker.get());
28  // Parse the rest of the arguments
29  std::string configFilePath = SWARMROS_CONFIG_PATH;
30  for (int i = 1; i < argc; ++i)
31  {
32  const char *current = argv[i];
33  if (current[0] == '-')
34  {
35  if (current[1] == 'C')
36  {
37  // Config file remapping
38  configFilePath = current + 2;
39  }
40  else if (current[1] == 'D' && current[2] == '\0')
41  {
42  // Enable debug mode
44  {
46  }
47  }
48  else
49  {
50  LOG(FATAL) << "Command line argument " << i << " is unknown";
51  return -10;
52  }
53  }
54  else
55  {
56  LOG(FATAL) << "Command line argument " << i << " cannot be processed";
57  return -10;
58  }
59  }
60 
61  // Load configuration and establish endpoint
62  libconfig::Config config;
63  std::unique_ptr<swarmio::Endpoint> endpoint;
64  try
65  {
66  config.readFile(configFilePath.c_str());
67  std::string type = (const char *)config.lookup("endpoint.type");
68  if (type == "zyre")
69  {
70  // Create endpoint
71  auto zyreEndpoint = std::make_unique<swarmio::transport::zyre::ZyreEndpoint>(config.lookup("endpoint.name"), config.lookup("endpoint.deviceClass"));
72  zyreEndpoint->SetConfig(configFilePath);
73  endpoint = std::move(zyreEndpoint);
74  }
75  else
76  {
77  LOG(FATAL) << "Unknown endpoint type specified in configuration file.";
78  return -1;
79  }
80  }
81  catch (const libconfig::SettingTypeException &e)
82  {
83  LOG(FATAL) << "Invalid type for setting at " << e.getPath() << ".";
84  return -1;
85  }
86  catch (const libconfig::SettingNotFoundException &e)
87  {
88  LOG(FATAL) << "Missing setting at " << e.getPath() << ".";
89  return -1;
90  }
91  catch (const libconfig::FileIOException &e)
92  {
93  LOG(DBUG) << e.what();
94  LOG(FATAL) << "An exception has occurred while trying to read the configuration file.";
95  return -1;
96  }
97  catch (const libconfig::ParseException &e)
98  {
99  LOG(DBUG) << e.getError();
100  LOG(FATAL) << "An exception has occurred while trying to parse the configuration file (line " << e.getLine() << ").";
101  return -1;
102  }
103  catch (const swarmio::Exception &e)
104  {
105  LOG(DBUG) << e.what();
106  LOG(FATAL) << "An exception has occurred while trying to initialize the endpoint.";
107  return -1;
108  }
109 
110  // Create device
111  auto device = std::make_unique<bridge::Node>(endpoint.get());
112 
113  // Process service descriptors
114  try
115  {
116  if (config.exists("services"))
117  {
118  auto &services = config.lookup("services");
119  for (int i = 0; i < services.getLength(); ++i)
120  {
121  auto &service = services[i];
122  std::string name = service.getName();
123  for (int j = 0; j < service.getLength(); ++j)
124  {
125  auto &entry = service[j];
126  if (name == "publishedParameters")
127  {
128  device->PublishParameter(
129  entry.lookup("suffix"),
130  entry.lookup("message"),
131  entry.lookup("name"),
132  entry.lookup("path"),
133  entry.lookup("rw"));
134  }
135  else if (name == "bridgedParameters")
136  {
137  device->BridgeParameter(
138  entry.lookup("name"),
139  entry.lookup("path"),
140  entry.lookup("rw"));
141  }
142  else if (name == "telemetryTopics")
143  {
144  device->ForwardTelemetry(
145  entry.lookup("source"),
146  entry.lookup("message"),
147  entry.lookup("name"),
148  entry.lookup("status"));
149  }
150  else if (name == "incomingEvents")
151  {
152  device->PublishEvent(
153  entry.lookup("suffix"),
154  entry.lookup("message"),
155  entry.lookup("name"));
156  }
157  else if (name == "outgoingEvents")
158  {
159  device->ForwardEvent(
160  entry.lookup("source"),
161  entry.lookup("message"));
162  }
163  else
164  {
165  LOG(WARNING) << "Unknown service type: " << name;
166  break;
167  }
168  }
169  }
170  }
171  }
172  catch (const libconfig::SettingTypeException &e)
173  {
174  LOG(FATAL) << "Invalid type for setting at " << e.getPath() << ".";
175  return -2;
176  }
177  catch (const libconfig::SettingNotFoundException &e)
178  {
179  LOG(FATAL) << "Missing setting at " << e.getPath() << ".";
180  return -2;
181  }
182  catch (const swarmio::Exception &e)
183  {
184  LOG(DBUG) << e.what();
185  LOG(FATAL) << "An exception has occurred while trying to initialize the endpoint.";
186  return -2;
187  }
188 
189  // Start endpoint
190  endpoint->Start();
191 
192  // Spin ROS
193  ros::spin();
194 
195  // Stop gracefully
196  endpoint->Stop();
197 
198  // Exit
199  return 0;
200 }
ROSCONSOLE_DECL void notifyLoggerLevelsChanged()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Exception class thrown by all library classes.
ROSCPP_DECL void spin()
int main(int argc, const char *argv[])
void ReceiveLogMessage(g3::LogMessageMover logEntry)
Receives messages from g3log and forwards them to ROS.
Definition: DebugSink.cpp:8
const char * what() const noexceptoverride
Get the error message.
ROSCONSOLE_DECL bool set_logger_level(const std::string &name, levels::Level level)
#define ROSCONSOLE_DEFAULT_NAME


swarmros
Author(s):
autogenerated on Fri Apr 3 2020 03:42:48