Skip to content

Commit a8eaa0f

Browse files
committed
Fix early destruction of device
1 parent 50e2395 commit a8eaa0f

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

libraries/singleton/include/GazeboYarpPlugins/Handler.hh

+11-1
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,18 @@ public:
145145
* If after removing the scope two devices have the same yarpDeviceName, the getModelDevicesAsPolyDriverList
146146
* prints an error and returns false, while true is returned if everything works as expected.
147147
*/
148-
bool getDevicesAsPolyDriverList(const std::string& modelScopedName, yarp::dev::PolyDriverList& list);
148+
bool getDevicesAsPolyDriverList(const std::string& modelScopedName, yarp::dev::PolyDriverList& list, std::vector<std::string>& deviceScopedNames);
149149

150+
/**
151+
* \brief Decrease the usage count for the devices that are acquired with the getDevicesAsPolyDriverList
152+
*
153+
* As Gazebo plugins are not denstructed in the same order that they are loaded, it is necessary to keep
154+
* a count of the users of each device, to ensure that is only destructed when no device are still attached to it.
155+
*
156+
* This function needs to be called by any plugin that has called the getDevicesAsPolyDriverList method during
157+
* the unload/destruction process.
158+
*/
159+
void releaseDevicesInList(const std::vector<std::string>& deviceScopedNames);
150160

151161
/** Destructor
152162
*/

libraries/singleton/src/Handler.cc

+17-5
Original file line numberDiff line numberDiff line change
@@ -237,18 +237,17 @@ inline bool startsWith(const std::string&completeString,
237237
return (completeString.rfind(candidatePrefix, 0) == 0);
238238
}
239239

240-
bool Handler::getDevicesAsPolyDriverList(const std::string& modelScopedName, yarp::dev::PolyDriverList& list)
240+
bool Handler::getDevicesAsPolyDriverList(const std::string& modelScopedName, yarp::dev::PolyDriverList& list, std::vector<std::string>& deviceScopedNames)
241241
{
242+
deviceScopedNames.resize(0);
243+
242244
list = yarp::dev::PolyDriverList();
243245

244246
// This map contains only the yarpDeviceName that we actually added
245247
// to the returned yarp::dev::PolyDriverList
246248
std::unordered_map<std::string, std::string> inserted_yarpDeviceName2deviceDatabaseKey;
247249

248250
for (auto&& devicesMapElem: m_devicesMap) {
249-
yDebug() << "DEBUG TO REMOVE: Add device deviceDatabaseKey " << devicesMapElem.first
250-
<< " modelScopedName " << modelScopedName;
251-
252251
std::string deviceDatabaseKey = devicesMapElem.first;
253252

254253
std::string yarpDeviceName;
@@ -267,7 +266,9 @@ bool Handler::getDevicesAsPolyDriverList(const std::string& modelScopedName, yar
267266
// If no name collision is found, insert and continue
268267
inserted_yarpDeviceName2deviceDatabaseKey.insert({yarpDeviceName, deviceDatabaseKey});
269268
list.push(devicesMapElem.second.object(), yarpDeviceName.c_str());
270-
yDebug() << " add yarpDeviceName " << yarpDeviceName;
269+
deviceScopedNames.push_back(deviceDatabaseKey);
270+
// Increase usage counter
271+
setDevice(deviceDatabaseKey, devicesMapElem.second.object());
271272
} else {
272273
// If a name collision is found, print a clear error and return
273274
yError() << "GazeboYARPPlugins robotinterface getDevicesAsPolyDriverList error: ";
@@ -277,6 +278,8 @@ bool Handler::getDevicesAsPolyDriverList(const std::string& modelScopedName, yar
277278
yError() << "Second instance: " << deviceDatabaseKey;
278279
yError() << "Please eliminate or rename one of the two instances. ";
279280
list = yarp::dev::PolyDriverList();
281+
releaseDevicesInList(deviceScopedNames);
282+
deviceScopedNames.resize(0);
280283
return false;
281284
}
282285

@@ -288,4 +291,13 @@ bool Handler::getDevicesAsPolyDriverList(const std::string& modelScopedName, yar
288291
}
289292

290293

294+
void Handler::releaseDevicesInList(const std::vector<std::string>& deviceScopedNames)
295+
{
296+
for (auto&& deviceScopedName: deviceScopedNames) {
297+
removeDevice(deviceScopedName);
298+
}
299+
return;
300+
}
301+
302+
291303
}

plugins/robotinterface/include/gazebo/GazeboYarpRobotInterface.hh

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public:
3131
private:
3232
yarp::robotinterface::experimental::XMLReader m_xmlRobotInterfaceReader;
3333
yarp::robotinterface::experimental::XMLReaderResult m_xmlRobotInterfaceResult;
34+
std::vector<std::string> m_deviceScopedNames;
3435
};
3536

3637

plugins/robotinterface/src/GazeboYarpRobotInterface.cc

+3-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ namespace gazebo
1818

1919
GazeboYarpRobotInterface::GazeboYarpRobotInterface()
2020
{
21-
std::cerr << "GazeboYarpRobotInterface constructor" << std::endl;
2221
}
2322

2423
GazeboYarpRobotInterface::~GazeboYarpRobotInterface()
@@ -33,6 +32,8 @@ GazeboYarpRobotInterface::~GazeboYarpRobotInterface()
3332
yError() << "GazeboYarpRobotInterface: impossible to run phase ActionPhaseShutdown in robotinterface";
3433
}
3534

35+
GazeboYarpPlugins::Handler::getHandler()->releaseDevicesInList(m_deviceScopedNames);
36+
3637
yarp::os::Network::fini();
3738
}
3839

@@ -85,7 +86,7 @@ void GazeboYarpRobotInterface::Load(physics::ModelPtr _parentModel, sdf::Element
8586

8687
// Extract externalDriverList of devices from the one that have been already opened in the Gazebo model by other gazebo_yarp plugins
8788
yarp::dev::PolyDriverList externalDriverList;
88-
GazeboYarpPlugins::Handler::getHandler()->getDevicesAsPolyDriverList(_parentModel->GetScopedName(), externalDriverList);
89+
GazeboYarpPlugins::Handler::getHandler()->getDevicesAsPolyDriverList(_parentModel->GetScopedName(), externalDriverList, m_deviceScopedNames);
8990

9091
// Set external devices from the one that have been already opened in the Gazebo model by other gazebo_yarp plugins
9192
bool ok = m_xmlRobotInterfaceResult.robot.setExternalDevices(externalDriverList);

0 commit comments

Comments
 (0)