Skip to content

Commit

Permalink
Add davidSDK documentation & tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorLamoine committed May 1, 2015
1 parent f1b3ca4 commit 6bb13e8
Show file tree
Hide file tree
Showing 7 changed files with 265 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/doxygen/doxyfile.in
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ INCLUDE_FILE_PATTERNS = *.h
PREDEFINED = = "HAVE_QHULL=1" \
"HAVE_OPENNI=1" \
"HAVE_ENSENSO=1" \
"HAVE_DAVIDSDK=1" \
"PCL_DEPRECATED(x)="
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
Expand Down
121 changes: 121 additions & 0 deletions doc/tutorials/content/davidsdk.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
.. _david_sdk:

=====================================================
Grabbing point clouds / meshes from davidSDK scanners
=====================================================

In this tutorial we will learn how to use the `davidSDK <http://www.david-3d.com/en/products/david-sdk>`_ through PCL. This tutorial will show you how to configure PCL and how to use the examples to fetch point clouds/meshes/images from a davidSDK compliant device (such as the `SLS-2 <http://www.david-3d.com/en/products/sls-2>`_).

.. contents::

Install davidSDK
================

You need a davidSDK to run the SDK on the server side, the official davidSDK does not come with a Makefile or a CMake project. An un-official fork provides a CMake project that enables to easily use the SDK under Linux (with minor tweaks)

* `Official davidSDK download page <http://www.david-3d.com/en/support/downloads>`_
* `Victor Lamoine davidSDK fork <https://github.com/VictorLamoine/davidSDK>`_

Please test `the example project <https://github.com/VictorLamoine/davidSDK/blob/master/README.md#example-project-using-the-davidsdk>`_ before going further.

.. note:: If you use the trial version of the server, the only format available is OBJ (used by default)

Configuring PCL
===============

You need at least PCL 1.8.0 to be able to use the davidSDK. You need to make sure ``WITH_DAVIDSDK`` is set to ``true`` in the CMake configuration (it should be set to true by default if you have used the un-official davidSDK fork).

The default following values can be tweaked into CMake if you don't have a standard installation, for example:

.. code-block:: cmake
DAVIDSDK_ABI_DIR /opt/davidsdk
You can deactivate building the davidSDK support by setting ``BUILD_DAVIDSDK`` to false. Compile and install PCL.

Platform specific directives
============================

It should be easy to use the davidSDK PCL support if you are using PCL on the davidSDK server; the meshes are locally exported on the storage drive and then loaded into PCL as point clouds/meshes. If you are using a Linux distribution you will need to configure more things for the davidSDK PCL implementation to work, create a temporary directory for the davidSDK meshes storage:

.. code-block:: bash
mkdir -p /var/tmp/davidsdk
sudo chmod 755 /var/tmp/davidsdk
Edit samba configuration (samba must be installed first):

.. code-block:: bash
echo -e "[davidsdk]\n\
path = /var/tmp/davidsdk\n\
public = yes\n\
writeable = yes\n\
browseable = yes\n\
guest ok = yes\n\
create mask = 0775" |\
sudo tee -a /etc/samba/smb.conf
Restard samba server:
.. code-block:: bash
sudo service smbd restart
Use the :pcl:`setLocalAndRemotePaths <pcl::DavidSDKGrabber::setLocalAndRemotePaths>` function to set the local and remote paths, if you use the same path as above; this doesn't have to be called if the server is running of the same machine as the client.

.. code-block:: cpp
davidsdk_ptr->setLocalAndRemotePaths ("/var/tmp/davidsdk/", "\\\\name_of_machine\\davidsdk\\");
.. note::

If you get a Error_Fail = -107 error, it is most probably a write access missing in the temporary directory.

File formats
============

Three file formats are available to export the meshes / clouds.

* STL: No texture support, binary format
* OBJ: Texture support, no binary format available
* PLY: Texture support, binary format is available but davidSDK uses ASCII format

Use the :pcl:`setFileFormatToOBJ <pcl::DavidSDKGrabber::setFileFormatToOBJ>`,
:pcl:`setFileFormatToPLY <pcl::DavidSDKGrabber::setFileFormatToPLY>`,
:pcl:`setFileFormatToSTL <pcl::DavidSDKGrabber::setFileFormatToSTL>` to choose between the different formats.

The default format used is OBJ. (it is compatible with davidSDK server trial version)

Calibration
===========

In order to use the davidSDK scanner the camera and the projector must be calibrated. This can be done by calling the :pcl:`calibrate <pcl::DavidSDKGrabber::calibrate>` function of the DavidSDKGrabber object, if the calibration fails, please check `the wiki <http://wiki.david-3d.com/david-wiki>`_.

The davidSDK will only allow you to scan if the scanner is calibrated, the davidSDK provides functions to load and save configuration files for the calibration. Also note that the davidSDK server will automatically reload the last calibration data when restarted.

Using the example
==================

The `pcl_davidsdk_viewer <https://github.com/PointCloudLibrary/pcl/blob/master/visualization/tools/davidsdk_viewer.cpp>`_ example shows how to display a point cloud grabbed from an davidSDK device using the :pcl:`DavidSDKGrabber <pcl::DavidSDKGrabber>` class.

When using the DavidSDKGrabber you must connect to the server first; if the server is running locally you don't need to specify an IP address. If you are using davidSDK over a network just call :pcl:`connect <pcl::DavidSDKGrabber::connect>` with the address IP as a string, please also check that the connection didn't failed:

.. code-block:: cpp
davidsdk_ptr->connect ("192.168.1.50");
if (!davidsdk_ptr->isConnected ())
{
PCL_ERROR ("Cannot connect to davidSDK server.\n");
return (-1);
}
.. image:: images/davidsdk/davidsdk_viewer.jpg
:height: 550

.. warning::

Fetching clouds/meshes from the davidSDK is very slow because the point clouds/meshes are sent through the JSON interface.
Do not expect better performance than 0.07 FPS (using STL format gives best performance).

Another example is available in `PCL sources <https://github.com/PointCloudLibrary/pcl/blob/master/doc/tutorials/content/sources/davidsdk/>`_, it uses OpenCV to display davidSDK images and the PCLVisualizer to display the point cloud at the same time.

Binary file added doc/tutorials/content/images/davidsdk/david.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions doc/tutorials/content/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,20 @@ I/O
.. |i_o7| image:: images/ensenso/ids.png
:height: 165px

* :ref:`david_sdk`

====== ======
|i_o8| Title: **Grabbing point clouds / meshes from davidSDK scanners**

Author: *Victor Lamoine*

Compatibility: >= PCL 1.8.0

In this tutorial, we will learn how to acquire point cloud or mesh data from an davidSDK scanner.
====== ======

.. |i_o8| image:: images/davidsdk/david.png
:height: 70px

.. _keypoints_tutorial:

Expand Down
13 changes: 13 additions & 0 deletions doc/tutorials/content/sources/davidsdk/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(pcl-davidSDK_images_viewer)

find_package(PCL 1.8.0 REQUIRED)
find_package(OpenCV REQUIRED)

include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable(davidsdk_images_viewer davidsdk_images_viewer.cpp)
target_link_libraries(davidsdk_images_viewer ${PCL_LIBRARIES} ${OpenCV_LIBS})
116 changes: 116 additions & 0 deletions doc/tutorials/content/sources/davidsdk/davidsdk_images_viewer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#include <iostream>
#include <pcl/io/davidsdk_grabber.h>
#include <pcl/console/print.h>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

/** @brief A pointer to the PCL DavidSDKGrabber object */
pcl::DavidSDKGrabber::Ptr davidsdk_ptr;

/** @brief Get OpenCV image type corresponding to the parameters given
* @param channels number of channels in the image
* @param bpe bytes per element
* @param isFlt is float
* @returns the OpenCV type
*/
int
getOpenCVType (std::string type)
{
if (type == "CV_32FC1")
return CV_32FC1;
else if (type == "CV_32FC2")
return CV_32FC2;
else if (type == "CV_32FC3")
return CV_32FC3;
else if (type == "CV_32FC4")
return CV_32FC4;
else if (type == "CV_64FC1")
return CV_64FC1;
else if (type == "CV_64FC2")
return CV_64FC2;
else if (type == "CV_64FC3")
return CV_64FC3;
else if (type == "CV_64FC4")
return CV_64FC4;
else if (type == "CV_8UC1")
return CV_8UC1;
else if (type == "CV_8UC2")
return CV_8UC2;
else if (type == "CV_8UC3")
return CV_8UC3;
else if (type == "CV_8UC4")
return CV_8UC4;
else if (type == "CV_16UC1")
return CV_16UC1;
else if (type == "CV_16UC2")
return CV_16UC2;
else if (type == "CV_16UC3")
return CV_16UC3;
else if (type == "CV_16UC4")
return CV_16UC4;
else if (type == "CV_32SC1")
return CV_32SC1;
else if (type == "CV_32SC2")
return CV_32SC2;
else if (type == "CV_32SC3")
return CV_32SC3;
else if (type == "CV_32SC4")
return CV_32SC4;

return (-1);
}

/** @brief Process and/or display DavidSDKGrabber image
* @param[in] image davidSDK image */
void
grabberCallback (const boost::shared_ptr<pcl::PCLImage>& image)
{
unsigned char *image_array = reinterpret_cast<unsigned char *> (&image->data[0]);

int type = getOpenCVType (image->encoding);
cv::Mat cv_image (image->height, image->width, type, image_array);

cv::imshow ("davidSDK images", cv_image);
cv::waitKey (5);
}

/** @brief Asks the user to press enter to continue
* @param[in] str Message to display */
void
waitForUser (std::string str = "Press enter to continue")
{
PCL_WARN (str.c_str ());
std::cout.flush ();
getc (stdin);
}

/** @brief Main function
* @param argc
* @param argv
* @return Exit status */
int
main (int argc,
char *argv[])
{
if (argc != 2)
{
PCL_ERROR ("Usage:\n%s 192.168.100.65\n", argv[0]);
return (-1);
}

davidsdk_ptr.reset (new pcl::DavidSDKGrabber);
davidsdk_ptr->connect (argv[1]);

if (!davidsdk_ptr->isConnected ())
return (-1);
PCL_WARN ("davidSDK connected\n");

boost::function<void
(const boost::shared_ptr<pcl::PCLImage> &)> f = boost::bind (&grabberCallback, _1);
davidsdk_ptr->registerCallback (f);
davidsdk_ptr->start ();
waitForUser ("Press enter to quit");

return (0);
}

0 comments on commit 6bb13e8

Please sign in to comment.