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
25// IVT
28
31
33
34#include <Image/ImageProcessor.h>
35
36namespace visionx
37{
38
39 std::string
41 {
42 return "ImageToArMem";
43 }
44
47 {
50
51 defs->topic(debugObserver);
52
53 defs->optional(p.imageProviderName, "img.ProviderName", "Name of the image provier.");
54 defs->optional(p.providerSegmentName,
55 "img.ProviderSegmentName",
56 "The provider (segment) name (if not specified in the entity ID).\n"
57 "If '(auto)', the image provider name is used.");
58
59 defs->optional(p.clearProviderSegmentWhenExists,
60 "mem.ClearProviderSegmentsWhenExisting",
61 "If true, the provider segments are cleared when this component starts.");
62
63 defs->optional(p.commitCameraCalib,
64 "mem.commitCameraCalibration",
65 "Commit camera calibration to memory");
66
67 defs->optional(p.maxFrequencyOfCommit,
68 "mem.maxCommitFrequency",
69 "Maximal frequency with which to commit images to Vision Memory in Hz. \n"
70 "Actual commit frequency might be lower, as we wait for next image.");
71
72 p.images.define(*defs);
73
74 return defs;
75 }
76
77 void
79 {
80 // Parse properties.
81 if (p.providerSegmentName == "(auto)")
82 {
83 p.providerSegmentName = p.imageProviderName;
84 }
85 p.images.read(*this, p.providerSegmentName);
86
87 imageToArMem.addImagesRGB(p.images.rgbEntityID, p.images.rgbIndices);
88 imageToArMem.addImagesDepth(p.images.depthEntityID, p.images.depthIndices);
89
90 ARMARX_INFO << "Memory image structure: \n" << imageToArMem.summarizeStructure();
91 ARMARX_VERBOSE << "Using image provider '" << p.imageProviderName << "'.";
92
93 usingImageProvider(p.imageProviderName);
94 }
95
96 void
98 {
99 // Connect to image provider.
100 {
101 imageProviderInfo = getImageProvider(p.imageProviderName);
102
103 // Init input images.
104 imageToArMem.initImages(imageProviderInfo.imageFormat);
105 inputImages = imageToArMem.makeCByteImageBuffer();
106 inputImageBuffer.clear();
107 for (CByteImage& img : inputImages)
108 {
109 inputImageBuffer.emplace_back(&img);
110 }
111 }
112
113 // Connect to memory server.
114 {
115 try
116 {
117 imageToArMem.setWriter(memoryNameSystem().useWriter(imageToArMem.getMemoryID()));
118 }
120 {
121 ARMARX_ERROR << e.what();
122 }
123
124 imageToArMem.setDebugObserver(debugObserver);
125
126 imageToArMem.addProviderSegments();
127 }
128 }
129
130 void
134
135 void
139
140 void
142 {
144 armarx::Duration timeGetImages;
145
146 int numImages = 0;
147 // int millisecondsSinceLastCommit = 0;
148 if (waitForImages(p.imageProviderName, static_cast<int>(timeout.toMilliSeconds())))
149 {
151 int timeDifference = (n.toMicroSecondsSinceEpoch() -
152 this->timeOfLastAcceptedImage.toMicroSecondsSinceEpoch()) /
153 1000;
154 ARMARX_DEBUG << "Time difference during commit is " << timeDifference;
155 float maxFrequency = p.maxFrequencyOfCommit;
156 float minWaitingTime = (1 / maxFrequency) * 1000;
157 ARMARX_DEBUG << "minWaitingTime is " << minWaitingTime;
158 if (timeDifference > minWaitingTime)
159 {
160 ARMARX_DEBUG << "resetting time of last accepted image";
161 this->timeOfLastAcceptedImage =
162 armarx::DateTime::Now(); //if we accept the image we reset the time
163 TIMING_START(GetImages);
164 numImages = getImages(p.imageProviderName, inputImageBuffer.data(), imageMetaInfo);
166 timeGetImages = armarx::Duration::MicroSeconds(GetImages.toMicroSeconds());
167
168 if (numImages == static_cast<int>(inputImageBuffer.size()))
169 {
170 using namespace armarx::armem;
171 imageToArMem.useImageBuffers(
172 inputImageBuffer.data(),
173 Time(Duration::MicroSeconds(imageMetaInfo->timeProvided)));
174 imageToArMem
175 .commitImages(); //TODO: limit how much images will be send to memory
176 }
177 else
178 {
179 ARMARX_ERROR << "Received unexpected number of input images. Got " << numImages
180 << " instead of " << inputImageBuffer.size() << ".";
181 }
182
183
184 // Initially commit the camera calibration once. Has to be done in the processing as it doesn't wait for the proxy
185 if (!commitedCameraCalib and p.commitCameraCalib and imageProviderInfo.proxy)
186 {
187 if (visionx::StereoCalibrationInterfacePrx calibrationProvider =
188 visionx::StereoCalibrationInterfacePrx::checkedCast(
189 imageProviderInfo.proxy);
190 calibrationProvider)
191 {
193 << "Found stereo camera calibration from StereoCalibrationInterface.";
194 visionx::StereoCalibration stereoCameraCalibration =
195 calibrationProvider->getStereoCalibration();
196 imageToArMem.commitCameraCalibration(stereoCameraCalibration);
197 }
198 else
199 {
200 ARMARX_INFO << "Could not cast to stereo calibration interface. Creating "
201 "default monocular ";
202 visionx::MonocularCalibration monocularCameraCalibration =
204
205 imageToArMem.commitCameraCalibration(monocularCameraCalibration);
206 }
207 commitedCameraCalib = true;
208 }
209 }
210 else
211 {
212 ARMARX_DEBUG << "Ignoring image due to high frequency of commits but lower max. "
213 "Frequency set in properties";
214 }
215 }
216 else
217 {
218 ARMARX_WARNING << "Timeout while waiting for camera images (> " << timeout << ").";
219 return;
220 }
221
222 if (debugObserver)
223 {
224 debugObserver->setDebugChannel(
225 getName(),
226 {
227 {"getImages() [us]", new armarx::Variant(timeGetImages.toMicroSecondsDouble())},
228 });
229 }
230 }
231
232} // namespace visionx
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.
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.