Repository: engnadeau/pybotics

Issue:
Robot Model-Specific Parameters Should be in External Files
Robot Model-Specific Parameters (e.g., MDH, joint limits, etc) Should be in External Files (e.g., csv, json, etc). This way, new models and modifications to models are not tied to the codebase. `robot_model.py` should be deprecated and example models should be saved in a separate `example` folder in the repo.


Discussion:

Resolving patch:
diff --git a/examples/example_robot.py b/examples/example_robot.py
--- a/examples/example_robot.py
+++ b/examples/example_robot.py
@@ -8,18 +8,17 @@
 np.set_printoptions(suppress=True)
 
 # create robot
-ideal_robot = py.Robot()
-ideal_robot.robot_model = py.robot_model.ur10()
+model = np.loadtxt('ur10-mdh.csv', delimiter=',')
+robot = py.Robot(model)
 
-# create pseudo-realistic robot with kinematic errors
-real_robot = copy.deepcopy(ideal_robot)
-real_robot.impair_robot_model()
-
-print('Ideal Robot Model:\n', ideal_robot.robot_model, '\n')
-print('Pseudo-Real Robot Model:\n', real_robot.robot_model, '\n')
+print('Robot Model:\n{}\n'.format(robot.robot_model))
 
 # demonstrate forward kinematics
-joints = [0, 0, 0, 0, 0, 0]
+joints = [0] * robot.num_dof()
+pose = robot.fk(joints)
+
+print('Pose:\n{}\n'.format(pose))
 
-print('Ideal Pose:\n', ideal_robot.fk(joints), '\n')
-print('Pseudo-Real Pose:\n', real_robot.fk(joints), '\n')
+# demonstrate inverse kinematics
+new_joints = robot.ik(pose)
+print('Solved Joints:\n{}\n'.format(new_joints))
diff --git a/pybotics/__init__.py b/pybotics/__init__.py
--- a/pybotics/__init__.py
+++ b/pybotics/__init__.py
@@ -1,5 +1,4 @@
 # make the follow accessible from pybotics namespace
 from . import geometry
 from . import kinematics
-from .robot import *
-from . import robot_model
+from .robot import Robot
diff --git a/pybotics/robot_model.py b/pybotics/robot_model.py
deleted file mode 100644
--- a/pybotics/robot_model.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import numpy as np
-
-'''
-Modified DH parameter matrices of various robots (rx, tx, rz, tz) aka (alpha, a, theta, d)
-'''
-
-
-def ur10():
-    model = np.array([
-        [0, 0, 0, 118.0],
-        [np.pi / 2.0, 0, np.pi, 0],
-        [0, 612.7, 0, 0],
-        [0, 571.6, 0, 163.9],
-        [-np.pi / 2.0, 0, 0, 115.7],
-        [np.pi / 2.0, 0, np.pi, 92.2]
-    ])
-    return model
-
-
-def puma_560():
-    model = np.array([
-        [0, 0, 0, 0],
-        [-np.pi / 2.0, 0, 0, 0],
-        [0, 612.7, 0, 0],
-        [0, 571.6, 0, 163.9],
-        [-np.pi / 2.0, 0, 0, 115.7],
-        [np.pi / 2.0, 0, np.pi, 92.2]
-    ])
-    return model
-
-
-def kuka_lbr_iiwa_7():
-    model = np.array([
-        [0, 0, 0, 340],
-        [-np.pi / 2.0, 0, 0, 0],
-        [np.pi / 2.0, 0, 0, 400],
-        [np.pi / 2.0, 0, 0, 0],
-        [-np.pi / 2.0, 0, 0, 400],
-        [-np.pi / 2.0, 0, 0, 0],
-        [np.pi / 2.0, 0, 0, 126]
-    ])
-    return model


Test patch:
diff --git a/tests/test_robot.py b/tests/test_robot.py
--- a/tests/test_robot.py
+++ b/tests/test_robot.py
@@ -1,15 +1,22 @@
 from unittest import TestCase
-import logging
-from pybotics import robot_model
+import copy
 from pybotics.robot import Robot
 import numpy as np
+import os
 
 
 class TestRobot(TestCase):
     def setUp(self):
-        logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:\t%(message)s')
-        np.set_printoptions(suppress=True)
-        self.robot = Robot(robot_model.ur10())
+        # load UR10 model for testing
+        model = np.array([
+            0, 0, 0, 118,
+            1.5707963267949, 0, 3.14159265358979, 0,
+            0, 612.7, 0, 0,
+            0, 571.6, 0, 163.9,
+            - 1.5707963267949, 0, 0, 115.7,
+            1.5707963267949, 0, 3.14159265358979, 92.2
+        ]).reshape((-1, 4))
+        self.robot = Robot(model)
 
     def test_num_dof(self):
         # ur10 has 6 DOF
@@ -35,7 +42,7 @@ def test_fk(self):
         np.testing.assert_allclose(actual=actual_transform, desired=expected_transform, rtol=1e-6, atol=1e-6)
 
     def test_impair_robot_model(self):
-        impaired_robot = Robot(robot_model.ur10())
+        impaired_robot = copy.deepcopy(self.robot)
         impaired_robot.impair_robot_model(0.1)
 
         model_diff = impaired_robot.robot_model - self.robot.robot_model
diff --git a/tests/test_robot_model.py b/tests/test_robot_model.py
deleted file mode 100644
--- a/tests/test_robot_model.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from unittest import TestCase
-
-from pybotics import robot_model
-
-
-class TestUr10(TestCase):
-    def test_ur10(self):
-        model = robot_model.ur10()
-
-        assert model.shape[0] == 6
-        assert model.shape[1] == 4
-
-    def test_puma_560(self):
-        model = robot_model.puma_560()
-
-        assert model.shape[0] == 6
-        assert model.shape[1] == 4
-
-    def test_kuka_lbr_iiwa_7(self):
-        model = robot_model.kuka_lbr_iiwa_7()
-
-        assert model.shape[0] == 7
-        assert model.shape[1] == 4