YARP
Yet Another Robot Platform
ServerGrabber.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 "ServerGrabber.h"
11 
12 #include <yarp/os/Log.h>
13 #include <yarp/dev/PolyDriver.h>
14 #include <yarp/os/LogStream.h>
15 #include <yarp/os/ResourceFinder.h>
16 #include <yarp/sig/Vector.h>
17 #include <yarp/sig/ImageUtils.h>
18 #include <yarp/os/PortablePair.h>
20 #include <yarp/dev/GenericVocabs.h>
21 
22 #include <cstring>
23 
24 using namespace yarp::os;
25 using namespace yarp::dev;
26 using namespace yarp::sig;
27 
28 namespace {
29 YARP_LOG_COMPONENT(SERVERGRABBER, "yarp.device.grabberDual")
30 }
31 
32 
34 {
35  fgCtrl_DC1394 = interface;
36  return true;
37 }
38 
39 bool DC1394Parser::respond(const Bottle& cmd, Bottle& response)
40 {
41  int code = cmd.get(1).asVocab();
42  if (fgCtrl_DC1394)
43  {
44  switch(code)
45  {
46  case VOCAB_DRGETMSK: // VOCAB_DRGETMSK 12
47  response.addInt32(int(fgCtrl_DC1394->getVideoModeMaskDC1394()));
48  return true;
49  case VOCAB_DRGETVMD: // VOCAB_DRGETVMD 13
50  response.addInt32(int(fgCtrl_DC1394->getVideoModeDC1394()));
51  return true;
52  case VOCAB_DRSETVMD: // VOCAB_DRSETVMD 14
53  response.addInt32(int(fgCtrl_DC1394->setVideoModeDC1394(cmd.get(1).asInt32())));
54  return true;
55  case VOCAB_DRGETFPM: // VOCAB_DRGETFPM 15
56  response.addInt32(int(fgCtrl_DC1394->getFPSMaskDC1394()));
57  return true;
58  case VOCAB_DRGETFPS: // VOCAB_DRGETFPS 16
59  response.addInt32(int(fgCtrl_DC1394->getFPSDC1394()));
60  return true;
61  case VOCAB_DRSETFPS: // VOCAB_DRSETFPS 17
62  response.addInt32(int(fgCtrl_DC1394->setFPSDC1394(cmd.get(1).asInt32())));
63  return true;
64 
65  case VOCAB_DRGETISO: // VOCAB_DRGETISO 18
66  response.addInt32(int(fgCtrl_DC1394->getISOSpeedDC1394()));
67  return true;
68  case VOCAB_DRSETISO: // VOCAB_DRSETISO 19
69  response.addInt32(int(fgCtrl_DC1394->setISOSpeedDC1394(cmd.get(1).asInt32())));
70  return true;
71 
72  case VOCAB_DRGETCCM: // VOCAB_DRGETCCM 20
73  response.addInt32(int(fgCtrl_DC1394->getColorCodingMaskDC1394(cmd.get(1).asInt32())));
74  return true;
75  case VOCAB_DRGETCOD: // VOCAB_DRGETCOD 21
76  response.addInt32(int(fgCtrl_DC1394->getColorCodingDC1394()));
77  return true;
78  case VOCAB_DRSETCOD: // VOCAB_DRSETCOD 22
79  response.addInt32(int(fgCtrl_DC1394->setColorCodingDC1394(cmd.get(1).asInt32())));
80  return true;
81 
82  case VOCAB_DRGETF7M: // VOCAB_DRGETF7M 25
83  {
84  unsigned int xstep,ystep,xdim,ydim,xoffstep,yoffstep;
85  fgCtrl_DC1394->getFormat7MaxWindowDC1394(xdim,ydim,xstep,ystep,xoffstep,yoffstep);
86  response.addInt32(xdim);
87  response.addInt32(ydim);
88  response.addInt32(xstep);
89  response.addInt32(ystep);
90  response.addInt32(xoffstep);
91  response.addInt32(yoffstep);
92  }
93  return true;
94  case VOCAB_DRGETWF7: // VOCAB_DRGETWF7 26
95  {
96  unsigned int xdim,ydim;
97  int x0,y0;
98  fgCtrl_DC1394->getFormat7WindowDC1394(xdim,ydim,x0,y0);
99  response.addInt32(xdim);
100  response.addInt32(ydim);
101  response.addInt32(x0);
102  response.addInt32(y0);
103  }
104  return true;
105  case VOCAB_DRSETWF7: // VOCAB_DRSETWF7 27
106  response.addInt32(int(fgCtrl_DC1394->setFormat7WindowDC1394(cmd.get(1).asInt32(),cmd.get(2).asInt32(),cmd.get(3).asInt32(),cmd.get(4).asInt32())));
107  return true;
108  case VOCAB_DRSETOPM: // VOCAB_DRSETOPM 28
109  response.addInt32(int(fgCtrl_DC1394->setOperationModeDC1394(cmd.get(1).asInt32()!=0)));
110  return true;
111  case VOCAB_DRGETOPM: // VOCAB_DRGETOPM 29
112  response.addInt32(fgCtrl_DC1394->getOperationModeDC1394());
113  return true;
114 
115  case VOCAB_DRSETTXM: // VOCAB_DRSETTXM 30
116  response.addInt32(int(fgCtrl_DC1394->setTransmissionDC1394(cmd.get(1).asInt32()!=0)));
117  return true;
118  case VOCAB_DRGETTXM: // VOCAB_DRGETTXM 31
119  response.addInt32(fgCtrl_DC1394->getTransmissionDC1394());
120  return true;
121  case VOCAB_DRSETBCS: // VOCAB_DRSETBCS 34
122  response.addInt32(int(fgCtrl_DC1394->setBroadcastDC1394(cmd.get(1).asInt32()!=0)));
123  return true;
124  case VOCAB_DRSETDEF: // VOCAB_DRSETDEF 35
125  response.addInt32(int(fgCtrl_DC1394->setDefaultsDC1394()));
126  return true;
127  case VOCAB_DRSETRST: // VOCAB_DRSETRST 36
128  response.addInt32(int(fgCtrl_DC1394->setResetDC1394()));
129  return true;
130  case VOCAB_DRSETPWR: // VOCAB_DRSETPWR 37
131  response.addInt32(int(fgCtrl_DC1394->setPowerDC1394(cmd.get(1).asInt32()!=0)));
132  return true;
133  case VOCAB_DRSETCAP: // VOCAB_DRSETCAP 38
134  response.addInt32(int(fgCtrl_DC1394->setCaptureDC1394(cmd.get(1).asInt32()!=0)));
135  return true;
136  case VOCAB_DRSETBPP: // VOCAB_DRSETCAP 39
137  response.addInt32(int(fgCtrl_DC1394->setBytesPerPacketDC1394(cmd.get(1).asInt32())));
138  return true;
139  case VOCAB_DRGETBPP: // VOCAB_DRGETTXM 40
140  response.addInt32(fgCtrl_DC1394->getBytesPerPacketDC1394());
141  return true;
142  }
143  }
144  else
145  {
146  yCWarning(SERVERGRABBER) << "DC1394Parser: firewire interface not implemented in subdevice, some features could not be available";
147 // response.clear();
148 // response.addVocab(VOCAB_FAILED);
149  return DeviceResponder::respond(cmd,response);
150  }
151 
152  return true;
153 }
154 
155 // **********ServerGrabberResponder**********
156 
158  left(_left)
159 {
160 }
161 
163 {
164  if(_server)
165  {
166  server=_server;
167  return true;
168  }
169  yCError(SERVERGRABBER) << "ServerGrabberResponder: invalid server pointer";
170  return false;
171 }
172 
174  if(server)
175  {
176  if(server->respond(command,reply,left,false))
177  {
178  return true;
179  }
180  else
181  {
182  return DeviceResponder::respond(command, reply);
183  }
184  }
185  else
186  return false;
187 }
188 
189 // **********ServerGrabber**********
190 
193 {
194 }
195 
197 {
198  if(param.active)
199  close();
200 }
201 
203  if (!param.active) {
204  return false;
205  }
206  stopThread();
207 
208  param.active = false;
209  pImg.interrupt();
210  pImg.close();
211  rpcPort.interrupt();
212  rpcPort.close();
213 
214  if(responder){
215  delete responder;
216  responder=nullptr;
217  }
218 
219  if(param.split)
220  {
221  pImg2.interrupt();
222  pImg2.close();
223  }
224 
225 
226  if(param.twoCameras)
227  {
228  rpcPort2.interrupt();
229  rpcPort2.close();
230  }
231 
232  cleanUp();
233  if(poly)
234  {
235  poly->close();
236  delete poly;
237  poly=nullptr;
238  }
239 
240  if(responder2)
241  {
242  delete responder2;
243  responder=nullptr;
244  }
245 
246  if(isSubdeviceOwned && poly2)
247  {
248  poly2->close();
249  delete poly2;
250  poly2=nullptr;
251  }
252  isSubdeviceOwned=false;
253  if (p2!=nullptr) {
254  delete p2;
255  p2 =nullptr;
256  }
257  return true;
258 }
259 
261  if (param.active) {
262  yCError(SERVERGRABBER, "Did you just try to open the same ServerGrabber twice?");
263  return false;
264  }
265 
266  if(!fromConfig(config))
267  {
268  yCError(SERVERGRABBER) << "Device ServerGrabber failed to open, check previous log for error messages.";
269  return false;
270  }
271 
272  if(!initialize_YARP(config))
273  {
274  yCError(SERVERGRABBER) <<"Error initializing YARP ports";
275  return false;
276  }
277 
278  if(isSubdeviceOwned){
279  if(! openAndAttachSubDevice(config))
280  {
281  yCError(SERVERGRABBER, "Error while opening subdevice");
282  return false;
283  }
284  }
285  else
286  {
287  yCInfo(SERVERGRABBER) << "Running, waiting for attach...";
288  if(!openDeferredAttach(config))
289  return false;
290  }
291 
292 
293  param.active = true;
294 // //ASK/TODO update usage and see if we need to add DeviceResponder as dependency
295 // DeviceResponder::makeUsage();
296 // addUsage("[set] [bri] $fBrightness", "set brightness");
297 // addUsage("[set] [expo] $fExposure", "set exposure");
298 // addUsage("[set] [shar] $fSharpness", "set sharpness");
299 // addUsage("[set] [whit] $fBlue $fRed", "set white balance");
300 // addUsage("[set] [hue] $fHue", "set hue");
301 // addUsage("[set] [satu] $fSaturation", "set saturation");
302 // addUsage("[set] [gamm] $fGamma", "set gamma");
303 // addUsage("[set] [shut] $fShutter", "set shutter");
304 // addUsage("[set] [gain] $fGain", "set gain");
305 // addUsage("[set] [iris] $fIris", "set iris");
306 
307 // addUsage("[get] [bri]", "get brightness");
308 // addUsage("[get] [expo]", "get exposure");
309 // addUsage("[get] [shar]", "get sharpness");
310 // addUsage("[get] [whit]", "get white balance");
311 // addUsage("[get] [hue]", "get hue");
312 // addUsage("[get] [satu]", "get saturation");
313 // addUsage("[get] [gamm]", "get gamma");
314 // addUsage("[get] [shut]", "get shutter");
315 // addUsage("[get] [gain]", "get gain");
316 // addUsage("[get] [iris]", "get iris");
317 
318 // addUsage("[get] [w]", "get width of image");
319 // addUsage("[get] [h]", "get height of image");
320 
321 
322  return true;
323 }
324 
326 {
327  if(config.check("period","refresh period(in ms) of the broadcasted values through yarp ports")
328  && config.find("period").isInt32())
329  period = config.find("period").asInt32() / 1000.0;
330  else
331  yCWarning(SERVERGRABBER) << "Period parameter not found, using default of"<< DEFAULT_THREAD_PERIOD << "s";
332  if((config.check("subdevice")) && (config.check("left_config") || config.check("right_config")))
333  {
334  yCError(SERVERGRABBER) << "Found both 'subdevice' and 'left_config/right_config' parameters...";
335  return false;
336  }
337  if(!config.check("subdevice", "name of the subdevice to use as a data source")
338  && config.check("left_config","name of the ini file containing the configuration of one of two subdevices to use as a data source")
339  && config.check("right_config" , "name of the ini file containing the configuration of one of two subdevices to use as a data source"))
340  param.twoCameras=true;
341  if(config.check("twoCameras", "if true ServerGrabber will open and handle two devices, if false only one"))//extra conf parameter for the yarprobotinterface
342  param.twoCameras=config.find("twoCameras").asBool();
343  if(config.check("split", "set 'true' to split the streaming on two different ports"))
344  param.split=config.find("split").asBool();
345  if(config.check("capabilities","two capabilities supported, COLOR and RAW respectively for rgb and raw streaming"))
346  {
347  if(config.find("capabilities").asString()=="COLOR")
348  param.cap=COLOR;
349  else if(config.find("capabilities").asString()=="RAW")
350  param.cap=RAW;
351  }
352  else
353  yCWarning(SERVERGRABBER) << "'capabilities' parameter not found or misspelled, the option available are COLOR(default) and RAW, using default";
354  param.canDrop = !config.check("no_drop","if present, use strict policy for sending data");
355  param.addStamp = config.check("stamp","if present, add timestamps to data");
356 
357  param.singleThreaded =
358  config.check("single_threaded",
359  "if present, operate in single threaded mode")!=0;
360  //TODO audio part
361  std::string rootName;
362  rootName = config.check("name",Value("/grabber"),
363  "name of port to send data on").asString();
364  if(!param.twoCameras && param.split)
365  param.splitterMode = true;
366 
367  responder = new ServerGrabberResponder(true);
368  if(!responder->configure(this))
369  return false;
370  if(param.twoCameras)
371  {
372  responder2 = new ServerGrabberResponder(false);
373  if(!responder2->configure(this))
374  return false;
375 
376  rpcPort_Name = rootName + "/left/rpc";
377  rpcPort2_Name = rootName + "/right/rpc";
378  if(param.split)
379  {
380  pImg_Name = rootName + "/left";
381  pImg2_Name = rootName + "/right";
382  }
383  else
384  pImg_Name = rootName;
385 
386  // check if we need to create subdevice or if they are
387  // passed later on thorugh attachAll()
388  if(config.check("left_config") && config.check("right_config"))
389  {
390  isSubdeviceOwned=true;
391  }
392  else
393  {
394  isSubdeviceOwned=false;
395  }
396  }
397  else
398  {
399  if(param.split)
400  {
401  responder2 = new ServerGrabberResponder(false);
402  if(!responder2->configure(this))
403  return false;
404  pImg_Name = rootName + "/left";
405  pImg2_Name = rootName + "/right";
406  }
407  else
408  {
409  pImg_Name = rootName;
410  }
411  rpcPort_Name = rootName + "/rpc";
412  if(config.check("subdevice"))
413  {
414  isSubdeviceOwned=true;
415  }
416  else
417  {
418  isSubdeviceOwned=false;
419  }
420  }
421 
422 
423  return true;
424 }
425 
427 {
428  // Open ports
429  bool bRet;
430  bRet = true;
431  if(!rpcPort.open(rpcPort_Name))
432  {
433  yCError(SERVERGRABBER) << "Unable to open rpc Port" << rpcPort_Name.c_str();
434  bRet = false;
435  }
436  rpcPort.setReader(*responder);
437 
438  pImg.promiseType(Type::byName("yarp/image"));
439  pImg.setWriteOnly();
440  if(!pImg.open(pImg_Name))
441  {
442  yCError(SERVERGRABBER) << "Unable to open image streaming Port" << pImg_Name.c_str();
443  bRet = false;
444  }
445  pImg.setReader(*responder);
446 
447  if(param.twoCameras)
448  {
449  if(!rpcPort2.open(rpcPort2_Name))
450  {
451  yCError(SERVERGRABBER) << "Unable to open rpc Port" << rpcPort2_Name.c_str();
452  bRet = false;
453  }
454  rpcPort2.setReader(*responder2);
455  }
456  if(param.split)
457  {
458  pImg2.promiseType(Type::byName("yarp/image"));
459  pImg2.setWriteOnly();
460 
461  if(!pImg2.open(pImg2_Name))
462  {
463  yCError(SERVERGRABBER) << "Unable to open image streaming Port" << pImg2_Name.c_str();
464  bRet = false;
465  }
466  pImg2.setReader(*responder2);
467  }
468 
469  return bRet;
470 }
471 
473  yarp::os::Bottle& response, bool left, bool both=false) {
474  int code = cmd.get(0).asVocab();
475  Bottle response2;
476  switch (code)
477  {
479  {
480  switch (cmd.get(1).asVocab())
481  {
482  case VOCAB_GET:
483  {
484  switch (cmd.get(2).asVocab())
485  {
486  case VOCAB_CROP:
487  {
488  response.clear();
489  // If the device driver support it, use the device implementation, because it may be more efficient.
490  // If not, acquire the whole image and crop it here before sending it.
491 
492  Bottle *list = cmd.get(4).asList();
493  int nPoints = list->size() /2; // divided by 2 because each pixel is identified by 2 numbers (u,v)
494 
496  vertices.resize(nPoints);
497 
498  for(int i=0; i<nPoints; i++)
499  {
500  vertices[i].first = list->get(i*2).asInt32();
501  vertices[i].second = list->get(i*2 +1).asInt32();
502  }
503 
504  ImageOf< PixelRgb > cropped;
505 
506  // Choose the interface and eventual offset depending on case.
507 
508  /* HW/SW configurations here: (1a, 1b, 2a, 2b), for each one the user can request a crop on left or right image
509  * 1) single HW camera as a source
510  * 1a) split false: a single image to handle
511  * 1b) split true : 2 images, I have to handle left or right image. If user request a crop in the right side,
512  * of the image, then add an offset
513  *
514  * 2) two HW sources
515  * 2a) split true: choose appropriate image source based on left/right request
516  * 2b) split false: choose appropriate image source based on crop position. Crop request have to belong to a
517  * single frame, either left or right. Example: 2 cameras with 320x240 pixels each placed
518  * one after the other, generates a single stitched image of 640x240.
519  * Anyway a crop request like (200,100)(400,200) shall be rejected, even if it could be
520  * considered as a part of the image resulting from the stitch.
521  * Right now the decision is took based on the first point of vector 'vertices', since all
522  * points are expected to belong to the same frame (left/right)
523  *
524  */
525 
526  // Default values here are valid for cases 1a and `left` side of 2a
527  IFrameGrabberImage *imageInterface = fgImage;
528  int u_offset = 0;
529 
530  if(param.twoCameras == false) // a single HW source of images
531  {
532  imageInterface = fgImage;
533  if(left == false) // if left is false, implicitly split is true
534  u_offset = imageInterface->width()/2; // 1b
535 
536  }
537  else
538  {
539  if(param.split) // 2a, right image
540  {
541  if(left == false)
542  {
543  imageInterface = fgImage2;
544  u_offset = 0;
545  }
546  }
547  else
548  {
549  if(vertices[0].first >= fgImage->width()) // 2b, right image
550  {
551  imageInterface = fgImage2;
552  u_offset = -fgImage->width();
553  }
554  }
555 
556  }
557 
558 
559  if(imageInterface != nullptr)
560  {
561  if(imageInterface->getImageCrop((cropType_id_t) cmd.get(3).asVocab(), vertices, cropped) )
562  {
563  // use the device output
564  }
565  else
566  {
567  // In case the device has not yet implemented this feature, do it here (less efficient)
568  if(cmd.get(3).asVocab() == YARP_CROP_RECT)
569  {
570  if(nPoints != 2)
571  {
572  response.addString("GetImageCrop failed: RECT mode requires 2 vertices.");
573  yCError(SERVERGRABBER) << "GetImageCrop failed: RECT mode requires 2 vertices, got " << nPoints;
574  return false;
575  }
576  ImageOf< PixelRgb > full;
577  imageInterface->getImage(full);
578 
579  cropped.resize(vertices[1].first - vertices[0].first +1, vertices[1].second - vertices[0].second +1); // +1 to be inclusive
580  cropped.zero();
581  for(int u_in=vertices[0].first + u_offset, u_out=0; u_in<=vertices[1].first + u_offset; u_in++, u_out++)
582  {
583  for(int v_in=vertices[0].second, v_out=0; v_in <= vertices[1].second; v_in++, v_out++)
584  {
585  cropped.pixel(u_out, v_out).r = full.pixel(u_in, v_in).r;
586  cropped.pixel(u_out, v_out).g = full.pixel(u_in, v_in).g;
587  cropped.pixel(u_out, v_out).b = full.pixel(u_in, v_in).b;
588  }
589  }
590  }
591  else if(cmd.get(3).asVocab() == YARP_CROP_LIST)
592  {
593  response.addString("List type not yet implemented");
594  }
595  else
596  {
597  response.addString("Crop type unknown");
598  }
599  }
600  }
601 
602  response.addVocab(VOCAB_CROP);
603  response.addVocab(VOCAB_IS);
604  response.addInt32(cropped.width()); // Actual width of image in pixels, to check everything is ok
605  response.addInt32(cropped.height()); // Actual height of image in pixels, to check everything is ok
606 
607  response.add(Value(cropped.getRawImage(), cropped.getRawImageSize()));
608  return true;
609  } break;
610  } break;
611 
612  } break;
613 
614  case VOCAB_SET: // Nothing to do here yet
615  default:
616  {
617  yCError(SERVERGRABBER) << "FrameGrabberImage interface received an unknown command " << cmd.toString();
618  } break;
619 
620  }
621 
622  } break;
623 
624  // first check if requests are coming from new iFrameGrabberControl2 interface and process them
626  {
627  if(param.twoCameras)
628  {
629  bool ret;
630  if(both){
631  ret=ifgCtrl_Parser.respond(cmd, response);
632  ret&=ifgCtrl2_Parser.respond(cmd, response2);
633  if(!ret || (response!=response2))
634  {
635  response.clear();
636  response.addVocab(VOCAB_FAILED);
637  ret=false;
638  yCWarning(SERVERGRABBER) << "Response different among cameras or failed";
639  }
640  }
641  else
642  {
643  if(left)
644  {
645  ret=ifgCtrl_Parser.respond(cmd, response);
646  }
647  else
648  {
649  ret=ifgCtrl2_Parser.respond(cmd, response);
650  }
651  }
652  return ret;
653  }
654  else
655  return ifgCtrl_Parser.respond(cmd, response);
656  } break;
657 
659  {
660  if(param.twoCameras)
661  {
662  bool ret;
663  ret=rgbParser.respond(cmd,response);
664  ret&=rgbParser2.respond(cmd,response2);
665  if(ret)
666  {
667  switch (cmd.get(2).asVocab())
668  {
669  //Only the intrinsic parameters are allowed to be different among the two cameras
670  // so we give both responses appending one to the other.
672  {
673  Bottle& newResponse = response.addList();
674  newResponse.append(*response2.get(3).asList());
675  break;
676  }
677  //In general if the two response are different we send a FAIL vocab
678  default:
679  {
680  if(response!=response2)
681  {
682  response.clear();
683  response.addVocab(VOCAB_FAILED);
684  ret=false;
685  yCWarning(SERVERGRABBER) << "Response different among cameras or failed";
686  }
687  break;
688  }
689  }
690  }
691 
692  return ret;
693  }
694  else
695  return rgbParser.respond(cmd,response);
696  } break;
698  // DC1394 COMMANDS
701  {
702  if(param.twoCameras)
703  {
704  bool ret;
705  if(both)
706  {
707  ret=ifgCtrl_DC1394_Parser.respond(cmd, response);
708  ret&=ifgCtrl2_DC1394_Parser.respond(cmd, response2);
709  if(!ret || (response!=response2))
710  {
711  response.clear();
712  response.addString("command not recognized");
713  ret=false;
714  yCWarning(SERVERGRABBER) << "Responses different among cameras or failed";
715 
716  }
717  }
718  else
719  {
720  if(left)
721  {
722  ret=ifgCtrl_DC1394_Parser.respond(cmd, response);
723  }
724  else
725  {
726  ret=ifgCtrl2_DC1394_Parser.respond(cmd, response);
727  }
728  }
729  return ret;
730  }
731  else
732  return ifgCtrl_DC1394_Parser.respond(cmd, response);
733  } break;
734  }
735  yCError(SERVERGRABBER) << "Command not recognized" << cmd.toString();
736  return false;
737 }
738 
739 bool ServerGrabber::attachAll(const PolyDriverList &device2attach)
740 {
741  bool ret=false;
742  if(param.twoCameras)
743  {
744  bool leftDone=false;//for avoiding double left
745  bool rightDone=false;//for avoiding double right
746  if (device2attach.size() != 2)
747  {
748  yCError(SERVERGRABBER, "Expected two devices to be attached");
749  return false;
750  }
751  for(int i=0;i<device2attach.size();i++)
752  {
753  yarp::dev::PolyDriver * Idevice2attach = device2attach[i]->poly;
754  if (!Idevice2attach->isValid())
755  {
756  yCError(SERVERGRABBER) << "Device " << device2attach[i]->key << " to attach to is not valid ... cannot proceed";
757  return false;
758  }
759  if(device2attach[i]->key == "LEFT" && !leftDone)
760  {
761  leftDone |= Idevice2attach->view(rgbVis_p);
762  leftDone |= Idevice2attach->view(fgImage);
763  leftDone |= Idevice2attach->view(fgImageRaw);
764  leftDone |= Idevice2attach->view(fgCtrl);
765  leftDone |= Idevice2attach->view(fgCtrl_DC1394);
766  }
767  else if(device2attach[i]->key == "RIGHT" && !rightDone)
768  {
769  rightDone |= Idevice2attach->view(rgbVis_p2);
770  rightDone |= Idevice2attach->view(fgImage2);
771  rightDone |= Idevice2attach->view(fgImageRaw2);
772  rightDone |= Idevice2attach->view(fgCtrl2);
773  rightDone |= Idevice2attach->view(fgCtrl2_DC1394);
774  }
775  else
776  {
777  yCError(SERVERGRABBER) << "Failed to attach. The two targets must be LEFT RIGHT and devices must implement"
778  " either IFrameGrabberImage or IFrameGrabberImageRaw";
779  return false;
780 
781  }
782  }
783  switch(param.cap)
784  {
785  case COLOR :
786  {
787  if((fgImage==nullptr) || (fgImage2==nullptr))
788  {
789  yCError(SERVERGRABBER) << "Capability required not supported";
790  return false;
791  }
792  }
793  break;
794  case RAW :
795  {
796  if((fgImageRaw==nullptr) || (fgImageRaw2==nullptr))
797  {
798  yCError(SERVERGRABBER) << "Capability required not supported";
799  return false;
800  }
801  }
802  }
803  if((rgbVis_p == nullptr) || (rgbVis_p2 == nullptr))
804  {
805  yCWarning(SERVERGRABBER) << "Targets has not IVisualParamInterface, some features cannot be available";
806  }
807  //Configuring parsers
808  if(rgbVis_p != nullptr && rgbVis_p2 != nullptr)
809  {
810  if(!(rgbParser.configure(rgbVis_p)) || !(rgbParser2.configure(rgbVis_p2)))
811  {
812  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
813  return false;
814  }
815  }
816  if(fgCtrl != nullptr && fgCtrl2 != nullptr)
817  {
818  if(!(ifgCtrl_Parser.configure(fgCtrl)) || !(ifgCtrl2_Parser.configure(fgCtrl2)))
819  {
820  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
821  return false;
822  }
823  }
824  if(fgCtrl_DC1394 != nullptr && fgCtrl2_DC1394 != nullptr)
825  {
826  if(!(ifgCtrl_DC1394_Parser.configure(fgCtrl_DC1394)) || !(ifgCtrl2_DC1394_Parser.configure(fgCtrl2_DC1394)))
827  {
828  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
829  return false;
830  }
831  }
832  }
833  else{
834  if (device2attach.size() != 1)
835  {
836  yCError(SERVERGRABBER, "Expected one device to be attached");
837  return false;
838  }
839  yarp::dev::PolyDriver * Idevice2attach = device2attach[0]->poly;
840  Idevice2attach->view(rgbVis_p);
841  Idevice2attach->view(fgImage);
842  Idevice2attach->view(fgImageRaw);
843  Idevice2attach->view(fgCtrl);
844  Idevice2attach->view(fgCtrl_DC1394);
845  switch(param.cap){
846  case COLOR :
847  {
848  if(fgImage==nullptr)
849  {
850  yCError(SERVERGRABBER) << "Capability required not supported";
851  return false;
852  }
853  }
854  break;
855  case RAW :
856  {
857  if(fgImageRaw==nullptr)
858  {
859  yCError(SERVERGRABBER) << "Capability required not supported";
860  return false;
861  }
862  }
863  }
864 
865  if (!Idevice2attach->isValid())
866  {
867  yCError(SERVERGRABBER) << "Device " << device2attach[0]->key << " to attach to is not valid ... cannot proceed";
868  return false;
869  }
870 
871  if(rgbVis_p == nullptr)
872  {
873  yCWarning(SERVERGRABBER) << "Targets has not IVisualParamInterface, some features cannot be available";
874  }
875 
876  //Configuring parsers
877  if(rgbVis_p != nullptr)
878  {
879  if(!(rgbParser.configure(rgbVis_p)))
880  {
881  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
882  return false;
883  }
884  }
885  if(fgCtrl != nullptr)
886  {
887  if(!(ifgCtrl_Parser.configure(fgCtrl)))
888  {
889  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
890  return false;
891  }
892  }
893 
894  if(fgCtrl_DC1394 != nullptr)
895  {
896  if(!(ifgCtrl_DC1394_Parser.configure(fgCtrl_DC1394)))
897  {
898  yCError(SERVERGRABBER) << "Error configuring interfaces for parsers";
899  return false;
900  }
901  }
902  }
903 
904  PeriodicThread::setPeriod(period);
905  ret = PeriodicThread::start();
906 
907  return ret;
908 }
910 {
911  //check if we already instantiated a subdevice previously
912  if (isSubdeviceOwned)
913  return false;
914  stopThread();
915  return true;
916 
917 }
919 {
922 
923  rgbVis_p = nullptr;
924  rgbVis_p2 = nullptr;
925  fgImage = nullptr;
926  fgImage2 = nullptr;
927  fgImageRaw = nullptr;
928  fgImageRaw2 = nullptr;
929  fgCtrl = nullptr;
930  fgCtrl2 = nullptr;
931  fgCtrl_DC1394 = nullptr;
932  fgCtrl2_DC1394 = nullptr;
933 }
934 
936 {
937  flex_i.setPixelCode(_img.getPixelCode());
938  flex_i.setQuantum(_img.getQuantum());
939  flex_i.setExternal(_img.getRawImage(), _img.width(),_img.height());
940 
941 }
942 
944 {
945  if(param.twoCameras)
946  {
947  yCError(SERVERGRABBER) << "Server grabber configured for two cameras, but only one provided";
948  return false;
949  }
950  PolyDriverList plist;
951  if(poly)
952  {
953  PolyDriverDescriptor p(poly,"poly");
954  plist.push(p);
955  return attachAll(plist);
956  }
957  else
958  {
959  yCError(SERVERGRABBER) << "Invalid device to be attached";
960  return false;
961  }
962  return true;
963 }
965 {
966  return detachAll();
967 }
968 
969 bool ServerGrabber::openDeferredAttach(Searchable &prop){
970  // I dunno what to do here now...
971  isSubdeviceOwned = false;
972  return true;
973 }
974 
975 bool ServerGrabber::openAndAttachSubDevice(Searchable &prop){
976  PolyDriverList plist;
977  if(param.twoCameras){
978  Property p,p2;
979  poly = new PolyDriver;
980  poly2 = new PolyDriver;
981  std::string file, file2;
982  if(!prop.check("left_config") || !prop.check("right_config"))
983  {
984  yCError(SERVERGRABBER) << "Missing 'left_config' or 'right_config' filename... ";
985  return false;
986  }
987  ResourceFinder rf, rf2;
988  if(prop.check("context"))
989  {
990  rf.setDefaultContext(prop.find("context").asString().c_str());
991  rf2.setDefaultContext(prop.find("context").asString().c_str());
992  }
993  file=prop.find("left_config").toString();
994  file2=prop.find("right_config").toString();
995  p.fromConfigFile(rf.findFileByName(file));
996  p2.fromConfigFile(rf2.findFileByName(file2));
997  if(p.isNull() || p2.isNull())
998  {
999  yCError(SERVERGRABBER) << "Unable to find files specified in 'left_config' and/or 'right_config'";
1000  return false;
1001  }
1002 // p.fromString(prop.findGroup("LEFT").toString().c_str());
1003 // p2.fromString(prop.findGroup("RIGHT").toString().c_str());
1004  if(param.cap==COLOR){
1005  p.put("pixelType", VOCAB_PIXEL_RGB);
1006  p2.put("pixelType", VOCAB_PIXEL_RGB);
1007  }
1008  else
1009  {
1010  p.put("pixelType", VOCAB_PIXEL_MONO);
1011  p2.put("pixelType", VOCAB_PIXEL_MONO);
1012  }
1013  if(p.find("height").asInt32() != p2.find("height").asInt32() ||
1014  p.find("width").asInt32() != p2.find("width").asInt32())
1015  {
1016  yCError(SERVERGRABBER) << "Error in the configuration file, the two images have to have the same dimensions";
1017  return false;
1018  }
1019  //COSA FA? Serve? Guardarci
1020  //p.setMonitor(prop.getMonitor(), "subdevice"); // pass on any monitoring
1021  // if errors occurred during open, quit here.
1022  poly->open(p);
1023  poly2->open(p2);
1024 
1025  if (!(poly->isValid()) || !(poly2->isValid()))
1026  {
1027  yCError(SERVERGRABBER, "Opening devices... FAILED");
1028  return false;
1029  }
1030  PolyDriverDescriptor pd(poly,"LEFT");
1031  PolyDriverDescriptor pd2(poly2,"RIGHT");
1032  plist.push(pd);
1033  plist.push(pd2);
1034  //The thread is started by attachAll()
1035  if(!attachAll(plist))
1036  return false;
1037  }
1038  else
1039  {
1040  Property p;
1041  poly = new PolyDriver;
1042  p.fromString(prop.toString());
1043  if(param.cap==COLOR){
1044  p.put("pixelType", VOCAB_PIXEL_RGB);
1045  }
1046  else
1047  {
1048  p.put("pixelType", VOCAB_PIXEL_MONO);
1049  }
1050  p.setMonitor(prop.getMonitor(), "subdevice"); // pass on any monitoring
1051  p.unput("device");
1052  p.put("device",prop.find("subdevice").asString()); // subdevice was already checked before
1053 
1054  // if errors occurred during open, quit here.
1055  poly->open(p);
1056 
1057  if (!(poly->isValid()))
1058  {
1059  yCError(SERVERGRABBER, "opening subdevice... FAILED");
1060  return false;
1061  }
1062  PolyDriverDescriptor pd(poly,"poly");
1063  plist.push(pd);
1064  //The thread is started by attachAll()
1065  if(!attachAll(plist))
1066  return false;
1067  }
1068  isSubdeviceOwned = true;
1069  return true;
1070 }
1071 
1073 {
1074  if(param.twoCameras)
1075  {
1076  if(param.cap==COLOR)
1077  {
1078  img= new ImageOf<PixelRgb>;
1079  img->resize(fgImage->width(),fgImage->height());
1080  img2= new ImageOf<PixelRgb>;
1081  img2->resize(fgImage2->width(),fgImage2->height());
1082  }
1083  else
1084  {
1085  img_Raw= new ImageOf<PixelMono>;
1086  img_Raw->resize(fgImageRaw->width(),fgImageRaw->height());
1087  img2_Raw= new ImageOf<PixelMono>;
1088  img2_Raw->resize(fgImageRaw2->width(),fgImageRaw2->height());
1089  }
1090  }
1091  else
1092  {
1093  if(param.cap==COLOR)
1094  {
1095  img= new ImageOf<PixelRgb>;
1096  if(param.splitterMode)
1097  {
1098  img->resize(fgImage->width()/2,fgImage->height());
1099 
1100  img2= new ImageOf<PixelRgb>;
1101  img2->resize(fgImage->width()/2,fgImage->height());
1102  }
1103  else
1104  {
1105  img->resize(fgImage->width(),fgImage->height());
1106  }
1107  }
1108  else
1109  {
1110  img_Raw= new ImageOf<PixelMono>;
1111  if(param.splitterMode)
1112  {
1113  img_Raw->resize(fgImageRaw->width()/2,fgImageRaw->height());
1114 
1115  img2_Raw= new ImageOf<PixelMono>;
1116  img2_Raw->resize(fgImageRaw->width()/2,fgImageRaw->height());
1117  }
1118  else
1119  {
1120  img_Raw->resize(fgImageRaw->width(), fgImageRaw->height());
1121  }
1122  }
1123  }
1124  return true;
1125 }
1126 
1128 
1129 
1130 
1131 }
1132 
1134 {
1135  if(param.twoCameras)
1136  {
1137  if(param.split)
1138  {
1139  FlexImage& flex_i=pImg.prepare();
1140  FlexImage& flex_i2=pImg2.prepare();
1141  if(param.cap==COLOR)
1142  {
1143  if(fgImage!=nullptr && fgImage2 !=nullptr)
1144  {
1145  fgImage->getImage(*img);
1146  setupFlexImage(*img,flex_i);
1147  fgImage2->getImage(*img2);
1148  setupFlexImage(*img2,flex_i2);
1149  }
1150  else
1151  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1152 
1153  }
1154  if(param.cap==RAW)
1155  {
1156  if(fgImageRaw!=nullptr && fgImageRaw2 !=nullptr)
1157  {
1158  fgImageRaw->getImage(*img_Raw);
1159  setupFlexImage(*img_Raw,flex_i);
1160  fgImageRaw2->getImage(*img2_Raw);
1161  setupFlexImage(*img2_Raw,flex_i2);
1162  }
1163  else
1164  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1165 
1166  }
1167  Stamp s = Stamp(count,Time::now());
1168  pImg.setStrict(!param.canDrop);
1169  pImg.setEnvelope(s);
1170  pImg.write();
1171  pImg2.setStrict(!param.canDrop);
1172  Stamp s2 = Stamp(count2,Time::now());
1173  pImg2.setEnvelope(s2);
1174  pImg2.write();
1175  count++;
1176  count2++;
1177 
1178  }
1179  else
1180  {
1181  FlexImage& flex_i=pImg.prepare();
1182  if(param.cap==COLOR)
1183  {
1184  if(fgImage!=nullptr && fgImage2 !=nullptr)
1185  {
1186  flex_i.setPixelCode(VOCAB_PIXEL_RGB);
1187  flex_i.resize(fgImage->width()*2,fgImage->height());
1188  fgImage->getImage(*img);
1189  fgImage2->getImage(*img2);
1190 
1191  bool ok = utils::horzConcat(*img, *img2, flex_i);
1192  if (!ok)
1193  {
1194  yCError(SERVERGRABBER) << "Failed to concatenate images";
1195  return;
1196  }
1197  }
1198  else
1199  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1200 
1201  }
1202  if(param.cap==RAW)
1203  {
1204  if(fgImageRaw!=nullptr && fgImageRaw2 !=nullptr)
1205  {
1207  flex_i.resize(fgImageRaw->width()*2,fgImageRaw->height());
1208  fgImageRaw->getImage(*img_Raw);
1209  fgImageRaw2->getImage(*img2_Raw);
1210  bool ok = utils::horzConcat(*img_Raw, *img2_Raw, flex_i);
1211  if (!ok)
1212  {
1213  yCError(SERVERGRABBER) << "Failed to concatenate images";
1214  return;
1215  }
1216  }
1217  else
1218  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1219 
1220  }
1221 
1222  Stamp s = Stamp(count,Time::now());
1223  pImg.setStrict(!param.canDrop);
1224  pImg.setEnvelope(s);
1225  pImg.write();
1226  count++;
1227  }
1228  }
1229  else
1230  {
1231  if(param.splitterMode)
1232  {
1233  FlexImage& flex_i=pImg.prepare();
1234  FlexImage& flex_i2=pImg2.prepare();
1235 
1236  if(param.cap==COLOR)
1237  {
1238  if(fgImage!=nullptr)
1239  {
1241  fgImage->getImage(inputImage);
1242 
1243  bool ok = utils::vertSplit(inputImage,*img,*img2);
1244  if (!ok)
1245  {
1246  yCError(SERVERGRABBER) << "Failed to split the image";
1247  return;
1248  }
1249 
1250  setupFlexImage(*img,flex_i);
1251  setupFlexImage(*img2,flex_i2);
1252  }
1253  else
1254  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1255  }
1256  if(param.cap==RAW)
1257  {
1258  if(fgImageRaw!=nullptr)
1259  {
1261  fgImageRaw->getImage(inputImage);
1262 
1263  bool ok = utils::vertSplit(inputImage,*img_Raw,*img2_Raw);
1264  if (!ok)
1265  {
1266  yCError(SERVERGRABBER) << "Failed to split the image";
1267  return;
1268  }
1269 
1270  setupFlexImage(*img_Raw,flex_i);
1271  setupFlexImage(*img2_Raw,flex_i2);
1272 
1273  }
1274  else
1275  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1276  }
1277  Stamp s = Stamp(count,Time::now());
1278  pImg.setStrict(!param.canDrop);
1279  pImg.setEnvelope(s);
1280  pImg.write();
1281  pImg2.setStrict(!param.canDrop);
1282  Stamp s2 = Stamp(count2,Time::now());
1283  pImg2.setEnvelope(s2);
1284  pImg2.write();
1285  count++;
1286  count2++;
1287  }
1288  else
1289  {
1290  FlexImage& flex_i=pImg.prepare();
1291 
1292  if(param.cap==COLOR)
1293  {
1294  if(fgImage!=nullptr)
1295  {
1296  fgImage->getImage(*img);
1297  setupFlexImage(*img,flex_i);
1298  }
1299  else
1300  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1301  }
1302  if(param.cap==RAW)
1303  {
1304  if(fgImageRaw!=nullptr)
1305  {
1306  fgImageRaw->getImage(*img_Raw);
1307  setupFlexImage(*img_Raw,flex_i);
1308  }
1309  else
1310  yCError(SERVERGRABBER) << "Image not captured.. check hardware configuration";
1311  }
1312  Stamp s = Stamp(count,Time::now());
1313  pImg.setStrict(!param.canDrop);
1314  pImg.setEnvelope(s);
1315  pImg.write();
1316  count++;
1317  }
1318  }
1319 }
1320 
1322 {
1323  dest.setPixelCode(src.getPixelCode());
1324  dest.setQuantum(src.getQuantum());
1325  dest.setExternal(src.getRawImage(), src.width(), src.height());
1326 }
1328 {
1329  if(param.cap==COLOR)
1330  {
1331  if(img!=nullptr)
1332  {
1333  delete img;
1334  img=nullptr;
1335  }
1336  if(img2!=nullptr)
1337  {
1338  delete img2;
1339  img2=nullptr;
1340  }
1341  }
1342  else
1343  {
1344  if(img_Raw!=nullptr)
1345  {
1346  delete img_Raw;
1347  img_Raw=nullptr;
1348  }
1349  if(img2_Raw!=nullptr)
1350  {
1351  delete img2_Raw;
1352  img2_Raw=nullptr;
1353  }
1354  }
1355 }
#define DEFAULT_THREAD_PERIOD
Definition: AnalogWrapper.h:46
define common interfaces to discover remote camera capabilities
constexpr yarp::conf::vocab32_t VOCAB_DRGETISO
constexpr yarp::conf::vocab32_t VOCAB_DRSETFPS
constexpr yarp::conf::vocab32_t VOCAB_DRSETDEF
constexpr yarp::conf::vocab32_t VOCAB_DRSETVMD
constexpr yarp::conf::vocab32_t VOCAB_FRAMEGRABBER_CONTROL_DC1394
constexpr yarp::conf::vocab32_t VOCAB_DRSETWF7
constexpr yarp::conf::vocab32_t VOCAB_DRGETF7M
constexpr yarp::conf::vocab32_t VOCAB_DRSETBCS
constexpr yarp::conf::vocab32_t VOCAB_DRSETCAP
constexpr yarp::conf::vocab32_t VOCAB_DRSETCOD
constexpr yarp::conf::vocab32_t VOCAB_DRGETMSK
constexpr yarp::conf::vocab32_t VOCAB_DRGETFPS
constexpr yarp::conf::vocab32_t VOCAB_DRSETOPM
constexpr yarp::conf::vocab32_t VOCAB_DRGETBPP
constexpr yarp::conf::vocab32_t VOCAB_DRSETPWR
constexpr yarp::conf::vocab32_t VOCAB_DRGETCCM
constexpr yarp::conf::vocab32_t VOCAB_DRGETTXM
constexpr yarp::conf::vocab32_t VOCAB_DRSETRST
constexpr yarp::conf::vocab32_t VOCAB_FRAMEGRABBER_IMAGE
constexpr yarp::conf::vocab32_t VOCAB_DRSETBPP
@ YARP_CROP_LIST
@ YARP_CROP_RECT
constexpr yarp::conf::vocab32_t VOCAB_DRGETWF7
constexpr yarp::conf::vocab32_t VOCAB_DRGETVMD
constexpr yarp::conf::vocab32_t VOCAB_DRGETFPM
constexpr yarp::conf::vocab32_t VOCAB_DRSETTXM
constexpr yarp::conf::vocab32_t VOCAB_FRAMEGRABBER_CONTROL
constexpr yarp::conf::vocab32_t VOCAB_CROP
constexpr yarp::conf::vocab32_t VOCAB_DRGETCOD
constexpr yarp::conf::vocab32_t VOCAB_DRSETISO
constexpr yarp::conf::vocab32_t VOCAB_DRGETOPM
constexpr yarp::conf::vocab32_t VOCAB_IS
Definition: GenericVocabs.h:17
constexpr yarp::conf::vocab32_t VOCAB_GET
Definition: GenericVocabs.h:16
constexpr yarp::conf::vocab32_t VOCAB_FAILED
Definition: GenericVocabs.h:19
constexpr yarp::conf::vocab32_t VOCAB_SET
Definition: GenericVocabs.h:15
constexpr yarp::conf::vocab32_t VOCAB_RGB_VISUAL_PARAMS
Definition: IVisualParams.h:44
constexpr yarp::conf::vocab32_t VOCAB_INTRINSIC_PARAM
Definition: IVisualParams.h:57
bool ret
@ COLOR
Definition: ServerGrabber.h:66
@ RAW
Definition: ServerGrabber.h:67
contains the definition of a Vector type
bool configure(yarp::dev::IFrameGrabberControlsDC1394 *interface)
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &response) override
Respond to a message.
ServerGrabberResponder(bool _left=false)
bool configure(ServerGrabber *_server)
bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply) override
Respond to a message.
void threadRelease() override
Release method.
~ServerGrabber() override
bool attach(yarp::dev::PolyDriver *poly) override
Attach to another object.
bool detach() override
Detach the object (you must have first called attach).
bool open(yarp::os::Searchable &config) override
Configure with a set of options.
bool close() override
Close the DeviceDriver.
void setupFlexImage(const yarp::sig::Image &img, yarp::sig::FlexImage &flex_i)
void shallowCopyImages(const yarp::sig::FlexImage &src, yarp::sig::FlexImage &dest)
void run() override
Loop function.
bool detachAll() override
Detach the object (you must have first called attach).
bool initialize_YARP(yarp::os::Searchable &params)
bool attachAll(const yarp::dev::PolyDriverList &device2attach) override
Attach to a list of objects.
bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply, bool left, bool both)
bool fromConfig(yarp::os::Searchable &config)
bool threadInit() override
Initialization method.
bool view(T *&x)
Get an interface to the device driver.
Definition: DeviceDriver.h:77
bool configure(IFrameGrabberControls *interface)
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &response) override
Respond to a message.
virtual int width() const =0
Return the width of each frame.
virtual bool getImage(yarp::sig::ImageOf< yarp::sig::PixelMono > &image)=0
Get a raw image from the frame grabber.
virtual int height() const =0
Return the height of each frame.
Read a YARP-format image from a device.
virtual bool getImageCrop(cropType_id_t cropType, yarp::sig::VectorOf< std::pair< int, int > > vertices, yarp::sig::ImageOf< yarp::sig::PixelRgb > &image)
Get a crop of the rgb image from the frame grabber, if required demosaicking/color reconstruction is ...
virtual bool getImage(yarp::sig::ImageOf< yarp::sig::PixelRgb > &image)=0
Get an rgb image from the frame grabber, if required demosaicking/color reconstruction is applied.
virtual int width() const =0
Return the width of each frame.
virtual int height() const =0
Return the height of each frame.
bool configure(IRgbVisualParams *interface)
bool respond(const yarp::os::Bottle &cmd, yarp::os::Bottle &response) override
Respond to a message.
void push(PolyDriver *p, const char *k)
A container for a device driver.
Definition: PolyDriver.h:27
bool close() override
Close the DeviceDriver.
Definition: PolyDriver.cpp:176
bool isValid() const
Check if device is valid.
Definition: PolyDriver.cpp:199
bool open(const std::string &txt)
Construct and configure a device by its common name.
Definition: PolyDriver.cpp:143
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition: Bottle.cpp:339
void append(const Bottle &alt)
Append the content of the given bottle to the current list.
Definition: Bottle.cpp:383
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
size_type size() const
Gets the number of elements in the bottle.
Definition: Bottle.cpp:254
void addVocab(int x)
Places a vocabulary item in the bottle, at the end of the list.
Definition: Bottle.cpp:167
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition: Bottle.cpp:249
void clear()
Empties the bottle of any objects it contains.
Definition: Bottle.cpp:124
void addInt32(std::int32_t x)
Places a 32-bit integer in the bottle, at the end of the list.
Definition: Bottle.cpp:143
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
void promiseType(const Type &typ) override
Commit the port to a particular type of data.
void close() override
Stop port activity.
bool setEnvelope(PortWriter &envelope) override
Set an envelope (e.g., a timestamp) to the next message which will be sent.
void setReader(PortReader &reader) override
Set an external reader for port data.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void interrupt() override
Interrupt any current reads or writes attached to the port.
void setStrict(bool strict=true) override
Call this to strictly keep all messages, or allow old ones to be quietly dropped.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
T & prepare()
Access the object which will be transmitted by the next call to yarp::os::BufferedPort::write.
void setWriteOnly()
Shorthand for setInputMode(false), setOutputMode(true), setRpcMode(false)
Definition: Contactable.cpp:29
An abstraction for a periodic thread.
bool isRunning() const
Returns true when the thread is started, false otherwise.
void stop()
Call this to stop the thread, this call blocks until the thread is terminated (and releaseThread() ca...
void setReader(PortReader &reader) override
Set an external reader for port data.
Definition: Port.cpp:505
void interrupt() override
Interrupt any current reads or writes attached to the port.
Definition: Port.cpp:377
void close() override
Stop port activity.
Definition: Port.cpp:357
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
Definition: Port.cpp:82
A class for storing options and configuration information.
Definition: Property.h:37
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition: Property.cpp:1034
void fromString(const std::string &txt, bool wipe=true)
Interprets a string as a list of properties.
Definition: Property.cpp:1046
bool fromConfigFile(const std::string &fname, bool wipe=true)
Interprets a file as a list of properties.
Definition: Property.cpp:1081
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition: Property.cpp:998
void unput(const std::string &key)
Remove the association from the given key to a value, if present.
Definition: Property.cpp:1029
Helper class for finding config files and other external resources.
bool setDefaultContext(const std::string &contextName)
Sets the context for the current ResourceFinder object.
std::string findFileByName(const std::string &name)
Find the full path to a file.
A base class for nested structures that can be searched.
Definition: Searchable.h:69
virtual bool isNull() const
Checks if the object is invalid.
Definition: Searchable.cpp:110
virtual Value & find(const std::string &key) const =0
Gets a value corresponding to a given keyword.
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.
An abstraction for a time stamp and/or sequence number.
Definition: Stamp.h:25
A single value (typically within a Bottle).
Definition: Value.h:47
virtual bool asBool() const
Get boolean value.
Definition: Value.cpp:189
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition: Value.cpp:207
virtual Bottle * asList() const
Get list value.
Definition: Value.cpp:243
std::string toString() const override
Return a standard text representation of the content of the object.
Definition: Value.cpp:359
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition: Value.cpp:135
virtual std::int32_t asVocab() const
Get vocabulary identifier as an integer.
Definition: Value.cpp:231
virtual std::string asString() const
Get string value.
Definition: Value.cpp:237
Image class with user control of representation details.
Definition: Image.h:403
void setQuantum(size_t imgQuantum)
Definition: Image.h:418
void setPixelCode(int imgPixelCode)
Definition: Image.h:406
T & pixel(size_t x, size_t y)
Definition: Image.h:663
Base class for storing images.
Definition: Image.h:85
size_t width() const
Gets width of image in pixels.
Definition: Image.h:153
void setExternal(const void *data, size_t imgWidth, size_t imgHeight)
Use this to wrap an external image.
Definition: Image.cpp:883
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition: Image.cpp:535
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
Definition: Image.cpp:544
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition: Image.cpp:467
size_t getQuantum() const
The size of a row is constrained to be a multiple of the "quantum".
Definition: Image.h:186
void zero()
Set all pixels to 0.
Definition: Image.cpp:460
size_t height() const
Gets height of image in pixels.
Definition: Image.h:159
virtual int getPixelCode() const
Gets pixel type identifier.
Definition: Image.cpp:455
Provides:
Definition: Vector.h:122
void resize(size_t size) override
Resize the vector.
Definition: Vector.h:254
#define yCInfo(component,...)
Definition: LogComponent.h:135
#define yCError(component,...)
Definition: LogComponent.h:157
#define yCWarning(component,...)
Definition: LogComponent.h:146
#define YARP_LOG_COMPONENT(name,...)
Definition: LogComponent.h:80
@ VOCAB_PIXEL_MONO
Definition: Image.h:48
@ VOCAB_PIXEL_RGB
Definition: Image.h:50
An interface for the device drivers.
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
An interface to the operating system, including Port based communication.
bool vertSplit(const yarp::sig::Image &inImg, yarp::sig::Image &outImgL, yarp::sig::Image &outImgR)
vertSplit, split vertically an image in two images of the same size.
Definition: ImageUtils.cpp:25
bool horzConcat(const yarp::sig::Image &inImgL, const yarp::sig::Image &inImgR, yarp::sig::Image &outImg)
horzConcat, concatenate horizontally two images of the same size in one with double width.
Definition: ImageUtils.cpp:69
Signal processing.
Definition: Image.h:25
Capabilities cap
Definition: ServerGrabber.h:82
unsigned char g
Definition: Image.h:455
unsigned char r
Definition: Image.h:454
unsigned char b
Definition: Image.h:456