ImageToArMem.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::SimpleEpisodicMemoryImageConnector
17 * @author Fabian Peller ( fabian dot peller-konrad at kit dot edu )
18 * @date 2020
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
23#include "ImageToArMem.h"
24
26
27// IVT
30
33
35
36#include <Image/ImageProcessor.h>
37
38namespace visionx
39{
40
41 std::string
43 {
44 return GetDefaultName();
45 }
46
47 std::string
49 {
50 return "ImageToArMem";
51 }
52
55 {
58
59 defs->topic(debugObserver);
60
61 defs->optional(p.imageProviderName, "img.ProviderName", "Name of the image provier.");
62 defs->optional(p.providerSegmentName,
63 "img.ProviderSegmentName",
64 "The provider (segment) name (if not specified in the entity ID).\n"
65 "If '(auto)', the image provider name is used.");
66
67 defs->optional(p.clearProviderSegmentWhenExists,
68 "mem.ClearProviderSegmentsWhenExisting",
69 "If true, the provider segments are cleared when this component starts.");
70
71 defs->optional(p.commitCameraCalib,
72 "mem.commitCameraCalibration",
73 "Commit camera calibration to memory");
74
75 defs->optional(p.maxFrequencyOfCommit,
76 "mem.maxCommitFrequency",
77 "Maximal frequency with which to commit images to Vision Memory in Hz. \n"
78 "Actual commit frequency might be lower, as we wait for next image.");
79
80 p.images.define(*defs);
81
82 return defs;
83 }
84
85 void
87 {
88 // Parse properties.
89 if (p.providerSegmentName == "(auto)")
90 {
91 p.providerSegmentName = p.imageProviderName;
92 }
93 p.images.read(*this, p.providerSegmentName);
94
95 imageToArMem.addImagesRGB(p.images.rgbEntityID, p.images.rgbIndices);
96 imageToArMem.addImagesDepth(p.images.depthEntityID, p.images.depthIndices);
97
98 ARMARX_INFO << "Memory image structure: \n" << imageToArMem.summarizeStructure();
99 ARMARX_VERBOSE << "Using image provider '" << p.imageProviderName << "'.";
100
101 usingImageProvider(p.imageProviderName);
102 }
103
104 void
106 {
107 // Connect to image provider.
108 {
109 imageProviderInfo = getImageProvider(p.imageProviderName);
110
111 // Init input images.
112 imageToArMem.initImages(imageProviderInfo.imageFormat);
113 inputImages = imageToArMem.makeCByteImageBuffer();
114 inputImageBuffer.clear();
115 for (CByteImage& img : inputImages)
116 {
117 inputImageBuffer.emplace_back(&img);
118 }
119 }
120
121 // Connect to memory server.
122 {
123 try
124 {
125 imageToArMem.setWriter(memoryNameSystem().useWriter(imageToArMem.getMemoryID()));
126 }
128 {
129 ARMARX_ERROR << e.what();
130 }
131
132 imageToArMem.setDebugObserver(debugObserver);
133
134 imageToArMem.addProviderSegments();
135 }
136 }
137
138 void
142
143 void
147
148 void
150 {
152 armarx::Duration timeGetImages;
153
154 int numImages = 0;
155 // int millisecondsSinceLastCommit = 0;
156 if (waitForImages(p.imageProviderName, static_cast<int>(timeout.toMilliSeconds())))
157 {
159 int timeDifference = (n.toMicroSecondsSinceEpoch() -
160 this->timeOfLastAcceptedImage.toMicroSecondsSinceEpoch()) /
161 1000;
162 ARMARX_DEBUG << "Time difference during commit is " << timeDifference;
163 float maxFrequency = p.maxFrequencyOfCommit;
164 float minWaitingTime = (1 / maxFrequency) * 1000;
165 ARMARX_DEBUG << "minWaitingTime is " << minWaitingTime;
166 if (timeDifference > minWaitingTime)
167 {
168 ARMARX_DEBUG << "resetting time of last accepted image";
169 this->timeOfLastAcceptedImage =
170 armarx::DateTime::Now(); //if we accept the image we reset the time
171 TIMING_START(GetImages);
172 numImages = getImages(p.imageProviderName, inputImageBuffer.data(), imageMetaInfo);
174 timeGetImages = armarx::Duration::MicroSeconds(GetImages.toMicroSeconds());
175
176 if (numImages == static_cast<int>(inputImageBuffer.size()))
177 {
178 using namespace armarx::armem;
179 imageToArMem.useImageBuffers(
180 inputImageBuffer.data(),
181 Time(Duration::MicroSeconds(imageMetaInfo->timeProvided)));
182 imageToArMem
183 .commitImages(); //TODO: limit how much images will be send to memory
184 }
185 else
186 {
187 ARMARX_ERROR << "Received unexpected number of input images. Got " << numImages
188 << " instead of " << inputImageBuffer.size() << ".";
189 }
190
191
192 // Initially commit the camera calibration once. Has to be done in the processing as it doesn't wait for the proxy
193 if (!commitedCameraCalib and p.commitCameraCalib and imageProviderInfo.proxy)
194 {
195 if (visionx::StereoCalibrationInterfacePrx calibrationProvider =
196 visionx::StereoCalibrationInterfacePrx::checkedCast(
197 imageProviderInfo.proxy);
198 calibrationProvider)
199 {
201 << "Found stereo camera calibration from StereoCalibrationInterface.";
202 visionx::StereoCalibration stereoCameraCalibration =
203 calibrationProvider->getStereoCalibration();
204 imageToArMem.commitCameraCalibration(stereoCameraCalibration);
205 }
206 else
207 {
208 ARMARX_INFO << "Could not cast to stereo calibration interface. Creating "
209 "default monocular ";
210 visionx::MonocularCalibration monocularCameraCalibration =
212
213 imageToArMem.commitCameraCalibration(monocularCameraCalibration);
214 }
215 commitedCameraCalib = true;
216 }
217 }
218 else
219 {
220 ARMARX_DEBUG << "Ignoring image due to high frequency of commits but lower max. "
221 "Frequency set in properties";
222 }
223 }
224 else
225 {
226 ARMARX_WARNING << "Timeout while waiting for camera images (> " << timeout << ").";
227 return;
228 }
229
230 if (debugObserver)
231 {
232 debugObserver->setDebugChannel(
233 getName(),
234 {
235 {"getImages() [us]", new armarx::Variant(timeGetImages.toMicroSecondsDouble())},
236 });
237 }
238 }
239
241
242} // namespace visionx
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
Default component property definition container.
Definition Component.h:70
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
static DateTime Now()
Definition DateTime.cpp:51
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Definition Duration.cpp:24
static Duration MilliSeconds(std::int64_t milliSeconds)
Constructs a duration in milliseconds.
Definition Duration.cpp:48
std::string getName() const
Retrieve name of object.
The Variant class is described here: Variants.
Definition Variant.h:224
Indicates that a query to the Memory Name System failed.
Definition mns.h:25
Represents a point in time.
Definition DateTime.h:25
Represents a duration.
Definition Duration.h:17
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Definition Duration.cpp:24
std::int64_t toMilliSeconds() const
Returns the amount of milliseconds.
Definition Duration.cpp:60
double toMicroSecondsDouble() const
Returns the amount of microseconds.
Definition Duration.cpp:42
void usingImageProvider(std::string name)
Registers a delayed topic subscription and a delayed provider proxy retrieval which all will be avail...
bool waitForImages(int milliseconds=1000)
Wait for new images.
ImageProviderInfo getImageProvider(std::string name, ImageType destinationImageType=eRgb, bool waitForProxy=false)
Select an ImageProvider.
int getImages(CByteImage **ppImages)
Poll images from provider.
void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
void onExitImageProcessor() override
Exit the ImapeProcessor component.
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void process() override
Process the vision component.
void onInitImageProcessor() override
Setup the vision component.
static std::string GetDefaultName()
void onDisconnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
std::string getDefaultName() const override
Retrieve default name of component.
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_DEBUG
The logging level for output that is only interesting while debugging.
Definition Logging.h:184
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193
#define ARMARX_VERBOSE
The logging level for verbose information.
Definition Logging.h:187
#define TIMING_START(name)
Helper macro to do timing tests.
Definition TimeUtil.h:289
#define TIMING_END_STREAM(name, os)
Prints duration.
Definition TimeUtil.h:310
armarx::core::time::DateTime Time
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
MonocularCalibration createDefaultMonocularCalibration()
Creates a MonocularCalibration with all parameters set to a neutral value.
ArmarX headers.