MultiViewPointCloudProcessor.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::MultiViewPointCloudProcessor
17  * @author Raphael Grimm ( raphael dot grimm 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 <pcl/filters/approximate_voxel_grid.h>
24 #include <pcl/common/transforms.h>
25 
27 
29 
30 #include <VisionX/interface/components/Calibration.h>
31 #include <VisionX/interface/core/PointCloudProcessorInterface.h>
32 
34 
35 #define call_template_function(F) \
36  switch(_pointCloudProviderInfo.pointCloudFormat->type) \
37  { \
38  case visionx::PointContentType::ePoints : F<pcl::PointXYZ>(); break; \
39  case visionx::PointContentType::eColoredPoints : F<pcl::PointXYZRGBA>(); break; \
40  case visionx::PointContentType::eColoredOrientedPoints : F<pcl::PointXYZRGBNormal>(); break; \
41  case visionx::PointContentType::eLabeledPoints : F<pcl::PointXYZL>(); break; \
42  case visionx::PointContentType::eColoredLabeledPoints : F<pcl::PointXYZRGBL>(); break; \
43  case visionx::PointContentType::eIntensity : F<pcl::PointXYZI>(); break; \
44  case visionx::PointContentType::eOrientedPoints : \
45  ARMARX_ERROR << "eOrientedPoints NOT HANDLED IN VISIONX"; \
46  [[fallthrough]]; default: \
47  ARMARX_ERROR << "Could not call " #F ", because format '" \
48  << _pointCloudProviderInfo.pointCloudFormat->type << "' is unknown"; \
49  } do{}while(false)
50 
51 //common
52 namespace armarx
53 {
55  {
56  return "MultiViewPointCloudProcessor";
57  }
59  {
61  prop->defineOptionalProperty<std::string>("ProviderReferenceFrame", "", "Name of the point cloud refence frame (empty = autodetect)");
62  std::lock_guard guard{_cfgBufWriteMutex};
63  prop->optional(_cfgBuf.getWriteBuffer(), "", "");
64  return prop;
65  }
66 }
67 //gui
68 namespace armarx
69 {
71  {
72  std::lock_guard guard{_cfgBufWriteMutex};
76  .addChild(RemoteGui::makeButton("start"))
77  .addChild(RemoteGui::makeButton("stop"))
78  .addChild(RemoteGui::makeButton("clear"))
79  .addHSpacer()
80  );
81  }
82 
84  {
85  prx.receiveUpdates();
86  std::lock_guard guard{_cfgBufWriteMutex};
87 
88  prx.getValue(_cfgBuf.getWriteBuffer(), "cfg");
89  if (prx.getButtonClicked("start"))
90  {
92  }
93  if (prx.getButtonClicked("stop"))
94  {
96  }
97  if (prx.getButtonClicked("clear"))
98  {
100  }
101  prx.sendUpdates();
102  _cfgBuf.commitWrite();
103  }
104 }
105 //hooks
106 namespace armarx
107 {
109  {
110  _pointCloudProviderName = getProperty<std::string>("ProviderName");
111  usingPointCloudProvider(_pointCloudProviderName);
112  }
113 
115  {
116  //provider
117  {
118  _pointCloudProviderInfo = getPointCloudProvider(_pointCloudProviderName, true);
119  _pointCloudProvider = _pointCloudProviderInfo.proxy;
120  _pointCloudProviderRefFrame = getProperty<std::string>("ProviderReferenceFrame");
121  if (_pointCloudProviderRefFrame.empty())
122  {
123  _pointCloudProviderRefFrame = "root";
124  auto frameprov = visionx::ReferenceFrameInterfacePrx::checkedCast(_pointCloudProvider);
125  if (frameprov)
126  {
127  _pointCloudProviderRefFrame = frameprov->getReferenceFrame();
128  }
129  }
130  ARMARX_INFO << VAROUT(_pointCloudProviderRefFrame);
131 
132  if (!_providerThread.joinable())
133  {
134  //result cloud of point type
136  _providerThread = std::thread
137  {
138  [&]{
140  }
141  };
142  }
143  }
144  //robot
145  {
146  _robot = addRobot("_robot", VirtualRobot::RobotIO::eStructure);
147  }
148  //gui
150  {
151  processGui(prx);
152  });
153  }
154 
156  {
157  _stopProviding = true;
158  _providerThread.join();
159  }
160 }
161 //Ice methods
162 namespace armarx
163 {
165  {
166  ++_currentViewpoint;
167  _doRecord = true;
168  }
170  {
171  _doRecord = false;
172  }
174  {
175  _doClear = true;
176  }
178  {
179  std::lock_guard guard{_cfgBufWriteMutex};
180  _cfgBuf.getWriteBuffer().maxNumberOfFramesPerViewPoint = n;
181  _cfgBuf.commitWrite();
182  }
184  {
185  std::lock_guard guard{_cfgBufWriteMutex};
186  _cfgBuf.getWriteBuffer().gridSize = s;
187  _cfgBuf.commitWrite();
188  }
190  {
191  std::lock_guard guard{_cfgBufWriteMutex};
192  _cfgBuf.getWriteBuffer().frameRate = r;
193  _cfgBuf.commitWrite();
194  }
195 }
196 //process
197 namespace armarx
198 {
200  {
202  }
203 
204  template<class PointType>
206  {
208  {
210  };
211  const auto doRecord = _doRecord.load();
212  if (_doClear)
213  {
214  std::lock_guard guard{_viewPointsMutex};
215  _viewPoints.clear();
216  _currentViewpoint = doRecord ? 0 : -1;
217  _doClear = false;
218  }
219  if (!doRecord)
220  {
221  return;
222  }
223  const auto currentViewpoint = _currentViewpoint.load();
224  ARMARX_CHECK_GREATER_EQUAL(currentViewpoint, 0);
225  using cloud_t = pcl::PointCloud<PointType>;
226  using cloud_ptr_t = typename cloud_t::Ptr;
227 
228  std::unique_lock lock{_cfgBufReadMutex};
229  const auto buf = _cfgBuf.getUpToDateReadBuffer();
230  lock.unlock();
231  setDebugObserverDatafield("cfg", buf);
232  setDebugObserverDatafield("currentViewpoint", currentViewpoint);
233  setDebugObserverDatafield("doRecord", doRecord);
234 
235  //get cloud + transform to global
236  cloud_ptr_t transformedCloud;
237  {
238  if (!waitForPointClouds(_pointCloudProviderName, 100))
239  {
240  ARMARX_INFO << deactivateSpam(10, _pointCloudProviderName)
241  << "Timeout or error while waiting for point cloud data of provider "
242  << _pointCloudProviderName;
243  return;
244  }
245  cloud_ptr_t inputCloud(new cloud_t);
246  getPointClouds(_pointCloudProviderName, inputCloud);
247  synchronizeLocalClone(_robot);
248 
249  const Eigen::Matrix4f providerInRootFrame = [&]() -> Eigen::Matrix4f
250  {
251  FramedPose fp {Eigen::Matrix4f::Identity(), _pointCloudProviderRefFrame, _robot->getName()};
252  fp.changeFrame(_robot, "Global");
253  return fp.toEigen();
254  }();
255 
256  transformedCloud = cloud_ptr_t(new cloud_t);
257  pcl::transformPointCloud(*inputCloud, *transformedCloud, providerInRootFrame);
258  }
259  setDebugObserverDatafield("cloud_size_in", transformedCloud->size());
260  std::lock_guard guard{_viewPointsMutex};
261  const auto p = static_cast<std::size_t>(currentViewpoint);
262  if (p + 1 > _viewPoints.size())
263  {
264  _viewPoints.resize(p + 1);
265  }
266  _viewPoints.at(p).clouds.emplace_back(transformedCloud);
267  if (buf.maxNumberOfFramesPerViewPoint > 0)
268  {
269  while (_viewPoints.at(p).clouds.size() > static_cast<std::size_t>(buf.maxNumberOfFramesPerViewPoint))
270  {
271  _viewPoints.at(p).clouds.pop_front();
272  }
273  }
274  setDebugObserverDatafield("current_view_num_clouds", _viewPoints.at(p).clouds.size());
275  }
276 
277  template<class PointType>
279  {
280  using cloud_t = pcl::PointCloud<PointType>;
281  using cloud_ptr_t = typename cloud_t::Ptr;
282  std::deque<std::uint64_t> idxVec;
283  while (!_stopProviding)
284  {
285  const auto timeBeg = std::chrono::high_resolution_clock::now();
286 
287  std::unique_lock lock{_cfgBufReadMutex};
288  const auto buf = _cfgBuf.getUpToDateReadBuffer();
289  lock.unlock();
290 
291  cloud_ptr_t cloud(new cloud_t);
292  {
293  std::lock_guard guard{_viewPointsMutex};
294  if (idxVec.size() < _viewPoints.size())
295  {
296  idxVec.resize(_viewPoints.size());
297  }
298  for (std::size_t i = 0; i < idxVec.size(); ++i)
299  {
300  const auto& inVec = _viewPoints.at(i).clouds;
301  const auto idx = (idxVec.at(i)++) % inVec.size();
302  const auto& in = *std::any_cast<cloud_ptr_t>(inVec.at(idx));
303  auto& out = cloud->points;
304  out.insert(out.end(), in.begin(), in.end());
305  }
306  }
307  //downsample
308  if (buf.gridSize > 0)
309  {
310  pcl::ApproximateVoxelGrid<PointType> grid;
311  grid.setLeafSize(Eigen::Vector3f::Constant(buf.gridSize));
312  grid.setInputCloud(cloud);
313  cloud_ptr_t tempCloud(new cloud_t);
314  grid.filter(*tempCloud);
315  tempCloud.swap(cloud);
316  }
317  //provide
319 
320  //sleep for frame rate
321  if (frameRate > 0)
322  {
323  const long dtms = 1 / frameRate * 1000;
324  std::this_thread::sleep_until(timeBeg + std::chrono::milliseconds{dtms});
325  }
326  }
327  }
328 }
armarx::RemoteGui::MakeGuiConfig
RemoteGui::WidgetPtr MakeGuiConfig(const std::string &name, const T &val)
Definition: MakeGuiConfig.h:8
armarx::RemoteGui::makeVBoxLayout
detail::VBoxLayoutBuilder makeVBoxLayout(std::string const &name="")
Definition: LayoutWidgets.h:245
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
armarx::MultiViewPointCloudProcessor::onInitPointCloudProcessor
void onInitPointCloudProcessor() override
Setup the vision component.
Definition: MultiViewPointCloudProcessor.cpp:108
armarx::RemoteGui::makeHBoxLayout
detail::HBoxLayoutBuilder makeHBoxLayout(std::string const &name="")
Definition: LayoutWidgets.h:230
OnScopeExit.h
armarx::RemoteGui::makeButton
detail::ButtonBuilder makeButton(std::string const &name)
Definition: IntegerWidgets.h:48
armarx::MultiViewPointCloudProcessor::process
void process() override
Process the vision component.
Definition: MultiViewPointCloudProcessor.cpp:199
armarx::FramedPose
The FramedPose class.
Definition: FramedPose.h:258
armarx::WriteBufferedTripleBuffer::commitWrite
void commitWrite()
Definition: TripleBuffer.h:326
visionx::PointCloudProviderInfo::proxy
PointCloudProviderInterfacePrx proxy
Proxy to PointCloud provider.
Definition: PointCloudProcessor.h:87
armarx::MultiViewPointCloudProcessor::setDownsamplingGridSize
void setDownsamplingGridSize(Ice::Float s, const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:183
ARMARX_ON_SCOPE_EXIT
#define ARMARX_ON_SCOPE_EXIT
Executes given code when the enclosing scope is left.
Definition: OnScopeExit.h:112
armarx::MultiViewPointCloudProcessor::setFrameRate
void setFrameRate(Ice::Float r, const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:189
armarx::RobotStateComponentPluginUser::addRobot
VirtualRobot::RobotPtr addRobot(const std::string &id, const VirtualRobot::RobotPtr &robot, const VirtualRobot::RobotNodeSetPtr &rns={}, const VirtualRobot::RobotNodePtr &node={})
Definition: RobotStateComponentPlugin.cpp:331
armarx::RobotStateComponentPluginUser::synchronizeLocalClone
bool synchronizeLocalClone(const VirtualRobot::RobotPtr &robot) const
Definition: RobotStateComponentPlugin.cpp:371
armarx::MultiViewPointCloudProcessor::onConnectPointCloudProcessor
void onConnectPointCloudProcessor() override
Implement this method in the PointCloudProcessor in order execute parts when the component is fully i...
Definition: MultiViewPointCloudProcessor.cpp:114
armarx::RemoteGui::TabProxy
Definition: WidgetProxy.h:17
armarx::MultiViewPointCloudProcessor::getDefaultName
std::string getDefaultName() const override
Definition: MultiViewPointCloudProcessor.cpp:54
GfxTL::Identity
void Identity(MatrixXX< N, N, T > *a)
Definition: MatrixXX.h:523
armarx::MultiViewPointCloudProcessor::setMaxNumberOfFramesPerViewPoint
void setMaxNumberOfFramesPerViewPoint(Ice::Int n, const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:177
armarx::RemoteGui::TabProxy::receiveUpdates
void receiveUpdates()
Definition: WidgetProxy.h:131
visionx::PointCloudProcessor::provideResultPointClouds
void provideResultPointClouds(const PointCloudPtrT &pointClouds, std::string providerName="")
sends result PointClouds for visualization
Definition: PointCloudProcessor.h:286
armarx::RemoteGui::detail::ChildrenMixin::addChild
Derived & addChild(WidgetPtr const &child)
Definition: LayoutWidgets.h:22
armarx::MultiViewPointCloudProcessor::clearViewPoints
void clearViewPoints(const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:173
FramedPose.h
armarx::MultiViewPointCloudProcessor::startRecordingNextViewPoint
void startRecordingNextViewPoint(const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:164
visionx::PointCloudProcessor::waitForPointClouds
bool waitForPointClouds(int milliseconds=1000)
Wait for new PointClouds.
Definition: PointCloudProcessor.cpp:433
armarx::MultiViewPointCloudProcessor::stopRecordingViewPoint
void stopRecordingViewPoint(const Ice::Current &=Ice::emptyCurrent) override
Definition: MultiViewPointCloudProcessor.cpp:169
armarx::MultiViewPointCloudProcessor::buildGui
RemoteGui::WidgetPtr buildGui()
Definition: MultiViewPointCloudProcessor.cpp:70
armarx::WriteBufferedTripleBuffer::getWriteBuffer
T & getWriteBuffer()
Definition: TripleBuffer.h:280
visionx::PointCloudProcessorPropertyDefinitions
Properties of PointCloudProcessor.
Definition: PointCloudProcessor.h:173
visionx::PointCloudProcessor::getPointClouds
int getPointClouds(const PointCloudPtrT &pointCloudPtr)
Poll PointClouds from provider.
Definition: PointCloudProcessor.h:373
ARMARX_CHECK_GREATER_EQUAL
#define ARMARX_CHECK_GREATER_EQUAL(lhs, rhs)
This macro evaluates whether lhs is greater or equal (>=) rhs and if it turns out to be false it will...
Definition: ExpressionException.h:123
MultiViewPointCloudProcessor.h
visionx::PointCloudProcessor::frameRate
float frameRate
Definition: PointCloudProcessor.h:624
armarx::WidgetDescription::WidgetPtr
::IceInternal::Handle<::armarx::WidgetDescription::Widget > WidgetPtr
Definition: NJointControllerBase.h:66
armarx::RemoteGui::TabProxy::getValue
ValueProxy< T > getValue(std::string const &name)
Definition: WidgetProxy.h:161
armarx::Component::getConfigIdentifier
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition: Component.cpp:74
GfxTL::Matrix4f
MatrixXX< 4, 4, float > Matrix4f
Definition: MatrixXX.h:601
armarx::RemoteGui::TabProxy::getButtonClicked
bool getButtonClicked(std::string const &name)
Definition: WidgetProxy.cpp:11
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
VAROUT
#define VAROUT(x)
Definition: StringHelpers.h:182
armarx::DebugObserverComponentPluginUser::sendDebugObserverBatch
void sendDebugObserverBatch()
Definition: DebugObserverComponentPlugin.cpp:122
IceUtil::Handle< class PropertyDefinitionContainer >
visionx::PointCloudProcessor::usingPointCloudProvider
void usingPointCloudProvider(std::string providerName)
Registers a delayed topic subscription and a delayed provider proxy retrieval which will be available...
Definition: PointCloudProcessor.cpp:261
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:916
armarx::RemoteGui::TabProxy::sendUpdates
void sendUpdates()
Definition: WidgetProxy.h:146
armarx::Logging::deactivateSpam
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:92
visionx::PointCloudProcessor::getPointCloudProvider
PointCloudProviderInfo getPointCloudProvider(std::string name, bool waitForProxy=false)
Select an PointCloudProvider.
Definition: PointCloudProcessor.cpp:304
armarx::MultiViewPointCloudProcessor::onExitPointCloudProcessor
void onExitPointCloudProcessor() override
Exit the ImapeProcessor component.
Definition: MultiViewPointCloudProcessor.cpp:155
armarx::RemoteGuiComponentPluginUser::createOrUpdateRemoteGuiTab
void createOrUpdateRemoteGuiTab(Ts &&...ts)
Definition: RemoteGuiComponentPlugin.h:255
armarx::MultiViewPointCloudProcessor::processGui
void processGui(RemoteGui::TabProxy &prx)
Definition: MultiViewPointCloudProcessor.cpp:83
armarx::MultiViewPointCloudProcessor::doProvide
void doProvide()
Definition: MultiViewPointCloudProcessor.cpp:278
armarx::WriteBufferedTripleBuffer::getUpToDateReadBuffer
const T & getUpToDateReadBuffer() const
Definition: TripleBuffer.h:296
armarx::MultiViewPointCloudProcessor::createPropertyDefinitions
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
Definition: MultiViewPointCloudProcessor.cpp:58
visionx::PointCloudProcessor::enableResultPointClouds
void enableResultPointClouds(std::string resultProviderName="")
Enables visualization.
Definition: PointCloudProcessor.h:240
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
call_template_function
#define call_template_function(F)
Definition: MultiViewPointCloudProcessor.cpp:35
armarx::DebugObserverComponentPluginUser::setDebugObserverDatafield
void setDebugObserverDatafield(Ts &&...ts) const
Definition: DebugObserverComponentPlugin.h:97