ImageProviderDynamicSimulation.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2013-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package
19  * @author Nikolaus Vahrenkamp
20  * @date 2014
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #include <exception>
26 
27 #include <Ice/Properties.h>
28 
32 
33 // VisionXCore
36 
37 // VisionXTools
41 
43 
44 #include <Calibration/Calibration.h>
45 #include <Inventor/SoInteraction.h>
46 #include <Inventor/nodes/SoDirectionalLight.h>
47 #include <Inventor/nodes/SoUnits.h>
48 #include <Math/Math3d.h>
49 
50 
51 namespace armarx
52 {
54  {
55  // init SoDB / Coin3D
56  //SoDB::init();
57 
58  ARMARX_INFO << "1";
59 
60  VirtualRobot::init(this->getName());
61 
62  // needed for SoSelection
63  SoInteraction::init();
64 
65  // image format
66  setImageSyncMode(visionx::eFpsSynchronization);
67  frameRate = getProperty<float>("FrameRate").getValue();
68 
69  std::string calibrationFileName = getProperty<std::string>("CalibrationFile").getValue();
70  ARMARX_VERBOSE << "Camera calibration file: " << calibrationFileName;
71 
72  if (!calibrationFileName.empty())
73  {
74  std::string fullCalibrationFileName;
75 
76  if (!ArmarXDataPath::getAbsolutePath(calibrationFileName, fullCalibrationFileName))
77  {
78  ARMARX_ERROR << "Could not find camera calibration file in ArmarXDataPath: " << calibrationFileName;
79  }
80 
81  setlocale(LC_NUMERIC, "C");
82 
83  CStereoCalibration ivtStereoCalibration;
84 
85  if (!ivtStereoCalibration.LoadCameraParameters(fullCalibrationFileName.c_str(), true))
86  {
87  ARMARX_ERROR << "Error loading camera calibration file: " << fullCalibrationFileName;
88  }
89  stereoCalibration = visionx::tools::convert(ivtStereoCalibration);
90 
91  renderImg_width = stereoCalibration->calibrationLeft.cameraParam.width;
92  renderImg_height = stereoCalibration->calibrationLeft.cameraParam.height;
93 
94  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationLeft.cameraParam.height, renderImg_height);
95  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationRight.cameraParam.height, renderImg_height);
96  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationLeft.cameraParam.width, renderImg_width);
97  ARMARX_CHECK_EQUAL(stereoCalibration->calibrationRight.cameraParam.width, renderImg_width);
98  }
99  else{
100  const visionx::ImageDimension dimensions = getProperty<visionx::ImageDimension>("ImageSize").getValue();
101 
102  renderImg_width = dimensions.width;
103  renderImg_height = dimensions.height;
104  }
105 
106  setImageFormat(visionx::ImageDimension{renderImg_width, renderImg_height}, visionx::eRgb);
107 
108  renderImg_bpp = 3;
109 
110 
111  setNumberImages(2);
112  images = new CByteImage*[getNumberImages()];
113 
114  for (int i = 0; i < getNumberImages(); i++)
115  {
116  images[i] = new CByteImage(renderImg_width, renderImg_height, CByteImage::eRGB24);
117  }
118 
119  resizedImages = new CByteImage*[getNumberImages()];
120 
121  for (int i = 0 ; i < getNumberImages() ; i++)
122  {
124  }
125 
126 
127 
128 
129 
130  std::stringstream svName;
131  svName << getName() << "_PhysicsWorldVisualization";
132  simVisu = Component::create<ArmarXPhysicsWorldVisualization>(getIceProperties(), svName.str());
133  getArmarXManager()->addObject(simVisu);
134  }
135 
136 
138  {
139  if (images != NULL)
140  {
141  for (int i = 0; i < getNumberImages(); i++)
142  {
143  delete images[i];
144  delete resizedImages[i];
145  }
146 
147  delete [] images;
148  delete [] resizedImages;
149 
150  images = NULL;
151  }
152 
153  rendererLeft.reset();
154  rendererRight.reset();
155 
156  if (simVisu)
157  {
158  simVisu->releaseResources();
159  getArmarXManager()->removeObjectBlocking(simVisu);
160  }
161 
162  simVisu = NULL;
163 
164  SoDB::finish();
165  }
166 
167 
169  {
170  ARMARX_VERBOSE << "start capture";
171 
172  // check nodes
173  robotName = getProperty<std::string>("RobotName").getValue();
174  leftNodeName = getProperty<std::string>("RobotNodeLeftCamera").getValue();
175  rightNodeName = getProperty<std::string>("RobotNodeRightCamera").getValue();
176  focalLength = getProperty<float>("focalLength").getValue();
177 
178  // ensure that all data is loaded
179  if (simVisu)
180  {
181  simVisu->synchronizeVisualizationData();
182  }
183  while (!simVisu->getRobot(robotName))
184  {
185  usleep(100000);
186  simVisu->synchronizeVisualizationData();
187  ARMARX_INFO << deactivateSpam(3) << "Waiting for visu";
188  }
190 
191  }
192 
193 
194  bool ImageProviderDynamicSimulation::setupCameraRendering(const std::string& robotName, const std::string& cameraSensorNameLeft, const std::string& cameraSensorNameRight)
195  {
196  std::unique_lock lock(captureMutex);
197  auto l = simVisu->getScopedLock();
198 
199  rendererLeft.reset(VirtualRobot::CoinVisualizationFactory::createOffscreenRenderer(renderImg_width, renderImg_height));
200  rendererRight.reset(VirtualRobot::CoinVisualizationFactory::createOffscreenRenderer(renderImg_width, renderImg_height));
201 
202  // some checks...
203  if (!simVisu || !simVisu->getVisualization())
204  {
205  ARMARX_ERROR << "No physics visualization scene";
206  return false;
207  }
208 
209  return true;
210  }
211 
212  static void copyRenderBufferToByteImage(CByteImage* image, std::uint8_t* renderBuffer)
213  {
214  int height = image->height;
215  int width = image->width;
216  std::uint8_t* pixelsRow = image->pixels;
217  std::uint8_t* renderBufferEndOfRow = renderBuffer + 3 * (width - 1);
218  for (int y = 0; y < height; y++)
219  {
220  for (int x = 0; x < width; x++)
221  {
222  pixelsRow[x * 3 + 0] = renderBufferEndOfRow[-x * 3 + 0];
223  pixelsRow[x * 3 + 1] = renderBufferEndOfRow[-x * 3 + 1];
224  pixelsRow[x * 3 + 2] = renderBufferEndOfRow[-x * 3 + 2];
225  }
226  pixelsRow += width * 3;
227  renderBufferEndOfRow += width * 3;
228  }
229  }
230 
231 
233  {
234  auto l = simVisu->getScopedLock();
235 
236  if (!simVisu || !simVisu->getRobot(robotName))
237  {
238  ARMARX_WARNING << deactivateSpam() << " no visu or no robot";
239  usleep(100000);
240  return false;
241  }
242 
243  unsigned char* renderBuffer = NULL;
244  bool renderOK = false;
245 
246 
247  cameraNodeL = simVisu->getRobot(robotName)->getRobotNode(leftNodeName);
248  cameraNodeR = simVisu->getRobot(robotName)->getRobotNode(rightNodeName);
249 
250  if (!rendererLeft || !cameraNodeL)
251  {
252  ARMARX_ERROR << deactivateSpam() << "No renderer Left, node:" << leftNodeName;
253  return false;
254  }
255 
256  if (!rendererRight || !cameraNodeR)
257  {
258  ARMARX_ERROR << deactivateSpam() << "No renderer Right, node: " << rightNodeName;
259  return false;
260  }
261 
262 
263  if(not stereoCalibration.has_value())
264  {
265  initStereoCalib();
266  }
267 
268  float fovLeft = 2.0 * std::atan(renderImg_height / (2.0 * stereoCalibration->calibrationLeft.cameraParam.focalLength[1]));
269  float fovRight = 2.0 * std::atan(renderImg_height / (2.0 * stereoCalibration->calibrationRight.cameraParam.focalLength[1]));
270  // ARMARX_LOG << "fov left: " << (fovLeft / M_PI * 180.0) << " fov right: " << (fovRight / M_PI * 180.0);
271 
272 
273 
274  // render Left Camera
275 #if 1
276  renderOK = VirtualRobot::CoinVisualizationFactory::renderOffscreen(rendererLeft.get(), cameraNodeL, simVisu->getVisualization(), &renderBuffer, 100.0f, 100000.0f, fovLeft);
277 #else
278  //////////////// optional: we render by our own
279  SoPerspectiveCamera* cam = new SoPerspectiveCamera();
280  cam->ref();
281  // set camera position and orientation
282  Eigen::Matrix4f camPose = cameraNodeL->getGlobalPose();
283  Eigen::Vector3f camPos = MathTools::getTranslation(camPose);
284  float sc = 0.001f; // to m
285  cam->position.setValue(camPos[0]*sc, camPos[1]*sc, camPos[2]*sc);
286 
287  SbRotation align(SbVec3f(1, 0, 0), (float)(M_PI)); // first align from default direction -z to +z by rotating with 180 degree around x axis
288  SbRotation align2(SbVec3f(0, 0, 1), (float)(-M_PI / 2.0)); // align up vector by rotating with -90 degree around z axis
289  SbRotation trans(CoinVisualizationFactory::getSbMatrix(camPose)); // get rotation from global pose
290  cam->orientation.setValue(align2 * align * trans); // perform total transformation
291 
292  // 10cm to 100m
293  cam->nearDistance.setValue(0.01f);
294  cam->farDistance.setValue(10000.0f);
295 
296  // add all to a inventor scene graph
297  SoSeparator* root = new SoSeparator();
298  root->ref();
299  SoDirectionalLight* light = new SoDirectionalLight;
300  root->addChild(light);
301 
302  // easy light model, no shadows or something
303  //SoLightModel *lightModel = new SoLightModel();
304  //lightModel->model = SoLightModel::BASE_COLOR;
305  //root->addChild(lightModel);
306 
307  root->addChild(cam);
308  root->addChild(simVisu->getVisualization());
309 
310  renderOK = rendererLeft.get()->render(root) == TRUE ? true : false;
311  root->unref();
312 
313  // get render buffer pointer
314  renderBuffer = rendererLeft.get()->getBuffer();
315  cam->unref();
316 
317 #endif
318 
319 
320  if (renderOK && renderBuffer != NULL)
321  {
322  copyRenderBufferToByteImage(images[0], renderBuffer);
323  }
324 
325 
326  // render Right Camera
327  renderOK = VirtualRobot::CoinVisualizationFactory::renderOffscreen(rendererRight.get(), cameraNodeR, simVisu->getVisualization(), &renderBuffer, 100.0f, 100000.0f, fovRight);
328 
329  if (renderOK && renderBuffer != NULL)
330  {
331  copyRenderBufferToByteImage(images[1], renderBuffer);
332  }
333 
334  return true;
335  }
336 
338  {
339  ARMARX_VERBOSE << "stop capture";
340  }
341 
342  bool ImageProviderDynamicSimulation::capture(void** ppImageBuffers)
343  {
344  bool succeeded = true;
345 
346  try
347  {
348  simVisu->synchronizeVisualizationData();
349 
350  {
351  std::unique_lock lock(captureMutex);
352  succeeded = updateCameraRendering();
353  }
354 
355  }
356  catch (...)
357  {
359  }
360 
361  if (succeeded)
362  {
363  try
364  {
366  {
367  ARMARX_WARNING << "Shared memory provider is null (possibly shutting down)";
368  return false;
369  }
371 
372  for (int i = 0; i < getNumberImages(); i++)
373  {
374  ::ImageProcessor::Resize(images[i], resizedImages[i]);
375 
376  memcpy(ppImageBuffers[i],
377  resizedImages[i]->pixels,
378  getImageFormat().dimension.width * getImageFormat().dimension.height * getImageFormat().bytesPerPixel);
379  }
380  }
381  catch (...)
382  {
384  }
385  }
386 
387 
388  return succeeded;
389  }
390 
391 
393  {
394 
395 
396  CCalibration leftCalibration;
397  leftCalibration.SetCameraParameters(focalLength,focalLength, renderImg_width / 2, renderImg_height / 2, 0,0,0,0, Math3d::unit_mat, Math3d::zero_vec, renderImg_width, renderImg_height);
398 
400  while (!simVisu->getRobot(robotName))
401  {
402  usleep(100000);
403  simVisu->synchronizeVisualizationData();
404  ARMARX_INFO << deactivateSpam(3) << "Waiting for visu";
405  }
406 
407  ARMARX_CHECK(simVisu->synchronizeVisualizationData());
408  auto robot = simVisu->getRobot(robotName);
409  ARMARX_CHECK_NOT_NULL(robot);
410 
411  cameraNodeL = robot->getRobotNode(leftNodeName);
412  cameraNodeR = robot->getRobotNode(rightNodeName);
413 
416 
417  const Eigen::Vector3f left_P_right = cameraNodeR->getPositionInFrame(cameraNodeL);
418  ARMARX_IMPORTANT << VAROUT(left_P_right);
419 
420  CCalibration rightCalibration;
421  Vec3d transRight{-left_P_right.x(), 0, 0};
422  rightCalibration.SetCameraParameters(focalLength,focalLength, renderImg_width / 2, renderImg_height / 2, 0,0,0,0, Math3d::unit_mat, transRight, renderImg_width, renderImg_height);
423 
424  CStereoCalibration ivtStereoCalibration;
425  ivtStereoCalibration.SetSingleCalibrations(leftCalibration, rightCalibration);
426  stereoCalibration = visionx::tools::convert(ivtStereoCalibration);
427  }
428 
429  visionx::StereoCalibration ImageProviderDynamicSimulation::getStereoCalibration(const Ice::Current& c)
430  {
431  if(not stereoCalibration.has_value())
432  {
433  initStereoCalib();
434  }
435 
436  return stereoCalibration.value();
437  }
438 
440  {
441  return true;
442  }
443 
444  std::string ImageProviderDynamicSimulation::getReferenceFrame(const Ice::Current&)
445  {
446  return getProperty<std::string>("ReferenceFrame").getValue();
447  }
448 
449 }
armarx::ImageProviderDynamicSimulation::renderImg_bpp
int renderImg_bpp
Definition: ImageProviderDynamicSimulation.h:161
StartingCaptureFailedException.h
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
armarx::ImageProviderDynamicSimulation::initStereoCalib
void initStereoCalib()
Definition: ImageProviderDynamicSimulation.cpp:392
armarx::ImageProviderDynamicSimulation::onStartCapture
void onStartCapture(float frameRate) override
Definition: ImageProviderDynamicSimulation.cpp:168
armarx::ImageProviderDynamicSimulation::simVisu
ArmarXPhysicsWorldVisualizationPtr simVisu
Definition: ImageProviderDynamicSimulation.h:167
ARMARX_IMPORTANT
#define ARMARX_IMPORTANT
Definition: Logging.h:183
visionx::CapturingImageProvider::frameRate
float frameRate
Required frame rate.
Definition: CapturingImageProvider.h:198
armarx::ImageProviderDynamicSimulation::images
CByteImage ** images
Definition: ImageProviderDynamicSimulation.h:153
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
visionx::ImageProvider::getNumberImages
int getNumberImages(const Ice::Current &c=Ice::emptyCurrent) override
Retrieve number of images handled by this provider.
Definition: ImageProvider.cpp:80
armarx::SharedMemoryScopedWriteLockPtr
std::shared_ptr< SharedMemoryScopedWriteLock > SharedMemoryScopedWriteLockPtr
Definition: SharedMemoryProvider.h:46
visionx::ImageProvider::setImageFormat
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
Definition: ImageProvider.cpp:275
armarx::ImageProviderDynamicSimulation::cameraNodeL
VirtualRobot::RobotNodePtr cameraNodeL
Definition: ImageProviderDynamicSimulation.h:181
visionx::ImageProvider::getImageFormat
ImageFormatInfo getImageFormat(const Ice::Current &c=Ice::emptyCurrent) override
Returns the entire image format info struct via Ice.
Definition: ImageProvider.cpp:75
armarx::ImageProviderDynamicSimulation::resizedImages
CByteImage ** resizedImages
Definition: ImageProviderDynamicSimulation.h:154
armarx::ImageProviderDynamicSimulation::onInitCapturingImageProvider
void onInitCapturingImageProvider() override
Definition: ImageProviderDynamicSimulation.cpp:53
ARMARX_CHECK
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
Definition: ExpressionException.h:82
visionx::tools::createByteImage
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
armarx::ImageProviderDynamicSimulation::renderImg_height
int renderImg_height
Definition: ImageProviderDynamicSimulation.h:163
visionx::ImageProvider::sharedMemoryProvider
armarx::IceSharedMemoryProvider< unsigned char >::pointer_type sharedMemoryProvider
shared memory provider
Definition: ImageProvider.h:256
armarx::ImageProviderDynamicSimulation::rendererLeft
std::shared_ptr< SoOffscreenRenderer > rendererLeft
Definition: ImageProviderDynamicSimulation.h:175
std::align
void * align(size_t alignment, size_t bytes, void *&bufferPlace, size_t &bufferSpace) noexcept
Definition: HeterogenousContinuousContainer.h:37
visionx::tools::convert
CByteImage::ImageType convert(const ImageType visionxImageType)
Converts a VisionX image type into an image type of IVT's ByteImage.
Definition: TypeMapping.cpp:95
armarx::ImageProviderDynamicSimulation::updateCameraRendering
bool updateCameraRendering()
Definition: ImageProviderDynamicSimulation.cpp:232
M_PI
#define M_PI
Definition: MathTools.h:17
GfxTL::Vec3d
VectorXD< 3, double > Vec3d
Definition: VectorXD.h:695
visionx::CapturingImageProvider::capture
virtual void capture()
Definition: CapturingImageProvider.cpp:106
FrameRateNotSupportedException.h
armarx::ImageProviderDynamicSimulation::renderImg_width
int renderImg_width
Definition: ImageProviderDynamicSimulation.h:162
InvalidFrameRateException.h
armarx::ImageProviderDynamicSimulation::leftNodeName
std::string leftNodeName
Definition: ImageProviderDynamicSimulation.h:179
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::ImageProviderDynamicSimulation::setupCameraRendering
bool setupCameraRendering(const std::string &robotName, const std::string &cameraSensorNameLeft, const std::string &cameraSensorNameRight)
Definition: ImageProviderDynamicSimulation.cpp:194
armarx::ImageProviderDynamicSimulation::stereoCalibration
std::optional< visionx::StereoCalibration > stereoCalibration
Definition: ImageProviderDynamicSimulation.h:186
visionx::ImageProvider::setNumberImages
void setNumberImages(int numberImages)
Sets the number of images on each capture.
Definition: ImageProvider.cpp:313
ExpressionException.h
armarx::ImageProviderDynamicSimulation::getImagesAreUndistorted
bool getImagesAreUndistorted(const Ice::Current &c=Ice::emptyCurrent) override
Returns whether images are undistorted.
Definition: ImageProviderDynamicSimulation.cpp:439
armarx::ImageProviderDynamicSimulation::focalLength
float focalLength
Definition: ImageProviderDynamicSimulation.h:184
visionx::CapturingImageProvider::setImageSyncMode
void setImageSyncMode(ImageSyncMode imageSyncMode)
Sets the image synchronization mode.
Definition: CapturingImageProvider.cpp:166
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::ImageProviderDynamicSimulation::getStereoCalibration
visionx::StereoCalibration getStereoCalibration(const Ice::Current &c=Ice::emptyCurrent) override
Returns the StereoCalibration as provided in configuration.
Definition: ImageProviderDynamicSimulation.cpp:429
armarx::ImageProviderDynamicSimulation::onExitCapturingImageProvider
void onExitCapturingImageProvider() override
Definition: ImageProviderDynamicSimulation.cpp:137
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::ImageProviderDynamicSimulation::getReferenceFrame
std::string getReferenceFrame(const ::Ice::Current &=Ice::emptyCurrent) override
Definition: ImageProviderDynamicSimulation.cpp:444
armarx::ImageProviderDynamicSimulation::onStopCapture
void onStopCapture() override
Definition: ImageProviderDynamicSimulation.cpp:337
ImageUtil.h
armarx::ImageProviderDynamicSimulation::rightNodeName
std::string rightNodeName
Definition: ImageProviderDynamicSimulation.h:180
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
TypeMapping.h
armarx::ArmarXDataPath::getAbsolutePath
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
Definition: ArmarXDataPath.cpp:111
armarx::PropertyUser::getIceProperties
Ice::PropertiesPtr getIceProperties() const
Returns the set of Ice properties.
Definition: PropertyUser.cpp:229
Logging.h
armarx::ImageProviderDynamicSimulation::cameraNodeR
VirtualRobot::RobotNodePtr cameraNodeR
Definition: ImageProviderDynamicSimulation.h:182
armarx::ImageProviderDynamicSimulation::robotName
std::string robotName
Definition: ImageProviderDynamicSimulation.h:178
ARMARX_CHECK_EQUAL
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
Definition: ExpressionException.h:130
armarx::handleExceptions
void handleExceptions()
Definition: Exception.cpp:141
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
ImageProviderDynamicSimulation.h
ArmarXDataPath.h
armarx::ImageProviderDynamicSimulation::captureMutex
std::mutex captureMutex
Definition: ImageProviderDynamicSimulation.h:156
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
visionx::CapturingImageProvider::getScopedWriteLock
armarx::SharedMemoryScopedWriteLockPtr getScopedWriteLock()
Retrieve scoped lock for writing to the memory.
Definition: CapturingImageProvider.h:152
armarx::ImageProviderDynamicSimulation::rendererRight
std::shared_ptr< SoOffscreenRenderer > rendererRight
Definition: ImageProviderDynamicSimulation.h:176