12
12
#include < gazebo/physics/Entity.hh>
13
13
#include < gazebo/sensors/sensors.hh>
14
14
15
+ #include < unordered_map>
16
+
15
17
using namespace gazebo ;
16
18
17
19
namespace GazeboYarpPlugins {
@@ -170,10 +172,10 @@ void Handler::removeSensor(const std::string& sensorName)
170
172
}
171
173
}
172
174
173
- bool Handler::setDevice (std::string deviceName , yarp::dev::PolyDriver* device2add)
175
+ bool Handler::setDevice (std::string deviceDatabaseKey , yarp::dev::PolyDriver* device2add)
174
176
{
175
177
bool ret = false ;
176
- DevicesMap::iterator device = m_devicesMap.find (deviceName );
178
+ DevicesMap::iterator device = m_devicesMap.find (deviceDatabaseKey );
177
179
if (device != m_devicesMap.end ()) {
178
180
// device already exists. Increment reference counting
179
181
if (device->second .object () == device2add)
@@ -190,7 +192,7 @@ bool Handler::setDevice(std::string deviceName, yarp::dev::PolyDriver* device2ad
190
192
} else {
191
193
// device does not exists. Add to map
192
194
ReferenceCountingDevice countedDevice (device2add);
193
- if (!m_devicesMap.insert (std::pair<std::string, ReferenceCountingDevice>(deviceName , countedDevice)).second ) {
195
+ if (!m_devicesMap.insert (std::pair<std::string, ReferenceCountingDevice>(deviceDatabaseKey , countedDevice)).second ) {
194
196
yError () << " Error in GazeboYarpPlugins::Handler while inserting a new device pointer!" ;
195
197
ret = false ;
196
198
} else {
@@ -200,11 +202,11 @@ bool Handler::setDevice(std::string deviceName, yarp::dev::PolyDriver* device2ad
200
202
return ret;
201
203
}
202
204
203
- yarp::dev::PolyDriver* Handler::getDevice (const std::string& deviceName ) const
205
+ yarp::dev::PolyDriver* Handler::getDevice (const std::string& deviceDatabaseKey ) const
204
206
{
205
207
yarp::dev::PolyDriver* tmp = NULL ;
206
208
207
- DevicesMap::const_iterator device = m_devicesMap.find (deviceName );
209
+ DevicesMap::const_iterator device = m_devicesMap.find (deviceDatabaseKey );
208
210
if (device != m_devicesMap.end ()) {
209
211
tmp = device->second .object ();
210
212
} else {
@@ -213,29 +215,76 @@ yarp::dev::PolyDriver* Handler::getDevice(const std::string& deviceName) const
213
215
return tmp;
214
216
}
215
217
216
- void Handler::removeDevice (const std::string& deviceName )
218
+ void Handler::removeDevice (const std::string& deviceDatabaseKey )
217
219
{
218
- DevicesMap::iterator device = m_devicesMap.find (deviceName );
220
+ DevicesMap::iterator device = m_devicesMap.find (deviceDatabaseKey );
219
221
if (device != m_devicesMap.end ()) {
220
222
device->second .decrementCount ();
221
223
if (!device->second .count ()) {
222
224
device->second .object ()->close ();
223
225
m_devicesMap.erase (device);
224
226
}
225
227
} else {
226
- yError () << " Could not remove device " << deviceName << " . Device was not found" ;
228
+ yError () << " Could not remove device " << deviceDatabaseKey << " . Device was not found" ;
227
229
}
228
230
return ;
229
231
}
230
232
231
- void Handler::getDevicesAsPolyDriverList (yarp::dev::PolyDriverList& list)
233
+ inline bool startsWith (const std::string&completeString,
234
+ const std::string&candidatePrefix)
235
+ {
236
+ // https://stackoverflow.com/a/40441240
237
+ return (completeString.rfind (candidatePrefix, 0 ) == 0 );
238
+ }
239
+
240
+ bool Handler::getDevicesAsPolyDriverList (const std::string& modelScopedName, yarp::dev::PolyDriverList& list)
232
241
{
233
- for (auto && devicesMapElem: m_devicesMap) {
234
- yDebug () << " DEBUG TO REMOVE: Add device to " << devicesMapElem.first ;
235
- list.push (devicesMapElem.second .object (), devicesMapElem.first .c_str ());
242
+ list = yarp::dev::PolyDriverList ();
243
+
244
+ // This map contains only the yarpDeviceName that we actually added
245
+ // to the returned yarp::dev::PolyDriverList
246
+ std::unordered_map<std::string, std::string> inserted_yarpDeviceName2deviceDatabaseKey;
247
+
248
+ for (auto && devicesMapElem: m_devicesMap) {
249
+ yDebug () << " DEBUG TO REMOVE: Add device deviceDatabaseKey " << devicesMapElem.first
250
+ << " modelScopedName " << modelScopedName;
251
+
252
+ std::string deviceDatabaseKey = devicesMapElem.first ;
253
+
254
+ std::string yarpDeviceName;
255
+
256
+ // If the deviceDatabaseKey starts with the modelScopedName, then it is eligible for insertion
257
+ // in the returned list
258
+ if (startsWith (deviceDatabaseKey, modelScopedName)) {
259
+ // Extract yarpDeviceName from deviceDatabaseKey
260
+ yarpDeviceName = deviceDatabaseKey.substr (deviceDatabaseKey.find_last_of (" :" )+1 );
261
+
262
+ // Check if a device with the same yarpDeviceName was already inserted
263
+ auto got = inserted_yarpDeviceName2deviceDatabaseKey.find (yarpDeviceName);
264
+
265
+ // If not found, insert and continue
266
+ if (got == inserted_yarpDeviceName2deviceDatabaseKey.end ()) {
267
+ // If no name collision is found, insert and continue
268
+ inserted_yarpDeviceName2deviceDatabaseKey.insert ({yarpDeviceName, deviceDatabaseKey});
269
+ list.push (devicesMapElem.second .object (), yarpDeviceName.c_str ());
270
+ yDebug () << " add yarpDeviceName " << yarpDeviceName;
271
+ } else {
272
+ // If a name collision is found, print a clear error and return
273
+ yError () << " GazeboYARPPlugins robotinterface getDevicesAsPolyDriverList error: " ;
274
+ yError () << " two YARP devices with yarpDeviceName " << yarpDeviceName
275
+ << " found in model " << modelScopedName;
276
+ yError () << " First instance: " << got->second ;
277
+ yError () << " Second instance: " << deviceDatabaseKey;
278
+ yError () << " Please eliminate or rename one of the two instances. " ;
279
+ list = yarp::dev::PolyDriverList ();
280
+ return false ;
281
+ }
282
+
283
+ }
284
+
236
285
}
237
286
238
- return ;
287
+ return true ;
239
288
}
240
289
241
290
0 commit comments