YARP
Yet Another Robot Platform
DeviceGroup.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include "DeviceGroup.h"
8 
9 #include <cstdio>
10 #include <yarp/os/Time.h>
11 #include <yarp/os/LogComponent.h>
12 #include <yarp/dev/Drivers.h>
14 
16 
17 #include <mutex>
18 #include <vector>
19 
20 using namespace yarp::os;
21 using namespace yarp::sig;
22 using namespace yarp::dev;
23 
24 namespace {
25 YARP_LOG_COMPONENT(DEVICEGROUP, "yarp.devices.DeviceGroup")
26 }
27 
28 #define HELPER(x) (*((DeviceGroupHelper*)(x)))
29 
30 
32 {
33 private:
34  std::vector<PolyDriver *> drivers;
35  std::vector<std::string> names;
36  std::vector<bool> needDrive;
37  std::mutex mutex;
38 public:
39  bool needDriveSummary{false};
40 
41  void clear()
42  {
43  mutex.lock();
44  std::vector<PolyDriver *>& lst = drivers;
45  for (unsigned int i=0; i<lst.size(); i++) {
46  yCInfo(DEVICEGROUP, "*** Removing %s",names[i].c_str());
47  Drivers::factory().remove(names[i].c_str());
48  yCTrace(DEVICEGROUP, "*** removed %s",names[i].c_str());
49  delete lst[i];
50  yCTrace(DEVICEGROUP, "*** deleted %s",names[i].c_str());
51  }
52  lst.clear();
53  names.clear();
54  mutex.unlock();
55  }
56 
57  void update()
58  {
59  mutex.lock();
60  std::vector<PolyDriver *>& lst = drivers;
61  for (unsigned int i=0; i<lst.size(); i++) {
62  if (needDrive[i]) {
63  IService *service;
64  lst[i]->view(service);
65  if (service!=nullptr) {
66  service->updateService();
67  }
68  }
69  }
70  mutex.unlock();
71  }
72 
73  bool close()
74  {
75  yCTrace(DEVICEGROUP, "*** Device group closing");
76  clear();
77  yCTrace(DEVICEGROUP, "*** Device group closed");
78  return true;
79  }
80 
82  {
83  clear();
84  }
85 
86  bool add(const std::string& name, yarp::os::Searchable& config)
87  {
88  yCTrace(DEVICEGROUP, "ADDING %s", config.toString().c_str());
89  auto* pd = new PolyDriver();
90  yCAssert(DEVICEGROUP, pd!=nullptr);
91  bool result = pd->open(config);
92  if (!result) {
93  delete pd;
94  return false;
95  }
96  drivers.push_back(pd);
97  names.push_back(name);
98  IService *service = nullptr;
99  pd->view(service);
100  bool backgrounded = true;
101  if (service!=nullptr) {
102  backgrounded = service->startService();
103  if (backgrounded) {
104  // we don't need to poll this, so forget about the
105  // service interface
106  yCInfo(DEVICEGROUP, "group: service backgrounded");
107  service = nullptr;
108  }
109  }
110  needDrive.push_back(!backgrounded);
111  needDriveSummary = needDriveSummary || (!backgrounded);
112  Drivers::factory().add(new DriverLinkCreator(name,*pd));
113  return true;
114  }
115 
116 };
117 
118 
119 
120 
122 {
123  if (implementation==nullptr) {
125  }
126  if (implementation==nullptr) {
127  yCError(DEVICEGROUP, "Out of memory");
128  return false;
129  }
130 
131  if (config.check("part","a list of section names, with each section containing a device")) {
132  Bottle bot = config.findGroup("part").tail();
133  yCInfo(DEVICEGROUP, "Assembly of: %s", bot.toString().c_str());
134  for (size_t i=0; i<bot.size(); i++) {
135  std::string name = bot.get(i).asString();
136  yCInfo(DEVICEGROUP, " %s -> %s", name.c_str(),
137  config.findGroup(name).toString().c_str());
138  bool result = HELPER(implementation).add(name,
139  config.findGroup(name));
140  if (!result) {
141  HELPER(implementation).close();
142  return false;
143  }
144  }
145  return true;
146  }
147  return false;
148 }
149 
150 
151 bool DeviceGroup::open(const char *key, PolyDriver& poly,
152  yarp::os::Searchable& config, const char *comment)
153 {
154  Value *name;
155  if (config.check(key,name,comment)) {
156  if (name->isString()) {
157  // maybe user isn't doing nested configuration
159  p.setMonitor(config.getMonitor(),
160  name->toString().c_str()); // pass on any monitoring
161  p.fromString(config.toString());
162  p.put("device",name->toString());
163  p.unput("subdevice");
164  p.unput("wrapped");
165  poly.open(p);
166  } else {
167  Bottle subdevice = config.findGroup(key).tail();
168  poly.open(subdevice);
169  }
170  if (!poly.isValid()) {
171  yCError(DEVICEGROUP, "cannot make <%s>", name->toString().c_str());
172  return false;
173  }
174  } else {
175  yCError(DEVICEGROUP, "\"--%s <name>\" not set", key);
176  return false;
177  }
178  return true;
179 }
180 
181 
182 bool DeviceGroup::closeMain()
183 {
184  yCInfo(DEVICEGROUP, "Devices closing");
185  HELPER(implementation).close();
186  source.close();
187  sink.close();
188  return true;
189 }
190 
192 {
193  return !HELPER(implementation).needDriveSummary;
194 }
195 
196 
198 {
199  HELPER(implementation).update();
200  return true;
201 }
202 
203 
205 {
206  if (implementation!=nullptr) {
207  delete &HELPER(implementation);
208  implementation = nullptr;
209  }
210 }
#define HELPER(x)
Definition: DeviceGroup.cpp:28
RandScalar * implementation(void *t)
Definition: RandnScalar.cpp:17
bool add(const std::string &name, yarp::os::Searchable &config)
Definition: DeviceGroup.cpp:86
bool open(yarp::os::Searchable &config) override
Open the DeviceDriver.
bool updateService() override
Give the service the chance to run for a while.
bool startService() override
Initiate the service, whatever it is.
~DeviceGroup() override
A factory for creating links to a driver that has already been created.
Common interface for devices that act like services (by which we mean they do something for remote us...
virtual bool startService()
Initiate the service, whatever it is.
virtual bool updateService()
Give the service the chance to run for a while.
A container for a device driver.
Definition: PolyDriver.h:24
bool isValid() const
Check if device is valid.
Definition: PolyDriver.cpp:196
bool open(const std::string &txt)
Construct and configure a device by its common name.
Definition: PolyDriver.cpp:140
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:74
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:246
Bottle tail() const
Get all but the first element of a bottle.
Definition: Bottle.cpp:388
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:211
A class for storing options and configuration information.
Definition: Property.h:34
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1063
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:1015
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Definition: Property.cpp:1046
A base class for nested structures that can be searched.
Definition: Searchable.h:66
virtual bool check(const std::string &key) const =0
Check if there exists a property of the given name.
virtual std::string toString() const =0
Return a standard text representation of the content of the object.
virtual Bottle & findGroup(const std::string &key) const =0
Gets a list corresponding to a given keyword.
A single value (typically within a Bottle).
Definition: Value.h:45
virtual bool isString() const
Checks if value is a string.
Definition: Value.cpp:156
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:356
virtual std::string asString() const
Get string value.
Definition: Value.cpp:234
#define yCInfo(component,...)
Definition: LogComponent.h:132
#define yCError(component,...)
Definition: LogComponent.h:154
#define yCAssert(component, x)
Definition: LogComponent.h:169
#define yCTrace(component,...)
Definition: LogComponent.h:85
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:77
An interface for the device drivers.
An interface to the operating system, including Port based communication.
Signal processing.
Definition: Image.h:22