diff --git a/CMakeLists.txt b/CMakeLists.txt
index 01e26c1d..b5c0aa66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -164,6 +164,7 @@ SET(rtabmap_ros_lib_src
src/nodelets/obstacles_detection.cpp
src/nodelets/obstacles_detection_old.cpp
src/nodelets/point_cloud_aggregator.cpp
+ src/nodelets/undistort_depth.cpp
src/nodelets/rgbd_sync.cpp
src/OdometryROS.cpp
src/MsgConversion.cpp
diff --git a/launch/calibration/distortion_model_PS1080.bin b/launch/calibration/distortion_model_PS1080.bin
new file mode 100644
index 00000000..54ee5d35
Binary files /dev/null and b/launch/calibration/distortion_model_PS1080.bin differ
diff --git a/launch/calibration/distortion_model_PS1080.png b/launch/calibration/distortion_model_PS1080.png
new file mode 100644
index 00000000..3c9ab89c
Binary files /dev/null and b/launch/calibration/distortion_model_PS1080.png differ
diff --git a/launch/tests/test_undistort_depth.launch b/launch/tests/test_undistort_depth.launch
new file mode 100644
index 00000000..45382886
--- /dev/null
+++ b/launch/tests/test_undistort_depth.launch
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nodelet_plugins.xml b/nodelet_plugins.xml
index e440f931..98b339b2 100644
--- a/nodelet_plugins.xml
+++ b/nodelet_plugins.xml
@@ -119,6 +119,14 @@
This is my nodelet.
+
+
+
+ This is my nodelet.
+
+
diff --git a/src/nodelets/undistort_depth.cpp b/src/nodelets/undistort_depth.cpp
new file mode 100644
index 00000000..c64c7e1a
--- /dev/null
+++ b/src/nodelets/undistort_depth.cpp
@@ -0,0 +1,123 @@
+/*
+Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Universite de Sherbrooke nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "rtabmap/core/clams/discrete_depth_distortion_model.h"
+#include "rtabmap/utilite/UConversion.h"
+
+namespace rtabmap_ros
+{
+
+class UndistortDepth : public nodelet::Nodelet
+{
+public:
+ UndistortDepth()
+ {}
+
+ virtual ~UndistortDepth()
+ {
+ }
+
+private:
+ virtual void onInit()
+ {
+ ros::NodeHandle & nh = getNodeHandle();
+ ros::NodeHandle & pnh = getPrivateNodeHandle();
+
+ int queueSize = 10;
+ std::string modelPath;
+ pnh.param("queue_size", queueSize, queueSize);
+ pnh.param("model", modelPath, modelPath);
+
+ if(modelPath.empty())
+ {
+ NODELET_ERROR("undistort_depth: \"model\" parameter should be set!");
+ }
+
+ model_.load(modelPath);
+ if(!model_.isValid())
+ {
+ NODELET_ERROR("Loaded distortion model from \"%s\" is not valid!", modelPath.c_str());
+ }
+ else
+ {
+ image_transport::ImageTransport it(nh);
+ sub_ = it.subscribe("depth", queueSize, &UndistortDepth::callback, this);
+ pub_ = it.advertise(uFormat("%s_undistorted", nh.resolveName("depth").c_str()), 1);
+ }
+ }
+
+ void callback(const sensor_msgs::ImageConstPtr& depth)
+ {
+ if(depth->encoding.compare(sensor_msgs::image_encodings::TYPE_16UC1)!=0 &&
+ depth->encoding.compare(sensor_msgs::image_encodings::TYPE_32FC1)!=0 &&
+ depth->encoding.compare(sensor_msgs::image_encodings::MONO16)!=0)
+ {
+ NODELET_ERROR("Input type depth=32FC1,16UC1,MONO16");
+ return;
+ }
+
+ if(pub_.getNumSubscribers())
+ {
+ if(depth->width == model_.getWidth() && depth->width == model_.getWidth())
+ {
+ cv_bridge::CvImagePtr imageDepthPtr = cv_bridge::toCvCopy(depth);
+ model_.undistort(imageDepthPtr->image);
+ pub_.publish(imageDepthPtr->toImageMsg());
+ }
+ else
+ {
+ NODELET_ERROR("Input depth image size (%dx%d) and distortion model "
+ "size (%dx%d) don't match! Cannot undistort image.",
+ depth->width, depth->height,
+ model_.getWidth(), model_.getHeight());
+ }
+ }
+ }
+
+private:
+ clams::DiscreteDepthDistortionModel model_;
+ image_transport::Publisher pub_;
+ image_transport::Subscriber sub_;
+};
+
+PLUGINLIB_EXPORT_CLASS(rtabmap_ros::UndistortDepth, nodelet::Nodelet);
+}
+