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