diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index fcefed3ff70d39b558214431217036b67edac6f9..5463ef857beed42f718ba1800eccc0d85bf9805c 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -1,2 +1,6 @@
 0067c8aa66aac548601e2a3fd029aa264cc59f2a
 76b68f785df31b00e153290b45ec290a9c5f7963
+# ruff --fix . (Guilhem Saurel, 2023-10-24)
+58dee5ae90eded5125825a2da0fe76a5031f3334
+# black . (Guilhem Saurel, 2023-10-24)
+889ff8d1ca00b9e317e1da4136e233bb49a049df
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0281d6e180a654024a34de55a293f03aac574343..fcd4d41458b519594780898d5e79b6ce0f97f495 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1 +1 @@
-include: http://rainboard.laas.fr/project/hpp-fcl/.gitlab-ci.yml
+include: https://rainboard.laas.fr/project/hpp-fcl/.gitlab-ci.yml
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 2ce48fbda3bbdab678fdf2f1fa1e31dcf5644456..aa16d1dd24d9ece0618b3a3c80abcd8f321916b6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,16 +1,24 @@
 ci:
-    autoupdate_branch: 'devel'
+  autoupdate_branch: devel
 repos:
--   repo: https://github.com/pre-commit/mirrors-clang-format
-    rev: v17.0.3
-    hooks:
-    -   id: clang-format
-        args: ['--style={BasedOnStyle: Google, SortIncludes: false}']
--   repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.5.0
-    hooks:
-    -   id: trailing-whitespace
--   repo: https://github.com/psf/black
-    rev: 23.10.0
-    hooks:
-    -   id: black
+- repo: https://github.com/charliermarsh/ruff-pre-commit
+  rev: v0.0.267
+  hooks:
+  - id: ruff
+    args:
+    - --fix
+    - --exit-non-zero-on-fix
+- repo: https://github.com/pre-commit/mirrors-clang-format
+  rev: v17.0.3
+  hooks:
+  - id: clang-format
+    args:
+    - '--style={BasedOnStyle: Google, SortIncludes: false}'
+- repo: https://github.com/pre-commit/pre-commit-hooks
+  rev: v4.5.0
+  hooks:
+  - id: trailing-whitespace
+- repo: https://github.com/psf/black
+  rev: 23.10.0
+  hooks:
+  - id: black
diff --git a/README.md b/README.md
index ba47568eee26e7fc0fd0651a81399218bc1837be..8c454ed3f6febd8abc2b1a4cbf7816c71b7a386f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
-HPP-FCL — An extension of the Flexible Collision Library
-=======
+# HPP-FCL — An extension of the Flexible Collision Library
 
 <p align="center">
   <a href="https://gepgitlab.laas.fr/humanoid-path-planner/hpp-fcl/commits/master/"><img src="https://gepgitlab.laas.fr/humanoid-path-planner/hpp-fcl/badges/master/pipeline.svg" alt="Pipeline status"/></a>
@@ -8,6 +7,8 @@ HPP-FCL — An extension of the Flexible Collision Library
   <a href="https://anaconda.org/conda-forge/hpp-fcl"><img src="https://img.shields.io/conda/dn/conda-forge/hpp-fcl.svg" alt="Conda Downloads"/></a>
   <a href="https://anaconda.org/conda-forge/hpp-fcl"><img src="https://img.shields.io/conda/vn/conda-forge/hpp-fcl.svg" alt="Conda Version"/></a>
   <a href="https://badge.fury.io/py/hpp-fcl"><img src="https://badge.fury.io/py/hpp-fcl.svg" alt="PyPI version"></a>
+  <a href="https://github.com/psf/black"><img alt="black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
+  <a href="https://github.com/astral-sh/ruff"><img alt="ruff" src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json"></a>
 </p>
 
 [FCL](https://github.com/flexible-collision-library/fcl) was forked in 2015. Since then, a large part of the code has been rewritten or removed (for the unused and untested part).
@@ -37,4 +38,3 @@ Unlike the original FCL library, HPP-FCL implements the well-established GJK alg
 ## Acknowledgments
 
 The development of **HPP-FCL** is actively supported by the [Gepetto team](http://projects.laas.fr/gepetto/) [@LAAS-CNRS](http://www.laas.fr), the [Willow team](https://www.di.ens.fr/willow/) [@INRIA](http://www.inria.fr) and, to some extend, [Eureka Robotics](https://eurekarobotics.com/).
-
diff --git a/doc/generate_distance_plot.py b/doc/generate_distance_plot.py
index bfc66deb822ff910ba5d5d92920581bf87640828..1456a2f88353191c890af6eb789ff5ebddb69a7b 100644
--- a/doc/generate_distance_plot.py
+++ b/doc/generate_distance_plot.py
@@ -1,6 +1,5 @@
 import matplotlib.pyplot as plt
 import numpy as np
-from math import sqrt
 
 interactive = False
 
diff --git a/doc/gjk.py b/doc/gjk.py
index 3d200b128a59c111316d8aff773072e0c88da885..d80564c4bed01c5384afb397e8dfcfb872d3fbf1 100644
--- a/doc/gjk.py
+++ b/doc/gjk.py
@@ -10,7 +10,8 @@ plane_fmt = ""
 edge_fmt = "{j}a * {b}a_{c}a + {j}{b} * {c}a_aa - {j}{c} * {b}a_aa"
 
 # These checks must be negative and not positive, as in the cheat sheet.
-# They are the same as in the cheat sheet, except that we consider (...).dot(A) instead of (...).dot(-A)
+# They are the same as in the cheat sheet, except that we consider (...).dot(A)
+# instead of (...).dot(-A)
 plane_tests = ["C.dot (a_cross_b)", "D.dot(a_cross_c)", "-D.dot(a_cross_b)"]
 checks = (
     plane_tests
@@ -247,9 +248,9 @@ implications = [
 def set_test_values(current_tests, test_values, itest, value):
     def satisfies(values, indices):
         for k in indices:
-            if k > 0 and values[k - 1] != True:
+            if k > 0 and values[k - 1] is not True:
                 return False
-            if k < 0 and values[-k - 1] != False:
+            if k < 0 and values[-k - 1] is not False:
                 return False
         return True
 
@@ -286,17 +287,17 @@ def set_tests_values(current_tests, test_values, itests, values):
 def apply_test_values(cases, test_values):
     def canSatisfy(values, indices):
         for k in indices:
-            if k > 0 and values[k - 1] == False:
+            if k > 0 and values[k - 1] is False:
                 return False
-            if k < 0 and values[-k - 1] == True:
+            if k < 0 and values[-k - 1] is True:
                 return False
         return True
 
     def satisfies(values, indices):
         for k in indices:
-            if k > 0 and values[k - 1] != True:
+            if k > 0 and values[k - 1] is not True:
                 return False
-            if k < 0 and values[-k - 1] != False:
+            if k < 0 and values[-k - 1] is not False:
                 return False
         return True
 
@@ -337,7 +338,7 @@ def max_number_of_tests(
     prevScore=0,
 ):
     for test in current_tests:
-        assert test_values[test] == None, "Test " + str(test) + " already performed"
+        assert test_values[test] is None, "Test " + str(test) + " already performed"
 
     left_cases = apply_test_values(cases, test_values)
 
@@ -375,7 +376,8 @@ def max_number_of_tests(
             remaining_tests = None
 
         if remaining_tests is not None:
-            # Do not put this in try catch as I do not want other ValueError to be understood as an infeasible branch.
+            # Do not put this in try catch as I do not want other ValueError to be
+            # understood as an infeasible branch.
             score_if_t, order_if_t = max_number_of_tests(
                 remaining_tests,
                 left_cases,
@@ -396,7 +398,8 @@ def max_number_of_tests(
             remaining_tests = None
 
         if remaining_tests is not None:
-            # Do not put this in try catch as I do not want other ValueError to be understood as an infeasible branch.
+            # Do not put this in try catch as I do not want other ValueError to be
+            # understood as an infeasible branch.
             score_if_f, order_if_f = max_number_of_tests(
                 remaining_tests,
                 left_cases,
@@ -438,37 +441,37 @@ def printOrder(order, indent="", start=True, file=sys.stdout, curTests=[]):
             file=file,
         )
         print(indent + "const vertex_id_t a = 3, b = 2, c = 1, d = 0;", file=file)
-        for l in "abcd":
+        for v in "abcd":
             print(
                 indent
-                + "const Vec3f& {} (current.vertex[{}]->w);".format(l.upper(), l),
+                + "const Vec3f& {} (current.vertex[{}]->w);".format(v.upper(), v),
                 file=file,
             )
-        print(indent + "const FCL_REAL aa = A.squaredNorm();".format(l), file=file)
-        for l in "dcb":
+        print(indent + "const FCL_REAL aa = A.squaredNorm();".format(), file=file)
+        for v in "dcb":
             for m in "abcd":
-                if m <= l:
+                if m <= v:
                     print(
                         indent
                         + "const FCL_REAL {0}{1}    = {2}.dot({3});".format(
-                            l, m, l.upper(), m.upper()
+                            v, m, v.upper(), m.upper()
                         ),
                         file=file,
                     )
                 else:
                     print(
-                        indent + "const FCL_REAL& {0}{1}    = {1}{0};".format(l, m),
+                        indent + "const FCL_REAL& {0}{1}    = {1}{0};".format(v, m),
                         file=file,
                     )
-            print(indent + "const FCL_REAL {0}a_aa = {0}a - aa;".format(l), file=file)
+            print(indent + "const FCL_REAL {0}a_aa = {0}a - aa;".format(v), file=file)
         for l0, l1 in zip("bcd", "cdb"):
             print(
                 indent + "const FCL_REAL {0}a_{1}a = {0}a - {1}a;".format(l0, l1),
                 file=file,
             )
-        for l in "bc":
+        for v in "bc":
             print(
-                indent + "const Vec3f a_cross_{0} = A.cross({1});".format(l, l.upper()),
+                indent + "const Vec3f a_cross_{0} = A.cross({1});".format(v, v.upper()),
                 file=file,
             )
         print("", file=file)
@@ -502,15 +505,12 @@ def printOrder(order, indent="", start=True, file=sys.stdout, curTests=[]):
         elif region == "A":
             print(indent + "originToPoint (current, a, A, next, ray);", file=file)
         elif len(region) == 2:
-            a = region[0]
+            region[0]
             B = region[1]
             print(
-                indent
-                + "originToSegment (current, a, {b}, A, {B}, {B}-A, -{b}a_aa, next, ray);".format(
-                    **{
-                        "b": B.lower(),
-                        "B": B,
-                    }
+                indent + "originToSegment "
+                "(current, a, {b}, A, {B}, {B}-A, -{b}a_aa, next, ray);".format(
+                    **{"b": B.lower(), "B": B}
                 ),
                 file=file,
             )
@@ -524,8 +524,8 @@ def printOrder(order, indent="", start=True, file=sys.stdout, curTests=[]):
             else:
                 test = "-" + test
             print(
-                indent
-                + "originToTriangle (current, a, {b}, {c}, ({B}-A).cross({C}-A), {t}, next, ray);".format(
+                indent + "originToTriangle "
+                "(current, a, {b}, {c}, ({B}-A).cross({C}-A), {t}, next, ray);".format(
                     **{"b": B.lower(), "c": C.lower(), "B": B, "C": C, "t": test}
                 ),
                 file=file,
diff --git a/doc/python/doxygen_xml_parser.py b/doc/python/doxygen_xml_parser.py
index a0235dace105a49b6eae41b438a3a61b6446e789..d9590b7e2c2e21c301e8d15d48bb92cc7397c234 100755
--- a/doc/python/doxygen_xml_parser.py
+++ b/doc/python/doxygen_xml_parser.py
@@ -1,4 +1,5 @@
 #!/usr/bin/python3
+# ruff: noqa: E501
 
 from __future__ import print_function
 from lxml import etree
@@ -120,8 +121,6 @@ def _templateParamToDict(param):
 
 
 def makeHeaderGuard(filename):
-    import os
-
     return filename.upper().replace(".", "_").replace("/", "_").replace("-", "_")
 
 
@@ -326,8 +325,6 @@ class MemberDef(Reference):
         return ", ".join([arg.format(n) for n in argnames])
 
     def include(self):
-        import os.path
-
         loc = self.xml.find("location")
         # The location is based on $CMAKE_SOURCE_DIR. Remove first directory.
         return loc.attrib["file"].split("/", 1)[1]
@@ -705,8 +702,6 @@ class Index:
 
     def write(self):
         # Header
-        from os.path import abspath, dirname
-        from time import asctime
 
         self.output.open("doxygen_xml_parser_for_cmake.hh")
         # self.output.out ("// Generated on {}".format (asctime()))
@@ -821,7 +816,7 @@ class OutputStreams(object):
         self._created_files = dict()
 
     def open(self, name):
-        assert self._out == None, "You did not close the previous file"
+        assert self._out is None, "You did not close the previous file"
         import os
 
         fullname = os.path.join(self.output_dir, name)
@@ -895,4 +890,4 @@ if __name__ == "__main__":
     index.parseCompound()
     index.write()
     index.output.writeFooterAndCloseFiles()
-    assert index.output._out == None
+    assert index.output._out is None
diff --git a/doc/python/xml_docstring.py b/doc/python/xml_docstring.py
index 0b1fd09752f709592bf87d173c24f5681f386b64..d36618b71f131e039989e8a83ab9c0ade92c885a 100644
--- a/doc/python/xml_docstring.py
+++ b/doc/python/xml_docstring.py
@@ -59,14 +59,14 @@ class XmlDocString(object):
 
     def _clean(self):
         s = 0
-        for l in self.lines:
-            if len(l.strip()) == 0:
+        for line in self.lines:
+            if len(line.strip()) == 0:
                 s += 1
             else:
                 break
         e = len(self.lines)
-        for l in reversed(self.lines):
-            if len(l.strip()) == 0:
+        for line in reversed(self.lines):
+            if len(line.strip()) == 0:
                 e -= 1
             else:
                 break
@@ -80,7 +80,7 @@ class XmlDocString(object):
             if brief is not None:
                 self._newline()
             self.visit(detailled)
-        from sys import stdout, stderr, version_info
+        from sys import version_info
 
         self.writeErrors(output)
         self._clean()
diff --git a/python/hppfcl/__init__.py b/python/hppfcl/__init__.py
index 34f11992627594885d3cfa093815314ed79d5633..b93784303693b41c29b0e3f89f9f37e4a3691a40 100644
--- a/python/hppfcl/__init__.py
+++ b/python/hppfcl/__init__.py
@@ -31,5 +31,6 @@
 #  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #  POSSIBILITY OF SUCH DAMAGE.
 
+# ruff: noqa: F401, F403
 from .hppfcl import *
-from .hppfcl import __version__, __raw_version__
+from .hppfcl import __raw_version__, __version__
diff --git a/python/hppfcl/viewer.py b/python/hppfcl/viewer.py
index 29cdb2ac8779c5528dad14bc1d4d3f5942ae59bf..15bf53c2d05410b4b6b1fdebfb2b0a92eb5bf7cb 100644
--- a/python/hppfcl/viewer.py
+++ b/python/hppfcl/viewer.py
@@ -3,9 +3,13 @@
 #  Copyright (c) 2019 CNRS
 #  Author: Joseph Mirabel
 
-import hppfcl, numpy as np
+import warnings
+
+import numpy as np
 from gepetto import Color
 
+import hppfcl
+
 
 def applyConfiguration(gui, name, tf):
     gui.applyConfiguration(
@@ -43,10 +47,7 @@ def displayShape(gui, name, geom, color=(0.9, 0.9, 0.9, 1.0)):
         gui.setLightingMode(name, "OFF")
         return True
     else:
-        msg = "Unsupported geometry type for %s (%s)" % (
-            geometry_object.name,
-            type(geom),
-        )
+        msg = "Unsupported geometry type for %s (%s)" % (name, type(geom))
         warnings.warn(msg, category=UserWarning, stacklevel=2)
         return False
 
diff --git a/test/python_unit/geometric_shapes.py b/test/python_unit/geometric_shapes.py
index c6b6b6ee4325b4828a66952552c31dab9f3295fb..b64850e5996c1a20eea9cbee33820434cd3cb728 100644
--- a/test/python_unit/geometric_shapes.py
+++ b/test/python_unit/geometric_shapes.py
@@ -167,11 +167,11 @@ class TestGeometricShapes(TestCase):
             ]
         )
         faces.append(hppfcl.Triangle(0, 1, 2))
-        convex = hppfcl.Convex(verts, faces)
+        hppfcl.Convex(verts, faces)
 
         verts.append(np.array([0, 0, 1]))
         try:
-            convexHull = hppfcl.Convex.convexHull(verts, False, None)
+            hppfcl.Convex.convexHull(verts, False, None)
             qhullAvailable = True
         except Exception as e:
             self.assertEqual(
@@ -180,11 +180,11 @@ class TestGeometricShapes(TestCase):
             qhullAvailable = False
 
         if qhullAvailable:
-            convexHull = hppfcl.Convex.convexHull(verts, False, "")
-            convexHull = hppfcl.Convex.convexHull(verts, True, "")
+            hppfcl.Convex.convexHull(verts, False, "")
+            hppfcl.Convex.convexHull(verts, True, "")
 
             try:
-                convexHull = hppfcl.Convex.convexHull(verts[:3], False, None)
+                hppfcl.Convex.convexHull(verts[:3], False, None)
             except Exception as e:
                 self.assertIn(
                     str(e), "You shouldn't use this function with less than 4 points."
diff --git a/test/scripts/collision-bench.py b/test/scripts/collision-bench.py
index 885995ad3dd9852d72e3da9bfa24ad296b8ac657..62d6e87ef86030f7937e82f0f6c13889904d56c3 100644
--- a/test/scripts/collision-bench.py
+++ b/test/scripts/collision-bench.py
@@ -1,6 +1,7 @@
+import csv
+import sys
+
 import matplotlib.pyplot as plt
-import csv, sys, numpy as np
-from math import sqrt
 
 filename = sys.argv[1]
 
@@ -43,8 +44,8 @@ cases = [
 idx_reorder = sorted(list(range(len(xvals))), key=lambda i: xvals[i])
 
 
-def reorder(l):
-    return [l[i] for i in idx_reorder]
+def reorder(v):
+    return [v[i] for i in idx_reorder]
 
 
 xvals_s = reorder(xvals)
diff --git a/test/scripts/collision.py b/test/scripts/collision.py
index 1604b9637c948e6e923fb2a0b1536790994a266a..73fc979cee5de8d4d7aa76cae9dfa964694cd501 100644
--- a/test/scripts/collision.py
+++ b/test/scripts/collision.py
@@ -1,6 +1,5 @@
 # Load "env.obj" and "rob.obj" in gepetto-gui
 
-import numpy as np
 import os
 from gepetto.corbaserver import Client
 
diff --git a/test/scripts/distance_lower_bound.py b/test/scripts/distance_lower_bound.py
index 1e4b29b52396c7bdaa20f870e1b2b395f02991d6..61e7b3ab318a3a5df4da2896749ef416a9dd2402 100644
--- a/test/scripts/distance_lower_bound.py
+++ b/test/scripts/distance_lower_bound.py
@@ -1,6 +1,5 @@
 # Load "env.obj" and "rob.obj" in gepetto-gui
 
-import numpy as np
 import os
 from gepetto.corbaserver import Client
 
diff --git a/test/scripts/geometric_shapes.py b/test/scripts/geometric_shapes.py
index 02dccadea390742740807d6ceb9e8621a5b623f1..1e893bbf390fd26e6d0bcd33c5bd25ef764c5d48 100644
--- a/test/scripts/geometric_shapes.py
+++ b/test/scripts/geometric_shapes.py
@@ -1,6 +1,6 @@
 # Datas for compare_convex_box
-from gepetto.corbaserver import Client
 from gepetto import Quaternion
+from gepetto.corbaserver import Client
 
 
 def translate(tr, t, d):
@@ -10,7 +10,7 @@ def translate(tr, t, d):
 cl = Client()
 try:
     cl.gui.getWindowID("fcl")
-except:
+except Exception:
     cl.gui.createWindow("fcl")
 
 cl.gui.addBox("fcl/b0", 2, 2, 2, [1, 0, 0, 0.5])
diff --git a/test/scripts/gjk.py b/test/scripts/gjk.py
index bdad975369bd22ab098cf5964b13a88a4d9be536..6eee6d88f9836e1e70aa06b6439c3e66cfecbb0f 100644
--- a/test/scripts/gjk.py
+++ b/test/scripts/gjk.py
@@ -1,6 +1,5 @@
 # This script displays two triangles and two spheres in gepetto-gui
 # It is useful to debug distance computation between two triangles.
-import numpy as np
 from gepetto.corbaserver import Client
 
 Red = [1, 0, 0, 0.5]
diff --git a/test/scripts/obb.py b/test/scripts/obb.py
index 7b59e61593b779afad1c498fecda5c05cbe0b33f..1418e0ee4be4fa2f04ceada4b125f62b41b3c9ed 100644
--- a/test/scripts/obb.py
+++ b/test/scripts/obb.py
@@ -1,7 +1,10 @@
-import matplotlib.pyplot as plt
-import csv, sys, numpy as np
+import csv
+import sys
 from math import sqrt
 
+import matplotlib.pyplot as plt
+import numpy as np
+
 filename = sys.argv[1]
 
 with open(filename, "r") as file:
@@ -67,9 +70,25 @@ if time_vs_sep_axis:
         plt.figure(iplot)
     plt.title("Time, with std dev, versus separating axis")
     for k, n in enumerate(fieldnames[4:]):
-        # plt.errorbar ([ np.linspace(0, 11, 12) + shift for shift in np.linspace (-0.2, 0.2, ) ], means[k], stddevs[k], label=n)
+        # plt.errorbar(
+        # [
+        # np.linspace(0, 11, 12) + shift
+        # for shift in np.linspace(
+        # -0.2,
+        # 0.2,
+        # )
+        # ],
+        # means[k],
+        # stddevs[k],
+        # label=n,
+        # )
         plt.errorbar(np.linspace(0, 11, 12), means[k], stddevs[k], label=n)
-        # plt.errorbar (np.linspace(0, 11, 12), means[k],  [ [ 0 ] * len(stddevs[k]), stddevs[k] ], label=n)
+        # plt.errorbar(
+        # np.linspace(0, 11, 12),
+        # means[k],
+        # [[0] * len(stddevs[k]), stddevs[k]],
+        # label=n,
+        # )
     plt.xlim([-0.5, 11.5])
     plt.ylabel("Time (ns)")
     plt.xlabel("Separating axis")
@@ -120,23 +139,23 @@ if avg_time_vs_impl:
         zip(fieldnames[4:], _means, _stddev, _mins, _maxs), key=lambda x: x[1]
     )
     plt.errorbar(
-        [f for f, m, s, l, u in _sorted],
-        [m for f, m, s, l, u in _sorted],
-        [s for f, m, s, l, u in _sorted],
+        [f for f, _, _, _, _ in _sorted],
+        [m for _, m, _, _, _ in _sorted],
+        [s for _, _, s, _, _ in _sorted],
         fmt="go",
         linestyle="",
         label="mean and std deviation",
     )
     plt.plot(
-        [f for f, m, s, l, u in _sorted],
-        [l for f, m, s, l, u in _sorted],
+        [f for f, _, _, _, _ in _sorted],
+        [v for _, _, _, v, _ in _sorted],
         "b+",
         ls="",
         label="min",
     )
     plt.plot(
-        [f for f, m, s, l, u in _sorted],
-        [u for f, m, s, l, u in _sorted],
+        [f for f, _, _, _, _ in _sorted],
+        [u for _, _, _, _, u in _sorted],
         "r+",
         ls="",
         label="max",
diff --git a/test/scripts/octree.py b/test/scripts/octree.py
index a5c865f1444747f5f43c5c44d2346c9bdddb11e4..c0ef6e4c726d0ef72b4a66acf31ed6dfce9519be 100644
--- a/test/scripts/octree.py
+++ b/test/scripts/octree.py
@@ -1,6 +1,5 @@
 # Load "env.obj" and "rob.obj" in gepetto-gui
 
-import numpy as np
 import csv
 import os
 from gepetto.corbaserver import Client