diff --git a/VirtualRobot/tests/MathHelpersTest.cpp b/VirtualRobot/tests/MathHelpersTest.cpp
index 426a34e511ca1ce4b520eb40d10c6b062d74ceb5..88ae8bad6ff5614d6944eef07b3b27f92bd35f95 100644
--- a/VirtualRobot/tests/MathHelpersTest.cpp
+++ b/VirtualRobot/tests/MathHelpersTest.cpp
@@ -187,3 +187,99 @@ BOOST_AUTO_TEST_CASE(test_toPose_matrix_and_rotation_matrix)
 
 
 BOOST_AUTO_TEST_SUITE_END()
+
+
+struct OrthogonolizeFixture
+{
+    void test(double angle, const Vector3d& axis, float noiseAmpl, float precAngularDist);
+    Eigen::Matrix3f test(Matrix3f matrix, float noiseAmpl);
+    
+    template <typename Distribution>
+    static Eigen::Matrix3f Random(Distribution& distrib)
+    {
+        static std::default_random_engine gen (42);
+        return Eigen::Matrix3f::NullaryExpr([&](int) { return distrib(gen); });
+    }
+};
+
+
+void OrthogonolizeFixture::test(
+        double angle, const Vector3d& axis, float noiseAmpl, float precAngularDist)
+{
+    // construct matrix with double to avoid rounding errors
+    Eigen::AngleAxisd rot(angle, axis);
+    Eigen::Quaterniond quat(rot);
+    
+    Eigen::Matrix3f matrix = quat.toRotationMatrix().cast<float>();
+    
+    Eigen::Matrix3f orth = test(matrix, noiseAmpl);
+    
+    Quaternionf quatOrth(orth);
+    BOOST_MESSAGE("Angular distance: " << quatOrth.angularDistance(quat.cast<float>()));
+    BOOST_CHECK_LE(quatOrth.angularDistance(quat.cast<float>()), precAngularDist);
+}
+
+Matrix3f OrthogonolizeFixture::test(Matrix3f matrix, float noiseAmpl)
+{
+    static const float PREC_ORTHOGONAL = 1e-6f;
+    
+    BOOST_MESSAGE("Rotation matrix: \n" << matrix);
+    BOOST_CHECK(math::Helpers::IsMatrixOrthogonal(matrix, PREC_ORTHOGONAL));
+    
+    // add noise (random coeffs are in [-1, 1])
+    
+    std::normal_distribution<float> distrib(0, noiseAmpl);
+    matrix += noiseAmpl * this->Random(distrib);
+    
+    BOOST_MESSAGE("Rotation matrix with noise: \n" << matrix);
+    if (noiseAmpl > 0)
+    {
+        BOOST_CHECK(!math::Helpers::IsMatrixOrthogonal(matrix, PREC_ORTHOGONAL));
+    }
+    
+    Eigen::Matrix3f orth = math::Helpers::Orthogonalize(matrix);
+    
+    BOOST_MESSAGE("Orthogonalized: \n" << orth);
+    BOOST_CHECK(math::Helpers::IsMatrixOrthogonal(orth, PREC_ORTHOGONAL));
+    
+    BOOST_MESSAGE("Q * Q.T: (should be Identitiy) \n" << (orth * orth.transpose()));
+    
+    return orth;
+}
+
+
+BOOST_FIXTURE_TEST_SUITE(Orthogonolization, OrthogonolizeFixture)
+
+BOOST_AUTO_TEST_CASE(test_orthogonalize_zero_rotation)
+{
+    test(Eigen::Matrix3f::Identity(), 0);
+    test(Eigen::Matrix3f::Identity(), 0.1f);
+    
+    test(0, Eigen::Vector3d::UnitX(), 0.0f, 0.0f);
+    test(0, Eigen::Vector3d::UnitX(), 1e-3f, 1e-3f);
+}
+
+BOOST_AUTO_TEST_CASE(test_orthogonalize_aligned_axis)
+{
+    test(M_PI / 2, Eigen::Vector3d::UnitX(), 1e-3f, 1e-3f);
+    test(M_PI / 2, Eigen::Vector3d::UnitX(), 0.1f, 0.2f);
+    
+    test(.75 * M_PI, Eigen::Vector3d::UnitZ(), 1e-3f, 1e-3f);
+    test(.75 * M_PI, Eigen::Vector3d::UnitZ(), 0.1f, 0.2f);
+    
+    test(M_PI, Eigen::Vector3d::UnitY(), 1e-3f, 1e-3f);
+    test(M_PI, Eigen::Vector3d::UnitY(), 0.1f, 0.2f);
+}
+
+BOOST_AUTO_TEST_CASE(test_orthogonalize_arbitrary_rotation)
+{
+    test(2.3, Eigen::Vector3d( 0.3, 1., -.5).normalized(), 1e-3f, 1e-3f);
+    test(2.3, Eigen::Vector3d( 0.3, 1., -.5).normalized(), 0.1f, 0.2f);
+    
+    test(1.02, Eigen::Vector3d( -2, .3, -.25).normalized(), 1e-3f, 1e-3f);
+    test(1.02, Eigen::Vector3d( -3,  2, -10).normalized(), 0.1f, 0.2f);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+