NuitrackPointCloudProvider.h
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::NuitrackPointCloudProvider
17 * @author Mirko Wächter
18 * @author Christian R. G. Dreher <c.dreher@kit.edu>
19 * @date 2019
20 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21 * GNU General Public License
22 */
23
24
25#pragma once
26
27// STD
28#include <chrono>
29#include <condition_variable>
30#include <mutex>
31
32// Eigen3
33#include <Eigen/Core>
34
35// OpenCV
36#include <opencv2/opencv.hpp>
37#include <VirtualRobot/VirtualRobot.h>
38
39// ArmarXCore
44#include <ArmarXCore/interface/observers/ObserverInterface.h>
46
47// RobotAPI
50#include <RobotAPI/interface/visualization/DebugDrawerInterface.h>
51
52// VisionX
56//#include <VisionX/interface/components/RGBDImageProvider.h>
57#include <VisionX/interface/components/AzureKinectPointCloudProviderInterface.h>
58#include <VisionX/libraries/armem_human/server/HumanMemoryServerInterface.h>
59
60// Nuitrack
62
64
65// Nuitrack SDK (suppress warnings from third-party headers)
66#pragma GCC diagnostic push
67#pragma GCC diagnostic ignored "-Wswitch"
68#pragma GCC diagnostic ignored "-Wreorder"
69#include <nuitrack/Nuitrack.h>
70#pragma GCC diagnostic pop
71
72namespace visionx
73{
74 /// @class NuitrackPointCloudProviderPropertyDefinitions
81
82 // TODO: Update the comments for this component.
83 /**
84 * @defgroup Component-NuitrackPointCloudProvider NuitrackPointCloudProvider
85 * @ingroup VisionX-Components
86 * Provides support for the Azure Kinect cameras for ArmarX.
87 *
88 * @class NuitrackPointCloudProvider
89 * @ingroup Component-NuitrackPointCloudProvider
90 * @brief Brief description of class NuitrackPointCloudProvider.
91 */
93 // virtual public visionx::RGBDPointCloudProviderInterface,
94 virtual public armarx::AzureKinectPointCloudProviderInterface,
96 virtual public visionx::ImageProvider,
99 {
100 public:
102
103 using CloudPointType = pcl::PointXYZRGBA;
104 /**
105 * @see armarx::ManagedIceObject::getDefaultName()
106 */
107 std::string getDefaultName() const override;
108
109 protected:
110 /**
111 * @see PropertyUser::createPropertyDefinitions()
112 */
114
115 // ManagedIceObject interface
116 protected:
117 void onInitComponent() override;
118 void onConnectComponent() override;
119 void onDisconnectComponent() override;
120
121 void onExitComponent() override;
122
123 // StereoCalibrationInterface interface
124 public:
125 visionx::StereoCalibration getStereoCalibration(const Ice::Current& c) override;
126 bool getImagesAreUndistorted(const ::Ice::Current& c) override;
127
128 std::string getReferenceFrame(const Ice::Current& c) override;
129
130 std::vector<imrec::ChannelPreferences>
131 getImageRecordingChannelPreferences(const Ice::Current&) override;
132
133 // NuitrackBodyTrackingInterface interface
134 public:
135 void enableHumanPoseEstimation(const armarx::EnableHumanPoseEstimationInput& input,
136 const Ice::Current& = Ice::emptyCurrent) override;
137
138 void setMaxDepthBodyTracking(int maxDepthInMM,
139 const Ice::Current& = Ice::emptyCurrent) override;
140
141 void setWidthBodyTracking(int minXinPixel,
142 int maxXinPixel,
143 const Ice::Current& = Ice::emptyCurrent) override;
144
145 protected:
146 void onStartCapture(float frames_per_second) override;
147 void onStopCapture() override;
148 void onInitImageProvider() override;
149 void onConnectImageProvider() override;
150 void onDisconnectImageProvider() override;
151
152 void
154 {
155 }
156
157 void onInitCapturingPointCloudProvider() override;
158 void onExitCapturingPointCloudProvider() override;
159 bool doCapture() override;
160
161 bool
162 hasSharedMemorySupport(const Ice::Current& c) override
163 {
164 return true;
165 }
166
167 MetaPointCloudFormatPtr
169 {
170 MetaPointCloudFormatPtr info = new MetaPointCloudFormat();
171 //info->frameId = getProperty<std::string>("frameId").getValue();
172 info->type = PointContentType::eColoredPoints;
173
174 ARMARX_CHECK_EXPRESSION(resultColorImage);
175
176 ARMARX_INFO << "default pointcloud format: " << resultColorImage->width << ", "
177 << resultColorImage->height;
178
179 info->capacity =
180 resultColorImage->width * resultColorImage->height * sizeof(ColoredPoint3D);
181 info->size = info->capacity;
182 return info;
183 }
184
186
187
188 std::function<void(armarx::Duration)> createSwCallback(const std::string& description);
189
190 void onNewDepthFrame(tdv::nuitrack::DepthFrame::Ptr frame);
191 void onNewColorFrame(tdv::nuitrack::RGBFrame::Ptr frame);
192 void onNewSkeletonData(tdv::nuitrack::SkeletonData::Ptr skeletonData);
193
194 std::optional<Eigen::Vector3f>
196
197 void
198 filterPosesByUpright(std::vector<armarx::armem::human::HumanPose>& poses,
199 const Eigen::Vector3f& worldUp,
200 float maxAngleDeg);
201
202 private:
203 // Time the last image was recorded.
204 IceUtil::Time imagesTime;
205
206 // Mutex to protect the point cloud provider.
207 std::mutex pointcloudProcMutex;
208 std::condition_variable pointcloudProcSignal;
209
210 bool depthImageReady;
211 bool depthImageProcessed;
212
213 // Task for the point cloud provider.
215
216 // IVT result images scaled to the size of the color image.
217 visionx::CByteImageUPtr resultDepthImage, resultColorImage;
218
219 // Result point cloud.
220 pcl::PointCloud<CloudPointType>::Ptr pointcloud;
221 MetaPointCloudFormatPtr cloudFormat;
222
223 // Stereo calibration used.
224 visionx::StereoCalibration calibration;
225
226 bool enableHeartbeat = true;
227
228 // Nuitrack handles.
229 tdv::nuitrack::DepthSensor::Ptr depthSensor;
230 tdv::nuitrack::ColorSensor::Ptr colorSensor;
231
232 // Latest frames from Nuitrack
233 tdv::nuitrack::DepthFrame::Ptr latestDepthFrame;
234 tdv::nuitrack::RGBFrame::Ptr latestColorFrame;
235 std::int64_t latestTimestamp;
236 std::mutex colorFrameMutex;
237 std::mutex depthFrameMutex;
238
239 // Processed images
240 cv::Mat alignedDepthImage;
241 cv::Mat colorImageRGB;
242
243 tdv::nuitrack::SkeletonTracker::Ptr skeletonTracker;
244 tdv::nuitrack::SkeletonData::Ptr latestSkeletonData;
245 std::mutex skeletonMutex;
246 // armarx::armem::human::HumanMemoryServerInterfacePrx humanMemoryServer;
247
249
251
252 void runPublishBodyTrackingResults();
253
254 bool bodyTrackingEnabled = true;
255 bool bodyTrackingRunAtStart = true;
256 std::atomic<bool> bodyTrackingIsRunning = false;
257 std::mutex bodyTrackingParameterMutex;
258 int bodyTrackingDepthMaskMinX = -1;
259 int bodyTrackingDepthMaskMaxX = -1;
260 int bodyTrackingDepthMaskMaxZ = -1;
261 double confidenceThreshold = 0.;
262 int minimumSegmentsWithConfidenceLargerThanThreshold = 0;
263 float uprightFilterMaxAngleDeg = 45.F;
264
265 std::string bodyCameraFrameName = "AzureKinect_Depth";
266 std::string robotName = "Armar6";
267
268 struct Framerate
269 {
270 int value = 30;
271
273 {
274 std::string name;
275 float value = 30;
276 unsigned int skipFrames = 0;
277 unsigned int skipFramesCount = 0;
278
279 void update(int higherFramerate);
280 bool skip();
281 };
282
283 Subordinate bodyTracking{.name = "Body Tracking"};
284 Subordinate pointCloud{.name = "Point Cloud"};
285 } framerate;
286
287 std::mutex deviceToRealtimeOffsetMtx;
288 std::chrono::nanoseconds device_to_realtime_offset_{0};
289
290 std::mutex debugObserverMtx;
291 std::mutex metaInfoMtx;
292
293 armarx::plugins::HeartbeatComponentPlugin* heartbeatPlugin = nullptr;
294
295 armarx::armem::robot_state::VirtualRobotReader robotReader;
297
298 };
299} // namespace visionx
constexpr T c
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
IceUtil::Handle< RunningTask< T > > pointer_type
Shared pointer type for convenience.
Represents a duration.
Definition Duration.h:17
The CapturingPointCloudProvider provides a callback function to trigger the capturing of point clouds...
ImageProvider abstract class defines a component which provide images via ice or shared memory.
void onNewSkeletonData(tdv::nuitrack::SkeletonData::Ptr skeletonData)
void onInitComponent() override
Pure virtual hook for the subclass.
void setMaxDepthBodyTracking(int maxDepthInMM, const Ice::Current &=Ice::emptyCurrent) override
bool doCapture() override
Main capturing function.
void enableHumanPoseEstimation(const armarx::EnableHumanPoseEstimationInput &input, const Ice::Current &=Ice::emptyCurrent) override
std::optional< Eigen::Vector3f > computeBodyUpVector(const armarx::armem::human::HumanPose &pose)
void onExitCapturingPointCloudProvider() override
This is called when the Component::onExitComponent() setup is called.
void onDisconnectComponent() override
Hook for subclass.
void onNewColorFrame(tdv::nuitrack::RGBFrame::Ptr frame)
void onStartCapture(float frames_per_second) override
This is called when the point cloud provider capturing has been started.
void filterPosesByUpright(std::vector< armarx::armem::human::HumanPose > &poses, const Eigen::Vector3f &worldUp, float maxAngleDeg)
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void onConnectImageProvider() override
This is called when the Component::onConnectComponent() setup is called.
visionx::StereoCalibration getStereoCalibration(const Ice::Current &c) override
std::string getReferenceFrame(const Ice::Current &c) override
std::function< void(armarx::Duration)> createSwCallback(const std::string &description)
void onInitCapturingPointCloudProvider() override
This is called when the Component::onInitComponent() is called.
MetaPointCloudFormatPtr getDefaultPointCloudFormat() override
default point cloud format used to initialize shared memory
void onConnectComponent() override
Pure virtual hook for the subclass.
void onStopCapture() override
This is called when the point cloud provider capturing has been stopped.
bool getImagesAreUndistorted(const ::Ice::Current &c) override
std::vector< imrec::ChannelPreferences > getImageRecordingChannelPreferences(const Ice::Current &) override
void onInitImageProvider() override
This is called when the Component::onInitComponent() is called.
void setWidthBodyTracking(int minXinPixel, int maxXinPixel, const Ice::Current &=Ice::emptyCurrent) override
void onExitComponent() override
Hook for subclass.
void onExitImageProvider() override
This is called when the Component::onExitComponent() setup is called.
bool hasSharedMemorySupport(const Ice::Current &c) override
void onNewDepthFrame(tdv::nuitrack::DepthFrame::Ptr frame)
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
std::shared_ptr< class Robot > RobotPtr
Definition Bus.h:19
client::plugins::PluginUser ClientPluginUser
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
ArmarX headers.
std::unique_ptr< CByteImage > CByteImageUPtr