device.cc
Go to the documentation of this file.
1 /*
2  * This file is part of the rc_genicam_api package.
3  *
4  * Copyright (c) 2017 Roboception GmbH
5  * All rights reserved
6  *
7  * Author: Heiko Hirschmueller
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include "device.h"
37 #include "stream.h"
38 
39 #include "gentl_wrapper.h"
40 #include "exception.h"
41 #include "cport.h"
42 
43 #include <iostream>
44 
45 namespace rcg
46 {
47 
48 Device::Device(const std::shared_ptr<Interface> &_parent,
49  const std::shared_ptr<const GenTLWrapper> &_gentl, const char *_id)
50 {
51  parent=_parent;
52  gentl=_gentl;
53  id=_id;
54 
55  n_open=0;
56  dev=0;
57  rp=0;
58 }
59 
61 {
62  if (n_open > 0)
63  {
64  try
65  {
66  gentl->DevClose(dev);
67  }
68  catch (...) // do not throw exceptions in destructor
69  { }
70 
71  parent->close();
72  }
73 }
74 
75 std::shared_ptr<Interface> Device::getParent() const
76 {
77  return parent;
78 }
79 
80 const std::string &Device::getID() const
81 {
82  return id;
83 }
84 
85 void Device::open(ACCESS access)
86 {
87  std::lock_guard<std::mutex> lock(mtx);
88 
89  if (n_open == 0)
90  {
91  parent->open();
92 
93  // convert access mode to GenTL flags
94 
97 
98  int i=0;
99  switch (access)
100  {
101  case READONLY:
102  i=0;
103  break;
104 
105  case CONTROL:
106  i=1;
107  break;
108 
109  default:
110  case EXCLUSIVE:
111  i=2;
112  break;
113  }
114 
115  // open device (if readonly fails, try control; if control fails try
116  // exclusive)
117 
119  while (err == GenTL::GC_ERR_NOT_IMPLEMENTED && i < 3)
120  {
121  err=gentl->IFOpenDevice(parent->getHandle(), id.c_str(), mode[i], &dev);
122  i++;
123  }
124 
125  // check if open was successful
126 
127  if (err != GenTL::GC_ERR_SUCCESS)
128  {
129  parent->close();
130  throw GenTLException("Device::open() failed", gentl);
131  }
132  }
133 
134  n_open++;
135 }
136 
138 {
139  std::lock_guard<std::mutex> lock(mtx);
140 
141  if (n_open > 0)
142  {
143  n_open--;
144  }
145 
146  if (n_open == 0)
147  {
148  gentl->DevClose(dev);
149  dev=0;
150  rp=0;
151 
152  nodemap=0;
153  rnodemap=0;
154 
155  cport=0;
156  rport=0;
157 
158  parent->close();
159  }
160 }
161 
162 namespace
163 {
164 
165 int find(const std::vector<std::shared_ptr<Stream> > &list, const std::string &id)
166 {
167  for (size_t i=0; i<list.size(); i++)
168  {
169  if (list[i]->getID() == id)
170  {
171  return static_cast<int>(i);
172  }
173  }
174 
175  return -1;
176 }
177 
178 }
179 
180 std::vector<std::shared_ptr<Stream> > Device::getStreams()
181 {
182  std::lock_guard<std::mutex> lock(mtx);
183 
184  std::vector<std::shared_ptr<Stream> > ret;
185 
186  if (dev != 0)
187  {
188  // get list of previously requested devices that are still in use
189 
190  std::vector<std::shared_ptr<Stream> > current;
191 
192  for (size_t i=0; i<slist.size(); i++)
193  {
194  std::shared_ptr<Stream> p=slist[i].lock();
195  if (p)
196  {
197  current.push_back(p);
198  }
199  }
200 
201  // create list of interfaces, using either existing interfaces or
202  // instantiating new ones
203 
204  uint32_t n=0;
205  if (gentl->DevGetNumDataStreams(dev, &n) != GenTL::GC_ERR_SUCCESS)
206  {
207  throw GenTLException("Device::getStreams()", gentl);
208  }
209 
210  for (uint32_t i=0; i<n; i++)
211  {
212  char tmp[256]="";
213  size_t size=sizeof(tmp);
214 
215  if (gentl->DevGetDataStreamID(dev, i, tmp, &size) != GenTL::GC_ERR_SUCCESS)
216  {
217  throw GenTLException("Device::getStreams()", gentl);
218  }
219 
220  int k=find(current, tmp);
221 
222  if (k >= 0)
223  {
224  ret.push_back(current[static_cast<size_t>(k)]);
225  }
226  else
227  {
228  ret.push_back(std::shared_ptr<Stream>(new Stream(shared_from_this(), gentl, tmp)));
229  }
230  }
231 
232  // update internal list of devices for reusage on next call
233 
234  slist.clear();
235  for (size_t i=0; i<ret.size(); i++)
236  {
237  slist.push_back(ret[i]);
238  }
239  }
240 
241  return ret;
242 
243 }
244 
245 namespace
246 {
247 
248 std::string cDevGetInfo(const Device *obj, const std::shared_ptr<const GenTLWrapper> &gentl,
250 {
251  std::string ret;
252 
254  char tmp[1024]="";
255  size_t tmp_size=sizeof(tmp);
257 
258  if (obj->getHandle() != 0)
259  {
260  err=gentl->DevGetInfo(obj->getHandle(), info, &type, tmp, &tmp_size);
261  }
262  else if (obj->getParent()->getHandle() != 0)
263  {
264  err=gentl->IFGetDeviceInfo(obj->getParent()->getHandle(), obj->getID().c_str(), info, &type,
265  tmp, &tmp_size);
266  }
267 
269  {
270  for (size_t i=0; i<tmp_size && tmp[i] != '\0'; i++)
271  {
272  ret.push_back(tmp[i]);
273  }
274  }
275 
276  return ret;
277 }
278 
279 }
280 
281 std::string Device::getVendor()
282 {
283  std::lock_guard<std::mutex> lock(mtx);
284  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_VENDOR);
285 }
286 
287 std::string Device::getModel()
288 {
289  std::lock_guard<std::mutex> lock(mtx);
290  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_MODEL);
291 }
292 
293 std::string Device::getTLType()
294 {
295  std::lock_guard<std::mutex> lock(mtx);
296  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_TLTYPE);
297 }
298 
300 {
301  std::lock_guard<std::mutex> lock(mtx);
302  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_DISPLAYNAME);
303 }
304 
306 {
307  std::lock_guard<std::mutex> lock(mtx);
308  std::string ret;
309 
311  int32_t status=-1;
312  size_t size=sizeof(status);
314 
315  if (dev != 0)
316  {
317  err=gentl->DevGetInfo(dev, GenTL::DEVICE_INFO_ACCESS_STATUS, &type, &status, &size);
318  }
319  else if (parent->getHandle() != 0)
320  {
321  err=gentl->IFGetDeviceInfo(getParent()->getHandle(), id.c_str(),
322  GenTL::DEVICE_INFO_ACCESS_STATUS, &type, &status, &size);
323  }
324 
325  if (err == GenTL::GC_ERR_SUCCESS)
326  {
327  if (type == GenTL::INFO_DATATYPE_INT32)
328  {
329  switch (status)
330  {
332  ret="ReadWrite";
333  break;
334 
336  ret="ReadOnly";
337  break;
338 
340  ret="NoAccess";
341  break;
342 
344  ret="Busy";
345  break;
346 
348  ret="OpenReadWrite";
349  break;
350 
352  ret="OpenReadWrite";
353  break;
354 
355  default:
356  ret="Unknown";
357  break;
358  }
359  }
360  }
361 
362  return ret;
363 }
364 
366 {
367  std::lock_guard<std::mutex> lock(mtx);
368  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_USER_DEFINED_NAME);
369 }
370 
372 {
373  std::lock_guard<std::mutex> lock(mtx);
374  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_SERIAL_NUMBER);
375 }
376 
377 std::string Device::getVersion()
378 {
379  std::lock_guard<std::mutex> lock(mtx);
380  return cDevGetInfo(this, gentl, GenTL::DEVICE_INFO_VERSION);
381 }
382 
384 {
385  std::lock_guard<std::mutex> lock(mtx);
387  uint64_t freq=0;
388  size_t size=sizeof(freq);
389 
390  if (dev != 0)
391  {
392  gentl->DevGetInfo(dev, GenTL::DEVICE_INFO_TIMESTAMP_FREQUENCY, &type, &freq, &size);
393  }
394  else if (parent->getHandle() != 0)
395  {
396  gentl->IFGetDeviceInfo(getParent()->getHandle(), id.c_str(),
397  GenTL::DEVICE_INFO_TIMESTAMP_FREQUENCY, &type, &freq, &size);
398  }
399 
400  return freq;
401 }
402 
403 std::shared_ptr<GenApi::CNodeMapRef> Device::getNodeMap()
404 {
405  std::lock_guard<std::mutex> lock(mtx);
406 
407  if (dev != 0 && !nodemap)
408  {
409  cport=std::shared_ptr<CPort>(new CPort(gentl, &dev));
411  }
412 
413  return nodemap;
414 }
415 
416 std::shared_ptr<GenApi::CNodeMapRef> Device::getRemoteNodeMap(const char *xml)
417 {
418  std::lock_guard<std::mutex> lock(mtx);
419 
420  if (dev != 0 && !rnodemap)
421  {
422  if (gentl->DevGetPort(dev, &rp) == GenTL::GC_ERR_SUCCESS)
423  {
424  rport=std::shared_ptr<CPort>(new CPort(gentl, &rp));
425  rnodemap=allocNodeMap(gentl, rp, rport.get(), xml);
426  }
427  }
428 
429  return rnodemap;
430 }
431 
432 void *Device::getHandle() const
433 {
434  return dev;
435 }
436 
437 std::vector<std::shared_ptr<Device> > getDevices()
438 {
439  std::vector<std::shared_ptr<Device> > ret;
440 
441  std::vector<std::shared_ptr<System> > system=System::getSystems();
442 
443  for (size_t i=0; i<system.size(); i++)
444  {
445  system[i]->open();
446 
447  std::vector<std::shared_ptr<Interface> > interf=system[i]->getInterfaces();
448 
449  for (size_t k=0; k<interf.size(); k++)
450  {
451  interf[k]->open();
452 
453  std::vector<std::shared_ptr<Device> > device=interf[k]->getDevices();
454 
455  for (size_t j=0; j<device.size(); j++)
456  {
457  ret.push_back(device[j]);
458  }
459 
460  interf[k]->close();
461  }
462 
463  system[i]->close();
464  }
465 
466  return ret;
467 }
468 
469 std::shared_ptr<Device> getDevice(const char *id)
470 {
471  int found=0;
472  std::shared_ptr<Device> ret;
473 
474  if (id != 0 && *id != '\0')
475  {
476  // split into interface and device id
477 
478  std::string interfid;
479  std::string devid=id;
480 
481  size_t p=devid.find(':');
482  if (p != std::string::npos)
483  {
484  interfid=devid.substr(0, p);
485  devid=devid.substr(p+1);
486  }
487 
488  // go through all systems
489 
490  std::vector<std::shared_ptr<System> > system=System::getSystems();
491 
492  for (size_t i=0; i<system.size(); i++)
493  {
494  system[i]->open();
495 
496  // get all interfaces
497 
498  std::vector<std::shared_ptr<Interface> > interf=system[i]->getInterfaces();
499 
500  if (interfid.size() > 0)
501  {
502  // if an interface is defined, then only search this interface
503 
504  for (size_t k=0; k<interf.size(); k++)
505  {
506  if (interf[k]->getID() == interfid)
507  {
508  interf[k]->open();
509 
510  std::shared_ptr<Device> dev=interf[k]->getDevice(devid.c_str());
511 
512  if (dev)
513  {
514  ret=dev;
515  found++;
516  }
517 
518  interf[k]->close();
519  }
520  }
521  }
522  else
523  {
524  // if interface is not defined, then check all interfaces
525 
526  std::shared_ptr<Device> dev;
527  for (size_t k=0; k<interf.size() && !dev; k++)
528  {
529  interf[k]->open();
530 
531  dev=interf[k]->getDevice(devid.c_str());
532 
533  if (dev)
534  {
535  ret=dev;
536  found++;
537  }
538 
539  interf[k]->close();
540  }
541  }
542 
543  system[i]->close();
544  }
545  }
546 
547  if (found > 1)
548  {
549  std::cerr << "ERROR: Finding device '" << id << "' through different producers."
550  << std::endl;
551  ret.reset();
552  }
553 
554  return ret;
555 }
556 
557 }
std::vector< std::shared_ptr< Stream > > getStreams()
Returns the currently available streams of this device.
Definition: device.cc:180
std::shared_ptr< Device > getDevice(const char *id)
Searches across all transport layers and interfaces for a device.
Definition: device.cc:469
std::string getDisplayName()
Returns the display name of the device.
Definition: device.cc:299
This is the port definition that connects GenAPI to GenTL.
Definition: cport.h:52
void open(ACCESS access)
Opens the device for working with it.
Definition: device.cc:85
static std::vector< std::shared_ptr< System > > getSystems()
Returns a list of systems (i.e.
Definition: system.cc:116
const std::string & getID() const
Get the internal ID of this device.
Definition: device.cc:80
std::shared_ptr< CPort > rport
Definition: device.h:266
void * getHandle() const
Get internal interface handle.
Definition: device.cc:432
int32_t GC_ERROR
Definition: GenTL_v1_5.h:181
void * rp
Definition: device.h:264
std::string getVendor()
Returns the vendor of the device.
Definition: device.cc:281
std::string getUserDefinedName()
Returns the user defined name of the device.
Definition: device.cc:365
std::shared_ptr< GenApi::CNodeMapRef > rnodemap
Definition: device.h:267
std::shared_ptr< const GenTLWrapper > gentl
Definition: device.h:257
std::mutex mtx
Definition: device.h:260
std::string getSerialNumber()
Returns the serial number of the device.
Definition: device.cc:371
std::shared_ptr< GenApi::CNodeMapRef > getRemoteNodeMap(const char *xml=0)
Returns the node map of the remote device.
Definition: device.cc:416
int32_t DEVICE_INFO_CMD
Definition: GenTL_v1_5.h:341
Device(const std::shared_ptr< Interface > &parent, const std::shared_ptr< const GenTLWrapper > &gentl, const char *id)
Constructs a device class.
Definition: device.cc:48
std::shared_ptr< Interface > getParent() const
Returns the pointer to the parent interface object.
Definition: device.cc:75
std::shared_ptr< GenApi::CNodeMapRef > allocNodeMap(std::shared_ptr< const GenTLWrapper > gentl, void *port, CPort *cport, const char *xml)
Convenience function that returns a GenICam node map from the given port.
Definition: cport.cc:133
std::shared_ptr< CPort > cport
Definition: device.h:266
std::shared_ptr< GenApi::CNodeMapRef > getNodeMap()
Returns the node map of this object.
Definition: device.cc:403
int n_open
Definition: device.h:262
void * dev
Definition: device.h:263
std::string getTLType()
Returns the transport layer type of the device.
Definition: device.cc:293
Definition: buffer.cc:47
std::string getModel()
Returns the model of the device.
Definition: device.cc:287
int32_t DEVICE_ACCESS_FLAGS
Definition: GenTL_v1_5.h:308
std::shared_ptr< GenApi::CNodeMapRef > nodemap
Definition: device.h:267
std::vector< std::shared_ptr< Device > > getDevices()
Returns a list of all devices that are available across all transport layers and interfaces.
Definition: device.cc:437
std::string id
Definition: device.h:258
uint64_t getTimestampFrequency()
Returns the timestamp frequency of the device.
Definition: device.cc:383
std::string getVersion()
Returns the version of the device.
Definition: device.cc:377
int32_t INFO_DATATYPE
Definition: GenTL_v1_5.h:258
std::vector< std::weak_ptr< Stream > > slist
Definition: device.h:269
std::shared_ptr< Interface > parent
Definition: device.h:256
The device class encapsulates a Genicam device.
Definition: device.h:54
The stream class encapsulates a Genicam stream.
Definition: stream.h:55
std::string getAccessStatus()
Returns the access status of the device.
Definition: device.cc:305
void close()
Closes the device.
Definition: device.cc:137


rc_genicam_api
Author(s): Heiko Hirschmueller
autogenerated on Wed Mar 17 2021 02:48:40