ArMemToImageProvider.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package VisionX::ArmarXObjects::ArMemToImage
17  * @author Rainer Kartmann ( rainer dot kartmann at kit dot edu )
18  * @date 2021
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #include "ArMemToImageProvider.h"
24 
25 #include <algorithm>
26 
30 
33 
34 
35 namespace visionx
36 {
37 
39  {
40  return "ArMemToImageProvider";
41  }
42 
43 
45  {
47 
48  defs->topic(debugObserver);
49 
50  defs->optional(p.providerSegmentName, "img.ProviderSegmentName",
51  "Name of the provider segment(s).");
52  defs->optional(p.resultImagesName, "img.ResultImagesName",
53  "Name of the resulting (provided) images.\n"
54  "If '(auto)', the provider segment name is used.");
55 
56  defs->defineOptionalPropertyVector("img.FallbackDimensions", p.fallbackDims,
57  "Image dimensions to use when they cannot be fetched from memory.", 'x');
58 
59  p.images.define(*defs);
60 
61  return defs;
62  }
63 
64 
66  {
67  // Parse properties.
68  getProperty(p.fallbackDims, "img.FallbackDimensions");
69  if (p.resultImagesName == "(auto)")
70  {
71  p.resultImagesName = p.providerSegmentName;
72  }
73  p.images.read(*this, p.providerSegmentName);
74 
75  // Setup images.
76  armemToImage.addImagesRGB(p.images.rgbEntityID, p.images.rgbIndices);
77  armemToImage.addImagesDepth(p.images.depthEntityID, p.images.depthIndices);
78  ARMARX_INFO << "Result image structure: \n" << armemToImage.summarizeStructure();
79 
80  // Connect to memory updates.
81  auto callback = [this](const armarx::armem::MemoryID & entityID, const std::vector<armarx::armem::MemoryID>& updatedSnapshotIDs)
82  {
83  this->fetchUpdates(entityID, updatedSnapshotIDs);
84  };
85  memoryNameSystem().subscribe(p.images.rgbEntityID, callback);
86  memoryNameSystem().subscribe(p.images.depthEntityID, callback);
87  }
88 
90  {
91  armemToImage.setDebugObserver(debugObserver, getName());
92  {
93  try
94  {
95  armemToImage.memoryReader = memoryNameSystem().useReader(armemToImage.getMemoryID());
96  }
98  {
99  ARMARX_ERROR << e.what();
100  }
101  }
102 
103  ARMARX_VERBOSE << "Trying initial fetch ...";
104  Eigen::Vector2i dimensions = p.fallbackDims;
105 
106  armemToImage.fetchLatest();
107  if (armemToImage.updated)
108  {
109  dimensions = armemToImage.getImageDimensions();
110  ARMARX_VERBOSE << "Image formats: \n" << armemToImage.printFormats();
111  }
112  // ToDo: We (or the result image provider) could also wait until images are available.
113  enableResultImages(armemToImage.images.size(), { dimensions(0), dimensions(1) }, eRgb, p.resultImagesName);
114  }
115 
117  {
118  if (resultImageProvider)
119  {
120  getArmarXManager()->removeObjectBlocking(resultImageProvider->getName());
121  resultImageProvider = nullptr;
122  }
123  }
124 
126  {
127  }
128 
129 
130 
132  {
133  // Allow calling setName() from outside.
135  virtual ~LocalResultImageProvider() override;
136  };
138 
139  void ArMemToImageProvider::enableResultImages(size_t numberImages, ImageDimension imageDimension, ImageType imageType, const std::string& name)
140  {
141  if (!resultImageProvider)
142  {
143  ARMARX_VERBOSE << "Enabling ImageProvider with " << numberImages << " result images of size "
144  << imageDimension.width << "x" << imageDimension.height << ".";
145 
146  IceInternal::Handle<LocalResultImageProvider> provider = Component::create<LocalResultImageProvider>();
147  provider->setName(name);
148  provider->setNumberResultImages(static_cast<int>(numberImages));
149  provider->setResultImageFormat(imageDimension, imageType);
150 
151  try
152  {
153  getArmarXManager()->addObject(provider);
154  }
155  catch (const Ice::AlreadyRegisteredException& e)
156  {
157  ARMARX_ERROR << "The name '" << name << "' is already used. Please choose another one.\n"
158  << "Reason: " << e.what();
159  getArmarXManager()->removeObjectBlocking(name);
160  }
161  provider->getObjectScheduler()->waitForObjectState(armarx::ManagedIceObjectState::eManagedIceObjectStarted);
162 
163  // Only now store it in member variable.
164  this->resultImageProvider = provider;
165  }
166  }
167 
168 
169  void ArMemToImageProvider::fetchUpdates(const armarx::armem::MemoryID& entityID, const std::vector<armarx::armem::MemoryID>& updatedSnapshotIDs)
170  {
171  std::scoped_lock lock(armemToImageMutex);
172  armemToImage.fetchUpdates(entityID, updatedSnapshotIDs);
173 
174  if (resultImageProvider && armemToImage.updated)
175  {
176  std::vector<CByteImage> ivtImages;
177  std::vector<CByteImage*> ivtImagesBuffer;
178  ivtImages.reserve(armemToImage.images.size());
179  ivtImagesBuffer.reserve(armemToImage.images.size());
180  for (auto& image : armemToImage.images)
181  {
182  CByteImage& ivt = ivtImages.emplace_back(image->toCByteImage());
183  ivtImagesBuffer.emplace_back(&ivt);
184  }
185  TIMING_START(Provide);
186  resultImageProvider->provideResultImages(ivtImagesBuffer.data(), armemToImage.timestamp.toMicroSecondsSinceEpoch());
188  armemToImage.updated = false;
189 
190  if (debugObserver)
191  {
192  debugObserver->setDebugChannel(getName(),
193  {
194  { "Provide [us]", new armarx::Variant(Provide.toMicroSecondsDouble()) },
195  });
196  }
197  }
198  }
199 
200 }
visionx::armem_images::ArMemToImage::timestamp
armarx::armem::Time timestamp
Definition: ArMemToImage.h:53
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
ARMARX_VERBOSE
#define ARMARX_VERBOSE
Definition: Logging.h:180
visionx::LocalResultImageProvider
Definition: ArMemToImageProvider.cpp:131
TIMING_START
#define TIMING_START(name)
Definition: TimeUtil.h:280
visionx::ArMemToImageProvider::onExitComponent
void onExitComponent() override
Hook for subclass.
Definition: ArMemToImageProvider.cpp:125
visionx::armem_images::ArMemToImage::memoryReader
armarx::armem::client::Reader memoryReader
Definition: ArMemToImage.h:50
visionx
ArmarX headers.
Definition: OpenPoseStressTest.h:38
client.h
visionx::LocalResultImageProvider::~LocalResultImageProvider
virtual ~LocalResultImageProvider() override
Definition: ArMemToImageProvider.cpp:137
visionx::ArMemToImageProvider::onConnectComponent
void onConnectComponent() override
Pure virtual hook for the subclass.
Definition: ArMemToImageProvider.cpp:89
armarx::armem::client::plugins::PluginUser::memoryNameSystem
MemoryNameSystem & memoryNameSystem()
Definition: PluginUser.cpp:22
armarx::ManagedIceObject::getArmarXManager
ArmarXManagerPtr getArmarXManager() const
Returns the ArmarX manager used to add and remove components.
Definition: ManagedIceObject.cpp:348
visionx::armem_images::ArMemToImage::getMemoryID
armarx::armem::MemoryID getMemoryID() const override
Definition: ArMemToImage.cpp:53
visionx::armem_images::detail::ImageAdapter::setDebugObserver
void setDebugObserver(armarx::DebugObserverInterfacePrx proxy)
Definition: ImageAdapter.cpp:18
visionx::armem_images::ArMemToImage::updated
bool updated
Definition: ArMemToImage.h:54
TIMING_END_STREAM
#define TIMING_END_STREAM(name, os)
Definition: TimeUtil.h:300
IceInternal::Handle
Definition: forward_declarations.h:8
armarx::armem::MemoryID
A memory ID.
Definition: MemoryID.h:47
visionx::armem_images::ArMemToImage::addImagesRGB
void addImagesRGB(const armarx::armem::MemoryID &entityID, const std::vector< size_t > &imageIndices) override
Definition: ArMemToImage.cpp:41
error.h
armarx::armem::client::MemoryNameSystem::useReader
Reader useReader(const MemoryID &memoryID)
Use a memory server and get a reader for it.
Definition: MemoryNameSystem.cpp:184
visionx::armem_images::ArMemToImage::summarizeStructure
std::string summarizeStructure() const override
Definition: ArMemToImage.cpp:103
visionx::armem_images::ArMemToImage::printFormats
std::string printFormats() const
Definition: ArMemToImage.cpp:149
ArmarXObjectScheduler.h
armarx::armem::client::util::MemoryListener::subscribe
SubscriptionHandle subscribe(const MemoryID &subscriptionID, Callback Callback)
Definition: MemoryListener.cpp:116
ARMARX_ERROR
#define ARMARX_ERROR
Definition: Logging.h:189
armarx::core::time::DateTime::toMicroSecondsSinceEpoch
std::int64_t toMicroSecondsSinceEpoch() const
Definition: DateTime.cpp:95
visionx::ArMemToImageProvider::onDisconnectComponent
void onDisconnectComponent() override
Hook for subclass.
Definition: ArMemToImageProvider.cpp:116
visionx::armem_images::ArMemToImage::fetchLatest
armarx::armem::client::QueryResult fetchLatest()
Definition: ArMemToImage.cpp:114
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
visionx::LocalResultImageProvider::ArMemToImageProvider
friend ArMemToImageProvider
Definition: ArMemToImageProvider.cpp:134
visionx::ArMemToImageProvider::getDefaultName
std::string getDefaultName() const override
Retrieve default name of component.
Definition: ArMemToImageProvider.cpp:38
armarx::ComponentPropertyDefinitions
Default component property definition container.
Definition: Component.h:70
TimeUtil.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::PropertyUser::getProperty
Property< PropertyType > getProperty(const std::string &name)
Property creation and retrieval.
Definition: PropertyUser.h:179
visionx::armem_images::ArMemToImage::addImagesDepth
void addImagesDepth(const armarx::armem::MemoryID &entityID, const std::vector< size_t > &imageIndices) override
Definition: ArMemToImage.cpp:47
IceUtil::Handle< class PropertyDefinitionContainer >
visionx::armem_images::ArMemToImage::getImageDimensions
Eigen::Vector2i getImageDimensions() const
Definition: ArMemToImage.cpp:65
ArMemToImageProvider.h
armarx::armem::error::CouldNotResolveMemoryServer
Indicates that a query to the Memory Name System failed.
Definition: mns.h:26
visionx::ResultImageProvider
The ResultImageProvider is used by the ImageProcessor to stream result images to any other processor ...
Definition: ImageProcessor.h:529
armarx::ManagedIceObject::getName
std::string getName() const
Retrieve name of object.
Definition: ManagedIceObject.cpp:107
visionx::armem_images::ArMemToImage::fetchUpdates
void fetchUpdates(const armarx::armem::MemoryID &entityID, const std::vector< armarx::armem::MemoryID > &updatedSnapshotIDs)
Definition: ArMemToImage.cpp:78
visionx::ArMemToImageProvider::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: ArMemToImageProvider.cpp:44
Variant.h
visionx::armem_images::ArMemToImage::images
std::vector< std::unique_ptr< ImageBase > > images
Definition: ArMemToImage.h:52
visionx::ArMemToImageProvider::onInitComponent
void onInitComponent() override
Pure virtual hook for the subclass.
Definition: ArMemToImageProvider.cpp:65