RGBDPoseEstimationWithMemoryWriter.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::RGBDOpenPoseEstimation
17 * @author Fabian Peller <fabian.peller@kit.edu>
18 * @date 2020
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22
24
25#include <VirtualRobot/Nodes/RobotNode.h>
26
28
33
34#include <VisionX/libraries/armem_human/aron/HumanPose.aron.generated.h>
38
39using namespace visionx;
40
41namespace armarx
42{
43
44 const std::string RGBDPoseEstimationWithMemoryWriter::defaultName =
45 "RGBDPoseEstimationWithMemoryWriter";
46
49 {
52
53 def->required(properties.providerName, "ImageProviderName");
54
55 def->optional(properties.enableMemory,
56 "humanMemory.enable",
57 "Enables or disables writing to the human memory.");
58 def->optional(properties.humanMemory.memoryName,
59 "humanMemory.memory_name",
60 "Name of the human memory.");
61 def->optional(properties.humanMemory.coreSegmentName,
62 "humanMemory.core_segment_name",
63 "Name of the core segment in the human memory.");
64
65 humanPoseWriter.registerPropertyDefinitions(def);
66
68 return def;
69 }
70
71 std::string
73 {
74 return RGBDPoseEstimationWithMemoryWriter::defaultName;
75 }
76
77 std::string
79 {
80 return RGBDPoseEstimationWithMemoryWriter::defaultName;
81 }
82
83 void
85 {
86 if (properties.enableMemory)
87 {
89
90 std::vector<armem::human::HumanPose> humanPoses;
91 humanPoses.reserve(openposeResult3D.size());
92 for (const auto& humanPose3D : openposeResult3D)
93 {
95 // Per-frame OpenPose person key. Not a true cross-frame track, but at least
96 // keeps simultaneously-visible people from collapsing into one identity.
97 humanPose.humanTrackingId = humanPose3D.first;
99 humanPose.poseModelId = op_settings.model_pose;
100
101 float meanZ = 0.;
102 for (const auto& keypoint3D : humanPose3D.second.keypointMap)
103 {
104 humanPose.keypoints[keypoint3D.first] = armarx::armem::human::PoseKeypoint{
105 .label = keypoint3D.first,
106 .confidence =
107 static_cast<float>(static_cast<int>(keypoint3D.second.confidence)),
108 .positionCamera = armarx::FramedPosition(
109 Eigen::Vector3f{
110 keypoint3D.second.x, keypoint3D.second.y, keypoint3D.second.z},
112 localRobot->getName())};
113 meanZ += keypoint3D.second.z;
114 }
115 meanZ /= humanPose3D.second.keypointMap.size();
116
117 if (meanZ > 100)
118 {
119 humanPoses.emplace_back(humanPose);
120 }
121 else
122 {
123 ARMARX_INFO << deactivateSpam(10) << "Ignoring human with mean depth < 100mm";
124 }
125 }
126
127 if (not humanPoseWriter.commitHumanPosesInCameraFrame(humanPoses, getName(), ts))
128 {
129 ARMARX_ERROR << "Failed to commit poses to memory";
130 }
131 }
132
134 }
135
136 void
146
147 void
149 {
151
152 if (properties.enableMemory)
153 {
154 // ARMARX_IMPORTANT << "Waiting for memory ...";
155 // try
156 // {
157 // humanMemoryWriter = memoryNameSystem().useWriter(properties.humanMemory);
158 // }
159 // catch (const armarx::armem::error::CouldNotResolveMemoryServer& e)
160 // {
161 // ARMARX_ERROR << e.what();
162 // return;
163 // }
164 humanPoseWriter.connect(memoryNameSystem());
165 }
166 else
167 {
168 ARMARX_IMPORTANT << "Writing to memroy disabled via properties.";
169 }
170
171 visionx::ImageType imageDisplayType = visionx::tools::typeNameToImageType("rgb");
172 imageProviderInfo = getImageProvider(properties.providerName, imageDisplayType);
173 rgbImageFormat = imageProviderInfo.imageFormat;
174
175 numImages = static_cast<unsigned int>(imageProviderInfo.numberImages);
176 if (numImages != 2)
177 {
178 ARMARX_FATAL << "invalid number of images. aborting";
179 return;
180 }
181
182 imageBuffer = new CByteImage*[2];
183 openposeResultImage = new CByteImage*[1];
188
190 1, imageProviderInfo.imageFormat.dimension, imageProviderInfo.imageFormat.type);
191
192 ARMARX_INFO << getName() << " connect done";
193
195 }
196
197 void
206
207 void
211
212 void
214 {
215 if (running2D)
216 {
217 // check for result images
219 {
220 std::lock_guard outputImage_lock(openposeResultImageMutex);
221 ARMARX_DEBUG << deactivateSpam() << "publish result openpose image";
223 }
224
225 // check for new images
226 if (!waitForImages(properties.providerName))
227 {
229 ARMARX_WARNING << "Timeout or error in wait for images"
230 << " (#timeout " << timeoutCounter2d << ", #read error "
231 << readErrorCounter2d << ", #success " << sucessCounter2d << ")";
232 }
233 else
234 {
235 std::lock_guard lock_images(imageBufferMutex);
236 if (static_cast<unsigned int>(getImages(
237 properties.providerName, imageBuffer, imageMetaInfo)) != numImages)
238 {
240 ARMARX_WARNING << "Unable to transfer or read images"
241 << " (#timeout " << timeoutCounter2d << ", #read error "
242 << readErrorCounter2d << ", #success " << sucessCounter2d << ")";
243 return;
244 }
245 else
246 {
247 ARMARX_DEBUG << "Received an Image.";
249
250 std::lock_guard lock_rgb(rgbImageBufferMutex);
251 std::lock_guard lock_depth(depthImageBufferMutex);
252 ::ImageProcessor::CopyImage(imageBuffer[0], rgbImageBuffer);
253 ::ImageProcessor::CopyImage(imageBuffer[1], depthImageBuffer);
254
255 timestamp_of_update = imageMetaInfo->timeProvided;
256 update_ready = true;
257 }
258 }
259 }
260 else
261 {
262 ARMARX_DEBUG << deactivateSpam() << "Not running. Wait until start signal comes";
263 usleep(10000);
264 }
265 }
266} // namespace armarx
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
The FramedPosition class.
Definition FramedPose.h:158
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:99
std::string getName() const
Retrieve name of object.
void postCreatePropertyDefinitions(PropertyDefinitionsPtr &properties) override
virtual void onConnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component is fully initia...
virtual void onExitImageProcessor() override
Exit the ImapeProcessor component.
virtual armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
virtual void process() override
Process the vision component.
virtual void onInitImageProcessor() override
Setup the vision component.
static std::string GetDefaultName()
Get the component's default name.
virtual void onDisconnectImageProcessor() override
Implement this method in the ImageProcessor in order execute parts when the component looses network ...
static Duration MicroSeconds(std::int64_t microSeconds)
Constructs a duration in microseconds.
Definition Duration.cpp:24
void enableResultImages(int numberImages, ImageDimension imageDimension, ImageType imageType, const std::string &name="")
Enables visualization.
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 provideResultImages(CByteImage **images, armarx::MetaInfoSizeBasePtr info=nullptr)
sends result images for visualization
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_FATAL
The logging level for unexpected behaviour, that will lead to a seriously malfunctioning program and ...
Definition Logging.h:199
#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
armarx::core::time::DateTime Time
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
ImageType typeNameToImageType(const std::string &imageTypeName)
Converts an image type name as string into an ImageType integer.
CByteImage * createByteImage(const ImageFormatInfo &imageFormat, const ImageType imageType)
Creates a ByteImage for the destination type specified in the given imageProviderInfo.
ArmarX headers.
std::optional< std::string > humanTrackingId
Definition types.h:47