30#include <opencv2/opencv.hpp>
32#include <SimoxUtility/algorithm/string/string_tools.h>
47#include <Calibration/Calibration.h>
48#include <Image/ByteImage.h>
49#include <Image/ImageProcessor.h>
63 "VisionX/examples/point_clouds/",
64 "The point cloud to read. If directory, all *.pcd files of this and all subdirectories "
66 "All point clouds are read in before the pointcloud providing starts.");
70 "scaleFactor", -1.0f,
"scale point cloud. only applied if value is larger than zero");
72 .map(
"320x240", Eigen::Vector2i(320, 240))
73 .map(
"640x480", Eigen::Vector2i(640, 480))
74 .map(
"320x240", Eigen::Vector2i(320, 240))
75 .map(
"640x480", Eigen::Vector2i(640, 480))
76 .map(
"800x600", Eigen::Vector2i(800, 600))
77 .map(
"768x576", Eigen::Vector2i(768, 576))
78 .map(
"1024x768", Eigen::Vector2i(1024, 768))
79 .map(
"1024x1024", Eigen::Vector2i(1024, 1024))
80 .map(
"1280x960", Eigen::Vector2i(1280, 960))
81 .map(
"1600x1200", Eigen::Vector2i(1600, 1200));
84 "depthCameraCalibrationFile",
"",
"Camera depth calibration file (YAML)");
86 "RGBCameraCalibrationFile",
"",
"Camera RGB calibration file (YAML)");
89 "sourceFrameName",
"",
"Assume point cloud was stored in this frame.");
93 "Coordinate frame in which point cloud will be transformed and provided.\n"
94 "If left empty, no transformation will be applied and source frame name\n"
95 "will be returned as reference frame.");
98 "RobotStateComponent",
99 "Name of the robot state component to use.");
102 "ProvidedPointCloudFormat",
104 "Format of the provided point cloud (XYZRGBA, XYZL, XYZRGBL)");
116 return "FakePointCloudProvider";
158 getProperty(pointCloudFileName,
"pointCloudFileName");
164 getProperty(providedPointCloudFormat,
"ProvidedPointCloudFormat");
165 ARMARX_INFO <<
"Providing point clouds in format " << providedPointCloudFormat <<
".";
167 getProperty(robotStateComponentName,
"RobotStateComponentName");
168 if (!robotStateComponentName.empty())
174 if (!(sourceFrameName.empty() && targetFrameName.empty()))
176 if (!sourceFrameName.empty() && !targetFrameName.empty() &&
177 robotStateComponentName.empty())
179 ARMARX_ERROR <<
"Source and target frames specified, but no RobotStateComponent is "
181 "No transformation will be applied.";
183 else if (sourceFrameName.empty() && !targetFrameName.empty())
185 ARMARX_WARNING <<
"Target frame was specified (" << targetFrameName
186 <<
"), but no source frame is specified.\n"
187 <<
"Did you set the property `sourceFrameName`? (No transformation "
190 else if (!sourceFrameName.empty() && targetFrameName.empty())
192 ARMARX_INFO <<
"Source frame was specified (" << sourceFrameName
193 <<
"), but no target frame is specified.\n"
194 <<
"No transformation will be applied and source frame is returned as "
202 ARMARX_ERROR <<
"Could not find point cloud file in ArmarXDataPath: "
203 << pointCloudFileName;
207 if (std::filesystem::is_directory(pointCloudFileName))
209 loadPointCloudDirectory(pointCloudFileName);
213 loadPointCloud(pointCloudFileName);
216 if (pointClouds.empty())
218 ARMARX_FATAL <<
"Unable to load point cloud: " << pointCloudFileName;
219 throw LocalException(
"Unable to load point cloud");
222 ARMARX_INFO <<
"Loaded " << pointClouds.size() <<
" point clouds.";
225 visionx::CameraParameters RGBCameraIntrinsics;
226 RGBCameraIntrinsics.focalLength.resize(2);
227 RGBCameraIntrinsics.principalPoint.resize(2);
231 RGBCameraIntrinsics))
235 <<
" - using camera uncalibrated";
238 visionx::CameraParameters depthCameraIntrinsics;
239 depthCameraIntrinsics.focalLength.resize(2);
240 depthCameraIntrinsics.principalPoint.resize(2);
244 depthCameraIntrinsics))
248 <<
" - using camera uncalibrated";
253 calibration.calibrationLeft.cameraParam = RGBCameraIntrinsics;
254 calibration.calibrationRight.cameraParam = depthCameraIntrinsics;
258 FakePointCloudProvider::loadPointCloud(
const std::string& fileName)
260 if (simox::alg::ends_with(fileName,
".pcd") && std::filesystem::is_regular_file(fileName))
262 pcl::PCLPointCloud2Ptr cloudptr(
new pcl::PCLPointCloud2());
265 if (io::loadPCDFile(fileName.c_str(), *cloudptr) == -1)
267 ARMARX_WARNING <<
"Unable to load point cloud from file " << fileName;
272 pointClouds.push_back(cloudptr);
281 FakePointCloudProvider::loadPointCloudDirectory(
const std::string& directoryName)
284 std::vector<std::string> fileNames;
286 for (std::filesystem::recursive_directory_iterator dir(directoryName), end;
287 dir != end &&
getState() < eManagedIceObjectExiting;
291 if (dir->path().extension() ==
".pcd")
293 fileNames.push_back(dir->path().string());
297 ARMARX_INFO <<
"In total " << fileNames.size() <<
" point clouds found.";
300 std::sort(fileNames.begin(), fileNames.end());
302 for (std::size_t f = 0; f < fileNames.size(); f++)
304 ARMARX_INFO <<
" File " << f <<
" / " << fileNames.size() <<
" is being loaded... "
308 loadPointCloud(fileNames[f]);
326 MetaPointCloudFormatPtr
329 MetaPointCloudFormatPtr format =
new MetaPointCloudFormat();
331 if (providedPointCloudFormat ==
"XYZL")
333 format->type = PointContentType::eLabeledPoints;
335 else if (providedPointCloudFormat ==
"XYZRGBL")
337 format->type = PointContentType::eColoredLabeledPoints;
341 format->type = PointContentType::eColoredPoints;
346 format->size = format->capacity;
354 setImageFormat(visionx::ImageDimension(dimensions(0), dimensions(1)), visionx::eRgb);
356 rgbImages =
new CByteImage*[1];
357 rgbImages[0] =
new CByteImage(dimensions(0), dimensions(1), CByteImage::eRGB24);
358 ::ImageProcessor::Zero(rgbImages[0]);
367 if (!robotStateComponentName.empty())
369 getProxy(robotStateComponent, robotStateComponentName);
370 if (!robotStateComponent)
372 ARMARX_ERROR <<
"Failed to obtain robot state component.";
388 pcl::PCLPointCloud2Ptr cloudptr;
391 std::scoped_lock lock(pointCloudMutex);
393 if (rewind &&
static_cast<size_t>(counter.load()) >= pointClouds.size())
398 cloudptr = pointClouds.at(counter);
402 if (providedPointCloudFormat ==
"XYZRGBA")
404 return processAndProvide<pcl::PointXYZRGBA>(cloudptr);
406 else if (providedPointCloudFormat ==
"XYZL")
408 return processAndProvide<pcl::PointXYZL>(cloudptr);
410 else if (providedPointCloudFormat ==
"XYZRGBL")
412 return processAndProvide<pcl::PointXYZRGBL>(cloudptr);
416 ARMARX_ERROR <<
"Could not provide point cloud, because format '"
417 << providedPointCloudFormat <<
"' is unknown";
423 FakePointCloudProvider::loadCalibrationFile(std::string fileName,
424 visionx::CameraParameters& calibration)
427 cv::FileStorage fs(fileName, cv::FileStorage::READ);
434 std::string cameraName = fs[
"camera_name"];
435 ARMARX_LOG <<
"loading calibration file for " << cameraName;
439 int imageWidth = fs[
"image_width"];
440 int imageHeight = fs[
"image_height"];
442 if (imageWidth != dimensions(0) || imageHeight != dimensions(1))
448 cv::Mat cameraMatrix, distCoeffs;
450 fs[
"camera_matrix"] >> cameraMatrix;
451 fs[
"distortion_coefficients:"] >> distCoeffs;
453 for (
int i = 0; i < 5; i++)
455 calibration.distortion[
static_cast<std::size_t
>(i)] = distCoeffs.at<
float>(0, i);
458 calibration.focalLength[0] = cameraMatrix.at<
float>(0, 0);
459 calibration.focalLength[1] = cameraMatrix.at<
float>(1, 1);
461 calibration.principalPoint[0] = cameraMatrix.at<
float>(2, 1);
462 calibration.principalPoint[1] = cameraMatrix.at<
float>(2, 2);
477 std::scoped_lock lock(pointCloudMutex);
479 ARMARX_INFO <<
"Changing point cloud filename to: " << filename;
482 loadPointCloud(filename);
491 template <
typename Po
intT>
493 FakePointCloudProvider::processAndProvide(
const PCLPointCloud2Ptr& pointCloud)
495 using PointCloudPtrT =
typename pcl::PointCloud<PointT>::Ptr;
497 PointCloudPtrT cloudptr(
new pcl::PointCloud<PointT>());
498 pcl::fromPCLPointCloud2(*pointCloud, *cloudptr);
500 if (cloudptr->isOrganized())
502 processRGBImage(pointCloud);
505 PointCloudPtrT resultCloudPtr(
new pcl::PointCloud<PointT>());
509 Eigen::Affine3f
transform(Eigen::Scaling(scaleFactor));
510 pcl::transformPointCloud(*cloudptr, *resultCloudPtr,
transform);
515 pcl::copyPointCloud(*cloudptr, *resultCloudPtr);
519 resultCloudPtr->header.stamp =
static_cast<uint64_t
>(time.toMicroSeconds());
521 if (!sourceFrameName.empty() || !targetFrameName.empty())
523 if (!sourceFrameName.empty() && !targetFrameName.empty())
529 localRobot, robotStateComponent, time.toMicroSeconds());
531 framedPointCloud.
changeFrame(targetFrameName, localRobot);
540 else if (sourceFrameName.empty())
546 else if (targetFrameName.empty())
557 std::vector<int> indices;
558 pcl::removeNaNFromPointCloud(*resultCloudPtr, *resultCloudPtr, indices);
562 << resultCloudPtr->points.size();
568 counter = freezeImageIdx.load();
578 FakePointCloudProvider::processRGBImage(
const PCLPointCloud2Ptr& pointCloud)
580 pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudptr(
new pcl::PointCloud<pcl::PointXYZRGB>());
581 pcl::fromPCLPointCloud2(*pointCloud, *cloudptr);
583 if (!cloudptr->isOrganized())
586 <<
"The point cloud is not organized, so no RGB image is generated";
590 if (
static_cast<int>(cloudptr->width) != rgbImages[0]->width ||
591 static_cast<int>(cloudptr->height) != rgbImages[0]->height)
594 <<
"Dimensions of point cloud and image do not match, so no RGB image is generated";
598 ::ImageProcessor::Zero(rgbImages[0]);
599 const int width =
static_cast<int>(cloudptr->width);
600 const int height =
static_cast<int>(cloudptr->height);
602 for (
int i = 0; i < height; i++)
604 for (
int j = 0; j < width; j++)
606 pcl::PointXYZRGB& point = cloudptr->at(
static_cast<std::size_t
>(i * width + j));
607 rgbImages[0]->pixels[3 * (i * width + j) + 0] = point.r;
608 rgbImages[0]->pixels[3 * (i * width + j) + 1] = point.g;
609 rgbImages[0]->pixels[3 * (i * width + j) + 2] = point.b;
619 for (std::size_t i = 0; i < 1; i++)
642 return !targetFrameName.empty() ? targetFrameName : sourceFrameName;
646 FakePointCloudProvider::buildGui()
665 .
addTextLabel(
" / " + std::to_string(pointClouds.size() - 1));
674 prx.
getValue(removeNAN,
"removeNAN");
675 prx.
getValue(scaleFactor,
"scaleFactor");
676 prx.
getValue(freezeImage,
"freezeImage");
679 prx.
getValue(freezeImageIdx,
"freezeImageIdx");
683 prx.
setValue(counter,
"freezeImageIdx");
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
static bool getAbsolutePath(const std::string &relativeFilename, std::string &storeAbsoluteFilename, const std::vector< std::string > &additionalSearchPaths={}, bool verbose=true)
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Property< PropertyType > getProperty(const std::string &name)
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.
virtual void onExitComponent()
Hook for subclass.
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
virtual void onDisconnectComponent()
Hook for subclass.
virtual void onConnectComponent()=0
Pure virtual hook for the subclass.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
virtual void onInitComponent()=0
Pure virtual hook for the subclass.
int getState() const
Retrieve current state of the ManagedIceObject.
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
void createOrUpdateRemoteGuiTab(Ts &&... ts)
void setValue(const T &val, std::string const &name)
ValueProxy< T > getValue(std::string const &name)
VirtualRobot::RobotPtr createLocalClone()
Clones the structure of this remote robot to a local instance.
static bool synchronizeLocalCloneToTimestamp(VirtualRobot::RobotPtr robot, RobotStateComponentInterfacePrx robotStatePrx, Ice::Long timestamp)
Synchronizes a local robot to a robot state at timestamp.
static IceUtil::Time GetTime(TimeMode timeMode=TimeMode::VirtualTime)
Get the current time.
CapturingPointCloudProviderPropertyDefinitions(std::string prefix)
FakePointCloudProviderPropertyDefinitions(std::string prefix)
void onInitComponent() override
Pure virtual hook for the subclass.
bool doCapture() override
void onExitCapturingPointCloudProvider() override
bool hasSharedMemorySupport(const Ice::Current &=Ice::emptyCurrent) override
void onDisconnectComponent() override
Hook for subclass.
bool getImagesAreUndistorted(const Ice::Current &=Ice::emptyCurrent) override
void onStartCapture(float frameRate) override
std::string getReferenceFrame(const Ice::Current &=Ice::emptyCurrent) override
void onInitCapturingPointCloudProvider() override
MetaPointCloudFormatPtr getDefaultPointCloudFormat() override
default point cloud format used to initialize shared memory
void onConnectComponent() override
Pure virtual hook for the subclass.
void onStopCapture() override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
static std::string GetDefaultName()
void onInitImageProvider() override
void setPointCloudFilename(const std::string &filename, const ::Ice::Current &=Ice::emptyCurrent) override
void onExitComponent() override
Hook for subclass.
void onExitImageProvider() override
StereoCalibration getStereoCalibration(const Ice::Current &=Ice::emptyCurrent) override
std::string getDefaultName() const override
A point cloud which keeps track of its reference coordinate frame and allows changing frames using ar...
void changeFrame(const std::string &newFrame, const VirtualRobot::RobotConstPtr &robot)
Transform the point cloud from the current frame to the new frame using the given reference robot.
void onInitComponent() override
void onDisconnectComponent() override
Hook for subclass.
void setImageFormat(ImageDimension imageDimension, ImageType imageType, BayerPatternType bayerPatternType=visionx::eBayerPatternRg)
Sets the image basic format data.
void provideImages(void **inputBuffers, const IceUtil::Time &imageTimestamp=IceUtil::Time())
send images raw.
void onConnectComponent() override
void setNumberImages(int numberImages)
Sets the number of images on each capture.
void onExitComponent() override
void providePointCloud(PointCloudPtrT pointCloudPtr)
offer the new point cloud.
#define ARMARX_INFO
The normal logging level.
#define ARMARX_FATAL
The logging level for unexpected behaviour, that will lead to a seriously malfunctioning program and ...
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
#define ARMARX_VERBOSE
The logging level for verbose information.
std::string const GlobalFrame
Variable of the global coordinate system.
detail::IntSpinBoxBuilder makeIntSpinBox(std::string const &name)
detail::CheckBoxBuilder makeCheckBox(std::string const &name)
detail::FloatSpinBoxBuilder makeFloatSpinBox(std::string const &name)
detail::SimpleGridLayoutBuilder makeSimpleGridLayout(std::string const &name="")
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::string GetHandledExceptionString()
auto transform(const Container< InputT, Alloc > &in, OutputT(*func)(InputT const &)) -> Container< OutputT, typename std::allocator_traits< Alloc >::template rebind_alloc< OutputT > >
Convenience function (with less typing) to transform a container of type InputT into the same contain...
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
SimpleGridLayoutBuilder & addTextLabel(std::string const &text, int colspan)
SimpleGridLayoutBuilder & cols(int n)
SimpleGridLayoutBuilder & addChild(WidgetPtr const &child, int colspan)