diff --git a/examples/angle_example.py b/examples/angle_example.py index bbe0fe0a1..0a58f52e6 100644 --- a/examples/angle_example.py +++ b/examples/angle_example.py @@ -23,21 +23,21 @@ import ignition.math -print("PI in degrees = {}\n".format(ignition.math.Angle.Pi.Degree())) +print("PI in degrees = {}\n".format(ignition.math.Angle.PI.degree())) a1 = ignition.math.Angle(1.5707) a2 = ignition.math.Angle(0.7854) -print("a1 = {} radians, {} degrees\n".format(a1.Radian(), a1.Degree())) -print("a2 = {} radians, {} degrees\n".format(a2.Radian(), a2.Degree())) -print("a1 * a2 = {} radians, {} degrees\n".format((a1 * a2).Radian(), - (a1 * a2).Degree())) -print("a1 + a2 = {} radians, {} degrees\n".format((a1 + a2).Radian(), - (a1 + a2).Degree())) -print("a1 - a2 = {} radians, {} degrees\n".format((a1 - a2).Radian(), - (a1 - a2).Degree())) +print("a1 = {} radians, {} degrees\n".format(a1.radian(), a1.degree())) +print("a2 = {} radians, {} degrees\n".format(a2.radian(), a2.degree())) +print("a1 * a2 = {} radians, {} degrees\n".format((a1 * a2).radian(), + (a1 * a2).degree())) +print("a1 + a2 = {} radians, {} degrees\n".format((a1 + a2).radian(), + (a1 + a2).degree())) +print("a1 - a2 = {} radians, {} degrees\n".format((a1 - a2).radian(), + (a1 - a2).degree())) a3 = ignition.math.Angle(15.707) -print("a3 = {} radians, {} degrees\n".format(a3.Radian(), a3.Degree())) -a3.Normalize() -print("a3.Normalize = {} radians, {} degrees\n".format(a3.Radian(), - a3.Degree())) +print("a3 = {} radians, {} degrees\n".format(a3.radian(), a3.degree())) +a3.normalize() +print("a3.Normalize = {} radians, {} degrees\n".format(a3.radian(), + a3.degree())) diff --git a/examples/vector2_example.py b/examples/vector2_example.py index ecdfc3120..7694ead21 100644 --- a/examples/vector2_example.py +++ b/examples/vector2_example.py @@ -26,14 +26,14 @@ vb = ignition.math.Vector2d(3, 4) vc = ignition.math.Vector2d(vb) -print("va = {} {}\n".format(va.X(), va.Y())) -print("vb = {} {}\n".format(vb.X(), vb.Y())) -print("vc = {} {}\n".format(vc.X(), vc.Y())) +print("va = {} {}\n".format(va.x(), va.y())) +print("vb = {} {}\n".format(vb.x(), vb.y())) +print("vc = {} {}\n".format(vc.x(), vc.y())) vb += va -print("vb += va: {} {}\n".format(vb.X(), vb.Y())) +print("vb += va: {} {}\n".format(vb.x(), vb.y())) -vb.Normalize() -print("vb.Normalize = {} {}\n".format(vb.X(), vb.Y())) +vb.normalize() +print("vb.normalize = {} {}\n".format(vb.x(), vb.y())) -print("vb.Distance(va) = {}\n".format(vb.Distance(va))) +print("vb.distance(va) = {}\n".format(vb.distance(va))) diff --git a/examples/vector3_example.py b/examples/vector3_example.py index 5e0b22f9b..202415c25 100644 --- a/examples/vector3_example.py +++ b/examples/vector3_example.py @@ -23,12 +23,12 @@ import ignition.math v1 = ignition.math.Vector3d(0, 0, 3) -print("v =: {} {} {}\n".format(v1.X(), v1.Y(), v1.Z())) +print("v =: {} {} {}\n".format(v1.x(), v1.y(), v1.z())) v2 = ignition.math.Vector3d(4, 0, 0) -print("v2 = {} {} {}\n".format(v2.X(), v2.Y(), v2.Z())) +print("v2 = {} {} {}\n".format(v2.x(), v2.y(), v2.z())) v3 = v1 + v2 -print("v1 + v2 = {} {} {}\n".format(v3.X(), v3.Y(), v3.Z())) +print("v1 + v2 = {} {} {}\n".format(v3.x(), v3.y(), v3.z())) -print("v1.Distance(v2) = {}\n".format(v1.Distance(v2))) +print("v1.Distance(v2) = {}\n".format(v1.distance(v2))) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a0f3630a..f9e15f386 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,145 +12,6 @@ ign_build_tests(TYPE UNIT SOURCES ${gtest_sources}) # graph namespace add_subdirectory(graph) -################################################# -# Setup swig -if (SWIG_FOUND) - if (POLICY CMP0078) - cmake_policy(SET CMP0078 NEW) - endif() - if (POLICY CMP0086) - cmake_policy(SET CMP0086 NEW) - endif() - - include(${SWIG_USE_FILE}) - set(CMAKE_SWIG_FLAGS "") - - include_directories(${PROJECT_SOURCE_DIR}/include) - include_directories(${PYTHON_INCLUDE_PATH}) - - set(swig_files - Angle - GaussMarkovProcess - Rand - Vector2 - Vector3 - Vector4) -endif() - -################################################# -# Create and install Ruby interfaces -# Example usage -# $ export RUBYLIB=/usr/local/lib/ruby -# $ ruby -e "require 'ignition/math'; a = Ignition::Math::Angle.new(20); puts a.Degree()" -if (RUBY_FOUND) - foreach (swig_file ${swig_files}) - # Assuming that each swig file has a test - list(APPEND ruby_tests ${swig_file}_TEST) - - # Generate the list if .i files - list(APPEND swig_i_files ${swig_file}.i) - endforeach() - list(APPEND ruby_tests ruby_TEST) - - # Turn on c++ - set_source_files_properties(${swig_i_files} ruby/ruby.i PROPERTIES CPLUSPLUS ON) - - # Create the ruby library - - set(CMAKE_SWIG_OUTDIR "${CMAKE_BINARY_DIR}/lib/ruby") - if(CMAKE_VERSION VERSION_GREATER 3.8.0) - SWIG_ADD_LIBRARY(math LANGUAGE ruby SOURCES ruby/ruby.i ${swig_i_files}) - else() - SWIG_ADD_MODULE(math ruby ruby/ruby.i ${swig_i_files}) - endif() - - # Suppress warnings on SWIG-generated files - target_compile_options(math PRIVATE - $<$:-Wno-pedantic -Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> - $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> - $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> - ) - target_include_directories(math SYSTEM PUBLIC ${RUBY_INCLUDE_DIRS}) - - SWIG_LINK_LIBRARIES(math - ${RUBY_LIBRARY} - ignition-math${PROJECT_VERSION_MAJOR} - ) - target_compile_features(math PUBLIC ${IGN_CXX_${c++standard}_FEATURES}) - install(TARGETS math DESTINATION ${IGN_LIB_INSTALL_DIR}/ruby/ignition) - - # Add the ruby tests - foreach (test ${ruby_tests}) - add_test(NAME ${test}.rb COMMAND - ruby -I${CMAKE_BINARY_DIR}/lib ${CMAKE_SOURCE_DIR}/src/${test}.rb - --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/${test}rb.xml) - endforeach() -endif() - -################################# -# Create and install Python interfaces -# Example usage -# $ export PYTHONPATH=/ws/install/lib/python/:$PYTHONPATH -if (PYTHONLIBS_FOUND) - set_source_files_properties(python/python.i PROPERTIES CPLUSPLUS ON) - set_source_files_properties(python/python.i PROPERTIES SWIG_FLAGS "-includeall") - set_source_files_properties(python/python.i PROPERTIES SWIG_MODULE_NAME "math") - set(SWIG_PY_LIB pymath) - set(SWIG_PY_LIB_OUTPUT math) - - set(CMAKE_SWIG_OUTDIR "${CMAKE_BINARY_DIR}/lib/python") - if(CMAKE_VERSION VERSION_GREATER 3.8.0) - SWIG_ADD_LIBRARY(${SWIG_PY_LIB} LANGUAGE python SOURCES python/python.i) - else() - SWIG_ADD_MODULE(${SWIG_PY_LIB} python python/python.i) - endif() - - SWIG_LINK_LIBRARIES(${SWIG_PY_LIB} - ${PYTHON_LIBRARIES} - ignition-math${PROJECT_VERSION_MAJOR} - ) - - if(NOT CMAKE_VERSION VERSION_GREATER_EQUAL 3.13.0) - set(SWIG_PY_LIB "_${SWIG_PY_LIB}") - set(SWIG_PY_LIB_OUTPUT "_${SWIG_PY_LIB_OUTPUT}") - endif() - - set_target_properties(${SWIG_PY_LIB} - PROPERTIES - OUTPUT_NAME ${SWIG_PY_LIB_OUTPUT} - ) - - # Suppress warnings on SWIG-generated files - target_compile_options(${SWIG_PY_LIB} PRIVATE - $<$:-Wno-pedantic -Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> - $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> - $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> - ) - install(TARGETS ${SWIG_PY_LIB} DESTINATION ${IGN_LIB_INSTALL_DIR}/python/ignition) - install(FILES ${CMAKE_BINARY_DIR}/lib/python/math.py DESTINATION ${IGN_LIB_INSTALL_DIR}/python/ignition) - - if (BUILD_TESTING) - # Add the Python tests - set(python_tests - Angle_TEST - GaussMarkovProcess_TEST - python_TEST - Rand_TEST - Vector2_TEST - Vector3_TEST - Vector4_TEST - ) - - foreach (test ${python_tests}) - add_test(NAME ${test}.py COMMAND - python3 ${CMAKE_SOURCE_DIR}/src/${test}.py) - - set(_env_vars) - list(APPEND _env_vars "PYTHONPATH=${FAKE_INSTALL_PREFIX}/lib/python/") - list(APPEND _env_vars "LD_LIBRARY_PATH=${FAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}") - set_tests_properties(${test}.py PROPERTIES - ENVIRONMENT "${_env_vars}") - endforeach() - endif() - -endif() +# Bindings subdirectories +add_subdirectory(python) +add_subdirectory(ruby) diff --git a/src/Rand_TEST.py b/src/Rand_TEST.py deleted file mode 100644 index 2b2d5d60b..000000000 --- a/src/Rand_TEST.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (C) 2021 Open Source Robotics Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import unittest -from ignition.math import Rand - -class TestRand(unittest.TestCase): - - def test_rand(self): - d = Rand.DblUniform(1, 2) - self.assertGreaterEqual(d, 1) - self.assertLessEqual(d, 2) - - i = Rand.IntUniform(1, 2) - self.assertGreaterEqual(i, 1) - self.assertLessEqual(i, 2) - - def test_set_seed(self): - N = 10 - first = [] - second = [] - - for i in range(N): - Rand.Seed(i) - first.append(Rand.IntUniform(-10, 10)) - second.append(Rand.IntUniform(-10, 10)) - - for i in range(N): - Rand.Seed(i) - self.assertEqual(Rand.Seed(), i) - self.assertEqual(first[i], Rand.IntUniform(-10, 10)) - self.assertEqual(second[i], Rand.IntUniform(-10, 10)) - - -if __name__ == '__main__': - unittest.main() diff --git a/src/python/Angle.i b/src/python/Angle.i new file mode 100644 index 000000000..77bd73341 --- /dev/null +++ b/src/python/Angle.i @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +%module angle +%{ +#include +%} + +namespace ignition +{ + namespace math + { + class Angle + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + %rename("%(uppercase)s", %$isstatic, %$isvariable) ""; + public: static const Angle Zero; + public: static const Angle Pi; + %rename(HALF_PI) HalfPi; + public: static const Angle HalfPi; + %rename(TWO_PI) TwoPi; + public: static const Angle TwoPi; + public: Angle(); + public: Angle(double _radian); + public: Angle(const Angle &_angle); + public: virtual ~Angle(); + public: void SetRadian(double _radian); + public: void SetDegree(double _degree); + public: double Radian() const; + public: double Degree() const; + public: void Normalize(); + public: Angle Normalized() const; + public: inline double operator*() const; + public: Angle operator-(const Angle &_angle) const; + public: Angle operator+(const Angle &_angle) const; + public: Angle operator*(const Angle &_angle) const; + public: Angle operator/(const Angle &_angle) const; + public: bool operator==(const Angle &_angle) const; + public: bool operator<(const Angle &_angle) const; + public: bool operator<=(const Angle &_angle) const; + public: bool operator>(const Angle &_angle) const; + public: bool operator>=(const Angle &_angle) const; + }; + } +} diff --git a/src/Angle_TEST.py b/src/python/Angle_TEST.py similarity index 56% rename from src/Angle_TEST.py rename to src/python/Angle_TEST.py index 00d1c7323..b28f9ae7d 100644 --- a/src/Angle_TEST.py +++ b/src/python/Angle_TEST.py @@ -22,62 +22,62 @@ class TestAngle(unittest.TestCase): def test_angle(self): angle1 = Angle() - self.assertEqual(0.0, angle1.Radian()) + self.assertEqual(0.0, angle1.radian()) - angle1.SetDegree(90.0) - self.assertTrue(angle1 == Angle.HalfPi) + angle1.set_degree(90.0) + self.assertTrue(angle1 == Angle.HALF_PI) - angle1.SetDegree(180.0) - self.assertTrue(angle1 == Angle.Pi) - self.assertFalse(angle1 == Angle.Pi + Angle(0.1)) - self.assertTrue(angle1 == Angle.Pi + Angle(0.0001)) - self.assertTrue(angle1 == Angle.Pi - Angle(0.0001)) + angle1.set_degree(180.0) + self.assertTrue(angle1 == Angle.PI) + self.assertFalse(angle1 == Angle.PI + Angle(0.1)) + self.assertTrue(angle1 == Angle.PI + Angle(0.0001)) + self.assertTrue(angle1 == Angle.PI - Angle(0.0001)) self.assertTrue(Angle(0) == Angle(0)) self.assertTrue(Angle(0) == Angle(0.001)) angle1 = Angle(0.1) - Angle(0.3) - self.assertAlmostEqual(angle1.Radian(), -0.2) + self.assertAlmostEqual(angle1.radian(), -0.2) angle = Angle(0.5) - self.assertEqual(0.5, angle.Radian()) + self.assertEqual(0.5, angle.radian()) - angle.SetRadian(math.pi/2) - self.assertAlmostEqual(math.degrees(math.pi/2), angle.Degree()) + angle.set_radian(math.pi/2) + self.assertAlmostEqual(math.degrees(math.pi/2), angle.degree()) - angle.SetRadian(math.pi) - self.assertAlmostEqual(math.degrees(math.pi), angle.Degree()) + angle.set_radian(math.pi) + self.assertAlmostEqual(math.degrees(math.pi), angle.degree()) def test_normalized_angles(self): - angle = Angle(Angle.Pi) - normalized = angle.Normalized() + angle = Angle(Angle.PI) + normalized = angle.normalized() - angle.Normalized() - self.assertEqual(math.degrees(math.pi), angle.Degree()) + angle.normalized() + self.assertEqual(math.degrees(math.pi), angle.degree()) self.assertEqual(normalized, angle) def test_angle_operations(self): angle = Angle(0.1) + Angle(0.2) - self.assertAlmostEqual(0.3, angle.Radian()) + self.assertAlmostEqual(0.3, angle.radian()) angle = Angle(0.1) * Angle(0.2) - self.assertAlmostEqual(0.02, angle.Radian()) + self.assertAlmostEqual(0.02, angle.radian()) angle = Angle(0.1) / Angle(0.2) - self.assertAlmostEqual(0.5, angle.Radian()) + self.assertAlmostEqual(0.5, angle.radian()) angle -= Angle(0.1) - self.assertAlmostEqual(0.4, angle.Radian()) + self.assertAlmostEqual(0.4, angle.radian()) angle += Angle(0.2) - self.assertAlmostEqual(0.6, angle.Radian()) + self.assertAlmostEqual(0.6, angle.radian()) angle *= Angle(0.5) - self.assertAlmostEqual(0.3, angle.Radian()) + self.assertAlmostEqual(0.3, angle.radian()) angle /= Angle(0.1) - self.assertAlmostEqual(3.0, angle.Radian()) + self.assertAlmostEqual(3.0, angle.radian()) self.assertTrue(angle == Angle(3)) self.assertTrue(angle != Angle(2)) self.assertTrue(angle < Angle(4)) diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt new file mode 100644 index 000000000..2d502ff5f --- /dev/null +++ b/src/python/CMakeLists.txt @@ -0,0 +1,92 @@ +################################################# +# Setup swig +if (SWIG_FOUND) + if (POLICY CMP0078) + cmake_policy(SET CMP0078 NEW) + endif() + if (POLICY CMP0086) + cmake_policy(SET CMP0086 NEW) + endif() + + include(${SWIG_USE_FILE}) + set(CMAKE_SWIG_FLAGS "") + + include_directories(${PROJECT_SOURCE_DIR}/include) + include_directories(${PYTHON_INCLUDE_PATH}) + + set(swig_files + Angle + GaussMarkovProcess + Rand + Vector2 + Vector3 + Vector4) +endif() + +################################# +# Create and install Python interfaces +# Example usage +# $ export PYTHONPATH=/ws/install/lib/python/:$PYTHONPATH +if (PYTHONLIBS_FOUND) + set_source_files_properties(python.i PROPERTIES CPLUSPLUS ON) + set_source_files_properties(python.i PROPERTIES SWIG_FLAGS "-includeall") + set_source_files_properties(python.i PROPERTIES SWIG_MODULE_NAME "math") + set(SWIG_PY_LIB pymath) + set(SWIG_PY_LIB_OUTPUT math) + + set(CMAKE_SWIG_OUTDIR "${CMAKE_BINARY_DIR}/lib/python") + if(CMAKE_VERSION VERSION_GREATER 3.8.0) + SWIG_ADD_LIBRARY(${SWIG_PY_LIB} LANGUAGE python SOURCES python.i) + else() + SWIG_ADD_MODULE(${SWIG_PY_LIB} python python.i) + endif() + + SWIG_LINK_LIBRARIES(${SWIG_PY_LIB} + ${PYTHON_LIBRARIES} + ignition-math${PROJECT_VERSION_MAJOR} + ) + + if(NOT CMAKE_VERSION VERSION_GREATER_EQUAL 3.13.0) + set(SWIG_PY_LIB "_${SWIG_PY_LIB}") + set(SWIG_PY_LIB_OUTPUT "_${SWIG_PY_LIB_OUTPUT}") + endif() + + set_target_properties(${SWIG_PY_LIB} + PROPERTIES + OUTPUT_NAME ${SWIG_PY_LIB_OUTPUT} + ) + + # Suppress warnings on SWIG-generated files + target_compile_options(${SWIG_PY_LIB} PRIVATE + $<$:-Wno-pedantic -Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> + $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> + $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter -Wno-cast-function-type -Wno-missing-field-initializers> + ) + install(TARGETS ${SWIG_PY_LIB} DESTINATION ${IGN_LIB_INSTALL_DIR}/python/ignition) + install(FILES ${CMAKE_BINARY_DIR}/lib/python/math.py DESTINATION ${IGN_LIB_INSTALL_DIR}/python/ignition) + + if (BUILD_TESTING) + # Add the Python tests + set(python_tests + Angle_TEST + GaussMarkovProcess_TEST + python_TEST + Rand_TEST + Vector2_TEST + Vector3_TEST + Vector4_TEST + ) + + foreach (test ${python_tests}) + add_test(NAME ${test}.py COMMAND + python3 ${CMAKE_SOURCE_DIR}/src/python/${test}.py) + + set(_env_vars) + list(APPEND _env_vars "PYTHONPATH=${FAKE_INSTALL_PREFIX}/lib/python/") + list(APPEND _env_vars "LD_LIBRARY_PATH=${FAKE_INSTALL_PREFIX}/lib:$ENV{LD_LIBRARY_PATH}") + set_tests_properties(${test}.py PROPERTIES + ENVIRONMENT "${_env_vars}") + endforeach() + endif() + +endif() diff --git a/src/python/GaussMarkovProcess.i b/src/python/GaussMarkovProcess.i new file mode 100644 index 000000000..f0914e17c --- /dev/null +++ b/src/python/GaussMarkovProcess.i @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +%module gaussMarkovProcess +%{ +#include +%} + +namespace ignition +{ + namespace math + { + class GaussMarkovProcess + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + public: GaussMarkovProcess(); + public: GaussMarkovProcess(double _start, double _theta, double _mu, + double _sigma); + public: ~GaussMarkovProcess(); + public: void Set(double _start, double _theta, double _mu, double _sigma); + public: double Start() const; + public: double Value() const; + public: double Theta() const; + public: double Mu() const; + public: double Sigma() const; + public: void Reset(); + public: double Update(double _dt); + }; + } +} diff --git a/src/GaussMarkovProcess_TEST.py b/src/python/GaussMarkovProcess_TEST.py similarity index 71% rename from src/GaussMarkovProcess_TEST.py rename to src/python/GaussMarkovProcess_TEST.py index 965961329..069b312b5 100644 --- a/src/GaussMarkovProcess_TEST.py +++ b/src/python/GaussMarkovProcess_TEST.py @@ -20,11 +20,11 @@ class TestGaussMarkovProcess(unittest.TestCase): def test_default_constructor(self): gmp = GaussMarkovProcess() - self.assertAlmostEqual(0.0, gmp.Start()) - self.assertAlmostEqual(0.0, gmp.Value()) - self.assertAlmostEqual(0.0, gmp.Theta()) - self.assertAlmostEqual(0.0, gmp.Mu()) - self.assertAlmostEqual(0.0, gmp.Sigma()) + self.assertAlmostEqual(0.0, gmp.start()) + self.assertAlmostEqual(0.0, gmp.value()) + self.assertAlmostEqual(0.0, gmp.theta()) + self.assertAlmostEqual(0.0, gmp.mu()) + self.assertAlmostEqual(0.0, gmp.sigma()) def test_no_noise(self): # Start value of -1.2 @@ -32,23 +32,23 @@ def test_no_noise(self): # Mu (mean value) 2.5 # Sigma (volatility) of 0.0 gmp = GaussMarkovProcess(-1.2, 1.0, 2.5, 0) - self.assertAlmostEqual(-1.2, gmp.Start()) - self.assertAlmostEqual(-1.2, gmp.Value()) - self.assertAlmostEqual(1.0, gmp.Theta()) - self.assertAlmostEqual(2.5, gmp.Mu()) - self.assertAlmostEqual(0.0, gmp.Sigma()) + self.assertAlmostEqual(-1.2, gmp.start()) + self.assertAlmostEqual(-1.2, gmp.value()) + self.assertAlmostEqual(1.0, gmp.theta()) + self.assertAlmostEqual(2.5, gmp.mu()) + self.assertAlmostEqual(0.0, gmp.sigma()) # This process should steadily increase to the mean value of 2.5 since # there is no noise. for i in range(200): - value = gmp.Update(0.1) + value = gmp.update(0.1) self.assertGreater(value, -1.2) self.assertAlmostEqual(2.5, value, delta=1e-4) - gmp.Reset() + gmp.reset() for i in range(200): - value = gmp.Update(0.1) + value = gmp.update(0.1) self.assertGreater(value, -1.2) self.assertAlmostEqual(2.5, value, delta=1e-4) diff --git a/src/python/Rand.i b/src/python/Rand.i new file mode 100644 index 000000000..238d65fc2 --- /dev/null +++ b/src/python/Rand.i @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +%module rand +%{ +#include +%} + +namespace ignition +{ + namespace math + { + class Rand + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + public: static void Seed(unsigned int _seed); + public: static unsigned int Seed(); + public: static double DblUniform(double _min, double _max); + public: static double DblNormal(double _mean, double _sigma); + public: static int IntUniform(int _min, int _max); + public: static int IntNormal(int _mean, int _sigma); + }; + } +} diff --git a/src/python/Rand_TEST.py b/src/python/Rand_TEST.py new file mode 100644 index 000000000..d9dfa9953 --- /dev/null +++ b/src/python/Rand_TEST.py @@ -0,0 +1,48 @@ +# Copyright (C) 2021 Open Source Robotics Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest +from ignition.math import Rand + + +class TestRand(unittest.TestCase): + + def test_rand(self): + d = Rand.dbl_uniform(1, 2) + self.assertGreaterEqual(d, 1) + self.assertLessEqual(d, 2) + + i = Rand.int_uniform(1, 2) + self.assertGreaterEqual(i, 1) + self.assertLessEqual(i, 2) + + def test_set_seed(self): + N = 10 + first = [] + second = [] + + for i in range(N): + Rand.seed(i) + first.append(Rand.int_uniform(-10, 10)) + second.append(Rand.int_uniform(-10, 10)) + + for i in range(N): + Rand.seed(i) + self.assertEqual(Rand.seed(), i) + self.assertEqual(first[i], Rand.int_uniform(-10, 10)) + self.assertEqual(second[i], Rand.int_uniform(-10, 10)) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/python/Vector2.i b/src/python/Vector2.i new file mode 100644 index 000000000..ff2f80098 --- /dev/null +++ b/src/python/Vector2.i @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifdef SWIGRUBY +%begin %{ +#define HAVE_ISFINITE 1 +%} +#endif + +%module vector2 +%{ +#include +%} + +namespace ignition +{ + namespace math + { + template + class Vector2 + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + %rename("%(uppercase)s", %$isstatic, %$isvariable) ""; + public: static const Vector2 Zero; + public: static const Vector2 One; + + public: Vector2(); + public: Vector2(const T &_x, const T &_y); + public: Vector2(const Vector2 &_v); + public: virtual ~Vector2(); + public: double Distance(const Vector2 &_pt) const; + public: T Length() const; + public: T SquaredLength() const; + public: void Normalize(); + public: void Set(T _x, T _y); + public: T Dot(const Vector2 &_v) const; + public: Vector2 Abs() const; + public: T AbsDot(const Vector2 &_v) const; + public: inline void Correct(); + public: void Max(const Vector2 &_v); + public: void Min(const Vector2 &_v); + public: T Max() const; + public: T Min() const; + public: Vector2 operator+(const Vector2 &_v) const; + public: inline Vector2 operator+(const T _s) const; + public: inline Vector2 operator-() const; + public: Vector2 operator-(const Vector2 &_v) const; + public: inline Vector2 operator-(const T _s) const; + public: const Vector2 operator/(const Vector2 &_v) const; + public: const Vector2 operator/(T _v) const; + public: const Vector2 operator*(const Vector2 &_v) const; + public: const Vector2 operator*(T _v) const; + public: bool operator==(const Vector2 &_v) const; + public: bool IsFinite() const; + public: inline T X() const; + public: inline T Y() const; + public: inline void X(const T &_v); + public: inline void Y(const T &_v); + public: bool Equal(const Vector2 &_v, const T &_tol) const; + }; + + %template(Vector2i) Vector2; + %template(Vector2d) Vector2; + %template(Vector2f) Vector2; + } +} diff --git a/src/Vector2_TEST.py b/src/python/Vector2_TEST.py similarity index 59% rename from src/Vector2_TEST.py rename to src/python/Vector2_TEST.py index 9ac6d667c..7bcac078f 100644 --- a/src/Vector2_TEST.py +++ b/src/python/Vector2_TEST.py @@ -21,12 +21,12 @@ class TestVector2(unittest.TestCase): def test_construction(self): v = Vector2d() - self.assertAlmostEqual(0.0, v.X()) - self.assertAlmostEqual(0.0, v.Y()) + self.assertAlmostEqual(0.0, v.x()) + self.assertAlmostEqual(0.0, v.y()) vec = Vector2d(1, 0) - self.assertEqual(vec.X(), 1) - self.assertEqual(vec.Y(), 0) + self.assertEqual(vec.x(), 1) + self.assertEqual(vec.y(), 0) vec2 = Vector2d(vec) self.assertEqual(vec2, vec) @@ -43,90 +43,90 @@ def test_vector2(self): v = Vector2d(1, 2) # Distance - self.assertAlmostEqual(2.236, v.Distance(Vector2d()), delta=1e-2) + self.assertAlmostEqual(2.236, v.distance(Vector2d()), delta=1e-2) # Normalize - v.Normalize() - self.assertTrue(v.Equal(Vector2d(0.447214, 0.894427), 1e-4)) + v.normalize() + self.assertTrue(v.equal(Vector2d(0.447214, 0.894427), 1e-4)) # Set - v.Set(4, 5) - self.assertTrue(v.Equal(Vector2d(4, 5), 1e-4)) + v.set(4, 5) + self.assertTrue(v.equal(Vector2d(4, 5), 1e-4)) # Abs - v.Set(-1, -2) - self.assertTrue(v.Abs().Equal(Vector2d(1, 2), 1e-4)) + v.set(-1, -2) + self.assertTrue(v.abs().equal(Vector2d(1, 2), 1e-4)) # _eq_ v = Vector2d(6, 7) - self.assertTrue(v.Equal(Vector2d(6, 7), 1e-4)) + self.assertTrue(v.equal(Vector2d(6, 7), 1e-4)) # _add_ v = v + Vector2d(1, 2) - self.assertTrue(v.Equal(Vector2d(7, 9), 1e-4)) + self.assertTrue(v.equal(Vector2d(7, 9), 1e-4)) v += Vector2d(5, 6) - self.assertTrue(v.Equal(Vector2d(12, 15), 1e-4)) + self.assertTrue(v.equal(Vector2d(12, 15), 1e-4)) # __sub__ v = v - Vector2d(2, 4) - self.assertTrue(v.Equal(Vector2d(10, 11), 1e-4)) + self.assertTrue(v.equal(Vector2d(10, 11), 1e-4)) - v.Set(2, 4) + v.set(2, 4) v -= Vector2d(1, 6) - self.assertTrue(v.Equal(Vector2d(1, -2), 1e-4)) + self.assertTrue(v.equal(Vector2d(1, -2), 1e-4)) # __truediv__ - v.Set(10, 6) + v.set(10, 6) v = v / Vector2d(2, 3) - self.assertTrue(v.Equal(Vector2d(5, 2), 1e-4)) + self.assertTrue(v.equal(Vector2d(5, 2), 1e-4)) - v.Set(10, 6) + v.set(10, 6) v /= Vector2d(2, 3) - self.assertTrue(v.Equal(Vector2d(5, 2), 1e-4)) + self.assertTrue(v.equal(Vector2d(5, 2), 1e-4)) # __truediv__ int - v.Set(10, 6) + v.set(10, 6) v = v / 2 - self.assertTrue(v.Equal(Vector2d(5, 3), 1e-4)) + self.assertTrue(v.equal(Vector2d(5, 3), 1e-4)) - v.Set(10, 6) + v.set(10, 6) v /= 2 - self.assertTrue(v.Equal(Vector2d(5, 3), 1e-4)) + self.assertTrue(v.equal(Vector2d(5, 3), 1e-4)) # __mul__ - v.Set(10, 6) + v.set(10, 6) v = v * Vector2d(2, 4) - self.assertTrue(v.Equal(Vector2d(20, 24), 1e-4)) + self.assertTrue(v.equal(Vector2d(20, 24), 1e-4)) - v.Set(10, 6) + v.set(10, 6) v *= Vector2d(2, 4) - self.assertTrue(v.Equal(Vector2d(20, 24), 1e-4)) + self.assertTrue(v.equal(Vector2d(20, 24), 1e-4)) # __mul__ int - v.Set(10, 6) + v.set(10, 6) v = v * 2 - self.assertTrue(v.Equal(Vector2d(20, 12), 1e-4)) + self.assertTrue(v.equal(Vector2d(20, 12), 1e-4)) - v.Set(10, 6) + v.set(10, 6) v *= 2 - self.assertTrue(v.Equal(Vector2d(20, 12), 1e-4)) + self.assertTrue(v.equal(Vector2d(20, 12), 1e-4)) - # IsFinite - self.assertTrue(v.IsFinite()) + # is_finite + self.assertTrue(v.is_finite()) def test_max(self): vec1 = Vector2d(0.1, 0.2) vec2 = Vector2d(0.3, 0.5) vec3 = Vector2d(0.4, 0.2) - self.assertAlmostEqual(vec1.Max(), 0.2) - self.assertAlmostEqual(vec3.Max(), 0.4) + self.assertAlmostEqual(vec1.max(), 0.2) + self.assertAlmostEqual(vec3.max(), 0.4) - vec1.Max(vec2) + vec1.max(vec2) self.assertAlmostEqual(vec1, Vector2d(0.3, 0.5)) - vec1.Max(vec3) + vec1.max(vec3) self.assertAlmostEqual(vec1, Vector2d(0.4, 0.5)) def test_min(self): @@ -134,38 +134,38 @@ def test_min(self): vec2 = Vector2d(0.1, 0.2) vec3 = Vector2d(0.05, 0.1) - self.assertAlmostEqual(vec1.Min(), 0.3) - self.assertAlmostEqual(vec3.Min(), 0.05) + self.assertAlmostEqual(vec1.min(), 0.3) + self.assertAlmostEqual(vec3.min(), 0.05) - vec1.Min(vec2) + vec1.min(vec2) self.assertAlmostEqual(vec1, Vector2d(0.1, 0.2)) - vec1.Min(vec3) + vec1.min(vec3) self.assertAlmostEqual(vec1, Vector2d(0.05, 0.1)) def test_equal_tolerance(self): # Test Equal function with specified tolerance - self.assertFalse(Vector2d.Zero.Equal(Vector2d.One, 1e-6)) - self.assertFalse(Vector2d.Zero.Equal(Vector2d.One, 1e-3)) - self.assertFalse(Vector2d.Zero.Equal(Vector2d.One, 1e-1)) - self.assertTrue(Vector2d.Zero.Equal(Vector2d.One, 1)) - self.assertTrue(Vector2d.Zero.Equal(Vector2d.One, 1.1)) + self.assertFalse(Vector2d.ZERO.equal(Vector2d.ONE, 1e-6)) + self.assertFalse(Vector2d.ZERO.equal(Vector2d.ONE, 1e-3)) + self.assertFalse(Vector2d.ZERO.equal(Vector2d.ONE, 1e-1)) + self.assertTrue(Vector2d.ZERO.equal(Vector2d.ONE, 1)) + self.assertTrue(Vector2d.ZERO.equal(Vector2d.ONE, 1.1)) def test_dot(self): v = Vector2d(1, 2) - self.assertAlmostEqual(v.Dot(Vector2d(3, 4)), 11.0) - self.assertAlmostEqual(v.Dot(Vector2d(0, 0)), 0.0) - self.assertAlmostEqual(v.Dot(Vector2d(1, 0)), 1.0) - self.assertAlmostEqual(v.Dot(Vector2d(0, 1)), 2.0) + self.assertAlmostEqual(v.dot(Vector2d(3, 4)), 11.0) + self.assertAlmostEqual(v.dot(Vector2d(0, 0)), 0.0) + self.assertAlmostEqual(v.dot(Vector2d(1, 0)), 1.0) + self.assertAlmostEqual(v.dot(Vector2d(0, 1)), 2.0) def test_correct(self): vec1 = Vector2d(0, float("nan")) vec2 = Vector2d(float("inf"), -1) vec3 = Vector2d(10, -2) - vec1.Correct() - vec2.Correct() - vec3.Correct() + vec1.correct() + vec2.correct() + vec3.correct() self.assertAlmostEqual(vec1, Vector2d(0, 0)) self.assertAlmostEqual(vec2, Vector2d(0, -1)) @@ -174,10 +174,10 @@ def test_correct(self): def test_abs_dot(self): v = Vector2d(1, -2) - self.assertAlmostEqual(v.AbsDot(Vector2d(3, 4)), 11.0) - self.assertAlmostEqual(v.AbsDot(Vector2d(0, 0)), 0.0) - self.assertAlmostEqual(v.AbsDot(Vector2d(1, 0)), 1.0) - self.assertAlmostEqual(v.AbsDot(Vector2d(0, 1)), 2.0) + self.assertAlmostEqual(v.abs_dot(Vector2d(3, 4)), 11.0) + self.assertAlmostEqual(v.abs_dot(Vector2d(0, 0)), 0.0) + self.assertAlmostEqual(v.abs_dot(Vector2d(1, 0)), 1.0) + self.assertAlmostEqual(v.abs_dot(Vector2d(0, 1)), 2.0) def test_add(self): vec1 = Vector2d(0.1, 0.2) @@ -194,14 +194,14 @@ def test_add(self): self.assertEqual(vec1 + 0, vec1) # Vector left and right - self.assertAlmostEqual(Vector2d.Zero + vec1, vec1) - self.assertAlmostEqual(vec1 + Vector2d.Zero, vec1) + self.assertAlmostEqual(Vector2d.ZERO + vec1, vec1) + self.assertAlmostEqual(vec1 + Vector2d.ZERO, vec1) # Addition assigment vec4 = Vector2d(vec1) vec4 += 0 self.assertEqual(vec4, vec1) - vec4 += Vector2d.Zero + vec4 += Vector2d.ZERO self.assertAlmostEqual(vec4, vec1) # Add non-trivial scalar values left and right @@ -226,14 +226,14 @@ def test_sub(self): self.assertEqual(vec1 - 0, vec1) # Vector left and right - self.assertAlmostEqual(Vector2d.Zero - vec1, -vec1) - self.assertAlmostEqual(vec1 - Vector2d.Zero, vec1) + self.assertAlmostEqual(Vector2d.ZERO - vec1, -vec1) + self.assertAlmostEqual(vec1 - Vector2d.ZERO, vec1) # Subtraction assignment vec4 = Vector2d(vec1) vec4 -= 0 self.assertEqual(vec4, vec1) - vec4 -= Vector2d.Zero + vec4 -= Vector2d.ZERO self.assertAlmostEqual(vec4, vec1) # Subtract non-trivial scalar values left and right @@ -254,17 +254,17 @@ def test_multiply(self): # Multiply by zero # Scalar right - self.assertEqual(v * 0, Vector2d.Zero) + self.assertEqual(v * 0, Vector2d.ZERO) # Element-wise vector multiplication - self.assertEqual(v * Vector2d.Zero, Vector2d.Zero) + self.assertEqual(v * Vector2d.ZERO, Vector2d.ZERO) # Multiply by one # Scalar right self.assertEqual(v * 1, v) # Element-wise vector multiplication - self.assertEqual(v * Vector2d.One, v) + self.assertEqual(v * Vector2d.ONE, v) # Multiply by non-trivial scalar value scalar = 2.5 @@ -272,28 +272,28 @@ def test_multiply(self): self.assertEqual(v * scalar, expect) # Multiply by itself element-wise - v.Set(0.1, 0.5) + v.set(0.1, 0.5) self.assertAlmostEqual(v * v, Vector2d(0.01, 0.25)) def test_lenght(self): # Zero vector - self.assertAlmostEqual(Vector2d.Zero.Length(), 0.0) - self.assertAlmostEqual(Vector2d.Zero.SquaredLength(), 0.0) + self.assertAlmostEqual(Vector2d.ZERO.length(), 0.0) + self.assertAlmostEqual(Vector2d.ZERO.squared_length(), 0.0) # One vector - self.assertAlmostEqual(Vector2d.One.Length(), + self.assertAlmostEqual(Vector2d.ONE.length(), math.sqrt(2), delta=1e-10) - self.assertAlmostEqual(Vector2d.One.SquaredLength(), 2.0) + self.assertAlmostEqual(Vector2d.ONE.squared_length(), 2.0) # Arbitrary vector v = Vector2d(0.1, -4.2) - self.assertAlmostEqual(v.Length(), 4.20119030752, delta=1e-10) - self.assertAlmostEqual(v.SquaredLength(), 17.65) + self.assertAlmostEqual(v.length(), 4.20119030752, delta=1e-10) + self.assertAlmostEqual(v.squared_length(), 17.65) # Integer vector v = Vector2d(3, 4) - self.assertAlmostEqual(v.Length(), 5) - self.assertAlmostEqual(v.SquaredLength(), 25) + self.assertAlmostEqual(v.length(), 5) + self.assertAlmostEqual(v.squared_length(), 25) if __name__ == '__main__': diff --git a/src/python/Vector3.i b/src/python/Vector3.i new file mode 100644 index 000000000..12b48ced9 --- /dev/null +++ b/src/python/Vector3.i @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifdef SWIGRUBY +%begin %{ +#define HAVE_ISFINITE 1 +%} +#endif + +%module vector3 +%{ +#include +%} + +namespace ignition +{ + namespace math + { + template + class Vector3 + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + %rename("%(uppercase)s", %$isstatic, %$isvariable) ""; + public: static const Vector3 Zero; + public: static const Vector3 One; + %rename(UNIT_X) UnitX; + public: static const Vector3 UnitX; + %rename(UNIT_Y) UnitY; + public: static const Vector3 UnitY; + %rename(UNIT_Z) UnitZ; + public: static const Vector3 UnitZ; + public: Vector3(); + public: Vector3(const T &_x, const T &_y, const T &_z); + public: Vector3(const Vector3 &_v); + public: virtual ~Vector3(); + public: T Sum() const; + public: T Distance(const Vector3 &_pt) const; + public: T Distance(T _x, T _y, T _z) const; + public: T Length() const; + public: T SquaredLength() const; + public: Vector3 Normalize(); + public: Vector3 Normalized() const; + public: Vector3 Round(); + public: Vector3 Rounded() const; + public: inline void Set(T _x = 0, T _y = 0, T _z = 0); + public: Vector3 Cross(const Vector3 &_v) const; + public: T Dot(const Vector3 &_v) const; + public: T AbsDot(const Vector3 &_v) const; + public: Vector3 Abs() const; + public: Vector3 Perpendicular() const; + public: static Vector3 Normal(const Vector3 &_v1, + const Vector3 &_v2, const Vector3 &_v3); + public: T DistToLine(const Vector3 &_pt1, const Vector3 &_pt2); + public: void Max(const Vector3 &_v); + public: void Min(const Vector3 &_v); + public: T Max() const; + public: T Min() const; + public: Vector3 operator+(const Vector3 &_v) const; + public: inline Vector3 operator+(const T _s) const; + public: inline Vector3 operator-() const; + public: inline Vector3 operator-(const Vector3 &_pt) const; + public: inline Vector3 operator-(const T _s) const; + public: const Vector3 operator/(const Vector3 &_pt) const; + public: const Vector3 operator/(T _v) const; + public: Vector3 operator*(const Vector3 &_p) const; + public: inline Vector3 operator*(T _s) const; + public: bool Equal(const Vector3 &_v, const T &_tol) const; + public: bool operator==(const Vector3 &_v) const; + public: bool IsFinite() const; + public: inline void Correct(); + public: void Round(int _precision); + public: bool Equal(const Vector3 &_v) const; + public: inline T X() const; + public: inline T Y() const; + public: inline T Z() const; + public: inline void X(const T &_v); + public: inline void Y(const T &_v); + public: inline void Z(const T &_v); + public: bool operator<(const Vector3 &_pt) const; + }; + + %template(Vector3i) Vector3; + %template(Vector3d) Vector3; + %template(Vector3f) Vector3; + } +} diff --git a/src/Vector3_TEST.py b/src/python/Vector3_TEST.py similarity index 64% rename from src/Vector3_TEST.py rename to src/python/Vector3_TEST.py index a7f1a84a5..2ac6ab18e 100644 --- a/src/Vector3_TEST.py +++ b/src/python/Vector3_TEST.py @@ -21,14 +21,14 @@ class TestVector3(unittest.TestCase): def test_construction(self): v = Vector3d() - self.assertAlmostEqual(0.0, v.X()) - self.assertAlmostEqual(0.0, v.Y()) - self.assertAlmostEqual(0.0, v.Z()) + self.assertAlmostEqual(0.0, v.x()) + self.assertAlmostEqual(0.0, v.y()) + self.assertAlmostEqual(0.0, v.z()) vec = Vector3d(1, 0, 0) - self.assertEqual(vec.X(), 1) - self.assertEqual(vec.Y(), 0) - self.assertEqual(vec.Z(), 0) + self.assertEqual(vec.x(), 1) + self.assertEqual(vec.y(), 0) + self.assertEqual(vec.z(), 0) vec2 = Vector3d(vec) self.assertEqual(vec2, vec) @@ -42,28 +42,28 @@ def test_construction(self): self.assertNotEqual(vec, vec4) def test_vector3(self): - # Distance, Length() + # Distance, length() v = Vector3d(1, 2, 3) - self.assertEqual(v.Length(), v.Distance(Vector3d.Zero)) + self.assertEqual(v.length(), v.distance(Vector3d.ZERO)) # Rounded - v.Set(1.23, 2.34, 3.55) - self.assertEqual(v.Rounded(), Vector3d(1, 2, 4)) + v.set(1.23, 2.34, 3.55) + self.assertEqual(v.rounded(), Vector3d(1, 2, 4)) # Round - v.Round() - self.assertEqual(v.Round(), Vector3d(1, 2, 4)) + v.round() + self.assertEqual(v.round(), Vector3d(1, 2, 4)) # DotProd - self.assertEqual(v.Dot(Vector3d(1, 2, 3)), 17.0) + self.assertEqual(v.dot(Vector3d(1, 2, 3)), 17.0) # DistToLine - v.Set(0, 0, 0) - self.assertEqual(1.0, v.DistToLine(Vector3d(1, -1, 0), + v.set(0, 0, 0) + self.assertEqual(1.0, v.dist_to_line(Vector3d(1, -1, 0), Vector3d(1, 1, 0))) # __truediv__ - v.Set(4, 4, 4) + v.set(4, 4, 4) v = v / Vector3d(1, 2, 4) self.assertEqual(v, Vector3d(4, 2, 1)) @@ -75,51 +75,51 @@ def test_vector3(self): v = v * Vector3d(2, 3, 4) self.assertEqual(v, Vector3d(4, 3, 2)) - v.Set(1.23, 2.35, 3.654321) - v.Round(1) + v.set(1.23, 2.35, 3.654321) + v.round(1) self.assertEqual(v, Vector3d(1.2, 2.4, 3.7)) # Abs - v.Set(-1, -2, -3) - self.assertEqual(v.Abs(), Vector3d(1, 2, 3)) + v.set(-1, -2, -3) + self.assertEqual(v.abs(), Vector3d(1, 2, 3)) # __truediv__ - v.Set(1, 2, 4) + v.set(1, 2, 4) v /= Vector3d(1, 4, 4) self.assertEqual(v, Vector3d(1, 0.5, 1)) # __mul__ - v.Set(1, 2, 4) + v.set(1, 2, 4) v *= Vector3d(2, 0.5, 0.1) - self.assertTrue(v.Equal(Vector3d(2, 1, 0.4))) + self.assertTrue(v.equal(Vector3d(2, 1, 0.4))) # Test the static defines. - self.assertEqual(Vector3d.Zero, Vector3d(0, 0, 0)) + self.assertEqual(Vector3d.ZERO, Vector3d(0, 0, 0)) - self.assertEqual(Vector3d.One, Vector3d(1, 1, 1)) + self.assertEqual(Vector3d.ONE, Vector3d(1, 1, 1)) - self.assertEqual(Vector3d.UnitX, Vector3d(1, 0, 0)) + self.assertEqual(Vector3d.UNIT_X, Vector3d(1, 0, 0)) - self.assertEqual(Vector3d.UnitY, Vector3d(0, 1, 0)) + self.assertEqual(Vector3d.UNIT_Y, Vector3d(0, 1, 0)) - self.assertEqual(Vector3d.UnitZ, Vector3d(0, 0, 1)) + self.assertEqual(Vector3d.UNIT_Z, Vector3d(0, 0, 1)) def test_distance(self): vec1 = Vector3d(0, 0, 0) vec2 = Vector3d(1, 2, 3) - dist = vec1.Distance(vec2) + dist = vec1.distance(vec2) self.assertTrue(abs(dist - 3.74165738677) < 1e-6) - dist2 = vec1.Distance(1, 2, 3) + dist2 = vec1.distance(1, 2, 3) self.assertEqual(dist, dist2) def test_sum(self): vec1 = Vector3d(0, 0, 0) vec2 = Vector3d(1, 2, 3) - sum1 = vec1.Sum() - sum2 = vec2.Sum() + sum1 = vec1.sum() + sum2 = vec2.sum() self.assertEqual(sum1, 0) self.assertEqual(sum2, 6) @@ -128,51 +128,51 @@ def test_squared_length(self): vec1 = Vector3d(0, 0, 0) vec2 = Vector3d(1, 2, 3) - sum1 = vec1.SquaredLength() - sum2 = vec2.SquaredLength() + sum1 = vec1.squared_length() + sum2 = vec2.squared_length() self.assertEqual(sum1, 0) self.assertEqual(sum2, 14) def test_length(self): # Zero vector - self.assertEqual(Vector3d.Zero.Length(), 0.0) - self.assertEqual(Vector3d.Zero.SquaredLength(), 0.0) + self.assertEqual(Vector3d.ZERO.length(), 0.0) + self.assertEqual(Vector3d.ZERO.squared_length(), 0.0) # UnitXYZ vectorsIgnition:: - self.assertEqual(Vector3d.UnitX.Length(), 1.0) - self.assertEqual(Vector3d.UnitY.Length(), 1.0) - self.assertEqual(Vector3d.UnitZ.Length(), 1.0) - self.assertEqual(Vector3d.UnitX.SquaredLength(), 1.0) - self.assertEqual(Vector3d.UnitY.SquaredLength(), 1.0) - self.assertEqual(Vector3d.UnitZ.SquaredLength(), 1.0) + self.assertEqual(Vector3d.UNIT_X.length(), 1.0) + self.assertEqual(Vector3d.UNIT_Y.length(), 1.0) + self.assertEqual(Vector3d.UNIT_Z.length(), 1.0) + self.assertEqual(Vector3d.UNIT_X.squared_length(), 1.0) + self.assertEqual(Vector3d.UNIT_Y.squared_length(), 1.0) + self.assertEqual(Vector3d.UNIT_Z.squared_length(), 1.0) # One vector - self.assertTrue(Vector3d.One.Length() - + self.assertTrue(Vector3d.ONE.length() - abs(math.sqrt(3.0)) < 1e-10) - self.assertEqual(Vector3d.One.SquaredLength(), 3.0) + self.assertEqual(Vector3d.ONE.squared_length(), 3.0) # Arbitrary vector v = Vector3d(0.1, -4.2, 2.5) - self.assertTrue(abs(v.Length() - 4.88876262463) < 1e-10) + self.assertTrue(abs(v.length() - 4.88876262463) < 1e-10) - self.assertTrue(abs(v.SquaredLength() - 23.9) < 1e-10) + self.assertTrue(abs(v.squared_length() - 23.9) < 1e-10) def test_normalize(self): vec1 = Vector3d(0, 0, 0) vec2 = Vector3d(1, 2, 3) - vec3 = vec1.Normalize() + vec3 = vec1.normalize() self.assertEqual(vec3, vec1) - self.assertEqual(vec1, Vector3d.Zero) + self.assertEqual(vec1, Vector3d.ZERO) - vec3 = vec2.Normalize() + vec3 = vec2.normalize() self.assertEqual(vec3, vec2) self.assertEqual(vec2, Vector3d(0.267261, 0.534522, 0.801784)) vecConst = Vector3d(1, 2, 3) - self.assertEqual(vecConst.Normalized(), vec3) + self.assertEqual(vecConst.normalized(), vec3) self.assertEqual(vecConst, Vector3d(1, 2, 3)) def test_ge_normal(self): @@ -180,7 +180,7 @@ def test_ge_normal(self): vec2 = Vector3d(0, 1, 0) vec3 = Vector3d(1, 1, 0) - norm = Vector3d.Normal(vec1, vec2, vec3) + norm = Vector3d.normal(vec1, vec2, vec3) self.assertEqual(norm, Vector3d(0, 0, -1)) def test_perpendicular(self): @@ -189,22 +189,22 @@ def test_perpendicular(self): vec3 = Vector3d(1e-7, 1e-7, 1e-7) vec4 = Vector3d(1, 0, 0) - self.assertEqual(vec1.Perpendicular(), Vector3d(0, 0, -1)) - self.assertEqual(vec2.Perpendicular(), Vector3d(0, 1, -1)) - self.assertEqual(vec3.Perpendicular(), Vector3d(0, 0, 0)) - self.assertEqual(vec4.Perpendicular(), Vector3d(0, 0, 1)) + self.assertEqual(vec1.perpendicular(), Vector3d(0, 0, -1)) + self.assertEqual(vec2.perpendicular(), Vector3d(0, 1, -1)) + self.assertEqual(vec3.perpendicular(), Vector3d(0, 0, 0)) + self.assertEqual(vec4.perpendicular(), Vector3d(0, 0, 1)) def test_max(self): vec1 = Vector3d(0.1, 0.2, 0.3) vec2 = Vector3d(0.2, 0.3, 0.4) vec3 = Vector3d(0.1, 0.2, 0.3) - self.assertTrue(abs(vec1.Max() - 0.3) < 1e-10) + self.assertTrue(abs(vec1.max() - 0.3) < 1e-10) - vec1.Max(vec2) + vec1.max(vec2) self.assertEqual(vec1, Vector3d(0.2, 0.3, 0.4)) - vec1.Max(vec3) + vec1.max(vec3) self.assertEqual(vec1, Vector3d(0.2, 0.3, 0.4)) def test_min(self): @@ -212,12 +212,12 @@ def test_min(self): vec2 = Vector3d(0.2, 0.3, 0.4) vec3 = Vector3d(0.05, 0.1, 0.2) - self.assertTrue(abs(vec1.Min() - 0.1) < 1e-10) + self.assertTrue(abs(vec1.min() - 0.1) < 1e-10) - vec1.Min(vec2) + vec1.min(vec2) self.assertEqual(vec1, Vector3d(0.1, 0.2, 0.3)) - vec1.Min(vec3) + vec1.min(vec3) self.assertEqual(vec1, Vector3d(0.05, 0.1, 0.2)) def test_add(self): @@ -235,14 +235,14 @@ def test_add(self): self.assertEqual(vec1 + 0, vec1) # Vector left and right - self.assertEqual(Vector3d.Zero + vec1, vec1) - self.assertEqual(vec1 + Vector3d.Zero, vec1) + self.assertEqual(Vector3d.ZERO + vec1, vec1) + self.assertEqual(vec1 + Vector3d.ZERO, vec1) # Addition assignment vec4 = vec1 vec4 += 0 self.assertEqual(vec4, vec1) - vec4 += Vector3d.Zero + vec4 += Vector3d.ZERO self.assertEqual(vec4, vec1) # Add non-trivial scalar values left and right @@ -267,14 +267,14 @@ def test_sub(self): self.assertEqual(vec1 - 0, vec1) # Vector left and right - self.assertEqual(Vector3d.Zero - vec1, -vec1) - self.assertEqual(vec1 - Vector3d.Zero, vec1) + self.assertEqual(Vector3d.ZERO - vec1, -vec1) + self.assertEqual(vec1 - Vector3d.ZERO, vec1) # Subtraction assignment vec4 = vec1 vec4 -= 0 self.assertEqual(vec4, vec1) - vec4 -= Vector3d.Zero + vec4 -= Vector3d.ZERO self.assertEqual(vec4, vec1) # Subtract non-trivial scalar values left and right @@ -304,17 +304,17 @@ def test_multiply(self): # Multiply by zero # Scalar right - self.assertEqual(v * 0, Vector3d.Zero) + self.assertEqual(v * 0, Vector3d.ZERO) # Element-wise vector multiplication - self.assertEqual(v * Vector3d.Zero, Vector3d.Zero) + self.assertEqual(v * Vector3d.ZERO, Vector3d.ZERO) # Multiply by one # Scalar right self.assertEqual(v * 1, v) # Element-wise vector multiplication - self.assertEqual(v * Vector3d.One, v) + self.assertEqual(v * Vector3d.ONE, v) # Multiply by non-trivial scalar value scalar = 2.5 @@ -333,22 +333,22 @@ def test_not_equal(self): self.assertTrue(not(vec1 != vec3)) def test_equal(self): - self.assertTrue(not Vector3d.Zero.Equal( - Vector3d.One, 1e-6)) - self.assertTrue(not Vector3d.Zero.Equal( - Vector3d.One, 1e-3)) - self.assertTrue(not Vector3d.Zero.Equal( - Vector3d.One, 1e-1)) - - self.assertTrue(Vector3d.Zero.Equal( - Vector3d.One, 1)) - self.assertTrue(Vector3d.Zero.Equal( - Vector3d.One, 1.1)) + self.assertTrue(not Vector3d.ZERO.equal( + Vector3d.ONE, 1e-6)) + self.assertTrue(not Vector3d.ZERO.equal( + Vector3d.ONE, 1e-3)) + self.assertTrue(not Vector3d.ZERO.equal( + Vector3d.ONE, 1e-1)) + + self.assertTrue(Vector3d.ZERO.equal( + Vector3d.ONE, 1)) + self.assertTrue(Vector3d.ZERO.equal( + Vector3d.ONE, 1.1)) def test_finite(self): vec1 = Vector3d(0.1, 0.2, 0.3) - self.assertTrue(vec1.IsFinite()) + self.assertTrue(vec1.is_finite()) if __name__ == '__main__': diff --git a/src/python/Vector4.i b/src/python/Vector4.i new file mode 100644 index 000000000..1608bce03 --- /dev/null +++ b/src/python/Vector4.i @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2021 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifdef SWIGRUBY +%begin %{ +#define HAVE_ISFINITE 1 +%} +#endif + +%module vector4 +%{ +#include +%} + +namespace ignition +{ + namespace math + { + template + class Vector4 + { + %rename("%(undercase)s", %$isfunction, %$ismember, %$not %$isconstructor) ""; + %rename("%(uppercase)s", %$isstatic, %$isvariable) ""; + public: static const Vector4 Zero; + public: static const Vector4 One; + public: Vector4(); + public: Vector4(const T &_x, const T &_y, const T &_z, const T &_w); + public: Vector4(const Vector4 &_v); + public: virtual ~Vector4(); + public: T Distance(const Vector4 &_pt) const; + public: T Length() const; + public: T SquaredLength() const; + public: void Normalize(); + public: inline void Set(T _x = 0, T _y = 0, T _z = 0, T _w = 0); + public: Vector4 operator+(const Vector4 &_v) const; + public: inline Vector4 operator+(const T _s) const; + public: inline Vector4 operator-() const; + public: inline Vector4 operator-(const Vector4 &_pt) const; + public: inline Vector4 operator-(const T _s) const; + public: const Vector4 operator/(const Vector4 &_pt) const; + public: const Vector4 operator/(T _v) const; + public: Vector4 operator*(const Vector4 &_p) const; + public: inline Vector4 operator*(T _s) const; + public: bool operator==(const Vector4 &_v) const; + public: bool Equal(const Vector4 &_v, const T &_tol) const; + public: bool IsFinite() const; + public: inline T X() const; + public: inline T Y() const; + public: inline T Z() const; + public: inline T W() const; + public: inline void X(const T &_v); + public: inline void Y(const T &_v); + public: inline void Z(const T &_v); + public: inline void W(const T &_v); + }; + + %template(Vector4i) Vector4; + %template(Vector4d) Vector4; + %template(Vector4f) Vector4; + } +} diff --git a/src/Vector4_TEST.py b/src/python/Vector4_TEST.py similarity index 71% rename from src/Vector4_TEST.py rename to src/python/Vector4_TEST.py index ca4a6fa60..b85ecf9cd 100644 --- a/src/Vector4_TEST.py +++ b/src/python/Vector4_TEST.py @@ -22,16 +22,16 @@ class TestVector4(unittest.TestCase): def test_construction(self): v = Vector4d() - self.assertAlmostEqual(0.0, v.X()) - self.assertAlmostEqual(0.0, v.Y()) - self.assertAlmostEqual(0.0, v.Z()) - self.assertAlmostEqual(0.0, v.W()) + self.assertAlmostEqual(0.0, v.x()) + self.assertAlmostEqual(0.0, v.y()) + self.assertAlmostEqual(0.0, v.z()) + self.assertAlmostEqual(0.0, v.w()) vec = Vector4d(1, 0, 0, 0) - self.assertEqual(vec.X(), 1) - self.assertEqual(vec.Y(), 0) - self.assertEqual(vec.Z(), 0) - self.assertEqual(vec.W(), 0) + self.assertEqual(vec.x(), 1) + self.assertEqual(vec.y(), 0) + self.assertEqual(vec.z(), 0) + self.assertEqual(vec.w(), 0) vec2 = Vector4d(vec) self.assertEqual(vec2, vec) @@ -46,12 +46,12 @@ def test_construction(self): def test_vector4(self): v = Vector4d() - # Distance, Length() - v.Set(1, 2, 3, 4) - self.assertEqual(v.Length(), v.Distance(Vector4d.Zero)) + # Distance, length() + v.set(1, 2, 3, 4) + self.assertEqual(v.length(), v.distance(Vector4d.ZERO)) # __truediv__ - v.Set(4, 4, 4, 4) + v.set(4, 4, 4, 4) v = v / Vector4d(1, 2, 2, 4) self.assertEqual(v, Vector4d(4, 2, 2, 1)) @@ -64,67 +64,67 @@ def test_vector4(self): self.assertEqual(v, Vector4d(4, 3, 3, 2)) # __truediv__ - v.Set(1, 2, 2, 4) + v.set(1, 2, 2, 4) v /= Vector4d(1, 4, 8, 4) self.assertEqual(v, Vector4d(1, 0.5, 0.25, 1)) # __mul__ - v.Set(1, 2, 2, 4) + v.set(1, 2, 2, 4) v *= Vector4d(2, 0.5, 0.25, 0.1) self.assertEqual(v, Vector4d(2, 1, 0.5, 0.4)) # Test the static defines. - self.assertEqual(Vector4d.Zero, + self.assertEqual(Vector4d.ZERO, Vector4d(0, 0, 0, 0)) - self.assertEqual(Vector4d.One, + self.assertEqual(Vector4d.ONE, Vector4d(1, 1, 1, 1)) def test_distance(self): vec1 = Vector4d(0, 0, 0, 0) vec2 = Vector4d(1, 2, 3, 4) - dist = vec1.Distance(vec2) + dist = vec1.distance(vec2) self.assertTrue(abs(dist - 5.47722557505) < 1e-6) def test_squared_length(self): vec1 = Vector4d(0, 0, 0, 0) vec2 = Vector4d(1, 2, 3, 4) - sum1 = vec1.SquaredLength() - sum2 = vec2.SquaredLength() + sum1 = vec1.squared_length() + sum2 = vec2.squared_length() self.assertEqual(sum1, 0) self.assertEqual(sum2, 30) def test_length(self): # Zero vector - self.assertEqual(Vector4d.Zero.Length(), 0.0) - self.assertEqual(Vector4d.Zero.SquaredLength(), 0.0) + self.assertEqual(Vector4d.ZERO.length(), 0.0) + self.assertEqual(Vector4d.ZERO.squared_length(), 0.0) # One vector - self.assertTrue(abs(Vector4d.One.Length() - math.sqrt(4.0)) < 1e-10) + self.assertTrue(abs(Vector4d.ONE.length() - math.sqrt(4.0)) < 1e-10) - self.assertEqual(Vector4d.One.SquaredLength(), 4.0) + self.assertEqual(Vector4d.ONE.squared_length(), 4.0) # Arbitrary vector v = Vector4d(0.1, -4.2, 2.5, -1.2) - self.assertTrue(abs(v.Length() - 5.03388517946) < 1e-10) + self.assertTrue(abs(v.length() - 5.03388517946) < 1e-10) - self.assertTrue(abs(v.SquaredLength() - 25.34) < 1e-10) + self.assertTrue(abs(v.squared_length() - 25.34) < 1e-10) def test_normalize(self): vec1 = Vector4d(0, 0, 0, 0) vec2 = Vector4d(1, 2, 3, 4) vec3 = vec1 - vec3.Normalize() + vec3.normalize() self.assertEqual(vec3, vec1) - self.assertEqual(vec1, Vector4d.Zero) + self.assertEqual(vec1, Vector4d.ZERO) vec3 = vec2 - vec2.Normalize() - self.assertTrue(vec2.Equal(Vector4d(0.182575, + vec2.normalize() + self.assertTrue(vec2.equal(Vector4d(0.182575, 0.365150, 0.547725, 0.730300), 1e-5)) def test_add(self): @@ -142,14 +142,14 @@ def test_add(self): self.assertEqual(vec1 + 0, vec1) # Vector left and right - self.assertEqual(Vector4d.Zero + vec1, vec1) - self.assertEqual(vec1 + Vector4d.Zero, vec1) + self.assertEqual(Vector4d.ZERO + vec1, vec1) + self.assertEqual(vec1 + Vector4d.ZERO, vec1) # Addition assignment vec4 = vec1 vec4 += 0 self.assertEqual(vec4, vec1) - vec4 += Vector4d.Zero + vec4 += Vector4d.ZERO self.assertEqual(vec4, vec1) # Add non-trivial scalar values left and right @@ -174,14 +174,14 @@ def test_sub(self): self.assertEqual(vec1 - 0, vec1) # Vector left and right - self.assertEqual(Vector4d.Zero - vec1, -vec1) - self.assertEqual(vec1 - Vector4d.Zero, vec1) + self.assertEqual(Vector4d.ZERO - vec1, -vec1) + self.assertEqual(vec1 - Vector4d.ZERO, vec1) # Subtraction assignment vec4 = vec1 vec4 -= 0 self.assertEqual(vec4, vec1) - vec4 -= Vector4d.Zero + vec4 -= Vector4d.ZERO self.assertEqual(vec4, vec1) # Subtract non-trivial scalar values left and right @@ -211,17 +211,17 @@ def test_multiply(self): # Multiply by zero # Scalar right - self.assertEqual(v * 0, Vector4d.Zero) + self.assertEqual(v * 0, Vector4d.ZERO) # Element-wise vector multiplication - self.assertEqual(v * Vector4d.Zero, Vector4d.Zero) + self.assertEqual(v * Vector4d.ZERO, Vector4d.ZERO) # Multiply by one # Scalar right self.assertEqual(v * 1, v) # Element-wise vector multiplication - self.assertEqual(v * Vector4d.One, v,) + self.assertEqual(v * Vector4d.ONE, v,) # Multiply by non-trivial scalar value scalar = 2.5 @@ -240,21 +240,21 @@ def test_not_equal(self): self.assertTrue(not(vec1 != vec3)) def test_equal(self): - self.assertTrue(not Vector4d.Zero.Equal( - Vector4d.One, 1e-6)) - self.assertTrue(not Vector4d.Zero.Equal( - Vector4d.One, 1e-3)) - self.assertTrue(not Vector4d.Zero.Equal( - Vector4d.One, 1e-1)) - - self.assertTrue(Vector4d.Zero.Equal( - Vector4d.One, 1)) - self.assertTrue(Vector4d.Zero.Equal( - Vector4d.One, 1.1)) + self.assertTrue(not Vector4d.ZERO.equal( + Vector4d.ONE, 1e-6)) + self.assertTrue(not Vector4d.ZERO.equal( + Vector4d.ONE, 1e-3)) + self.assertTrue(not Vector4d.ZERO.equal( + Vector4d.ONE, 1e-1)) + + self.assertTrue(Vector4d.ZERO.equal( + Vector4d.ONE, 1)) + self.assertTrue(Vector4d.ZERO.equal( + Vector4d.ONE, 1.1)) def test_finite(self): vec1 = Vector4d(0.1, 0.2, 0.3, 0.4) - self.assertTrue(vec1.IsFinite()) + self.assertTrue(vec1.is_finite()) if __name__ == '__main__': diff --git a/src/python/python.i b/src/python/python.i index e80c81f87..614c220bd 100644 --- a/src/python/python.i +++ b/src/python/python.i @@ -1,7 +1,7 @@ %module "math" -%include ../Angle.i -%include ../GaussMarkovProcess.i -%include ../Rand.i -%include ../Vector2.i -%include ../Vector3.i -%include ../Vector4.i +%include Angle.i +%include GaussMarkovProcess.i +%include Rand.i +%include Vector2.i +%include Vector3.i +%include Vector4.i diff --git a/src/python_TEST.py b/src/python/python_TEST.py similarity index 83% rename from src/python_TEST.py rename to src/python/python_TEST.py index 86b6372bb..ed393904b 100644 --- a/src/python_TEST.py +++ b/src/python/python_TEST.py @@ -20,12 +20,12 @@ class TestPythonInterface(unittest.TestCase): def test_construction(self): angle1 = ignition.math.Angle() - self.assertEqual(angle1.Radian(), 0.0) + self.assertEqual(angle1.radian(), 0.0) v1 = ignition.math.Vector3d(0, 0, 0) - self.assertEqual(v1, ignition.math.Vector3d.Zero) + self.assertEqual(v1, ignition.math.Vector3d.ZERO) v2 = ignition.math.Vector2d(1, 2) - self.assertEqual(v2.X(), 1) - self.assertEqual(v2.Y(), 2) + self.assertEqual(v2.x(), 1) + self.assertEqual(v2.y(), 2) if __name__ == '__main__': diff --git a/src/Angle.i b/src/ruby/Angle.i similarity index 100% rename from src/Angle.i rename to src/ruby/Angle.i diff --git a/src/Angle_TEST.rb b/src/ruby/Angle_TEST.rb similarity index 100% rename from src/Angle_TEST.rb rename to src/ruby/Angle_TEST.rb diff --git a/src/ruby/CMakeLists.txt b/src/ruby/CMakeLists.txt new file mode 100644 index 000000000..012f396a1 --- /dev/null +++ b/src/ruby/CMakeLists.txt @@ -0,0 +1,73 @@ +################################################# +# Setup swig +if (SWIG_FOUND) + if (POLICY CMP0078) + cmake_policy(SET CMP0078 NEW) + endif() + if (POLICY CMP0086) + cmake_policy(SET CMP0086 NEW) + endif() + + include(${SWIG_USE_FILE}) + set(CMAKE_SWIG_FLAGS "") + + include_directories(${PROJECT_SOURCE_DIR}/include) + + set(swig_files + Angle + GaussMarkovProcess + Rand + Vector2 + Vector3 + Vector4) +endif() + +################################################# +# Create and install Ruby interfaces +# Example usage +# $ export RUBYLIB=/usr/local/lib/ruby +# $ ruby -e "require 'ignition/math'; a = Ignition::Math::Angle.new(20); puts a.Degree()" +if (RUBY_FOUND) + foreach (swig_file ${swig_files}) + # Assuming that each swig file has a test + list(APPEND ruby_tests ${swig_file}_TEST) + + # Generate the list if .i files + list(APPEND swig_i_files ${swig_file}.i) + endforeach() + list(APPEND ruby_tests ruby_TEST) + + # Turn on c++ + set_source_files_properties(${swig_i_files} ruby.i PROPERTIES CPLUSPLUS ON) + + # Create the ruby library + + set(CMAKE_SWIG_OUTDIR "${CMAKE_BINARY_DIR}/lib/ruby") + if(CMAKE_VERSION VERSION_GREATER 3.8.0) + SWIG_ADD_LIBRARY(math LANGUAGE ruby SOURCES ruby.i ${swig_i_files}) + else() + SWIG_ADD_MODULE(math ruby ruby.i ${swig_i_files}) + endif() + + # Suppress warnings on SWIG-generated files + target_compile_options(math PRIVATE + $<$:-Wno-pedantic -Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> + $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> + $<$:-Wno-shadow -Wno-maybe-uninitialized -Wno-unused-parameter> + ) + target_include_directories(math SYSTEM PUBLIC ${RUBY_INCLUDE_DIRS}) + + SWIG_LINK_LIBRARIES(math + ${RUBY_LIBRARY} + ignition-math${PROJECT_VERSION_MAJOR} + ) + target_compile_features(math PUBLIC ${IGN_CXX_${c++standard}_FEATURES}) + install(TARGETS math DESTINATION ${IGN_LIB_INSTALL_DIR}/ruby/ignition) + + # Add the ruby tests + foreach (test ${ruby_tests}) + add_test(NAME ${test}.rb COMMAND + ruby -I${CMAKE_BINARY_DIR}/lib ${CMAKE_SOURCE_DIR}/src/ruby/${test}.rb + --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/${test}rb.xml) + endforeach() +endif() diff --git a/src/GaussMarkovProcess.i b/src/ruby/GaussMarkovProcess.i similarity index 100% rename from src/GaussMarkovProcess.i rename to src/ruby/GaussMarkovProcess.i diff --git a/src/GaussMarkovProcess_TEST.rb b/src/ruby/GaussMarkovProcess_TEST.rb similarity index 100% rename from src/GaussMarkovProcess_TEST.rb rename to src/ruby/GaussMarkovProcess_TEST.rb diff --git a/src/Rand.i b/src/ruby/Rand.i similarity index 100% rename from src/Rand.i rename to src/ruby/Rand.i diff --git a/src/Rand_TEST.rb b/src/ruby/Rand_TEST.rb similarity index 100% rename from src/Rand_TEST.rb rename to src/ruby/Rand_TEST.rb diff --git a/src/Vector2.i b/src/ruby/Vector2.i similarity index 100% rename from src/Vector2.i rename to src/ruby/Vector2.i diff --git a/src/Vector2_TEST.rb b/src/ruby/Vector2_TEST.rb similarity index 100% rename from src/Vector2_TEST.rb rename to src/ruby/Vector2_TEST.rb diff --git a/src/Vector3.i b/src/ruby/Vector3.i similarity index 100% rename from src/Vector3.i rename to src/ruby/Vector3.i diff --git a/src/Vector3_TEST.rb b/src/ruby/Vector3_TEST.rb similarity index 100% rename from src/Vector3_TEST.rb rename to src/ruby/Vector3_TEST.rb diff --git a/src/Vector4.i b/src/ruby/Vector4.i similarity index 100% rename from src/Vector4.i rename to src/ruby/Vector4.i diff --git a/src/Vector4_TEST.rb b/src/ruby/Vector4_TEST.rb similarity index 100% rename from src/Vector4_TEST.rb rename to src/ruby/Vector4_TEST.rb diff --git a/src/ruby/ruby.i b/src/ruby/ruby.i index 0364d1d74..31168b833 100644 --- a/src/ruby/ruby.i +++ b/src/ruby/ruby.i @@ -1,7 +1,7 @@ %module "ignition::math" -%include ../Angle.i -%include ../GaussMarkovProcess.i -%include ../Rand.i -%include ../Vector2.i -%include ../Vector3.i -%include ../Vector4.i +%include Angle.i +%include GaussMarkovProcess.i +%include Rand.i +%include Vector2.i +%include Vector3.i +%include Vector4.i diff --git a/src/ruby_TEST.rb b/src/ruby/ruby_TEST.rb similarity index 100% rename from src/ruby_TEST.rb rename to src/ruby/ruby_TEST.rb