From 37f31a977fa6f23c821d2481ca8e37e46b0b8826 Mon Sep 17 00:00:00 2001
From: m-guberina <gubi.guberina@gmail.com>
Date: Mon, 18 Nov 2024 19:09:19 +0100
Subject: [PATCH] getting closer to using casadi withing SMC. fixed opencv with
 conda. ellipses put in but untested. added something to __init__.py's,
 hopefully more usable now but definitely not done. whatever was last changed
 in drawing example. freedrive_v2 is here - it's freedrive but in controlLoop
 to get all of those benefits.

---
 Dockerfile                                    |   3 +-
 docs/installation.md                          |   4 +-
 python/convenience_tool_box/freedrive_v2.0.py |   4 +
 .../open_close_gripper.py                     |  52 +-
 .../casadi_ocp_collision_avoidance.py         |  34 +
 python/examples/crocoddyl_mpc.py              |   3 +-
 python/examples/crocoddyl_ocp_clik.py         |   3 +-
 python/examples/drawing_from_input_drawing.py |  80 +--
 python/examples/joint_trajectory.csv          | 667 ++++++++++--------
 python/examples/path_in_pixels.csv            | 667 ++++++++++--------
 python/ur_simple_control/__init__.py          |   2 +-
 .../__pycache__/__init__.cpython-312.pyc      | Bin 391 -> 391 bytes
 .../__pycache__/managers.cpython-312.pyc      | Bin 47221 -> 47217 bytes
 python/ur_simple_control/basics/__init__.py   |   1 +
 .../__pycache__/__init__.cpython-312.pyc      | Bin 209 -> 237 bytes
 python/ur_simple_control/clik/__init__.py     |   1 +
 .../clik/__pycache__/__init__.cpython-312.pyc | Bin 207 -> 233 bytes
 python/ur_simple_control/clik/clik.py         |  30 +-
 python/ur_simple_control/dmp/__init__.py      |   1 +
 .../dmp/__pycache__/__init__.cpython-312.pyc  | Bin 206 -> 231 bytes
 python/ur_simple_control/managers.py          |   8 +-
 .../optimal_control/__init__.py               |   4 +
 .../create_pinocchio_casadi_ocp.py            | 149 ++++
 .../crocoddyl_optimal_control.py              |  15 -
 .../optimal_control/get_ocp_args.py           |  15 +
 python/ur_simple_control/util/__init__.py     |   8 +
 .../util/__pycache__/__init__.cpython-312.pyc | Bin 207 -> 207 bytes
 .../calib_board_hacks.cpython-312.pyc         | Bin 13445 -> 13443 bytes
 .../__pycache__/get_model.cpython-312.pyc     | Bin 8245 -> 8617 bytes
 .../util/calib_board_hacks.py                 |   3 -
 .../util/encapsulating_ellipses.py            | 185 +++++
 python/ur_simple_control/util/get_model.py    |  17 +
 .../util/grippers/__init__.py                 |   0
 .../__pycache__/visualize.cpython-312.pyc     | Bin 17531 -> 16894 bytes
 .../meshcat_viewer_wrapper/__init__.py        |   0
 .../meshcat_viewer_wrapper/colors.py          |  49 ++
 .../meshcat_viewer_wrapper/visualizer.py      | 103 +++
 .../ur_simple_control/visualize/visualize.py  |  32 +-
 38 files changed, 1381 insertions(+), 759 deletions(-)
 create mode 100644 python/examples/casadi_ocp_collision_avoidance.py
 create mode 100644 python/ur_simple_control/optimal_control/__init__.py
 create mode 100644 python/ur_simple_control/optimal_control/create_pinocchio_casadi_ocp.py
 create mode 100644 python/ur_simple_control/optimal_control/get_ocp_args.py
 create mode 100644 python/ur_simple_control/util/encapsulating_ellipses.py
 create mode 100644 python/ur_simple_control/util/grippers/__init__.py
 create mode 100644 python/ur_simple_control/visualize/meshcat_viewer_wrapper/__init__.py
 create mode 100644 python/ur_simple_control/visualize/meshcat_viewer_wrapper/colors.py
 create mode 100644 python/ur_simple_control/visualize/meshcat_viewer_wrapper/visualizer.py

diff --git a/Dockerfile b/Dockerfile
index 79df137..ac05d11 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -25,6 +25,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
         vim-python-jedi \
         zsh \
         zsh-syntax-highlighting \
+        libarchive-tools \
         python3-python-qt-binding 
         
 # qt-binding is a really unnecessary 300MB, but i don't want
@@ -74,6 +75,6 @@ RUN pip install -e ./SimpleManipulatorControl/python/
 RUN conda config --add channels conda-forge 
 #RUN conda install --solver=classic conda-forge::conda-libmamba-solver conda-forge::libmamba conda-forge::libmambapy conda-forge::libarchive
 RUN conda install -y casadi opencv
-RUN conda install -y pinocchio -c conda-forge
+RUN conda install --solver=classic -y pinocchio -c conda-forge
 RUN pip install matplotlib meshcat ur_rtde \
                 qpsolvers ecos example_robot_data meshcat_shapes
diff --git a/docs/installation.md b/docs/installation.md
index ff8d3d2..3d92bd0 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -47,7 +47,9 @@ To proceed you need to have the Docker desktop GUI app running (open).
 ----------------------
 7. to run the image run  "docker run --rm -it --net=host -e DISPLAY=$DISPLAY -v /tmp:/tmp ur_simple_control /bin/zsh".
    [Linux and MAC]: NOTE: FIRST RUN "xhost +" EVERY TIME before you run the image. otherwise docker can't open new windows,
-   so real-time-plotting won't work. [MAC] you need to have xquartz installed
+   so real-time-plotting won't work. [MAC] you need to have xquartz installed to have the xhost + command (look at installation for more).
+   NOTE! if you don't get real-time-plotting with xhost +, do xhost + 127.0.0.1 and replace -e DISPLAY=$DISPLAY with 
+   -e DISPLAY=127.0.0.1:0 .
    [WINDOWS]: NOTE: i've been told that mapping the /tmp folder is not necessary on windows and that it in fact might cause problems.
    in this case just remove the "-v /tmp:/tmp" from the command
 8. verify installation by running an example with --visualize-manipulator and --real-time-plotting arguments
diff --git a/python/convenience_tool_box/freedrive_v2.0.py b/python/convenience_tool_box/freedrive_v2.0.py
index fd41882..ea35610 100644
--- a/python/convenience_tool_box/freedrive_v2.0.py
+++ b/python/convenience_tool_box/freedrive_v2.0.py
@@ -5,6 +5,7 @@ import argparse
 from functools import partial
 from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
 from ur_simple_control.basics.basics import freedriveUntilKeyboard
+import pickle
 
 def get_args():
     parser = getMinimalArgParser()
@@ -18,6 +19,9 @@ if __name__ == "__main__":
     robot = RobotManager(args)
 
     pose_n_q_dict = freedriveUntilKeyboard(args, robot)    
+    file = open("./pose_n_q_dict.pickle", 'wb')
+    pickle.dump(pose_n_q_dict, file)
+    file.close()
     print(pose_n_q_dict)
 
     # get expected behaviour here (library can't know what the end is - you have to do this here)
diff --git a/python/convenience_tool_box/open_close_gripper.py b/python/convenience_tool_box/open_close_gripper.py
index af5f97c..32d9e36 100644
--- a/python/convenience_tool_box/open_close_gripper.py
+++ b/python/convenience_tool_box/open_close_gripper.py
@@ -1,31 +1,35 @@
-from rtde_control import RTDEControlInterface as RTDEControl
-from rtde_receive import RTDEReceiveInterface as RTDEReceive
-from rtde_io import RTDEIOInterface
-from ur_simple_control.util.robotiq_gripper import RobotiqGripper
 import pinocchio as pin
 import numpy as np
-import os
 import time
-import signal
-import matplotlib.pyplot as plt
+import argparse
+from functools import partial
+from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
 
+def get_args():
+    parser = getMinimalArgParser()
+    parser.description = 'open gripper, wait a few seconds, then close the gripper'
+    # add more arguments here from different Simple Manipulator Control modules
+    args = parser.parse_args()
+    return args
 
-def handler(signum, frame):
-    gripper.move(255,255,255)
-    time.sleep(2)
-    exit()
+if __name__ == "__main__": 
+    args = get_args()
+    robot = RobotManager(args)
 
-signal.signal(signal.SIGINT, handler)
+    robot.openGripper()
+    time.sleep(5)
+    robot.closeGripper()
 
-gripper = RobotiqGripper()
-gripper.connect("192.168.1.102", 63352)
-#gripper.connect("192.168.1.3", 63352)
-time.sleep(6)
-gripper.activate()
-#time.sleep(3)
-gripper.move(0,100,100)
-time.sleep(4)
-gripper.move(255,255,255)
-#time.sleep(300)
-input("press Enter to close and quit")
-handler(None, None)
+    # get expected behaviour here (library can't know what the end is - you have to do this here)
+    if not args.pinocchio_only:
+        robot.stopRobot()
+
+    if args.save_log:
+        robot.log_manager.plotAllControlLoops()
+
+    if args.visualize_manipulator:
+        robot.killManipulatorVisualizer()
+    
+    if args.save_log:
+        robot.log_manager.saveLog()
+    #loop_manager.stopHandler(None, None)
diff --git a/python/examples/casadi_ocp_collision_avoidance.py b/python/examples/casadi_ocp_collision_avoidance.py
new file mode 100644
index 0000000..cc84856
--- /dev/null
+++ b/python/examples/casadi_ocp_collision_avoidance.py
@@ -0,0 +1,34 @@
+import pinocchio as pin
+import numpy as np
+import time
+import argparse
+from functools import partial
+from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
+from ur_simple_control.optimal_control.get_ocp_args import get_OCP_args
+
+def get_args():
+    parser = getMinimalArgParser()
+    parser.description = 'optimal control in pinocchio.casadi for obstacle avoidance'
+    # add more arguments here from different Simple Manipulator Control modules
+    args = parser.parse_args()
+    return args
+
+if __name__ == "__main__": 
+    args = get_args()
+    robot = RobotManager(args)
+
+    
+
+    # get expected behaviour here (library can't know what the end is - you have to do this here)
+    if not args.pinocchio_only:
+        robot.stopRobot()
+
+    if args.save_log:
+        robot.log_manager.plotAllControlLoops()
+
+    if args.visualize_manipulator:
+        robot.killManipulatorVisualizer()
+    
+    if args.save_log:
+        robot.log_manager.saveLog()
+    #loop_manager.stopHandler(None, None)
diff --git a/python/examples/crocoddyl_mpc.py b/python/examples/crocoddyl_mpc.py
index a8ac8f3..ce9bd05 100644
--- a/python/examples/crocoddyl_mpc.py
+++ b/python/examples/crocoddyl_mpc.py
@@ -3,7 +3,8 @@ import time
 import argparse
 from functools import partial
 from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
-from ur_simple_control.optimal_control.crocoddyl_optimal_control import get_OCP_args, createCrocoIKOCP, solveCrocoOCP
+from ur_simple_control.optimal_control.crocoddyl_optimal_control import createCrocoIKOCP, solveCrocoOCP
+from ur_simple_control.optimal_control.get_ocp_args import get_OCP_args
 from ur_simple_control.optimal_control.crocoddyl_mpc import CrocoIKMPC
 from ur_simple_control.basics.basics import followKinematicJointTrajP
 from ur_simple_control.util.logging_utils import LogManager
diff --git a/python/examples/crocoddyl_ocp_clik.py b/python/examples/crocoddyl_ocp_clik.py
index 986ce88..1b7ece6 100644
--- a/python/examples/crocoddyl_ocp_clik.py
+++ b/python/examples/crocoddyl_ocp_clik.py
@@ -3,7 +3,8 @@ import time
 import argparse
 from functools import partial
 from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
-from ur_simple_control.optimal_control.crocoddyl_optimal_control import get_OCP_args, createCrocoIKOCP, solveCrocoOCP
+from ur_simple_control.optimal_control.crocoddyl_optimal_control import createCrocoIKOCP, solveCrocoOCP
+from ur_simple_control.optimal_control.get_ocp_args import get_OCP_args
 from ur_simple_control.basics.basics import followKinematicJointTrajP
 from ur_simple_control.util.logging_utils import LogManager
 from ur_simple_control.visualize.visualize import plotFromDict
diff --git a/python/examples/drawing_from_input_drawing.py b/python/examples/drawing_from_input_drawing.py
index 02d8bca..a0622a1 100644
--- a/python/examples/drawing_from_input_drawing.py
+++ b/python/examples/drawing_from_input_drawing.py
@@ -21,9 +21,6 @@ from ur_simple_control.basics.basics import moveJPI
 #######################################################################
 
 def getArgs():
-    #######################################################################
-    #                          generic arguments                          #
-    #######################################################################
     parser = getMinimalArgParser()
     parser = getClikArgs(parser)
     parser = getDMPArgs(parser)
@@ -60,7 +57,7 @@ def getArgs():
 
 # go and pick up the marker
 # marker position:
-# NOTE: this function does not really work (needs more points)
+# NOTE: this function does not work (needs more points)
 """
   R =
  -0.73032 -0.682357 0.0319574
@@ -125,16 +122,16 @@ def getMarker(args, robot, rotation_matrix, translation_vector):
     #moveL(args, robot, Tinit.copy())
     print("got back")
 
-"""
-findMarkerOffset
----------------
-This relies on having the correct orientation of the plane 
-and the correct translation vector for top-left corner.
-Idea is you pick up the marker, go to the top corner,
-touch it, and see the difference between that and the translation vector.
-Obviously it's just a hacked solution, but it works so who cares.
-"""
 def findMarkerOffset(args, robot, plane_pose):
+    """
+    findMarkerOffset
+    ---------------
+    This relies on having the correct orientation of the plane 
+    and the correct translation vector for top-left corner.
+    Idea is you pick up the marker, go to the top corner,
+    touch it, and see the difference between that and the translation vector.
+    Obviously it's just a hacked solution, but it works so who cares.
+    """
     above_starting_write_point = pin.SE3.Identity()
     above_starting_write_point.translation[2] = -0.2
     plane_pose = pin.SE3(rotation_matrix, translation_vector)
@@ -158,16 +155,7 @@ def findMarkerOffset(args, robot, plane_pose):
     compliantMoveL(args, robot, above_starting_write_point)
     return marker_offset
 
-#######################################################################
-#                            control loop                             #
-#######################################################################
-
-# feedforward velocity, feedback position and force for impedance
-# TODO: actually write this out
-def controller():
-    pass
-
-def controlLoopWriting(args, robot : RobotManager, dmp, tc, controller, i, past_data):
+def controlLoopWriting(args, robot : RobotManager, dmp, tc, i, past_data):
     """
     controlLoopWriting
     -----------------------
@@ -182,7 +170,7 @@ def controlLoopWriting(args, robot : RobotManager, dmp, tc, controller, i, past_
     dmp.set_tau(tau_dmp)
     q = robot.getQ()
     T_w_e = robot.getT_w_e()
-    Z = np.diag(np.array([0.0, 0.0, 2.0, 1.0, 1.0, 1.0]))
+    Z = np.diag(np.array([0.0, 0.0, 1.0, 0.5, 0.5, 0.5]))
 
     wrench = robot.getWrench()
     save_past_dict['wrench'] = wrench.copy()
@@ -203,9 +191,7 @@ def controlLoopWriting(args, robot : RobotManager, dmp, tc, controller, i, past_
     # compute control law:
     # - feedforward the velocity and the force reading
     # - feedback the position 
-    # TODO: don't use vel for qd, it's confusion (yes, that means changing dmp code too)
-    # TODO: put this in a controller function for easy swapping (or don't if you won't swap)
-    # solve this q[:6] bs (clean it up)
+    # TODO solve this q[:6] bs (clean it up)
     vel_cmd = dmp.vel + args.kp * (dmp.pos - q[:6].reshape((6,1))) + args.alpha * tau
     robot.sendQd(vel_cmd)
 
@@ -248,12 +234,10 @@ def write(args, robot : RobotManager, joint_trajectory):
     first_q = np.array(first_q)
     # move to initial pose
     mtool = robot.getT_w_e(q_given=first_q)
-    #mtool.translation[1] = mtool.translation[1] - 0.0035
-    #mtool.translation[1] = mtool.translation[1] - 0.012
-    # NOTE: magic number for how close to the board to get
-    # it should be fine without it too, 
-    # this might just be an atavism which fixed something broken before
-    mtool.translation[1] = mtool.translation[1] - 0.006
+    # start a bit above 
+    go_away_from_plane_transf = pin.SE3.Identity()
+    go_away_from_plane_transf.translation[2] = -0.002
+    mtool = mtool.act(go_away_from_plane_transf)
     if not args.board_wiping:
         compliantMoveL(args, robot, mtool)
     else:
@@ -272,7 +256,7 @@ def write(args, robot : RobotManager, joint_trajectory):
             'tau' : np.zeros(robot.n_arm_joints),
         }
     #moveJ(args, robot, dmp.pos.reshape((6,)))
-    controlLoop = partial(controlLoopWriting, args, robot, dmp, tc, controller)
+    controlLoop = partial(controlLoopWriting, args, robot, dmp, tc)
     loop_manager = ControlLoopManager(robot, controlLoop, args, save_past_dict, log_item)
     # and now we can actually run
     loop_manager.run()
@@ -316,7 +300,7 @@ if __name__ == "__main__":
                            args.n_calibration_tests)
         print("finished calibration")
     else:
-        print("using predefined values")
+        print("using existing plane calibration")
         file = open('./plane_pose.pickle', 'rb')
         plane_calib_dict = pickle.load(file)
         file.close()
@@ -338,6 +322,7 @@ if __name__ == "__main__":
     if args.find_marker_offset:
         # find the marker offset
         marker_offset = findMarkerOffset(args, robot, plane_pose)
+        robot.sendQd(np.zeros(6))
         print('marker_offset', marker_offset)
         # we're going in a bit deeper
         if not args.board_wiping:
@@ -350,34 +335,47 @@ if __name__ == "__main__":
     else:
         print("i hope you know the magic number of marker length + going into board")
         #path = path + np.array([0.0, 0.0, -0.1503])
-        path_points_3D = path_points_3D + np.array([0.0, 0.0, - 0.092792+ 0.003])
+        path_points_3D = path_points_3D + np.array([0.0, 0.0, - 0.192792+ 0.003])
 
     # create a joint space trajectory based on the 3D path
     if args.draw_new or args.calibration or args.find_marker_offset:
         path = []
         for i in range(len(path_points_3D)):
-            # TODO: test
             path_pose = pin.SE3.Identity()
             path_pose.translation = path_points_3D[i]
             path.append(plane_pose.act(path_pose))
 
+        print(
+    """
+    look at the viz now! we're constructing a trajectory for the drawing. 
+    it has to look reasonable, otherwise we can't run it!
+    """
+              )
         joint_trajectory = clikCartesianPathIntoJointPath(args, robot, path, \
             clikController, q_init, plane_pose)
+        answer = input("did the movement of the manipulator look reasonable? [Y/n]")
+        if not (answer == "Y" or answer == "y"):
+            print("well if it doesn't look reasonable i'll just exit!")
+            answer = False
+        else:
+            answer = True
     else:
         joint_trajectory_file_path = './joint_trajectory.csv'
         joint_trajectory = np.genfromtxt(joint_trajectory_file_path, delimiter=',')
     
-    write(args, robot, joint_trajectory)
+    if answer:
+        write(args, robot, joint_trajectory)
 
     if not args.pinocchio_only:
         robot.stopRobot()
 
-    if args.save_log:
-        robot.log_manager.plotAllControlLoops()
-
     if args.save_log:
         robot.log_manager.saveLog()
 
     if args.visualize_manipulator:
         robot.killManipulatorVisualizer()
 
+    if args.save_log:
+        robot.log_manager.plotAllControlLoops()
+
+
diff --git a/python/examples/joint_trajectory.csv b/python/examples/joint_trajectory.csv
index 97892e5..54aba40 100644
--- a/python/examples/joint_trajectory.csv
+++ b/python/examples/joint_trajectory.csv
@@ -1,312 +1,355 @@
-0.00000,1.34590,-1.33594,-1.29510,-1.17724,1.75084,-0.14072
-0.01608,1.34159,-1.33577,-1.29548,-1.17667,1.75514,-0.14275
-0.03215,1.33709,-1.33611,-1.29547,-1.17620,1.75937,-0.14505
-0.04823,1.32423,-1.33884,-1.29400,-1.17530,1.77067,-0.15221
-0.06431,1.31543,-1.34128,-1.29251,-1.17488,1.77818,-0.15730
-0.08039,1.30795,-1.34349,-1.29125,-1.17453,1.78445,-0.16172
-0.09646,1.30107,-1.34576,-1.28984,-1.17430,1.79014,-0.16586
-0.11254,1.28205,-1.35248,-1.28596,-1.17368,1.80551,-0.17758
-0.12862,1.27491,-1.35492,-1.28473,-1.17339,1.81124,-0.18204
-0.14469,1.26023,-1.35986,-1.28263,-1.17263,1.82290,-0.19130
-0.16077,1.25317,-1.36218,-1.28177,-1.17223,1.82850,-0.19580
-0.17685,1.24586,-1.36487,-1.28048,-1.17197,1.83427,-0.20048
-0.19293,1.24225,-1.36626,-1.27973,-1.17190,1.83711,-0.20280
-0.20900,1.23684,-1.36847,-1.27844,-1.17186,1.84137,-0.20628
-0.22508,1.23142,-1.37080,-1.27698,-1.17189,1.84563,-0.20979
-0.24116,1.21891,-1.37634,-1.27346,-1.17202,1.85540,-0.21792
-0.25723,1.21477,-1.37826,-1.27216,-1.17214,1.85864,-0.22062
-0.27331,1.21001,-1.38040,-1.27078,-1.17224,1.86236,-0.22374
-0.28939,1.20533,-1.38259,-1.26930,-1.17239,1.86600,-0.22681
-0.30547,1.20075,-1.38480,-1.26775,-1.17258,1.86958,-0.22983
-0.32154,1.19668,-1.38681,-1.26630,-1.17279,1.87274,-0.23251
-0.33762,1.19210,-1.38914,-1.26458,-1.17306,1.87630,-0.23554
-0.35370,1.18814,-1.39119,-1.26303,-1.17333,1.87938,-0.23817
-0.36977,1.18420,-1.39328,-1.26143,-1.17362,1.88243,-0.24079
-0.38585,1.17969,-1.39583,-1.25932,-1.17407,1.88593,-0.24379
-0.40193,1.17526,-1.39836,-1.25721,-1.17454,1.88936,-0.24675
-0.41801,1.16867,-1.40218,-1.25403,-1.17526,1.89446,-0.25115
-0.43408,1.16756,-1.40283,-1.25348,-1.17539,1.89532,-0.25190
-0.45016,1.15106,-1.41442,-1.24218,-1.17858,1.90804,-0.26301
-0.46624,1.14644,-1.41766,-1.23899,-1.17955,1.91160,-0.26615
-0.48232,1.12804,-1.43093,-1.22595,-1.18348,1.92573,-0.27870
-0.49839,1.10622,-1.44721,-1.20974,-1.18864,1.94242,-0.29376
-0.51447,1.09031,-1.45936,-1.19752,-1.19273,1.95456,-0.30488
-0.53055,1.08222,-1.46554,-1.19130,-1.19489,1.96072,-0.31057
-0.54662,1.06092,-1.48124,-1.17639,-1.19985,1.97686,-0.32569
-0.56270,1.05295,-1.48708,-1.17085,-1.20180,1.98289,-0.33141
-0.57878,1.03476,-1.50012,-1.15912,-1.20575,1.99658,-0.34455
-0.59486,1.00663,-1.51969,-1.14270,-1.21119,2.01759,-0.36516
-0.61093,1.00031,-1.52427,-1.13863,-1.21270,2.02232,-0.36987
-0.62701,0.98879,-1.53295,-1.13086,-1.21553,2.03089,-0.37849
-0.64309,0.98620,-1.53499,-1.12895,-1.21626,2.03282,-0.38045
-0.65916,0.98145,-1.53882,-1.12532,-1.21765,2.03635,-0.38403
-0.67524,0.97888,-1.54104,-1.12308,-1.21852,2.03826,-0.38598
-0.69132,0.97804,-1.54177,-1.12235,-1.21881,2.03887,-0.38662
-0.70740,0.96816,-1.55120,-1.11238,-1.22269,2.04617,-0.39412
-0.72347,0.96335,-1.55587,-1.10738,-1.22470,2.04973,-0.39781
-0.73955,0.93624,-1.58432,-1.07616,-1.23709,2.06957,-0.41875
-0.75563,0.91973,-1.60169,-1.05703,-1.24505,2.08159,-0.43177
-0.77170,0.91602,-1.60575,-1.05239,-1.24708,2.08429,-0.43473
-0.78778,0.90376,-1.61842,-1.03877,-1.25283,2.09316,-0.44454
-0.80386,0.89814,-1.62402,-1.03288,-1.25538,2.09721,-0.44908
-0.81994,0.89217,-1.62999,-1.02665,-1.25806,2.10151,-0.45392
-0.83601,0.87900,-1.64249,-1.01447,-1.26317,2.11093,-0.46465
-0.85209,0.87408,-1.64711,-1.00997,-1.26512,2.11444,-0.46870
-0.86817,0.86697,-1.65382,-1.00354,-1.26788,2.11951,-0.47459
-0.88424,0.86247,-1.65798,-0.99962,-1.26958,2.12270,-0.47832
-0.90032,0.85648,-1.66352,-0.99448,-1.27178,2.12694,-0.48332
-0.91640,0.85291,-1.66658,-0.99186,-1.27292,2.12947,-0.48631
-0.93248,0.84329,-1.67346,-0.98746,-1.27474,2.13624,-0.49440
-0.94855,0.83925,-1.67610,-0.98606,-1.27534,2.13907,-0.49782
-0.96463,0.83255,-1.68001,-0.98468,-1.27588,2.14376,-0.50351
-0.98071,0.82612,-1.68366,-0.98363,-1.27626,2.14825,-0.50901
-0.99678,0.82132,-1.68630,-0.98304,-1.27645,2.15159,-0.51313
-1.01286,0.81780,-1.68819,-0.98272,-1.27655,2.15403,-0.51616
-1.02894,0.81397,-1.69007,-0.98271,-1.27650,2.15669,-0.51947
-1.04502,0.81035,-1.69151,-0.98332,-1.27619,2.15920,-0.52262
-1.06109,0.81005,-1.69164,-0.98336,-1.27617,2.15940,-0.52288
-1.07717,0.80253,-1.69403,-0.98584,-1.27495,2.16458,-0.52942
-1.09325,0.79362,-1.69606,-0.99038,-1.27277,2.17070,-0.53723
-1.10932,0.77332,-1.69478,-1.01200,-1.26273,2.18450,-0.55523
-1.12540,0.76826,-1.69395,-1.01844,-1.25974,2.18793,-0.55978
-1.14148,0.75504,-1.69079,-1.03734,-1.25095,2.19682,-0.57171
-1.15756,0.74132,-1.68557,-1.06081,-1.24006,2.20597,-0.58423
-1.17363,0.73275,-1.68133,-1.07744,-1.23235,2.21165,-0.59213
-1.18971,0.72231,-1.67464,-1.10060,-1.22168,2.21851,-0.60181
-1.20579,0.71612,-1.67012,-1.11544,-1.21483,2.22257,-0.60759
-1.22186,0.71252,-1.66712,-1.12477,-1.21053,2.22492,-0.61097
-1.23794,0.70935,-1.66445,-1.13308,-1.20669,2.22698,-0.61394
-1.25402,0.70459,-1.66003,-1.14625,-1.20066,2.23007,-0.61844
-1.27010,0.69914,-1.65458,-1.16207,-1.19344,2.23359,-0.62360
-1.28617,0.68943,-1.64413,-1.19158,-1.18008,2.23982,-0.63286
-1.30225,0.68593,-1.64008,-1.20281,-1.17495,2.24205,-0.63621
-1.31833,0.67948,-1.63232,-1.22397,-1.16539,2.24616,-0.64242
-1.33441,0.67324,-1.62432,-1.24534,-1.15578,2.25011,-0.64846
-1.35048,0.67113,-1.62146,-1.25289,-1.15235,2.25144,-0.65051
-1.36656,0.66937,-1.61901,-1.25929,-1.14946,2.25255,-0.65221
-1.38264,0.66525,-1.61303,-1.27464,-1.14260,2.25514,-0.65624
-1.39871,0.66030,-1.60523,-1.29412,-1.13398,2.25824,-0.66109
-1.41479,0.65705,-1.60018,-1.30683,-1.12832,2.26026,-0.66428
-1.43087,0.65382,-1.59506,-1.31961,-1.12266,2.26227,-0.66746
-1.44695,0.64890,-1.58621,-1.34082,-1.11340,2.26531,-0.67232
-1.46302,0.64540,-1.57941,-1.35680,-1.10642,2.26748,-0.67580
-1.47910,0.64316,-1.57467,-1.36770,-1.10166,2.26885,-0.67802
-1.49518,0.64155,-1.57103,-1.37595,-1.09807,2.26984,-0.67962
-1.51125,0.64000,-1.56717,-1.38448,-1.09438,2.27079,-0.68116
-1.52733,0.63747,-1.55937,-1.40092,-1.08736,2.27235,-0.68368
-1.54341,0.63581,-1.55178,-1.41590,-1.08101,2.27336,-0.68533
-1.55949,0.63493,-1.54478,-1.42894,-1.07552,2.27389,-0.68617
-1.57556,0.63316,-1.52769,-1.46010,-1.06257,2.27495,-0.68789
-1.59164,0.63221,-1.51349,-1.48539,-1.05204,2.27551,-0.68876
-1.60772,0.63216,-1.50879,-1.49351,-1.04862,2.27553,-0.68877
-1.62379,0.63269,-1.49662,-1.51348,-1.04041,2.27519,-0.68815
-1.63987,0.63461,-1.47987,-1.53939,-1.02992,2.27399,-0.68608
-1.65595,0.63543,-1.47356,-1.54913,-1.02591,2.27347,-0.68518
-1.67203,0.63932,-1.44529,-1.59159,-1.00910,2.27102,-0.68105
-1.68810,0.64420,-1.42186,-1.62482,-0.99603,2.26797,-0.67594
-1.70418,0.64618,-1.41472,-1.63452,-0.99214,2.26673,-0.67388
-1.72026,0.65299,-1.39679,-1.65637,-0.98377,2.26248,-0.66691
-1.73633,0.65714,-1.38706,-1.66787,-0.97932,2.25987,-0.66268
-1.75241,0.66338,-1.37441,-1.68179,-0.97407,2.25594,-0.65638
-1.76849,0.66825,-1.36548,-1.69119,-0.97053,2.25286,-0.65150
-1.78457,0.67009,-1.36229,-1.69448,-0.96926,2.25169,-0.64965
-1.80064,0.67675,-1.35170,-1.70469,-0.96552,2.24747,-0.64305
-1.81672,0.68418,-1.33854,-1.71823,-0.96060,2.24271,-0.63571
-1.83280,0.68759,-1.33207,-1.72523,-0.95801,2.24051,-0.63235
-1.84887,0.70951,-1.28849,-1.77196,-0.94200,2.22631,-0.61116
-1.86495,0.72178,-1.26753,-1.79329,-0.93459,2.21826,-0.59946
-1.88103,0.74630,-1.23254,-1.82477,-0.92457,2.20204,-0.57658
-1.89711,0.75264,-1.22413,-1.83234,-0.92200,2.19778,-0.57073
-1.91318,0.76787,-1.20425,-1.84954,-0.91669,2.18753,-0.55687
-1.92926,0.77264,-1.19835,-1.85458,-0.91506,2.18429,-0.55255
-1.94534,0.78785,-1.17995,-1.86965,-0.91072,2.17395,-0.53899
-1.96141,0.79083,-1.17659,-1.87235,-0.90989,2.17190,-0.53633
-1.97749,0.80471,-1.16147,-1.88378,-0.90682,2.16239,-0.52417
-1.99357,0.81927,-1.14714,-1.89364,-0.90439,2.15233,-0.51156
-2.00965,0.83295,-1.13495,-1.90122,-0.90269,2.14281,-0.49987
-2.02572,0.83955,-1.12940,-1.90452,-0.90195,2.13820,-0.49428
-2.04180,0.84876,-1.12252,-1.90789,-0.90137,2.13174,-0.48654
-2.05788,0.86004,-1.11456,-1.91138,-0.90093,2.12380,-0.47715
-2.07395,0.86745,-1.10973,-1.91319,-0.90077,2.11855,-0.47103
-2.09003,0.87339,-1.10617,-1.91425,-0.90077,2.11434,-0.46615
-2.10611,0.89191,-1.09652,-1.91542,-0.90165,2.10117,-0.45112
-2.12219,0.90239,-1.09156,-1.91560,-0.90225,2.09365,-0.44271
-2.13826,0.90662,-1.08953,-1.91576,-0.90245,2.09060,-0.43933
-2.15434,0.91547,-1.08570,-1.91552,-0.90311,2.08422,-0.43231
-2.17042,0.92992,-1.07962,-1.91489,-0.90437,2.07377,-0.42096
-2.18650,0.94218,-1.07489,-1.91391,-0.90558,2.06486,-0.41143
-2.20257,0.96523,-1.06839,-1.90891,-0.90895,2.04802,-0.39377
-2.21865,0.98232,-1.06456,-1.90417,-0.91175,2.03543,-0.38087
-2.23473,0.99294,-1.06227,-1.90123,-0.91351,2.02757,-0.37293
-2.25080,0.99879,-1.06116,-1.89945,-0.91452,2.02323,-0.36858
-2.26688,1.00699,-1.05969,-1.89685,-0.91601,2.01713,-0.36252
-2.28296,1.02140,-1.05808,-1.89093,-0.91909,2.00640,-0.35196
-2.29904,1.05607,-1.05879,-1.87052,-0.92872,1.98044,-0.32699
-2.31511,1.07392,-1.06069,-1.85824,-0.93422,1.96694,-0.31434
-2.33119,1.10160,-1.06934,-1.83120,-0.94547,1.94592,-0.29503
-2.34727,1.11093,-1.07307,-1.82102,-0.94964,1.93878,-0.28858
-2.36334,1.12426,-1.07956,-1.80469,-0.95630,1.92858,-0.27945
-2.37942,1.13314,-1.08465,-1.79269,-0.96117,1.92176,-0.27341
-2.39550,1.13905,-1.08837,-1.78419,-0.96461,1.91722,-0.26941
-2.41158,1.14452,-1.09230,-1.77558,-0.96807,1.91301,-0.26571
-2.42765,1.14900,-1.09604,-1.76778,-0.97116,1.90956,-0.26270
-2.44373,1.15034,-1.09746,-1.76498,-0.97223,1.90852,-0.26180
-2.45981,1.15489,-1.10840,-1.74649,-0.97879,1.90497,-0.25875
-2.47588,1.15687,-1.11706,-1.73251,-0.98368,1.90341,-0.25743
-2.49196,1.15834,-1.13231,-1.70866,-0.99197,1.90224,-0.25649
-2.50804,1.15864,-1.13773,-1.70016,-0.99499,1.90201,-0.25631
-2.52412,1.15882,-1.14716,-1.68549,-1.00020,1.90186,-0.25622
-2.54019,1.15859,-1.15378,-1.67529,-1.00384,1.90204,-0.25640
-2.55627,1.15725,-1.16292,-1.66172,-1.00856,1.90306,-0.25733
-2.57235,1.15578,-1.17032,-1.65085,-1.01236,1.90418,-0.25835
-2.58842,1.15426,-1.17568,-1.64318,-1.01501,1.90535,-0.25939
-2.60450,1.14787,-1.19345,-1.61843,-1.02338,1.91024,-0.26376
-2.62058,1.14427,-1.20277,-1.60538,-1.02791,1.91301,-0.26623
-2.63666,1.14068,-1.21143,-1.59333,-1.03212,1.91577,-0.26870
-2.65273,1.13717,-1.21982,-1.58161,-1.03626,1.91847,-0.27112
-2.66881,1.12678,-1.24254,-1.55035,-1.04718,1.92644,-0.27829
-2.68489,1.12348,-1.24899,-1.54151,-1.05036,1.92898,-0.28058
-2.70096,1.11189,-1.27164,-1.51060,-1.06140,1.93786,-0.28864
-2.71704,1.10629,-1.28244,-1.49568,-1.06691,1.94216,-0.29257
-2.73312,1.10326,-1.28834,-1.48747,-1.06999,1.94448,-0.29471
-2.74920,1.09566,-1.30314,-1.46696,-1.07762,1.95029,-0.30005
-2.76527,1.09163,-1.31041,-1.45698,-1.08138,1.95337,-0.30291
-2.78135,1.08757,-1.31712,-1.44796,-1.08475,1.95647,-0.30578
-2.79743,1.07968,-1.32958,-1.43148,-1.09085,1.96246,-0.31137
-2.81350,1.07274,-1.34038,-1.41720,-1.09619,1.96774,-0.31631
-2.82958,1.05816,-1.36517,-1.38370,-1.10888,1.97879,-0.32676
-2.84566,1.04961,-1.37884,-1.36531,-1.11604,1.98525,-0.33295
-2.86174,1.04497,-1.38606,-1.35562,-1.11986,1.98877,-0.33633
-2.87781,1.03278,-1.40496,-1.33052,-1.12963,1.99794,-0.34522
-2.89389,1.03000,-1.40918,-1.32487,-1.13191,2.00004,-0.34727
-2.90997,1.02342,-1.41899,-1.31190,-1.13707,2.00498,-0.35211
-2.92605,1.01811,-1.42653,-1.30207,-1.14099,2.00896,-0.35603
-2.94212,1.01382,-1.43240,-1.29454,-1.14399,2.01218,-0.35921
-2.95820,1.00366,-1.45144,-1.26781,-1.15486,2.01979,-0.36680
-2.97428,0.99961,-1.45814,-1.25861,-1.15868,2.02281,-0.36985
-2.99035,0.97719,-1.48617,-1.22450,-1.17213,2.03940,-0.38671
-3.00643,0.96953,-1.49530,-1.21346,-1.17668,2.04507,-0.39257
-3.02251,0.95589,-1.51079,-1.19549,-1.18394,2.05511,-0.40304
-3.03859,0.95101,-1.51620,-1.18923,-1.18654,2.05869,-0.40682
-3.05466,0.93337,-1.53508,-1.16846,-1.19487,2.07158,-0.42056
-3.07074,0.91409,-1.55597,-1.14557,-1.20418,2.08557,-0.43579
-3.08682,0.90819,-1.56250,-1.13823,-1.20731,2.08985,-0.44053
-3.10289,0.88996,-1.58155,-1.11825,-1.21553,2.10296,-0.45521
-3.11897,0.86951,-1.60113,-1.09943,-1.22328,2.11756,-0.47195
-3.13505,0.86651,-1.60407,-1.09649,-1.22458,2.11970,-0.47445
-3.15113,0.85661,-1.61184,-1.09052,-1.22710,2.12672,-0.48269
-3.16720,0.85011,-1.61647,-1.08748,-1.22839,2.13131,-0.48814
-3.18328,0.83699,-1.62384,-1.08526,-1.22916,2.14052,-0.49921
-3.19936,0.82860,-1.62765,-1.08555,-1.22893,2.14638,-0.50635
-3.21543,0.82456,-1.62937,-1.08593,-1.22873,2.14920,-0.50982
-3.23151,0.81654,-1.63176,-1.08862,-1.22744,2.15477,-0.51672
-3.24759,0.81045,-1.63300,-1.09178,-1.22597,2.15899,-0.52199
-3.26367,0.80267,-1.63317,-1.09838,-1.22298,2.16435,-0.52876
-3.27974,0.79058,-1.63048,-1.11422,-1.21584,2.17264,-0.53937
-3.29582,0.78380,-1.62780,-1.12530,-1.21085,2.17727,-0.54535
-3.31190,0.77217,-1.62003,-1.15019,-1.19967,2.18516,-0.55569
-3.32797,0.76619,-1.61470,-1.16551,-1.19277,2.18920,-0.56103
-3.34405,0.76225,-1.61068,-1.17658,-1.18776,2.19186,-0.56456
-3.36013,0.74988,-1.59306,-1.22016,-1.16833,2.20013,-0.57570
-3.37621,0.74722,-1.58829,-1.23139,-1.16325,2.20190,-0.57808
-3.39228,0.74482,-1.58312,-1.24305,-1.15802,2.20350,-0.58025
-3.40836,0.74009,-1.57069,-1.26986,-1.14616,2.20663,-0.58451
-3.42444,0.73420,-1.54185,-1.32645,-1.12158,2.21049,-0.58978
-3.44051,0.73352,-1.53636,-1.33692,-1.11691,2.21094,-0.59035
-3.45659,0.73387,-1.51686,-1.37061,-1.10245,2.21070,-0.58990
-3.47267,0.73432,-1.50718,-1.38713,-1.09529,2.21038,-0.58939
-3.48875,0.73504,-1.49447,-1.40855,-1.08612,2.20989,-0.58863
-3.50482,0.74032,-1.45974,-1.46276,-1.06366,2.20635,-0.58355
-3.52090,0.74553,-1.44067,-1.49035,-1.05223,2.20286,-0.57862
-3.53698,0.74772,-1.43270,-1.50193,-1.04737,2.20138,-0.57653
-3.55305,0.75715,-1.39971,-1.54840,-1.02880,2.19503,-0.56775
-3.56913,0.76064,-1.38902,-1.56325,-1.02273,2.19266,-0.56449
-3.58521,0.77143,-1.36289,-1.59665,-1.00980,2.18536,-0.55465
-3.60129,0.78200,-1.34275,-1.62039,-1.00077,2.17818,-0.54512
-3.61736,0.78711,-1.33387,-1.63057,-0.99686,2.17468,-0.54053
-3.63344,0.80577,-1.30483,-1.66151,-0.98582,2.16189,-0.52409
-3.64952,0.80983,-1.29892,-1.66780,-0.98345,2.15907,-0.52053
-3.66559,0.82188,-1.28115,-1.68646,-0.97687,2.15071,-0.51008
-3.68167,0.82511,-1.27653,-1.69135,-0.97509,2.14845,-0.50729
-3.69775,0.84297,-1.25091,-1.71767,-0.96627,2.13597,-0.49208
-3.71383,0.85322,-1.23789,-1.73037,-0.96204,2.12875,-0.48346
-3.72990,0.86131,-1.22855,-1.73895,-0.95926,2.12303,-0.47671
-3.74598,0.86643,-1.22305,-1.74378,-0.95772,2.11940,-0.47245
-3.76206,0.87939,-1.21061,-1.75355,-0.95494,2.11021,-0.46182
-3.77814,0.88533,-1.20536,-1.75745,-0.95384,2.10596,-0.45697
-3.79421,0.90371,-1.19315,-1.76318,-0.95292,2.09284,-0.44219
-3.81029,0.91331,-1.18808,-1.76443,-0.95299,2.08592,-0.43454
-3.82637,0.93480,-1.18069,-1.76132,-0.95534,2.07038,-0.41766
-3.84244,0.95225,-1.17748,-1.75498,-0.95855,2.05767,-0.40417
-3.85852,0.96453,-1.17655,-1.74869,-0.96145,2.04866,-0.39478
-3.87460,0.97479,-1.17646,-1.74246,-0.96425,2.04110,-0.38700
-3.89068,1.00055,-1.18224,-1.71776,-0.97470,2.02206,-0.36777
-3.90675,1.01125,-1.18628,-1.70512,-0.97992,2.01407,-0.35988
-3.92283,1.02443,-1.19453,-1.68451,-0.98824,2.00422,-0.35027
-3.93891,1.04450,-1.21478,-1.64078,-1.00580,1.98918,-0.33583
-3.95498,1.05217,-1.22507,-1.61985,-1.01428,1.98339,-0.33038
-3.97106,1.05589,-1.23158,-1.60723,-1.01937,1.98058,-0.32776
-3.98714,1.05915,-1.24111,-1.59001,-1.02617,1.97810,-0.32547
-4.00322,1.05903,-1.26292,-1.55492,-1.03946,1.97815,-0.32562
-4.01929,1.05433,-1.28951,-1.51413,-1.05498,1.98167,-0.32907
-4.03537,1.05033,-1.30388,-1.49259,-1.06331,1.98469,-0.33200
-4.05145,1.04659,-1.31468,-1.47673,-1.06947,1.98750,-0.33474
-4.06752,1.03355,-1.34330,-1.43670,-1.08468,1.99728,-0.34424
-4.08360,1.02085,-1.36684,-1.40462,-1.09706,2.00681,-0.35359
-4.09968,1.01444,-1.37729,-1.39069,-1.10254,2.01160,-0.35834
-4.11576,0.99251,-1.40565,-1.35643,-1.11543,2.02790,-0.37466
-4.13183,0.98399,-1.41518,-1.34549,-1.11967,2.03422,-0.38108
-4.14791,0.97018,-1.42898,-1.33091,-1.12514,2.04441,-0.39155
-4.16399,0.94610,-1.45113,-1.30941,-1.13297,2.06207,-0.41004
-4.18006,0.93756,-1.45832,-1.30287,-1.13547,2.06831,-0.41669
-4.19614,0.92106,-1.47183,-1.29135,-1.13966,2.08031,-0.42965
-4.21222,0.91341,-1.47755,-1.28697,-1.14129,2.08586,-0.43572
-4.22830,0.89429,-1.49071,-1.27856,-1.14409,2.09962,-0.45102
-4.24437,0.88914,-1.49414,-1.27648,-1.14485,2.10332,-0.45519
-4.26045,0.87587,-1.50178,-1.27352,-1.14566,2.11279,-0.46600
-4.27653,0.87219,-1.50379,-1.27288,-1.14585,2.11541,-0.46902
-4.29260,0.86406,-1.50764,-1.27262,-1.14573,2.12119,-0.47572
-4.30868,0.85615,-1.51069,-1.27365,-1.14508,2.12678,-0.48229
-4.32476,0.84808,-1.51305,-1.27612,-1.14382,2.13248,-0.48903
-4.34084,0.83990,-1.51427,-1.28074,-1.14166,2.13822,-0.49591
-4.35691,0.83374,-1.51440,-1.28562,-1.13946,2.14253,-0.50112
-4.37299,0.82706,-1.51371,-1.29242,-1.13644,2.14720,-0.50680
-4.38907,0.81761,-1.51075,-1.30561,-1.13065,2.15377,-0.51489
-4.40514,0.80908,-1.50612,-1.32103,-1.12394,2.15966,-0.52223
-4.42122,0.79888,-1.49638,-1.34682,-1.11283,2.16668,-0.53107
-4.43730,0.79110,-1.48209,-1.37832,-1.09945,2.17202,-0.53784
-4.45338,0.78724,-1.47074,-1.40130,-1.08971,2.17466,-0.54119
-4.46945,0.78569,-1.46093,-1.41950,-1.08207,2.17572,-0.54251
-4.48553,0.78942,-1.43301,-1.46330,-1.06433,2.17320,-0.53914
-4.50161,0.79174,-1.42199,-1.47999,-1.05745,2.17161,-0.53702
-4.51768,0.80062,-1.39919,-1.51045,-1.04540,2.16554,-0.52915
-4.53376,0.82638,-1.35909,-1.55500,-1.02872,2.14777,-0.50683
-4.54984,0.83494,-1.34790,-1.56675,-1.02418,2.14179,-0.49948
-4.56592,0.84919,-1.33091,-1.58339,-1.01810,2.13179,-0.48742
-4.58199,0.86029,-1.31833,-1.59542,-1.01378,2.12396,-0.47813
-4.59807,0.86959,-1.30742,-1.60618,-1.00994,2.11736,-0.47041
-4.61415,0.88812,-1.28542,-1.62785,-1.00258,2.10415,-0.45525
-4.63023,0.90184,-1.27291,-1.63808,-0.99932,2.09432,-0.44417
-4.64630,0.90534,-1.27016,-1.64007,-0.99869,2.09179,-0.44135
-4.66238,0.90890,-1.26777,-1.64143,-0.99831,2.08923,-0.43851
-4.67846,0.91491,-1.26482,-1.64203,-0.99830,2.08490,-0.43373
-4.69453,0.92271,-1.26240,-1.64062,-0.99911,2.07926,-0.42756
-4.71061,0.94054,-1.26427,-1.62592,-1.00520,2.06632,-0.41362
-4.72669,0.95222,-1.26990,-1.60948,-1.01172,2.05777,-0.40459
-4.74277,0.96250,-1.28244,-1.58293,-1.02205,2.05019,-0.39673
-4.75884,0.97012,-1.30320,-1.54440,-1.03714,2.04455,-0.39098
-4.77492,0.97216,-1.31397,-1.52534,-1.04474,2.04303,-0.38948
-4.79100,0.97014,-1.34796,-1.47035,-1.06640,2.04450,-0.39112
-4.80707,0.96862,-1.35988,-1.45113,-1.07427,2.04563,-0.39234
-4.82315,0.96195,-1.38844,-1.40717,-1.09201,2.05054,-0.39755
-4.83923,0.95683,-1.40250,-1.38648,-1.10047,2.05431,-0.40153
-4.85531,0.94773,-1.41812,-1.36599,-1.10862,2.06095,-0.40858
-4.87138,0.92991,-1.43959,-1.34182,-1.11789,2.07390,-0.42248
-4.88746,0.92248,-1.44714,-1.33404,-1.12095,2.07929,-0.42834
-4.90354,0.91802,-1.45114,-1.33030,-1.12241,2.08252,-0.43187
-4.91961,0.90944,-1.45702,-1.32640,-1.12380,2.08871,-0.43869
-4.93569,0.90301,-1.46051,-1.32508,-1.12419,2.09333,-0.44384
-4.95177,0.89730,-1.46288,-1.32521,-1.12400,2.09743,-0.44843
-4.96785,0.88930,-1.46472,-1.32800,-1.12265,2.10317,-0.45489
-4.98392,0.87499,-1.46402,-1.34011,-1.11725,2.11336,-0.46653
-5.00000,0.87496,-1.46402,-1.34014,-1.11724,2.11338,-0.46656
+0.00000,1.31458,-1.32887,-1.36187,-1.12090,1.77566,-0.15965
+0.01412,1.31427,-1.32875,-1.36211,-1.12073,1.77600,-0.15978
+0.02825,1.31319,-1.32822,-1.36314,-1.12008,1.77717,-0.16023
+0.04237,1.31119,-1.32692,-1.36563,-1.11865,1.77929,-0.16109
+0.05650,1.30567,-1.32131,-1.37625,-1.11329,1.78488,-0.16367
+0.07062,1.29821,-1.31016,-1.39722,-1.10346,1.79195,-0.16747
+0.08475,1.29492,-1.30442,-1.40804,-1.09846,1.79497,-0.16923
+0.09887,1.29222,-1.29917,-1.41793,-1.09396,1.79737,-0.17071
+0.11299,1.28799,-1.28971,-1.43562,-1.08606,1.80100,-0.17312
+0.12712,1.28387,-1.27952,-1.45463,-1.07766,1.80442,-0.17554
+0.14124,1.28074,-1.27134,-1.46985,-1.07097,1.80696,-0.17740
+0.15537,1.27873,-1.26591,-1.47995,-1.06654,1.80858,-0.17861
+0.16949,1.27625,-1.25913,-1.49252,-1.06106,1.81055,-0.18012
+0.18362,1.27234,-1.24832,-1.51250,-1.05243,1.81363,-0.18252
+0.19774,1.26875,-1.23983,-1.52843,-1.04549,1.81643,-0.18473
+0.21186,1.26571,-1.23346,-1.54055,-1.04017,1.81880,-0.18663
+0.22599,1.26253,-1.22642,-1.55381,-1.03442,1.82128,-0.18861
+0.24011,1.25274,-1.20557,-1.59288,-1.01772,1.82886,-0.19475
+0.25424,1.24919,-1.19883,-1.60574,-1.01213,1.83162,-0.19698
+0.26836,1.24507,-1.19164,-1.61959,-1.00612,1.83481,-0.19959
+0.28249,1.23813,-1.17974,-1.64238,-0.99634,1.84018,-0.20399
+0.29661,1.23450,-1.17318,-1.65483,-0.99104,1.84299,-0.20629
+0.31073,1.23127,-1.16794,-1.66493,-0.98670,1.84549,-0.20836
+0.32486,1.22332,-1.15520,-1.68935,-0.97639,1.85163,-0.21344
+0.33898,1.21695,-1.14551,-1.70803,-0.96850,1.85655,-0.21753
+0.35311,1.21259,-1.13940,-1.71998,-0.96342,1.85992,-0.22034
+0.36723,1.20806,-1.13342,-1.73176,-0.95842,1.86341,-0.22326
+0.38136,1.20047,-1.12446,-1.74978,-0.95075,1.86926,-0.22818
+0.39548,1.19037,-1.11309,-1.77278,-0.94103,1.87703,-0.23477
+0.40960,1.18520,-1.10754,-1.78413,-0.93622,1.88101,-0.23815
+0.42373,1.17637,-1.09866,-1.80251,-0.92845,1.88779,-0.24395
+0.43785,1.16808,-1.09102,-1.81868,-0.92160,1.89416,-0.24942
+0.45198,1.16238,-1.08584,-1.82965,-0.91697,1.89854,-0.25321
+0.46610,1.15325,-1.07798,-1.84652,-0.90988,1.90552,-0.25928
+0.48023,1.14054,-1.06696,-1.87004,-0.90016,1.91524,-0.26780
+0.49435,1.13557,-1.06296,-1.87878,-0.89652,1.91905,-0.27115
+0.50847,1.13001,-1.05857,-1.88840,-0.89253,1.92329,-0.27490
+0.52260,1.12594,-1.05556,-1.89516,-0.88971,1.92640,-0.27766
+0.53672,1.12372,-1.05385,-1.89893,-0.88816,1.92809,-0.27917
+0.55085,1.12262,-1.05298,-1.90083,-0.88738,1.92893,-0.27992
+0.56497,1.12206,-1.05255,-1.90178,-0.88699,1.92936,-0.28029
+0.57910,1.12154,-1.05213,-1.90269,-0.88662,1.92975,-0.28065
+0.59322,1.11992,-1.05078,-1.90558,-0.88545,1.93099,-0.28175
+0.60734,1.11992,-1.05078,-1.90559,-0.88545,1.93099,-0.28175
+0.62147,1.11993,-1.05078,-1.90558,-0.88545,1.93099,-0.28175
+0.63559,1.12656,-1.05579,-1.89457,-0.88976,1.92607,-0.27725
+0.64972,1.13229,-1.06079,-1.88407,-0.89385,1.92179,-0.27338
+0.66384,1.13765,-1.06605,-1.87337,-0.89800,1.91774,-0.26977
+0.67797,1.14074,-1.07031,-1.86542,-0.90098,1.91540,-0.26769
+0.69209,1.14284,-1.07371,-1.85923,-0.90327,1.91380,-0.26628
+0.70621,1.14570,-1.07899,-1.84984,-0.90674,1.91162,-0.26436
+0.72034,1.14746,-1.08342,-1.84228,-0.90948,1.91027,-0.26319
+0.73446,1.14882,-1.08813,-1.83449,-0.91225,1.90923,-0.26229
+0.74859,1.15022,-1.09430,-1.82443,-0.91582,1.90815,-0.26136
+0.76271,1.15102,-1.09933,-1.81638,-0.91867,1.90754,-0.26084
+0.77684,1.15144,-1.10382,-1.80933,-0.92114,1.90721,-0.26057
+0.79096,1.15212,-1.11106,-1.79789,-0.92520,1.90669,-0.26014
+0.80508,1.15239,-1.11632,-1.78965,-0.92812,1.90648,-0.25997
+0.81921,1.15244,-1.12097,-1.78243,-0.93068,1.90644,-0.25996
+0.83333,1.15256,-1.12774,-1.77185,-0.93446,1.90636,-0.25991
+0.84746,1.15223,-1.13351,-1.76305,-0.93758,1.90661,-0.26015
+0.86158,1.15188,-1.13905,-1.75455,-0.94061,1.90689,-0.26041
+0.87571,1.15150,-1.14460,-1.74604,-0.94367,1.90718,-0.26069
+0.88983,1.15080,-1.14987,-1.73812,-0.94648,1.90773,-0.26119
+0.90395,1.14985,-1.15458,-1.73119,-0.94890,1.90846,-0.26185
+0.91808,1.14911,-1.15756,-1.72687,-0.95041,1.90903,-0.26236
+0.93220,1.14862,-1.15945,-1.72414,-0.95137,1.90940,-0.26269
+0.94633,1.14743,-1.16298,-1.71918,-0.95305,1.91031,-0.26351
+0.96045,1.14577,-1.16661,-1.71435,-0.95463,1.91158,-0.26464
+0.97458,1.14296,-1.17076,-1.70932,-0.95614,1.91372,-0.26655
+0.98870,1.13943,-1.17461,-1.70517,-0.95724,1.91640,-0.26894
+1.00282,1.13559,-1.17796,-1.70200,-0.95794,1.91932,-0.27155
+1.01695,1.12921,-1.18243,-1.69847,-0.95849,1.92417,-0.27589
+1.03107,1.11998,-1.18770,-1.69528,-0.95860,1.93118,-0.28220
+1.04520,1.11103,-1.19201,-1.69347,-0.95827,1.93797,-0.28835
+1.05932,1.09781,-1.19708,-1.69297,-0.95700,1.94801,-0.29750
+1.07345,1.08318,-1.20134,-1.69471,-0.95479,1.95909,-0.30770
+1.08757,1.07519,-1.20327,-1.69632,-0.95337,1.96513,-0.31332
+1.10169,1.06494,-1.20515,-1.69942,-0.95117,1.97289,-0.32057
+1.11582,1.05480,-1.20661,-1.70323,-0.94872,1.98053,-0.32777
+1.12994,1.04419,-1.20767,-1.70806,-0.94584,1.98851,-0.33537
+1.14407,1.03245,-1.20816,-1.71462,-0.94222,1.99732,-0.34383
+1.15819,1.02458,-1.20814,-1.71963,-0.93958,2.00322,-0.34954
+1.17232,1.01755,-1.20766,-1.72487,-0.93696,2.00847,-0.35466
+1.18644,1.01072,-1.20681,-1.73060,-0.93418,2.01357,-0.35967
+1.20056,1.00734,-1.20633,-1.73355,-0.93276,2.01608,-0.36215
+1.21469,1.00266,-1.20540,-1.73806,-0.93065,2.01957,-0.36560
+1.22881,0.99564,-1.20372,-1.74535,-0.92728,2.02478,-0.37079
+1.24294,0.98893,-1.20228,-1.75212,-0.92412,2.02976,-0.37578
+1.25706,0.98377,-1.20091,-1.75775,-0.92154,2.03357,-0.37962
+1.27119,0.98030,-1.20015,-1.76130,-0.91989,2.03613,-0.38221
+1.28531,0.97487,-1.19923,-1.76650,-0.91741,2.04013,-0.38628
+1.29944,0.97235,-1.19882,-1.76890,-0.91627,2.04198,-0.38818
+1.31356,0.96934,-1.19845,-1.77158,-0.91497,2.04420,-0.39045
+1.32768,0.96373,-1.19820,-1.77594,-0.91277,2.04831,-0.39469
+1.34181,0.95922,-1.19842,-1.77882,-0.91121,2.05161,-0.39810
+1.35593,0.95434,-1.19899,-1.78144,-0.90970,2.05517,-0.40182
+1.37006,0.95069,-1.19960,-1.78313,-0.90868,2.05784,-0.40460
+1.38418,0.94519,-1.20098,-1.78500,-0.90737,2.06184,-0.40881
+1.39831,0.94049,-1.20265,-1.78585,-0.90651,2.06526,-0.41243
+1.41243,0.93311,-1.20607,-1.78598,-0.90561,2.07061,-0.41813
+1.42655,0.92533,-1.21036,-1.78508,-0.90506,2.07625,-0.42418
+1.44068,0.91878,-1.21453,-1.78347,-0.90494,2.08099,-0.42931
+1.45480,0.91035,-1.22095,-1.77975,-0.90542,2.08708,-0.43596
+1.46893,0.90291,-1.22721,-1.77551,-0.90625,2.09245,-0.44187
+1.48305,0.89199,-1.23827,-1.76638,-0.90861,2.10030,-0.45062
+1.49718,0.88618,-1.24479,-1.76042,-0.91037,2.10448,-0.45532
+1.51130,0.87981,-1.25278,-1.75255,-0.91284,2.10906,-0.46051
+1.52542,0.87378,-1.26132,-1.74348,-0.91585,2.11339,-0.46545
+1.53955,0.86829,-1.26961,-1.73436,-0.91896,2.11731,-0.46997
+1.55367,0.86235,-1.27925,-1.72340,-0.92280,2.12156,-0.47490
+1.56780,0.85729,-1.28883,-1.71176,-0.92703,2.12518,-0.47913
+1.58192,0.85078,-1.30510,-1.69024,-0.93510,2.12983,-0.48462
+1.59605,0.84846,-1.31289,-1.67908,-0.93949,2.13151,-0.48662
+1.61017,0.84688,-1.32175,-1.66547,-0.94497,2.13268,-0.48801
+1.62429,0.84610,-1.32763,-1.65614,-0.94878,2.13326,-0.48871
+1.63842,0.84616,-1.33685,-1.64040,-0.95531,2.13328,-0.48874
+1.65254,0.84672,-1.34102,-1.63275,-0.95857,2.13292,-0.48833
+1.66667,0.84818,-1.34614,-1.62265,-0.96294,2.13194,-0.48717
+1.68079,0.85047,-1.35154,-1.61132,-0.96789,2.13037,-0.48532
+1.69492,0.85277,-1.35541,-1.60261,-0.97176,2.12879,-0.48347
+1.70904,0.85552,-1.35909,-1.59383,-0.97570,2.12689,-0.48124
+1.72316,0.85778,-1.36167,-1.58739,-0.97862,2.12532,-0.47941
+1.73729,0.85952,-1.36318,-1.58322,-0.98054,2.12411,-0.47800
+1.75141,0.86049,-1.36393,-1.58107,-0.98154,2.12343,-0.47721
+1.76554,0.86095,-1.36429,-1.58004,-0.98202,2.12311,-0.47684
+1.77966,0.86208,-1.36495,-1.57788,-0.98304,2.12233,-0.47593
+1.79379,0.86210,-1.36497,-1.57783,-0.98307,2.12231,-0.47591
+1.80791,0.86246,-1.36509,-1.57729,-0.98334,2.12206,-0.47561
+1.82203,0.86315,-1.36520,-1.57646,-0.98376,2.12158,-0.47505
+1.83616,0.86505,-1.36507,-1.57493,-0.98465,2.12025,-0.47352
+1.85028,0.86508,-1.36507,-1.57491,-0.98466,2.12023,-0.47349
+1.86441,0.86691,-1.36438,-1.57436,-0.98515,2.11895,-0.47201
+1.87853,0.86910,-1.36312,-1.57445,-0.98544,2.11741,-0.47024
+1.89266,0.87241,-1.36064,-1.57556,-0.98547,2.11509,-0.46757
+1.90678,0.87787,-1.35513,-1.57983,-0.98454,2.11123,-0.46317
+1.92090,0.88226,-1.34958,-1.58522,-0.98297,2.10811,-0.45962
+1.93503,0.88520,-1.34509,-1.59018,-0.98136,2.10601,-0.45726
+1.94915,0.88788,-1.34040,-1.59575,-0.97945,2.10408,-0.45509
+1.96328,0.89044,-1.33505,-1.60254,-0.97700,2.10223,-0.45302
+1.97740,0.89247,-1.33054,-1.60841,-0.97485,2.10077,-0.45137
+1.99153,0.89421,-1.32570,-1.61510,-0.97233,2.09950,-0.44996
+2.00565,0.89638,-1.31592,-1.62971,-0.96666,2.09789,-0.44816
+2.01977,0.89641,-1.30684,-1.64497,-0.96048,2.09781,-0.44808
+2.03390,0.89520,-1.30024,-1.65708,-0.95544,2.09861,-0.44897
+2.04802,0.89388,-1.29650,-1.66449,-0.95227,2.09953,-0.44999
+2.06215,0.89231,-1.29348,-1.67090,-0.94950,2.10062,-0.45121
+2.07627,0.88988,-1.29040,-1.67811,-0.94631,2.10231,-0.45312
+2.09040,0.88749,-1.28787,-1.68437,-0.94353,2.10399,-0.45501
+2.10452,0.88514,-1.28602,-1.68944,-0.94123,2.10564,-0.45687
+2.11864,0.87751,-1.28422,-1.69903,-0.93652,2.11100,-0.46298
+2.13277,0.87051,-1.28439,-1.70484,-0.93340,2.11592,-0.46862
+2.14689,0.86091,-1.28618,-1.71028,-0.93016,2.12266,-0.47644
+2.16102,0.85370,-1.28833,-1.71306,-0.92829,2.12772,-0.48237
+2.17514,0.83998,-1.29438,-1.71523,-0.92600,2.13730,-0.49375
+2.18927,0.83555,-1.29651,-1.71564,-0.92543,2.14040,-0.49747
+2.20339,0.83157,-1.29863,-1.71568,-0.92505,2.14318,-0.50082
+2.21751,0.82885,-1.30022,-1.71547,-0.92488,2.14508,-0.50313
+2.23164,0.82517,-1.30260,-1.71484,-0.92479,2.14764,-0.50625
+2.24576,0.81962,-1.30725,-1.71222,-0.92529,2.15149,-0.51097
+2.25989,0.81243,-1.31571,-1.70486,-0.92747,2.15649,-0.51714
+2.27401,0.80750,-1.32348,-1.69654,-0.93031,2.15993,-0.52141
+2.28814,0.80319,-1.33229,-1.68586,-0.93420,2.16294,-0.52518
+2.30226,0.80103,-1.33804,-1.67820,-0.93713,2.16446,-0.52709
+2.31638,0.79821,-1.35101,-1.65904,-0.94468,2.16648,-0.52963
+2.33051,0.79704,-1.36090,-1.64335,-0.95105,2.16735,-0.53073
+2.34463,0.79630,-1.37121,-1.62649,-0.95798,2.16791,-0.53145
+2.35876,0.79577,-1.38093,-1.61038,-0.96465,2.16832,-0.53199
+2.37288,0.79562,-1.38999,-1.59498,-0.97109,2.16847,-0.53220
+2.38701,0.79557,-1.39844,-1.58049,-0.97719,2.16854,-0.53231
+2.40113,0.79565,-1.40411,-1.57062,-0.98138,2.16851,-0.53229
+2.41525,0.79595,-1.41027,-1.55966,-0.98606,2.16833,-0.53208
+2.42938,0.79655,-1.41698,-1.54745,-0.99130,2.16795,-0.53161
+2.44350,0.79730,-1.42150,-1.53885,-0.99504,2.16746,-0.53101
+2.45763,0.79795,-1.42481,-1.53244,-0.99785,2.16703,-0.53047
+2.47175,0.79857,-1.42715,-1.52773,-0.99993,2.16661,-0.52995
+2.48588,0.79892,-1.42830,-1.52537,-1.00098,2.16639,-0.52967
+2.50000,0.79892,-1.42833,-1.52531,-1.00101,2.16638,-0.52966
+2.51412,0.79909,-1.42887,-1.52421,-1.00150,2.16627,-0.52952
+2.52825,0.79928,-1.42945,-1.52299,-1.00204,2.16614,-0.52936
+2.54237,0.79928,-1.42946,-1.52297,-1.00205,2.16614,-0.52937
+2.55650,0.79928,-1.42947,-1.52296,-1.00206,2.16614,-0.52937
+2.57062,0.79927,-1.42946,-1.52298,-1.00205,2.16615,-0.52938
+2.58475,0.79829,-1.42820,-1.52583,-1.00101,2.16681,-0.53025
+2.59887,0.79214,-1.41980,-1.54498,-0.99352,2.17096,-0.53569
+2.61299,0.78919,-1.41608,-1.55381,-0.98993,2.17296,-0.53829
+2.62712,0.78703,-1.41318,-1.56062,-0.98714,2.17441,-0.54019
+2.64124,0.78333,-1.40872,-1.57151,-0.98258,2.17690,-0.54345
+2.65537,0.77870,-1.40367,-1.58438,-0.97711,2.18002,-0.54753
+2.66949,0.77526,-1.40085,-1.59246,-0.97359,2.18234,-0.55057
+2.68362,0.77207,-1.39854,-1.59945,-0.97052,2.18448,-0.55339
+2.69774,0.76938,-1.39726,-1.60427,-0.96834,2.18628,-0.55577
+2.71186,0.76556,-1.39626,-1.60977,-0.96578,2.18884,-0.55917
+2.72599,0.76147,-1.39603,-1.61429,-0.96358,2.19157,-0.56281
+2.74011,0.75744,-1.39643,-1.61773,-0.96181,2.19426,-0.56643
+2.75424,0.74975,-1.39836,-1.62238,-0.95923,2.19937,-0.57337
+2.76836,0.74545,-1.39987,-1.62427,-0.95809,2.20223,-0.57727
+2.78249,0.74267,-1.40097,-1.62528,-0.95744,2.20407,-0.57981
+2.79661,0.74082,-1.40187,-1.62569,-0.95712,2.20530,-0.58150
+2.81073,0.73742,-1.40394,-1.62577,-0.95678,2.20755,-0.58462
+2.82486,0.73304,-1.40714,-1.62499,-0.95671,2.21044,-0.58865
+2.83898,0.72798,-1.41160,-1.62286,-0.95713,2.21378,-0.59333
+2.85311,0.72186,-1.41848,-1.61779,-0.95865,2.21781,-0.59903
+2.86723,0.71721,-1.42495,-1.61184,-0.96070,2.22088,-0.60341
+2.88136,0.71112,-1.43586,-1.59989,-0.96513,2.22489,-0.60917
+2.89548,0.70610,-1.44931,-1.58235,-0.97206,2.22822,-0.61400
+2.90960,0.70338,-1.46003,-1.56681,-0.97846,2.23004,-0.61666
+2.92373,0.70091,-1.48971,-1.51812,-0.99889,2.23178,-0.61922
+2.93785,0.70083,-1.49936,-1.50109,-1.00639,2.23189,-0.61940
+2.95198,0.70108,-1.50661,-1.48790,-1.01223,2.23176,-0.61925
+2.96610,0.70141,-1.51107,-1.47957,-1.01596,2.23157,-0.61898
+2.98023,0.70191,-1.51546,-1.47115,-1.01972,2.23127,-0.61856
+2.99435,0.70259,-1.52086,-1.46077,-1.02434,2.23086,-0.61797
+3.00847,0.70297,-1.52407,-1.45461,-1.02710,2.23063,-0.61765
+3.02260,0.70377,-1.52898,-1.44497,-1.03141,2.23013,-0.61693
+3.03672,0.70444,-1.53226,-1.43834,-1.03439,2.22971,-0.61633
+3.05085,0.70642,-1.53911,-1.42388,-1.04089,2.22846,-0.61452
+3.06497,0.70718,-1.54136,-1.41899,-1.04312,2.22798,-0.61383
+3.07910,0.70805,-1.54354,-1.41408,-1.04537,2.22742,-0.61303
+3.09322,0.70875,-1.54513,-1.41043,-1.04705,2.22698,-0.61239
+3.10734,0.70978,-1.54721,-1.40553,-1.04931,2.22633,-0.61145
+3.12147,0.71003,-1.54772,-1.40431,-1.04987,2.22616,-0.61121
+3.13559,0.71056,-1.54873,-1.40189,-1.05099,2.22582,-0.61073
+3.14972,0.71083,-1.54924,-1.40067,-1.05155,2.22565,-0.61048
+3.16384,0.71111,-1.54974,-1.39946,-1.05211,2.22548,-0.61023
+3.17797,0.71138,-1.55023,-1.39825,-1.05267,2.22530,-0.60997
+3.19209,0.71140,-1.55026,-1.39819,-1.05270,2.22529,-0.60996
+3.20621,0.71080,-1.54999,-1.39922,-1.05230,2.22567,-0.61054
+3.22034,0.69281,-1.53790,-1.43887,-1.03564,2.23716,-0.62780
+3.23446,0.67926,-1.52760,-1.47161,-1.02141,2.24577,-0.64093
+3.24859,0.67718,-1.52596,-1.47680,-1.01912,2.24709,-0.64295
+3.26271,0.66976,-1.52019,-1.49522,-1.01100,2.25177,-0.65020
+3.27684,0.66361,-1.51546,-1.51047,-1.00426,2.25562,-0.65624
+3.29096,0.66007,-1.51241,-1.51984,-1.00014,2.25784,-0.65974
+3.30508,0.65440,-1.50687,-1.53593,-0.99313,2.26138,-0.66536
+3.31921,0.64956,-1.50218,-1.54964,-0.98716,2.26438,-0.67018
+3.33333,0.64547,-1.49819,-1.56129,-0.98208,2.26691,-0.67427
+3.34746,0.64152,-1.49392,-1.57325,-0.97692,2.26934,-0.67823
+3.36158,0.63696,-1.48881,-1.58735,-0.97087,2.27214,-0.68283
+3.37571,0.63439,-1.48478,-1.59723,-0.96669,2.27371,-0.68544
+3.38983,0.63152,-1.47937,-1.60973,-0.96145,2.27546,-0.68834
+3.40395,0.62927,-1.47369,-1.62195,-0.95639,2.27683,-0.69062
+3.41808,0.62768,-1.46750,-1.63419,-0.95138,2.27780,-0.69223
+3.43220,0.62665,-1.46026,-1.64747,-0.94600,2.27842,-0.69326
+3.44633,0.62629,-1.45512,-1.65648,-0.94236,2.27864,-0.69361
+3.46045,0.62652,-1.44729,-1.66919,-0.93730,2.27850,-0.69334
+3.47458,0.62853,-1.43459,-1.68778,-0.93006,2.27727,-0.69124
+3.48870,0.63145,-1.42238,-1.70451,-0.92357,2.27548,-0.68819
+3.50282,0.63707,-1.40299,-1.72984,-0.91390,2.27201,-0.68236
+3.51695,0.64269,-1.38561,-1.75194,-0.90548,2.26851,-0.67655
+3.53107,0.64843,-1.36933,-1.77208,-0.89786,2.26492,-0.67065
+3.54520,0.65298,-1.35758,-1.78619,-0.89254,2.26207,-0.66600
+3.55932,0.65603,-1.35017,-1.79494,-0.88924,2.26014,-0.66289
+3.57345,0.66393,-1.33402,-1.81230,-0.88301,2.25517,-0.65493
+3.58757,0.67285,-1.31734,-1.82947,-0.87696,2.24952,-0.64604
+3.60169,0.67765,-1.30941,-1.83717,-0.87423,2.24646,-0.64128
+3.61582,0.68564,-1.29736,-1.84804,-0.87055,2.24135,-0.63343
+3.62994,0.69426,-1.28527,-1.85839,-0.86713,2.23581,-0.62503
+3.64407,0.70248,-1.27404,-1.86787,-0.86403,2.23050,-0.61709
+3.65819,0.71103,-1.26292,-1.87690,-0.86116,2.22493,-0.60891
+3.67232,0.71749,-1.25483,-1.88332,-0.85913,2.22070,-0.60276
+3.68644,0.74384,-1.22335,-1.90677,-0.85262,2.20333,-0.57818
+3.70056,0.75587,-1.21030,-1.91605,-0.84996,2.19528,-0.56714
+3.71469,0.76552,-1.20032,-1.92285,-0.84809,2.18878,-0.55837
+3.72881,0.78272,-1.18334,-1.93367,-0.84548,2.17713,-0.54297
+3.74294,0.79738,-1.16938,-1.94241,-0.84346,2.16711,-0.53003
+3.75706,0.80594,-1.16136,-1.94749,-0.84227,2.16122,-0.52255
+3.77119,0.81038,-1.15738,-1.94992,-0.84171,2.15815,-0.51869
+3.78531,0.82048,-1.14841,-1.95520,-0.84065,2.15116,-0.50998
+3.79944,0.82971,-1.14043,-1.95979,-0.83979,2.14474,-0.50210
+3.81356,0.85132,-1.12253,-1.96930,-0.83853,2.12963,-0.48390
+3.82768,0.86152,-1.11467,-1.97325,-0.83803,2.12242,-0.47542
+3.84181,0.86802,-1.10979,-1.97566,-0.83774,2.11782,-0.47006
+3.85593,0.87580,-1.10399,-1.97848,-0.83746,2.11229,-0.46367
+3.87006,0.89724,-1.08833,-1.98568,-0.83722,2.09700,-0.44633
+3.88418,0.90983,-1.07961,-1.98954,-0.83714,2.08795,-0.43628
+3.89831,0.92103,-1.07190,-1.99300,-0.83710,2.07986,-0.42742
+3.91243,0.92994,-1.06607,-1.99541,-0.83719,2.07340,-0.42043
+3.92655,0.93737,-1.06126,-1.99738,-0.83730,2.06800,-0.41464
+3.94068,0.94693,-1.05548,-1.99937,-0.83764,2.06103,-0.40724
+3.95480,0.96057,-1.04800,-2.00116,-0.83851,2.05106,-0.39678
+3.96893,0.97122,-1.04262,-2.00205,-0.83935,2.04324,-0.38868
+3.98305,0.98065,-1.03822,-2.00240,-0.84024,2.03630,-0.38158
+3.99718,0.98971,-1.03413,-2.00261,-0.84114,2.02960,-0.37479
+4.01130,1.00704,-1.02695,-2.00213,-0.84328,2.01677,-0.36194
+4.02542,1.01695,-1.02310,-2.00165,-0.84453,2.00938,-0.35466
+4.03955,1.02677,-1.01989,-2.00043,-0.84600,2.00205,-0.34749
+4.05367,1.03748,-1.01705,-1.99824,-0.84787,1.99404,-0.33973
+4.06780,1.04414,-1.01564,-1.99646,-0.84913,1.98903,-0.33493
+4.08192,1.05354,-1.01417,-1.99325,-0.85114,1.98196,-0.32820
+4.09605,1.05924,-1.01340,-1.99117,-0.85241,1.97766,-0.32413
+4.11017,1.07392,-1.01223,-1.98466,-0.85609,1.96658,-0.31374
+4.12429,1.07934,-1.01208,-1.98196,-0.85752,1.96247,-0.30992
+4.13842,1.08294,-1.01220,-1.97986,-0.85854,1.95973,-0.30739
+4.15254,1.08814,-1.01287,-1.97618,-0.86020,1.95577,-0.30375
+4.16667,1.09236,-1.01372,-1.97278,-0.86167,1.95255,-0.30080
+4.18079,1.09871,-1.01612,-1.96613,-0.86431,1.94770,-0.29638
+4.19492,1.10299,-1.01912,-1.95978,-0.86658,1.94441,-0.29340
+4.20904,1.10587,-1.02196,-1.95437,-0.86843,1.94218,-0.29141
+4.22316,1.10718,-1.02633,-1.94775,-0.87036,1.94114,-0.29049
+4.23729,1.10565,-1.03482,-1.93697,-0.87301,1.94220,-0.29152
+4.25141,1.10095,-1.04451,-1.92612,-0.87531,1.94566,-0.29474
+4.26554,1.09636,-1.05131,-1.91913,-0.87666,1.94908,-0.29791
+4.27966,1.08624,-1.06263,-1.90876,-0.87828,1.95666,-0.30494
+4.29379,1.07525,-1.07270,-1.90055,-0.87930,1.96491,-0.31263
+4.30791,1.06270,-1.08294,-1.89294,-0.88006,1.97434,-0.32150
+4.32203,1.05216,-1.09102,-1.88726,-0.88058,1.98225,-0.32901
+4.33616,1.04007,-1.09993,-1.88130,-0.88108,1.99132,-0.33768
+4.35028,1.02390,-1.11158,-1.87381,-0.88168,2.00341,-0.34939
+4.36441,1.00247,-1.12664,-1.86467,-0.88236,2.01937,-0.36512
+4.37853,0.98677,-1.13787,-1.85772,-0.88312,2.03101,-0.37681
+4.39266,0.96692,-1.15318,-1.84748,-0.88466,2.04567,-0.39177
+4.40678,0.94099,-1.17435,-1.83272,-0.88735,2.06467,-0.41166
+4.42090,0.92302,-1.18979,-1.82135,-0.88989,2.07777,-0.42569
+4.43503,0.90453,-1.20606,-1.80932,-0.89274,2.09116,-0.44035
+4.44915,0.88499,-1.22453,-1.79486,-0.89652,2.10520,-0.45607
+4.46328,0.87203,-1.23697,-1.78499,-0.89930,2.11447,-0.46666
+4.47740,0.85167,-1.25692,-1.76931,-0.90372,2.12890,-0.48351
+4.49153,0.83370,-1.27469,-1.75541,-0.90784,2.14154,-0.49863
+4.50565,0.82171,-1.28673,-1.74588,-0.91083,2.14992,-0.50887
+4.51977,0.79376,-1.31510,-1.72420,-0.91741,2.16922,-0.53311
+4.53390,0.78323,-1.32592,-1.71571,-0.92031,2.17646,-0.54245
+4.54802,0.76554,-1.34367,-1.70271,-0.92456,2.18848,-0.55829
+4.56215,0.74870,-1.36145,-1.68920,-0.92915,2.19982,-0.57363
+4.57627,0.73972,-1.37123,-1.68149,-0.93192,2.20583,-0.58193
+4.59040,0.72862,-1.38381,-1.67137,-0.93556,2.21321,-0.59228
+4.60452,0.71880,-1.39562,-1.66140,-0.93922,2.21970,-0.60153
+4.61864,0.71203,-1.40379,-1.65449,-0.94183,2.22415,-0.60797
+4.63277,0.70692,-1.41016,-1.64896,-0.94394,2.22750,-0.61286
+4.64689,0.70331,-1.41475,-1.64490,-0.94550,2.22986,-0.61633
+4.66102,0.69896,-1.42021,-1.64017,-0.94732,2.23269,-0.62052
+4.67514,0.69403,-1.42661,-1.63452,-0.94949,2.23589,-0.62530
+4.68927,0.68718,-1.43580,-1.62625,-0.95265,2.24032,-0.63197
+4.70339,0.68047,-1.44508,-1.61772,-0.95594,2.24463,-0.63855
+4.71751,0.67521,-1.45251,-1.61077,-0.95868,2.24800,-0.64375
+4.73164,0.67260,-1.45623,-1.60724,-0.96010,2.24967,-0.64634
+4.74576,0.67004,-1.45992,-1.60372,-0.96151,2.25130,-0.64888
+4.75989,0.66684,-1.46460,-1.59924,-0.96330,2.25334,-0.65208
+4.77401,0.66370,-1.46925,-1.59477,-0.96509,2.25533,-0.65522
+4.78814,0.65935,-1.47579,-1.58843,-0.96762,2.25809,-0.65959
+4.80226,0.65384,-1.48422,-1.58022,-0.97090,2.26156,-0.66515
+4.81638,0.64901,-1.49173,-1.57282,-0.97388,2.26459,-0.67005
+4.83051,0.64426,-1.49924,-1.56535,-0.97692,2.26756,-0.67490
+4.84463,0.64249,-1.50205,-1.56252,-0.97809,2.26867,-0.67671
+4.85876,0.64014,-1.50581,-1.55873,-0.97966,2.27013,-0.67912
+4.87288,0.63957,-1.50674,-1.55779,-0.98006,2.27049,-0.67972
+4.88701,0.63899,-1.50766,-1.55685,-0.98045,2.27085,-0.68031
+4.90113,0.63782,-1.50955,-1.55493,-0.98125,2.27157,-0.68152
+4.91525,0.63437,-1.51521,-1.54919,-0.98361,2.27372,-0.68508
+4.92938,0.62927,-1.52368,-1.54058,-0.98713,2.27687,-0.69036
+4.94350,0.62758,-1.52650,-1.53767,-0.98836,2.27791,-0.69212
+4.95763,0.62703,-1.52743,-1.53670,-0.98876,2.27825,-0.69269
+4.97175,0.62646,-1.52839,-1.53570,-0.98919,2.27860,-0.69330
+4.98588,0.62590,-1.52932,-1.53474,-0.98960,2.27894,-0.69387
+5.00000,0.62588,-1.52936,-1.53470,-0.98962,2.27896,-0.69390
diff --git a/python/examples/path_in_pixels.csv b/python/examples/path_in_pixels.csv
index dea19bc..5437a62 100644
--- a/python/examples/path_in_pixels.csv
+++ b/python/examples/path_in_pixels.csv
@@ -1,312 +1,355 @@
-0.07124,0.92223
-0.08401,0.92223
-0.09207,0.92223
-0.10887,0.92223
-0.11895,0.92223
-0.12702,0.92097
-0.13441,0.92097
-0.15457,0.91846
-0.16196,0.91595
-0.17742,0.91218
-0.18481,0.90967
-0.19288,0.90967
-0.19691,0.90967
-0.20296,0.90967
-0.20901,0.90967
-0.22312,0.90841
-0.22782,0.90841
-0.23320,0.90716
-0.23858,0.90716
-0.24395,0.90716
-0.24866,0.90716
-0.25403,0.90716
-0.25874,0.90716
-0.26344,0.90716
-0.26882,0.90841
-0.27419,0.90841
-0.28226,0.90841
-0.28360,0.90841
-0.30444,0.91469
-0.31048,0.91469
-0.33468,0.91720
-0.36425,0.91972
-0.38642,0.92097
-0.39785,0.92097
-0.42809,0.91972
-0.43952,0.91846
-0.46573,0.91595
-0.50672,0.90967
-0.51613,0.90841
-0.53360,0.90716
-0.53763,0.90716
-0.54503,0.90716
-0.54906,0.90841
-0.55040,0.90841
-0.56653,0.91092
-0.57460,0.91092
-0.62164,0.91469
-0.65121,0.91344
-0.65793,0.91344
-0.68011,0.91092
-0.69019,0.90841
-0.70094,0.90716
-0.72446,0.90213
-0.73320,0.89962
-0.74597,0.89711
-0.75403,0.89460
-0.76478,0.89208
-0.77083,0.88832
-0.78629,0.87827
-0.79234,0.87324
-0.80242,0.86571
-0.81250,0.85943
-0.81989,0.85440
-0.82527,0.85064
-0.83065,0.84561
-0.83468,0.83933
-0.83535,0.83933
-0.84476,0.82803
-0.85551,0.81421
-0.87366,0.77528
-0.87769,0.76523
-0.88978,0.73885
-0.89987,0.70871
-0.90524,0.68861
-0.90995,0.66224
-0.91263,0.64591
-0.91331,0.63586
-0.91465,0.62707
-0.91532,0.61325
-0.91599,0.59693
-0.91667,0.56678
-0.91667,0.55548
-0.91599,0.53413
-0.91465,0.51277
-0.91398,0.50524
-0.91331,0.49896
-0.91129,0.48389
-0.90793,0.46505
-0.90659,0.45249
-0.90457,0.43993
-0.89919,0.41983
-0.89516,0.40476
-0.89180,0.39471
-0.88911,0.38717
-0.88575,0.37964
-0.87836,0.36582
-0.86962,0.35452
-0.86089,0.34573
-0.84409,0.32186
-0.82930,0.30302
-0.82325,0.29800
-0.80847,0.28544
-0.78763,0.27037
-0.78024,0.26409
-0.74731,0.23645
-0.71774,0.21761
-0.70766,0.21385
-0.68212,0.20757
-0.66868,0.20380
-0.65054,0.20129
-0.63777,0.20003
-0.63306,0.20003
-0.61761,0.20003
-0.60013,0.19249
-0.59207,0.18747
-0.53562,0.16486
-0.50739,0.15733
-0.45901,0.15105
-0.44758,0.14853
-0.42070,0.14351
-0.41263,0.14225
-0.38777,0.13849
-0.38306,0.13849
-0.36223,0.13723
-0.34207,0.13849
-0.32460,0.14100
-0.31653,0.14225
-0.30645,0.14728
-0.29435,0.15105
-0.28696,0.15481
-0.28159,0.15858
-0.26546,0.16989
-0.25672,0.17617
-0.25269,0.17742
-0.24597,0.18370
-0.23387,0.19124
-0.22446,0.19877
-0.20968,0.21761
-0.19892,0.23143
-0.19153,0.23897
-0.18817,0.24399
-0.18280,0.25027
-0.17540,0.26409
-0.15860,0.30177
-0.15121,0.32312
-0.14315,0.36457
-0.14113,0.37964
-0.13710,0.40225
-0.13508,0.41857
-0.13374,0.42988
-0.13306,0.44118
-0.13306,0.45123
-0.13508,0.45500
-0.14315,0.47635
-0.14852,0.49142
-0.15659,0.51654
-0.15927,0.52533
-0.16398,0.54041
-0.16801,0.55045
-0.17540,0.56301
-0.18078,0.57306
-0.18616,0.57934
-0.20094,0.60069
-0.20833,0.61200
-0.21573,0.62205
-0.22245,0.63209
-0.24261,0.65721
-0.24933,0.66349
-0.27016,0.68736
-0.28024,0.69866
-0.28562,0.70494
-0.29973,0.72001
-0.30780,0.72629
-0.31586,0.73132
-0.32997,0.74137
-0.34207,0.75016
-0.36761,0.77276
-0.38374,0.78281
-0.39247,0.78784
-0.41465,0.80165
-0.42003,0.80416
-0.43212,0.81044
-0.44220,0.81421
-0.45027,0.81672
-0.46774,0.83682
-0.47715,0.83933
-0.51949,0.84561
-0.53360,0.84687
-0.55780,0.84938
-0.56653,0.84938
-0.59745,0.85064
-0.63172,0.85189
-0.64247,0.85189
-0.67540,0.84938
-0.71169,0.84184
-0.71707,0.84059
-0.73320,0.83054
-0.74328,0.82426
-0.76210,0.80919
-0.77285,0.79788
-0.77823,0.79286
-0.78696,0.78030
-0.79301,0.77025
-0.79839,0.75518
-0.80511,0.73006
-0.80780,0.71499
-0.81048,0.68610
-0.81048,0.66977
-0.81048,0.65847
-0.80578,0.61702
-0.80309,0.60697
-0.79973,0.59693
-0.79234,0.57432
-0.76949,0.53036
-0.76411,0.52282
-0.74261,0.50147
-0.73320,0.49017
-0.72110,0.47509
-0.68280,0.44118
-0.65860,0.42737
-0.64987,0.41983
-0.61223,0.39094
-0.59946,0.38215
-0.56586,0.36582
-0.53831,0.35703
-0.52621,0.35326
-0.48656,0.34196
-0.47849,0.33945
-0.45497,0.33065
-0.44892,0.32814
-0.41532,0.31558
-0.39718,0.31181
-0.38374,0.31056
-0.37567,0.31056
-0.35685,0.31181
-0.34879,0.31307
-0.32796,0.32563
-0.31922,0.33442
-0.30309,0.35577
-0.29301,0.37587
-0.28696,0.39094
-0.28159,0.40350
-0.27285,0.44369
-0.27083,0.46253
-0.27016,0.49017
-0.27083,0.54292
-0.27285,0.56678
-0.27554,0.58060
-0.28159,0.59818
-0.30040,0.62958
-0.32258,0.66349
-0.33602,0.67982
-0.34677,0.69113
-0.37702,0.71750
-0.40390,0.73634
-0.41734,0.74262
-0.45766,0.75392
-0.47312,0.75392
-0.49597,0.75392
-0.53427,0.75267
-0.54772,0.74890
-0.57325,0.74513
-0.58468,0.74011
-0.61290,0.73006
-0.62030,0.72629
-0.63844,0.71499
-0.64315,0.71122
-0.65323,0.70243
-0.66196,0.69238
-0.67003,0.68108
-0.67608,0.66726
-0.67944,0.65596
-0.68280,0.64340
-0.68548,0.62330
-0.68616,0.60321
-0.68280,0.57432
-0.67204,0.54417
-0.66263,0.52408
-0.65188,0.51026
-0.61761,0.48389
-0.60484,0.47384
-0.57392,0.46128
-0.51546,0.45123
-0.49866,0.44997
-0.47312,0.44746
-0.45430,0.44495
-0.43884,0.43993
-0.40793,0.43113
-0.38710,0.43616
-0.38239,0.43993
-0.37836,0.44495
-0.37366,0.45500
-0.36962,0.46756
-0.36828,0.50147
-0.37097,0.52659
-0.37970,0.55799
-0.39315,0.59693
-0.40121,0.61451
-0.43011,0.65973
-0.44019,0.67480
-0.46707,0.70620
-0.48387,0.71750
-0.50739,0.72253
-0.54234,0.72253
-0.55578,0.71876
-0.56317,0.71499
-0.57527,0.70494
-0.58266,0.69615
-0.58804,0.68736
-0.59341,0.67354
-0.60013,0.64717
-0.60013,0.64717
+0.10651,0.86222
+0.10651,0.86097
+0.10651,0.85721
+0.10651,0.85093
+0.10651,0.83462
+0.10651,0.81078
+0.10651,0.79949
+0.10651,0.78945
+0.10651,0.77188
+0.10651,0.75306
+0.10651,0.73800
+0.10651,0.72796
+0.10651,0.71542
+0.10651,0.69534
+0.10794,0.67903
+0.10938,0.66648
+0.10938,0.65268
+0.11081,0.61127
+0.11224,0.59747
+0.11367,0.58241
+0.11511,0.55731
+0.11511,0.54351
+0.11654,0.53222
+0.11797,0.50461
+0.11940,0.48328
+0.12083,0.46948
+0.12227,0.45567
+0.12513,0.43434
+0.12799,0.40674
+0.12943,0.39294
+0.13229,0.37035
+0.13515,0.35027
+0.13659,0.33647
+0.13945,0.31514
+0.14231,0.28502
+0.14375,0.27373
+0.14518,0.26118
+0.14661,0.25240
+0.14661,0.24738
+0.14661,0.24487
+0.14661,0.24362
+0.14661,0.24236
+0.14661,0.23860
+0.14231,0.26746
+0.14088,0.27750
+0.13515,0.31890
+0.13515,0.33271
+0.13515,0.34651
+0.13802,0.35655
+0.13945,0.36408
+0.14088,0.37537
+0.14375,0.38415
+0.14661,0.39294
+0.14948,0.40423
+0.15234,0.41301
+0.15520,0.42054
+0.15807,0.43309
+0.16093,0.44187
+0.16380,0.44940
+0.16666,0.46069
+0.17096,0.46948
+0.17382,0.47826
+0.17669,0.48704
+0.18098,0.49457
+0.18528,0.50085
+0.18814,0.50461
+0.18957,0.50712
+0.19387,0.51089
+0.19960,0.51339
+0.20819,0.51339
+0.21678,0.51089
+0.22394,0.50712
+0.23254,0.50210
+0.24256,0.49583
+0.25115,0.48955
+0.26261,0.47952
+0.27407,0.46697
+0.27980,0.45944
+0.28696,0.44940
+0.29412,0.43936
+0.30128,0.42807
+0.30844,0.41427
+0.31273,0.40423
+0.31560,0.39419
+0.31846,0.38415
+0.31990,0.37913
+0.32133,0.37160
+0.32419,0.36031
+0.32849,0.35027
+0.32992,0.34149
+0.33278,0.33647
+0.33708,0.32894
+0.33851,0.32518
+0.34138,0.32141
+0.34711,0.31514
+0.35283,0.31137
+0.35856,0.30761
+0.36286,0.30510
+0.37002,0.30259
+0.37718,0.30259
+0.38720,0.30259
+0.39723,0.30259
+0.40582,0.30385
+0.41728,0.30761
+0.42730,0.31012
+0.44306,0.31765
+0.45165,0.32267
+0.46167,0.32894
+0.47170,0.33647
+0.48172,0.34274
+0.49318,0.35027
+0.50320,0.36031
+0.51896,0.37913
+0.52469,0.39043
+0.53041,0.40423
+0.53471,0.41301
+0.53901,0.42932
+0.53901,0.43811
+0.53901,0.44940
+0.53901,0.46195
+0.53757,0.47199
+0.53614,0.48203
+0.53471,0.48955
+0.53185,0.49457
+0.53041,0.49708
+0.53041,0.49834
+0.52755,0.50085
+0.52755,0.50085
+0.52325,0.50085
+0.51896,0.50085
+0.51180,0.50085
+0.50893,0.49834
+0.50177,0.49583
+0.49461,0.49081
+0.48745,0.48579
+0.47743,0.47701
+0.47027,0.46822
+0.46597,0.46069
+0.46167,0.45442
+0.45738,0.44689
+0.45308,0.44187
+0.45022,0.43434
+0.44449,0.41929
+0.44306,0.40172
+0.44306,0.38792
+0.44449,0.37913
+0.44592,0.37160
+0.44878,0.36282
+0.45022,0.35529
+0.45308,0.34902
+0.46597,0.33647
+0.47743,0.32894
+0.49032,0.32016
+0.50034,0.31514
+0.51896,0.30761
+0.52469,0.30510
+0.53041,0.30385
+0.53471,0.30385
+0.54044,0.30385
+0.55046,0.30887
+0.56335,0.32016
+0.57195,0.33145
+0.58054,0.34274
+0.58483,0.35153
+0.59486,0.37035
+0.60202,0.38541
+0.61061,0.40046
+0.61920,0.41427
+0.62636,0.42807
+0.63353,0.44062
+0.63782,0.44940
+0.64212,0.45944
+0.64641,0.47073
+0.64785,0.47952
+0.64928,0.48579
+0.64928,0.49081
+0.64928,0.49332
+0.64928,0.49332
+0.64928,0.49457
+0.64928,0.49583
+0.64498,0.47450
+0.64355,0.46822
+0.64069,0.45317
+0.63496,0.42807
+0.63209,0.40674
+0.63209,0.39670
+0.63066,0.38917
+0.63066,0.37662
+0.63066,0.36157
+0.63353,0.35153
+0.63496,0.34274
+0.63925,0.33647
+0.64498,0.32894
+0.65214,0.32267
+0.65930,0.31765
+0.67076,0.30887
+0.67792,0.30510
+0.68222,0.30259
+0.68651,0.30259
+0.69367,0.30259
+0.70227,0.30259
+0.71229,0.30385
+0.72518,0.30887
+0.73520,0.31514
+0.74953,0.32518
+0.76385,0.34149
+0.77387,0.35529
+0.80108,0.39545
+0.80824,0.41050
+0.81397,0.42180
+0.81683,0.42932
+0.81970,0.43685
+0.82399,0.44564
+0.82686,0.45066
+0.82972,0.45944
+0.83116,0.46571
+0.83402,0.47952
+0.83402,0.48453
+0.83402,0.48955
+0.83402,0.49332
+0.83402,0.49834
+0.83402,0.49959
+0.83402,0.50210
+0.83402,0.50336
+0.83402,0.50461
+0.83402,0.50587
+0.83259,0.50461
+0.83259,0.43936
+0.83259,0.38917
+0.83259,0.34902
+0.83259,0.34274
+0.83259,0.32016
+0.83259,0.30134
+0.83116,0.29004
+0.82829,0.27122
+0.82686,0.25491
+0.82543,0.24111
+0.82256,0.22730
+0.81970,0.21099
+0.81397,0.20095
+0.80824,0.18841
+0.80108,0.17711
+0.79249,0.16707
+0.78246,0.15704
+0.77530,0.15076
+0.76385,0.14323
+0.74523,0.13445
+0.72804,0.12692
+0.70227,0.11437
+0.67935,0.10308
+0.65787,0.09304
+0.64212,0.08677
+0.63209,0.08300
+0.60918,0.07924
+0.58627,0.07422
+0.57481,0.07422
+0.55762,0.07422
+0.54044,0.07422
+0.52469,0.07297
+0.50893,0.07297
+0.49748,0.07297
+0.45308,0.07297
+0.43446,0.07422
+0.42014,0.07548
+0.39580,0.07798
+0.37575,0.07924
+0.36429,0.07924
+0.35856,0.08049
+0.34567,0.08175
+0.33422,0.08300
+0.30844,0.08677
+0.29698,0.08928
+0.28982,0.09053
+0.28123,0.09179
+0.25832,0.09555
+0.24543,0.09806
+0.23397,0.09932
+0.22538,0.10183
+0.21822,0.10308
+0.20962,0.10684
+0.19817,0.11312
+0.18957,0.11814
+0.18241,0.12316
+0.17525,0.12692
+0.16236,0.13570
+0.15520,0.14072
+0.14948,0.14825
+0.14375,0.15704
+0.14088,0.16331
+0.13659,0.17209
+0.13372,0.17711
+0.12656,0.19092
+0.12513,0.19719
+0.12513,0.20221
+0.12513,0.20974
+0.12513,0.21601
+0.12656,0.22730
+0.13086,0.23734
+0.13372,0.24487
+0.14375,0.25240
+0.15807,0.26118
+0.17239,0.26746
+0.18241,0.26997
+0.19817,0.27248
+0.21249,0.27248
+0.22681,0.27248
+0.23827,0.27248
+0.25115,0.27248
+0.26834,0.27248
+0.29125,0.27122
+0.30844,0.27122
+0.33135,0.27373
+0.36286,0.27624
+0.38577,0.27875
+0.41012,0.28001
+0.43733,0.28377
+0.45595,0.28502
+0.48602,0.28628
+0.51323,0.28628
+0.53185,0.28628
+0.57624,0.28377
+0.59343,0.28251
+0.62207,0.27750
+0.65071,0.27499
+0.66646,0.27373
+0.68651,0.27248
+0.70513,0.27248
+0.71802,0.27122
+0.72804,0.27122
+0.73520,0.27122
+0.74380,0.26997
+0.75382,0.26997
+0.76814,0.26997
+0.78246,0.26997
+0.79392,0.26997
+0.79965,0.26997
+0.80538,0.26997
+0.81254,0.26997
+0.81970,0.26997
+0.82972,0.26997
+0.84261,0.26997
+0.85407,0.26997
+0.86553,0.26997
+0.86982,0.26997
+0.87555,0.26997
+0.87698,0.26997
+0.87841,0.26997
+0.88128,0.26997
+0.88987,0.26997
+0.90276,0.26997
+0.90706,0.26997
+0.90849,0.26997
+0.90992,0.26997
+0.91135,0.26997
+0.91135,0.26997
diff --git a/python/ur_simple_control/__init__.py b/python/ur_simple_control/__init__.py
index 4cbd4c8..5cb8d28 100644
--- a/python/ur_simple_control/__init__.py
+++ b/python/ur_simple_control/__init__.py
@@ -1,4 +1,4 @@
 from ur_simple_control import clik, dmp, robot_descriptions, util, visualize
 __all__ = [
-"clik", "dmp", "robot_descriptions", "util", "visualize", "basics",
+"clik", "dmp", "robot_descriptions", "util", "visualize", "basics"
 ]
diff --git a/python/ur_simple_control/__pycache__/__init__.cpython-312.pyc b/python/ur_simple_control/__pycache__/__init__.cpython-312.pyc
index 9b2834644867a509017a904089c126c95aadacf2..020d0f164aa0e0b0d8f6cab89bf1677599bec9c6 100644
GIT binary patch
delta 28
jcmZo?ZfE8_&CAQhz`($8I@&sY-bP+;M#fu{BN_DoWTyvr

delta 28
jcmZo?ZfE8_&CAQhz`(%ZX7VR>{zhJJM#f*0BN_DoWf}*o

diff --git a/python/ur_simple_control/__pycache__/managers.cpython-312.pyc b/python/ur_simple_control/__pycache__/managers.cpython-312.pyc
index a1ee685af1c3b75aa6819392fdc500bbc70a3e9a..96a852891d509709b84808fbed70a2d7f0248b4a 100644
GIT binary patch
delta 619
zcmezRf$8H1Cf?J$yj%<n3=A?c*6Cauc?+2tg(e5GC^HIA7G#xY6q#(us>&z|Vl#`S
zKxD+hJP8O-Sh9ozq#cA)q*A2Q8B$~>?`KjKlr7-_iGgs6T#Eb}{>hEZih>Fyd>|1J
zPEkxzf`~FIgG^*p0of&}iljm<MIE9-Py<O+6RuAStWO)Hk5LEA)&;Qz^^n}8pJD(t
z!w^Z-D8(2e%4h=CXA0J5hU8}R6bpz7K}#gNtx~Ml*noXvizI57Vh<5jbU+eyOmSMn
zznTT)R|W<~h8l)o22JP9%h`7`F@|hT;>zXbPWiyhz$)>Dfsr+2@-0z&gG@L-oACh)
z*L4>0i!9<7B=ojaTsIHBXdZe)F#AGjC0tSUW>2wRTPAj!$qvC5lLbN^Fp5q781j`-
ze6n<?98-$;WPdQVSv~AMBcsG*@d!gk$;qA(i<w?BO@0?~WAo|Ao6>BP85kIfCT(6-
zI*)~Y5(5K+pC<R@1C5fKGpa1u87FOC*x1O*IBBzTJ1d9i1dviN!NkD8@RAwK-E7-`
gid6_KYRtgEpvhPSW>4BIIdwfh<Alv8m#h&60R0t^$N&HU

delta 627
zcmezPf$8f9Cf?J$yj%<n3=FFy%+q-{@)j~rHeyv_6q+o^D$gi9*^pJ0Q3T8u1+&G#
zY;h1<SfYdjq!ENuBvYi)8B(Mt?`KjKlqul>iGgs6Y>M0({>hEZih}Ybd>|1JPEklv
zgorXKfz49}nJ1`%q(U`C4WdF&9Z6IJu1^!JPYa}vQ5($G0kH*jk=&%0q7OC007=v^
z#RwwGXbje80@i1W<Yu!JbBGE-3naTOQ>@llgMDIyBx;*t2N6}YM-p{Naa_Z{ng!%n
z1_nlk8irs7O{dMv*>^K-PUgzx=1%><%)lz~g@KVZbn<OcdxI=EKZo%F3)giP@rx|t
z7bNtyR9rU?y=WeKLooY7X%$>i&1NsLURx$Ho5_yB7L#*B<R<Hf9AXro{3+xsqr_yH
zP&uX)iOB(AYO_Yzdqzgd$r2HUj8c=mA{H|hDNlYMaf9h4)8-?Qccj@SF)%O`P29Y!
zbRG-)L<R;1KTYn*dm1G-r&L+6Gfvz*x3Q6xapGqAc2*9levncy!NkD8@RAwE)#RJ(
m(4)LLv40V(5Lnunfq_Aju?WnbxLI`SdVa?K%}1B45e5L%vXd?V

diff --git a/python/ur_simple_control/basics/__init__.py b/python/ur_simple_control/basics/__init__.py
index e69de29..71b8f3e 100644
--- a/python/ur_simple_control/basics/__init__.py
+++ b/python/ur_simple_control/basics/__init__.py
@@ -0,0 +1 @@
+from .basics import *
diff --git a/python/ur_simple_control/basics/__pycache__/__init__.cpython-312.pyc b/python/ur_simple_control/basics/__pycache__/__init__.cpython-312.pyc
index bfdbb02db5158c96d88c7565cf618180c158a478..e59be1cb003dba22092cd0ab31c6aa7026ae1251 100644
GIT binary patch
delta 126
zcmcb}_?9u?G%qg~0|Ns?VU%^c7y|>tV-N?1nV^i%d<+Z>(-~42QW$d>)-o|NR5EEY
zzhq=!V9;c|#i-?{$#{z`DX};+xp?J7^9t2l95%W6DWy57c10Wv3=AN3#URE9W=2NF
My9}a5Yzzzx0N@lDxBvhE

delta 98
zcmaFMc#+ZkG%qg~0|Ntto5`P45d9cLpySUh3=9m@87dhx8U0o=6frR{Obn<{`o&?B
ho1apelWJGQ%D}+D$iTo*3}Sp_W@Kb6VrF1q0040X5gGsh

diff --git a/python/ur_simple_control/clik/__init__.py b/python/ur_simple_control/clik/__init__.py
index e69de29..89ff317 100644
--- a/python/ur_simple_control/clik/__init__.py
+++ b/python/ur_simple_control/clik/__init__.py
@@ -0,0 +1 @@
+from .clik import *
diff --git a/python/ur_simple_control/clik/__pycache__/__init__.cpython-312.pyc b/python/ur_simple_control/clik/__pycache__/__init__.cpython-312.pyc
index da51c5e2ade3792316b9ed1771c9d1b7da7ccf70..2a81ddc6cd46f2c3255161f2c7285382187bf2c9 100644
GIT binary patch
delta 124
zcmX@l_>$4@G%qg~0|NuY<1p)V5fBaHz%Ub(@tKc-fnhpB3PTEG4#Qd|MutizP3D)3
z3=9mKjJFuI{4^PFu_WhYX0M!RUZ#4B!zMRBr8Fniu84zyfdQnd7{vI%%*e=imqECQ
Ije&sy0LhvdL;wH)

delta 98
zcmaFKc%ISxG%qg~0|Ntto5`P45d9cLpySUh3=9m@87dhx8U0o=6frR{O!O;L`o&?B
ho1apelWJGQ%D}+D$iTo*3}Sp_W@Kb6VrF1q003?)5fA_X

diff --git a/python/ur_simple_control/clik/clik.py b/python/ur_simple_control/clik/clik.py
index ff4d882..830838a 100644
--- a/python/ur_simple_control/clik/clik.py
+++ b/python/ur_simple_control/clik/clik.py
@@ -146,8 +146,9 @@ def controlLoopClik(robot : RobotManager, clik_controller, i, past_data):
     breakFlag = False
     log_item = {}
     q = robot.getQ()
+    T_w_e = robot.getT_w_e()
     # first check whether we're at the goal
-    SEerror = robot.data.oMi[robot.JOINT_ID].actInv(robot.Mgoal)
+    SEerror = T_w_e.actInv(robot.Mgoal)
     err_vector = pin.log6(SEerror).vector 
     if np.linalg.norm(err_vector) < robot.args.goal_error:
 #      print("Convergence achieved, reached destionation!")
@@ -221,7 +222,7 @@ def moveUntilContact(args, robot, speed):
     time.sleep(0.01)
     print("Collision detected!!")
 
-def moveL(args, robot, goal_point):
+def moveL(args, robot : RobotManager, goal_point):
     """
     moveL
     -----
@@ -240,19 +241,20 @@ def moveL(args, robot, goal_point):
         }
     loop_manager = ControlLoopManager(robot, controlLoop, args, {}, log_item)
     loop_manager.run()
-    # TODO: remove, this isn't doing anything
-    time.sleep(0.01)
-    print("MoveL done: convergence achieved, reached destionation!")
 
 # TODO: implement
-# the idea is to make a path from current to goal position
-# which is just a straight line between them.
-# the question is what to do with orientations.
-# i suppose it makes sense to have one function that enforces/assumes
-# that the start and end positions have the same orientation.
-# then another version goes in a line and linearly updates the orientation
-# as it goes
 def moveLFollowingLine(args, robot, goal_point):
+    """
+    moveLFollowingLine
+    ------------------
+    make a path from current to goal position, i.e.
+    just a straight line between them.
+    the question is what to do with orientations.
+    i suppose it makes sense to have one function that enforces/assumes
+    that the start and end positions have the same orientation.
+    then another version goes in a line and linearly updates the orientation
+    as it goes
+    """
     pass
 
 # TODO: implement
@@ -340,9 +342,6 @@ def compliantMoveL(args, robot, goal_point):
             }
     loop_manager = ControlLoopManager(robot, controlLoop, args, save_past_dict, log_item)
     loop_manager.run()
-    # TODO: remove, this isn't doing anything
-    time.sleep(0.01)
-    print("compliantMoveL done: convergence achieved, reached destionation!")
 
 
 def clikCartesianPathIntoJointPath(args, robot, path, \
@@ -389,6 +388,7 @@ def clikCartesianPathIntoJointPath(args, robot, path, \
         # loop logs is a dict, dict keys list preserves input order
         new_q = sim_robot.q.copy() 
         robot.updateViz(sim_robot.q, sim_robot.T_w_e)
+        time.sleep(0.05)
         qs.append(new_q[:6])
         # plot this on the real robot
 
diff --git a/python/ur_simple_control/dmp/__init__.py b/python/ur_simple_control/dmp/__init__.py
index e69de29..79beb15 100644
--- a/python/ur_simple_control/dmp/__init__.py
+++ b/python/ur_simple_control/dmp/__init__.py
@@ -0,0 +1 @@
+from .dmp import *
diff --git a/python/ur_simple_control/dmp/__pycache__/__init__.cpython-312.pyc b/python/ur_simple_control/dmp/__pycache__/__init__.cpython-312.pyc
index 1391575a09999c264117e9287f69a1b2d7b7006d..76ca428c42d8c7da269804cca80bbe7ef51db740 100644
GIT binary patch
delta 123
zcmX@d_?*%AG%qg~0|Ns?S(J6UFara_V-N?1nV^i%d<+Z>(-~42QW$d>)-o|NR5EEY
zzhq=!V9;c|#i-?{$#{!7CAVPZMDtSBTO2mI`6;D2sdhyi3=9k)Ma3Y-2WCb_#=8tc
JMQjWV3;=q?7jXap

delta 98
zcmaFPc#hHhG%qg~0|Ntto5`P45d9cLpySUh3=9m@87dhx8U0o=6frR{O!O^P`o&?B
ho1apelWJGQ%D}+D$iTo*3}Sp_W@Kb6VrF1q003;h5eonS

diff --git a/python/ur_simple_control/managers.py b/python/ur_simple_control/managers.py
index 42cd882..d09e663 100644
--- a/python/ur_simple_control/managers.py
+++ b/python/ur_simple_control/managers.py
@@ -78,13 +78,13 @@ def getMinimalArgParser():
             help="robot's ip address (only needed if running on the real robot)", \
                     default="192.168.1.102")
     parser.add_argument('--pinocchio-only', action=argparse.BooleanOptionalAction, \
-            help="whether you want to just integrate with pinocchio", default=False)
+            help="whether you want to just integrate with pinocchio", default=True)
     parser.add_argument('--fast-simulation', action=argparse.BooleanOptionalAction, \
             help="do you want simulation to run over 500Hz? (real-time viz relies on 500Hz)", default=False)
     parser.add_argument('--visualize-manipulator', action=argparse.BooleanOptionalAction, \
-            help="whether you want to visualize the manipulator and workspace with meshcat", default=False)
+            help="whether you want to visualize the manipulator and workspace with meshcat", default=True)
     parser.add_argument('--real-time-plotting', action=argparse.BooleanOptionalAction, \
-            help="whether you want to have some real-time matplotlib graphs (parts of log_dict you select)", default=False)
+            help="whether you want to have some real-time matplotlib graphs (parts of log_dict you select)", default=True)
     parser.add_argument('--gripper', type=str, \
             help="gripper you're using (no gripper is the default)", \
                         default="none", choices=['none', 'robotiq', 'onrobot'])
@@ -457,7 +457,7 @@ class RobotManager:
                                                      args=(self.args, self.model, self.collision_model, self.visual_model, self.manipulator_visualizer_queue, ))
             self.manipulator_visualizer_process.start()
             # give it time to start
-            time.sleep(5)
+            time.sleep(2)
             if args.debug_prints:
                 print("ROBOT_MANAGER: manipulator_visualizer_process started")
             self.manipulator_visualizer_queue.put(np.zeros(self.model.nq))
diff --git a/python/ur_simple_control/optimal_control/__init__.py b/python/ur_simple_control/optimal_control/__init__.py
new file mode 100644
index 0000000..255cf7b
--- /dev/null
+++ b/python/ur_simple_control/optimal_control/__init__.py
@@ -0,0 +1,4 @@
+from .create_pinocchio_casadi_ocp import *
+from .crocoddyl_mpc import *
+from .crocoddyl_optimal_control import *
+from .get_ocp_args import *
diff --git a/python/ur_simple_control/optimal_control/create_pinocchio_casadi_ocp.py b/python/ur_simple_control/optimal_control/create_pinocchio_casadi_ocp.py
new file mode 100644
index 0000000..d0e2717
--- /dev/null
+++ b/python/ur_simple_control/optimal_control/create_pinocchio_casadi_ocp.py
@@ -0,0 +1,149 @@
+import casadi
+import pinocchio as pin
+from pinocchio import casadi as cpin
+import numpy as np
+from ur_simple_control.managers import RobotManager, ControlLoopManager
+import pickle
+from importlib.resources import files
+
+"""
+CREDIT: jrnh2023 pinocchio.casadi tutorial
+Implement and solve the following nonlinear program:
+decide q \in R^NQ
+minimizing   sum_t || q - robot.q0 ||**2
+so that
+      h(q) = target
+      forall obstacles o,    (e_p - e_c)' e_A (e_p-e_c) >= 1
+      TODO: here also define the table/floor as a plane, which would be 
+                    normal_plane_vector (0,0,1) \cdot T_w_e.translation > 0
+with h(q) the forward geometry (position of end effector) to be at target position,
+e_A,e_c the ellipse matrix and center in the attached joint frame e_, and e_p = oMe^-1 o_p
+the position of the obstacle point p in frame e_.
+
+The following tools are used:
+- the ur10 model (loaded by example-robot-data)
+- pinocchio.casadi for writing the problem and computing its derivatives
+- the IpOpt solver wrapped in casadi
+- the meshcat viewer
+
+It assumes that the ellipses parameters are already computed, see ellipses.py for that.
+"""
+
+def createCasadiIKObstacleAvoidanceOCP(args, robot : RobotManager, x0, goal: pin.SE3):
+    # TODO have ellipses in robot.ellipses. this is loaded if you load whatever argument is responsible
+    # or you load them here from a file in robot_descriptions
+    # which you need to generate from generate_ellipses.py in utils
+    # there should be one for each link more or less
+    # TODO: make this for every robot.
+    # TODO; calculate ellipses if they don't exist already
+    ellipses_path = files('ur_simple_control.robot_descriptions.ellipses').joinpath("ur5e_robotiq_ellipses.pickle")
+    file = open(ellipses_path, 'rb')
+    ellipses = pickle.load(file)
+    file.close()
+
+    for ellipse in ellipses:
+        ellipse.id = model.getJointId(ellipse.name)
+        l, P = np.linalg.eig(ellipse.A)
+        ellipse.radius = 1 / l**0.5
+        ellipse.rotation = P
+        # TODO: use wrapped meshcat visualizer to have access to more nifty plotting
+        #ellipse.placement = pin.SE3(P, ellipse.center)
+        #viz.addEllipsoid(f"el_{e.name}", e.radius, [0.3, 0.9, 0.3, 0.3])
+
+    # TODO: obstacles
+    # here you need to define other obstacles, namely the table (floor) 
+    # it's obviously going to be a plane 
+    # alternatively just forbid z-axis of end-effector to be negative
+    obstacles = []
+
+
+    cmodel = cpin.Model(robot.model)
+    cdata = cmodel.createData()
+
+    #######################################################################
+    #                           kinematics level                          #
+    #######################################################################
+
+#    cq = casadi.SX.sym("q", robot.model.nq, 1)
+#    cpin.framesForwardKinematics(cmodel, cdata, cq)
+#    error6_tool = casadi.Function(
+#        "etool",
+#        [cq],
+#        [cpin.log6(cdata.oMf[robot.ee_frame_id].inverse() * cpin.SE3(Mtarget)).vector],
+#    )
+    for ellipse in ellipses:
+        # Position of the obstacle cpos in the ellipse frame.
+        ellipse.e_pos = casadi.Function(
+            f"e{e.id}", [cq, cpos], [cdata.oMi[ellipse.id].inverse().act(casadi.SX(cpos))]
+        )
+    #######################################################################
+    #                           dynamics level                            #
+    #######################################################################
+
+    # variables on a single time-step
+    nx = robot.model.nq + robot.model.nv
+    ndx = 2 * robot.model.nv
+    cx = casadi.SX.sym("x", nx, 1)
+    cdx = casadi.SX.sym("dx", robot.model.nv * 2, 1)
+    cq = cx[:robot.model.nq]
+    cv = cx[robot.model.nq:]
+    caq = casadi.SX.sym("a", robot.model.nv, 1)
+    cpin.forwardKinematics(cmodel, cdata, cq, cv, caq)
+    cpin.updateFramePlacements(cmodel, cdata)
+
+    # cost function - reaching goal
+    error_tool = casadi.Function(
+        "etool6", [cx], [cpin.log6(cdata.oMf[endEffector_ID].inverse() * cpin.SE3(Mtarget)).vector],)
+
+    # nonlinear dynamics constraint
+    cnext = casadi.Function(
+        "next",
+        [cx, caq],
+        [
+            casadi.vertcat(
+                cpin.integrate(cmodel, cx[:robot.model.nq], cx[robot.model.nq:] * args.ocp_dt + caq * args.ocp_dt**2),
+                cx[nq:] + caq * args.ocp_dt,
+            )
+        ],
+    )
+    opti = casadi.Opti()
+    # one set of decision variables per knot (both states and control input)
+    var_xs = [opti.variable(nx) for t in range(args.n_knots + 1)]
+    var_as = [opti.variable(nv) for t in range(args.n_knots)]
+
+    # running costs - x**2 and u**@ - used more for regularization than anything else
+    totalcost = 0
+    for t in range(T):
+        # running
+        totalcost += 1e-3 * DT * casadi.sumsqr(var_xs[t][nq:])
+        totalcost += 1e-4 * DT * casadi.sumsqr(var_as[t])
+    # terminal cost
+    totalcost += 1e4 * casadi.sumsqr(error_tool(var_xs[T]))
+
+
+    # collision avoidance (hard) constraints
+    # TODO: idk if you need to input x0 in this way, maybe robot.getQ(d) is better?
+    opti.subject_to(var_xs[0][:nq] == x0[:robot.model.nq])
+    opti.subject_to(var_xs[0][nq:] == x0[robot.model.nq:])
+    for t in range(T):
+        opti.subject_to(cnext(var_xs[t], var_as[t]) == var_xs[t + 1])
+    for ellipse in ellipses:
+        for obstacle in obstacles:
+            for x in var_xs:
+                # obstacle position in ellipsoid (joint) frame
+                #e_pos = e.e_pos(var_q, o.pos)
+                e_pos = ellipse.e_pos(x[:nq], obstacle.pos)
+                opti.subject_to((e_pos - ellipse.center).T @ e.A @ (e_pos - e.center) >= 1)
+
+    # now that the ocp has been transcribed as nlp,
+    # solve it
+    try:
+        sol = opti.solve_limited()
+        #sol_q = opti.value(var_q)
+        sol_xs = [opti.value(var_x) for var_x in var_xs]
+        sol_as = [opti.value(var_a) for var_a in var_as]
+    except:
+        print("ERROR in convergence, plotting debug info.")
+        #sol_q = opti.debug.value(var_q)
+        sol_xs = [opti.debug.value(var_x) for var_x in var_xs]
+        sol_as = [opti.debug.value(var_a) for var_a in var_as]
diff --git a/python/ur_simple_control/optimal_control/crocoddyl_optimal_control.py b/python/ur_simple_control/optimal_control/crocoddyl_optimal_control.py
index eb07d99..0b9a45d 100644
--- a/python/ur_simple_control/optimal_control/crocoddyl_optimal_control.py
+++ b/python/ur_simple_control/optimal_control/crocoddyl_optimal_control.py
@@ -9,21 +9,6 @@ from ur_simple_control.visualize.visualize import plotFromDict
 import example_robot_data
 import time
 
-
-def get_OCP_args(parser : argparse.ArgumentParser):
-    parser.add_argument("--ocp-dt", type=float, default=1e-2, \
-                        help="time length between state-control-pair decision variables")
-    parser.add_argument("--n-knots", type=int, default=100, \
-                        help="number of state-control-pair decision variables")
-    parser.add_argument("--stop-at-final", type=int, default=1, \
-                        help="the trajectory generated by the OCP will be followed. it might not have finally velocity 0. \
-                             if this argument is set to true, the final velocity will be set to 0 (there will be overshoot).")
-    parser.add_argument("--solver", type=str, default="boxfddp", \
-                        help="optimal control problem solver you want", choices=["boxfddp", "csqp"])
-    parser.add_argument("--max-solver-iter", type=int, default=200, \
-                        help="number of iterations the ocp solver takes. ~100-500 for just ocp (it can converge before ofc), ~10 for mpc")
-    return parser
-                        
 def createCrocoIKOCP(args, robot : RobotManager, x0, goal : pin.SE3):
     # create torque bounds which correspond to percentage
     # of maximum allowed acceleration 
diff --git a/python/ur_simple_control/optimal_control/get_ocp_args.py b/python/ur_simple_control/optimal_control/get_ocp_args.py
new file mode 100644
index 0000000..97d87a1
--- /dev/null
+++ b/python/ur_simple_control/optimal_control/get_ocp_args.py
@@ -0,0 +1,15 @@
+import argparse
+
+def get_OCP_args(parser : argparse.ArgumentParser):
+    parser.add_argument("--ocp-dt", type=float, default=1e-2, \
+                        help="time length between state-control-pair decision variables")
+    parser.add_argument("--n-knots", type=int, default=100, \
+                        help="number of state-control-pair decision variables")
+    parser.add_argument("--stop-at-final", type=int, default=1, \
+                        help="the trajectory generated by the OCP will be followed. it might not have finally velocity 0. \
+                             if this argument is set to true, the final velocity will be set to 0 (there will be overshoot).")
+    parser.add_argument("--solver", type=str, default="boxfddp", \
+                        help="optimal control problem solver you want", choices=["boxfddp", "csqp"])
+    parser.add_argument("--max-solver-iter", type=int, default=200, \
+                        help="number of iterations the ocp solver takes. ~100-500 for just ocp (it can converge before ofc), ~10 for mpc")
+    return parser
diff --git a/python/ur_simple_control/util/__init__.py b/python/ur_simple_control/util/__init__.py
index e69de29..fabba21 100644
--- a/python/ur_simple_control/util/__init__.py
+++ b/python/ur_simple_control/util/__init__.py
@@ -0,0 +1,8 @@
+#from .calib_board_hacks import *
+#from .draw_path import *
+#from .encapsulating_ellipses import *
+#from .freedrive import *
+#from .ft_calibration import *
+#from .get_model import *
+#from .logging_utils import *
+#from .map2DPathTo3DPlane import *
diff --git a/python/ur_simple_control/util/__pycache__/__init__.cpython-312.pyc b/python/ur_simple_control/util/__pycache__/__init__.cpython-312.pyc
index 3fbe9907280c84609fe3b1cea8305bb8ce0c7421..52194c1d073869e8b7aa28fc186e22a92633ed64 100644
GIT binary patch
delta 26
icmX@lc%G5>G%qg~0|NuY?`Z4v?-O|!Fy5NDP7wfXtqBDH

delta 26
icmX@lc%G5>G%qg~0|Ntto5`P4hKalj7=KM%rw9OHum}+V

diff --git a/python/ur_simple_control/util/__pycache__/calib_board_hacks.cpython-312.pyc b/python/ur_simple_control/util/__pycache__/calib_board_hacks.cpython-312.pyc
index 4ac2f3a069d20ebbb0e8dd7eac2be20e189b1bbe..54d7c441ab3d60c2b2f3e0a916348d21a5b09f9b 100644
GIT binary patch
delta 74
zcmZq8Y|i98&CAQhz`(%Z7j2zhypdOeg;8>|8p~}qM)l21+*4T@-8Rn<2;gB%*!)sv
fuOQ>H&CB)LS$TXI7#Kb<Gcq#XW)PojW8w(_<tY>O

delta 76
zcmZq9Y|Z37&CAQhz`(%J5NMu$X(O)$3!}_tHJ00Kj9QzSxTmr*dTyQ}5WvHjy!oZf
hUO~o{o0sdgv-0^dFfe>zW@Kdi%)!7YG1<z*696pR6srIL

diff --git a/python/ur_simple_control/util/__pycache__/get_model.cpython-312.pyc b/python/ur_simple_control/util/__pycache__/get_model.cpython-312.pyc
index ff30b90edef8b10d19dfe9251aa3735474ea1fab..b58f1882fb35dc03e56f929f8a076affb090553c 100644
GIT binary patch
delta 1199
zcmdn$u+o|DG%qg~0|Ns?Z=7{HpUOr)3q~dhj?Es7fo$~>SqdN-RP4eKtI5DnE14ot
zBblXyDhJ|~F%&cQ2-QetsepK>xK^r0Dn+nLh=Bpbs*#Krg30%2voO?%quN&wk))x8
zY&Bw8Y7kqH$rK?Q1_p+jdQKeD!eD709I_%{S$-U{qF`Ae9I|3ySy6~AM&PE1gQQFN
zVQ$URnEZfEWO5D%C%<%!SdDm%M2&PBOE80`#O4-`xs3d`STYjxQl9@=`SFr(Qh@zr
zMJ{<p(aDZnlP%Lz^K(;6iYon+vQm>vif^&xCFZ8y;>=Ag&InFU%t^h)pOv4PR}zqu
zn4FrMng>$hl30?cDYN-CR}P~PNc%0u;#({!i6x1}G7Jn1lM{I)CztayaN9F5Fo0sd
zSdw`&6R!aiBhTcYateMAcz7p>c6xO<-jJ2+aOw5?z|A12`+<i+P~p0O{uKfJ4wf6-
zf)hffM^22q#4UG2Kx8`KM7|D3Y}yPy2y8ay_h3}9U|?V<vIG%UAi|b`fkBh;7Hd&{
zQhrG>BLf42LXq9%`2rHGZVU_znUnVj*s(Z(oNB-*wpm2*3uC4TNSg$RkOUD@AVL~M
zfP7S>2r`eYNEsxc3L>!BSIh>oMgath>=+mrZt<t5mc(bI7Uk!~=jNxR<`j8=bWSc5
zUdiaNSz6>aD;p<BfMfC>Ne`z05Yr!|jU_3uIJF35SP?tOTKOVSI2M5%c#G8+Y>*sC
z9j`ky;viz8lY6AP*+7}7NO-cWbSzhqEXYWCkT0i6A7u2K93i763wAd=h>EO1N<ayz
zSQw-(kw;ho;&x$(yAulvit;Nma}!H4^Ye<z7#J8jHeZzKWMXuf94#*;4slanX>LJf
z5y<9S%*B<(Mf{U{<kjqAK}I`+2(a@(;SLD^kSQw}ia@~+v5UhdH$SB`C)KW~j)8#z
m6j{Y~lRwC7OFJ_%ntk$OVq)}T{3Im8X!cphg^|$;tP=o%7x2yi

delta 803
zcmZ4Kyw!p4G%qg~0|<y3rSDYS$Y;UGWWm1KgE5fJk*!87O93Q>ic<t^7#J98IC01d
zf@OI?vXkpLBw6{vtT`N#wn88ls#zdjiU?STC=OXskZcM6<aH7<lf5{(`6X+_YQ$?K
zY9!NGf*CZ$Hm7jTWt=R)Ezc-4*?@bpcvgO9UP(YsVsdJ3YF<h4Ef$x=l0;3Z&40La
z7&%iCOA?Ev7#J8PH}Z;3p1{jGc^Ypmw*><Og9-x!L-A^+&2oGOOpI)s_X>D0IvO)D
zFcg`92vZPY#=yX!$#{#kC_gE`q?nO`fkC0joPmMimQZ?XiF;9IK|yL!PHJ&+Xpm`Y
zkv#(gL&Rh^Av+dJkaY%(Vw>j)ePQ$$0+}QRBE&(21c;CX5g=C;$$+e2E0O~VfI_|q
zixZ03KsGCYK#}?6ha#e^jtmS8iIabetYoy@yj1iyD;qmVKilLsX%7!i5Yq$XN|vO=
z;?!F#8Hsr*>3>#!yyTk{V6Q1(1oC_l$W^ykee+XNb8fNZCFZ8y;&o5W&rK~Usssxb
z2~QS~>1GoE874S+p-imIE&g<<0{^6})Z~)lTb#M6#TmiLi8-m0Ib;tqx=%hOt0fM0
zKRonqv4Aw)Vl1A_BPS^j4m;tD)S~>n_{4&OqWp@?+{BX1{Jf%41_p-m%`S4COpKP3
z&nZZWL)@2Fnp;p=1aibJ=HklYBHqdW71Zn^K#l^X5r|hn0bc|P5wIyM8HzyR4~ZuZ
yo80`A(wtPgqFM$922cbR+fGha)Rr=0H2ajn$i(Q!_(@2F(d@I13nQZySR(-Ym$w)I

diff --git a/python/ur_simple_control/util/calib_board_hacks.py b/python/ur_simple_control/util/calib_board_hacks.py
index ef42370..f753a18 100644
--- a/python/ur_simple_control/util/calib_board_hacks.py
+++ b/python/ur_simple_control/util/calib_board_hacks.py
@@ -1,6 +1,3 @@
-# TODO: make prints prettier (remove \ in code, and also
-# make it look good in the terminal)
-
 import pinocchio as pin
 import numpy as np
 import time
diff --git a/python/ur_simple_control/util/encapsulating_ellipses.py b/python/ur_simple_control/util/encapsulating_ellipses.py
new file mode 100644
index 0000000..3e20424
--- /dev/null
+++ b/python/ur_simple_control/util/encapsulating_ellipses.py
@@ -0,0 +1,185 @@
+"""
+CREDIT: jnrh2023 pinocchio tutorial
+
+Optimization of the shape of an ellipse so that it contains a set of 3d points.
+Used to construct ellipses around manipulator links to get convex self-collision checking.
+NOTE: probably cylinders are better but let's run with this.
+decide:
+ - w in so3: ellipse orientation
+ - r in r3: ellipse main dimensions
+minimizing:
+  r1*r2*r3 the volum of the ellipse
+so that:
+  r>=0
+  for all points pk in a list,     pk in ellipse:     (pk-c)@A@pk-c)<=1
+
+with A,c the matrix representation of the ellipsoid A=exp(w)@diag(1/r**2)@exp(w).T
+
+Once solved, this can be stored instead of recomputed all the time.
+"""
+
+import casadi
+import numpy as np
+import pinocchio as pin
+from pinocchio import casadi as cpin
+from ur_simple_control.visualize.meshcat_viewer_wrapper.visualizer import MeshcatVisualizer
+from ur_simple_control.util.get_model import get_model, get_heron_model
+from types import SimpleNamespace
+import time
+import pickle
+from importlib.resources import files
+
+# plotting the ellipse in matplotlib for verification
+def plotEllipse(ax, opti_A, opti_c):
+    # find the rotation matrix and radii of the axes
+    U, s, rotation = np.linalg.svd(opti_A)
+    radii = 1.0 / np.sqrt(s)
+
+    # now carry on with EOL's answer
+    u = np.linspace(0.0, 2.0 * np.pi, 100)
+    v = np.linspace(0.0, np.pi, 100)
+    x = radii[0] * np.outer(np.cos(u), np.sin(v))
+    y = radii[1] * np.outer(np.sin(u), np.sin(v))
+    z = radii[2] * np.outer(np.ones_like(u), np.cos(v))
+    for i in range(len(x)):
+        for j in range(len(x)):
+            [x[i, j], y[i, j], z[i, j]] = (
+                np.dot([x[i, j], y[i, j], z[i, j]], rotation) + opti_c
+            )
+
+    # plot
+    ax.plot_wireframe(x, y, z, rstride=4, cstride=4, color="b", alpha=0.2)
+
+
+# plotting the vertices in the ellipse in matplotlib for verification
+def plotVertices(ax, vertices, nsubsample):
+    """
+    plot a 3xN array of vertices in 3d. If nsubsample is not 0, plot the main once in
+    large red, the others in small green.
+    """
+    vert = vertices
+    NS = nsubsample
+
+    # Plot the vertices
+    ax.plot3D(vert[::, 0], vert[::, 1], vert[::, 2], "g.", markersize=1)
+    ax.plot3D(vert[::NS, 0], vert[::NS, 1], vert[::NS, 2], "r*")
+
+    # Change the scalling for a regular one centered on the vertices.
+    m, M = np.min(vert, 0), np.max(vert, 0)
+    plot_center = (m + M) / 2
+    plot_length = max(M - m) / 2
+    ax.axes.set_xlim3d(
+        left=plot_center[0] - plot_length, right=plot_center[0] + plot_length
+    )
+    ax.axes.set_ylim3d(
+        bottom=plot_center[1] - plot_length, top=plot_center[1] + plot_length
+    )
+    ax.axes.set_zlim3d(
+        bottom=plot_center[2] - plot_length, top=plot_center[2] + plot_length
+    )
+
+model, collision_model, visual_model, data = get_model()
+#viz = MeshcatVisualizer(model=model, collision_model=collision_model, visual_model=visual_model)
+#viz.display(np.zeros(model.nq))
+
+ellipses = []
+for geom in collision_model.geometryObjects:
+    vertices = geom.geometry.vertices()
+
+#    for i in np.arange(0, vertices.shape[0]):
+#        viz.addSphere(f"world/point_{i}", 5e-3, [1, 0, 0, 0.8])
+#        viz.applyConfiguration(f"world/point_{i}", vertices[i].tolist() + [1, 0, 0, 0])
+
+    cw = casadi.SX.sym("w", 3)
+    exp = casadi.Function("exp3", [cw], [cpin.exp3(cw)])
+
+    """
+    decide 
+     - w in so3: ellipse orientation
+     - r in r3: ellipse main dimensions
+    minimizing:
+      r1*r2*r3 the volum of the ellipse
+    so that:
+      r>=0
+      for all points pk in a list, pk in ellipse
+
+    """
+    opti = casadi.Opti()
+    var_w = opti.variable(3)
+    var_r = opti.variable(3)
+    var_c = opti.variable(3)
+
+    # The ellipsoid matrix is represented by w=log3(R),diag(P) with R,P=eig(A)
+    R = exp(var_w)
+    A = R @ casadi.diag(1 / var_r**2) @ R.T
+
+    totalcost = var_r[0] * var_r[1] * var_r[2]
+
+    opti.subject_to(var_r >= 0)
+
+    for g_v in vertices:
+        # g_v is the vertex v expressed in the geometry frame.
+        # Convert point from geometry frame to joint frame
+        j_v = geom.placement.act(g_v)
+        # Constraint the ellipsoid to be including the point
+        opti.subject_to((j_v - var_c).T @ A @ (j_v - var_c) <= 1)
+
+    ### SOLVE
+    opti.minimize(totalcost)
+    opti.solver("ipopt")  # set numerical backend
+    opti.set_initial(var_r, 10)
+
+    sol = opti.solve_limited()
+
+    sol_r = opti.value(var_r)
+    sol_A = opti.value(A)
+    sol_c = opti.value(var_c)
+    sol_R = opti.value(exp(var_w))
+
+    ellipse = SimpleNamespace(
+        name=model.names[geom.parentJoint],
+        A=sol_A,
+        center=sol_c)
+    ellipses.append(ellipse)
+    print(ellipse)
+
+ellipses_path = files('ur_simple_control.robot_descriptions.ellipses').joinpath("ur5e_robotiq_ellipses.pickle")
+file = open(ellipses_path, 'wb')
+pickle.dump(ellipses, file)
+file.close()
+
+    # Recover r,R from A (for fun)
+#    e, P = np.linalg.eig(sol_A)
+#    recons_r = 1 / e**0.5
+#    recons_R = P
+#
+#    # Build the ellipsoid 3d shape
+#    # Ellipsoid in meshcat
+#    viz.addEllipsoid("el", sol_r, [0.3, 0.9, 0.3, 0.3])
+#    # jMel is the placement of the ellipsoid in the joint frame
+#    jMel = pin.SE3(sol_R, sol_c)
+#
+#    # Place the body, the vertices and the ellispod at a random configuration oMj_rand
+#    oMj_rand = pin.SE3.Random()
+#    viz.applyConfiguration(viz.getViewerNodeName(geom, pin.VISUAL), oMj_rand)
+#    for i in np.arange(0, vertices.shape[0]):
+#        viz.applyConfiguration(
+#            f"world/point_{i}", oMj_rand.act(vertices[i]).tolist() + [1, 0, 0, 0]
+#        )
+#    viz.applyConfiguration("el", oMj_rand * jMel)
+#
+#    print(
+#        f'SimpleNamespace(name="{model.names[geom.parentJoint]}",\n'
+#        + f"                A=np.{repr(sol_A)},\n"
+#        + f"                center=np.{repr(sol_c)})"
+#    )
+#    time.sleep(5)
+    # Matplotlib (for fun)
+    #import matplotlib.pyplot as plt
+    #
+    #plt.ion()
+    #from utils.plot_ellipse import plotEllipse, plotVertices
+
+    #fig, ax = plt.subplots(1, subplot_kw={"projection": "3d"})
+    #plotEllipse(ax, sol_A, sol_c)
+    #plotVertices(ax, np.vstack([geom.placement.act(p) for p in vertices]), 1)
diff --git a/python/ur_simple_control/util/get_model.py b/python/ur_simple_control/util/get_model.py
index 8842981..c53ade8 100644
--- a/python/ur_simple_control/util/get_model.py
+++ b/python/ur_simple_control/util/get_model.py
@@ -74,6 +74,23 @@ def get_model():
     visual_model = pin.buildGeomFromUrdf(model, urdf_path_absolute, pin.GeometryType.VISUAL, None, mesh_dir_absolute)
     collision_model = pin.buildGeomFromUrdf(model, urdf_path_absolute, pin.GeometryType.COLLISION, None, mesh_dir_absolute)
 
+    # for whatever reason the hand-e files don't have/
+    # meshcat can't read scaling information.
+    # so we scale manually,
+    # and the stupid gripper is in milimeters
+    for geom in visual_model.geometryObjects:
+        if "hand" in geom.name:
+            s = geom.meshScale
+            # this looks exactly correct lmao
+            s *= 0.001
+            geom.meshScale = s
+    for geom in collision_model.geometryObjects:
+        if "hand" in geom.name:
+            s = geom.meshScale
+            # this looks exactly correct lmao
+            s *= 0.001
+            geom.meshScale = s
+
     # updating joint placements.
     model.jointPlacements[1] = shoulder_se3
     model.jointPlacements[2] = upper_arm_se3
diff --git a/python/ur_simple_control/util/grippers/__init__.py b/python/ur_simple_control/util/grippers/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python/ur_simple_control/visualize/__pycache__/visualize.cpython-312.pyc b/python/ur_simple_control/visualize/__pycache__/visualize.cpython-312.pyc
index 9dd45e1af3f798ed65e27a6b9dcc08e32431e013..73420587c7f2ef3c0238de3d2df72ad882fa8306 100644
GIT binary patch
delta 1910
zcmey}!T7J4k?%AwFBby?14Bcub^1e>jeHlG7zH;!VEV|ysJ{6UyPN={)8>!j4_O3)
zSQr?lGo&!qvZgTBvXwASzOOFM%3i~s#XR{Sr-;BB=GBZKV;C418EV+GSSKfP%F41s
zL>L%SSP-(D44e!#ELohB8QG+aYB_2+To@)W#`-ZZ)N<Bvrm$vfFfbIA)-Ys&T?I1$
zLKktDuuoQy6Je=g&*GV^$S*wEjYVW~p`0*Nmhj|49a&}!VbRHqY%(g040%^-I8)fc
zW{1_VrZ9q8Y9-<ja~T-2BqnbZ6k*EZnS78_Sejjufq@}~V-4qOCWrz?h7_h+R<NxH
zIfdE5@>$Z8Hwp@Ka-=|bGLsqEgeNCxa>;Y1aDj~vt6?K#5f@gA*x(j{<>3}VcyNmZ
zIa9bn78Ns1VC=E3Vb78WIf$7fg?sWF1!+eGh|?JuR2YiN7#VPfC`?@n4<eGlE+9I9
zC;w68W#;vBn=Gw#kx_6mzw#VLuE}eZgN2#PGOKPeC+DWzV$M#jECxmCWLXt;xmE@S
zh9wLP48^Az85kNEK5#Hd%3WX)y&)pm;QNJR^97atj7A3;TzTBo8IJKuf=G2o8xJ++
z6RM0JYRt)OFefuGFt9Q(FfcPPFnpfGI{BcQETit^`)W!&B_Lt2sw}q2@*1MDOp6#{
zzN=x2X8}twFfjD!voMr!gVHiHdky>K{hXqL%xjPmYYlrAKS;kY>mtTAY%mkRNn8+=
zRQTCZ#Du|Os98Y-B*x7FifK@4&k_gm1vyi=5Q(dX11id$!h<O)&YQxM&X~ei#mc~d
zkcGIKm9vI3ix-l1MPMnAnKO$YYzhAw0VL<KWJyk*s436RRm)w&4oOs#c}%%kYB-^s
z1=>8!tXZ-kt&^+Fx#ddaVZoFlgfIu1e<eZrx4xFAL=mQ_2A+OOlwe|@^jXw`WRNhz
zpc<YO5wLto4MUa+Ob3E4;zrUZilmP{O9ZNFvIaj7quS(&I_iwt&;mdNR4zcoCKu?)
z3RE)G@We1NFw_$3ZM~lR$_yoXP#X}r2ZswMZ`2ZHX3s*h7MD{%xx`G|?-ol&VqS_S
z%kx<?LExl)Q3nG91A+)C%4T3-&}2b~6m?8C&<$YA11sCyrpv>~C^7l1lDJ}#3`i(|
zfq~%`XKre7hI4*Seo+x9=@%7(WQryq)>BU`2Fddjr<TMQ6y+DB7L`;M`GRC?K!gv7
z@Bk5hAOaNQMeZP035X~K5oI8v97M!|9L8G&3Y(%@kU$-XsGsbuFUfI>B|SAix2S1y
zfxZN10Vr?tGB7Yqo}_PLH=BWh;VMYPnhBKKZwSa-7tpyPpwq!}gIjPy$n?mGk(apT
z?#Rl|kC+*8NzMGStVM@Quipn&20`5~Y?Cjj$ZRe#_{=DIRNYC<lbzuNpQR@|!%22W
z8*et|)2xi%Y?~X5Y`Gb;C-1Y3W9;25YbVOcxM;GmeJa}&ko%@io@ejRxMcD>`w-R*
z3=9lLo828&Gs{<i<U~P)8HmUP5ukFZ2;|(N4U+|3q=I%bfa)^_hGGW>28IvJjEs!8
z8HDaK$lqtsyv@LUn}Pc-gW+d321c<@0>X?^pLE0+`9GP(GcpQ)a$(kC)cusi7|6(|
R`?-oKnUPVrNQ{Aj0RY~1j9mZ#

delta 2436
zcmey@%=o*5k?%AwFBby?14Ey+R(h%XM!t(ojQpD)FnwfURNZ`uT~2_}Ve?1vhb#g{
ztPBj(8B!Q)SyLEm*=m?43krzvxG=<OGBDJ#r!dv9PmWcUGOJ<FVgZ?kifcJ)I8vCa
zgcuk=tQz)sCYXGWHVZ=y6ZOn0VW0d_O`4H&@<C2vL6$YFs~I6SF*4L}W^qqW<dl`>
zg@`aPq_81mIT<(^YFH*as*6mP*Wi@ks^M~Bn7|n8$G}j_UBjKio~^;aP*hqo*-=hZ
zrii-)VFm}nj2g}?p~;H;!jqNMg(n~65@E`coXp53!-6h8`HLLL77iIk21bUwD>d9H
zoM7X_YFJYk!7Q~B*~u3Sp*jz83QKcJGB7ZtaIN894GlR)h7^`sR<OwjIfdE5@>z<L
zHwp?fbER-j-pH*W!N^d<ox%e)FRX?Qm&rU>O=g3e43>wR%mXr61Z*-d$mC+C35-3~
zHJn+hP^)<-^C(CQsKJ6*g`ud7kpWAv@sS^FllN-z3-SB8-D1f|%u9LxXXVFBzDWW0
zlXVm?DvR9WPfyLyO)V*^^iRr4O)e?E#gdnpn|g~gH?=q;I5{yVb@D&OIgC7$XDbEE
zv4GUxVl2MJT$WjNi#a(r<rZ^xYGpAG0|SGC!emBe_4*zL28Klp3=GAVObiSS3?Dcc
zB;_u!h~5y9Z1DZS#vmwrT|noGfKCU?4Q{~+A=4u#Mqc8UyCEPloo^yvhvNet-U*_e
zULB4%WaT<sdi_3dGYIN_;9(F{xGtc7ML?gRHeQ52gD*UjZ|cfyPEuaXD0#@hmB&Mz
z;kccohd9FtaYq|3G3HaEj9y}s<y6HvjMzX~6_Q0+To__qCx@yk8P%|1&6?~r>?us(
ztjS)(Uc-jSnkDR$8w_L=(iu{i7cs)3tA;I}6&ATY?y$TIvP2VPi5aPufbxF{@8pka
z;>;X19FrZ@MJ-WtEk~9h%svF2&XB^kh;a=&%vFpGH5^&OlM~fMkkb`MmMEwgnCvOb
z%~Zny%8@)N;EYnsS;Ltn36c}!N<qp}a8aHVUPMNNiHh^3@TN1S@K>=iFd$^1j_0c3
z0u>%mdnWf=aj-Em)No}9f^6XzSR;t!RF=t!n&1L}Cx!`BzSQ#6aAe7XGSK81nmo*0
z5H>##k`~r1d5}Sqf2niJlqkXiB1IUX1X_SWOy+dsEm4N4s^NvHDp7%nf%0xq3zA79
zFg1(}HM}XJVEK}o$s068rHZ(b)QKUf0|)8kUM*2ZEpV}CrYQ^aKU|Pee=;MREI&gH
zFFAe{?YXbaP+|acHLNtjaFsYYu9BI&UyIjD!mlWsfq|hYhk=1XljZrWnILe|zNil*
z2q!{{a>4S*!jqY_1K0|{$~H%6^DqiX78QedB_N`dfq`LijgB;18HiUtd9IGSWCa5Q
z!!4fT)ROpuqWpr?qLRuYUyy9$<hweu^_3uI6^N(?5j7wp7Gx=3ksgTM1R|P2L<`6q
z&g9&b_`=fE($rg=iOJazW>Gsxz5_&bf)ugj<)@_HVkyh4GP=c7Xn2dM(5R>gRGRUD
zOE?82Fu6omy?!181H(O#d_SzTBdLJv@%zHYAg3@tVrIl8HS^1|7T_{Z5LD&~5mV*~
zqnDKiUwAg()a7TAJZA2s<|WQ>QqIy#oZ*zXqm7Rk^BGY_AF<7h2DaRc&6Dk|;}|Dz
zo@Xt}$hdU!7MoPI8K6LzIa%J;pK<x*eA^J#%?u0-UYk$Yu4b;U1<8qm2s03o2_irR
zeG$n2MIePM8H&U}q9UMB<gm%jPbtkwwJX}gz`y`%P!!uSFfe>zW@Kc%%^-A_LH<62
z=4}S<+YH=y84PbTh<*|fW|aD*BgV-8$t<3cQTUS!vpJ*grwYadMn>Jw5nRm4jEury
F3jhskBi;Z2

diff --git a/python/ur_simple_control/visualize/meshcat_viewer_wrapper/__init__.py b/python/ur_simple_control/visualize/meshcat_viewer_wrapper/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/python/ur_simple_control/visualize/meshcat_viewer_wrapper/colors.py b/python/ur_simple_control/visualize/meshcat_viewer_wrapper/colors.py
new file mode 100644
index 0000000..d97cb12
--- /dev/null
+++ b/python/ur_simple_control/visualize/meshcat_viewer_wrapper/colors.py
@@ -0,0 +1,49 @@
+import meshcat
+
+
+def rgb2int(r, g, b):
+    """
+    Convert 3 integers (chars) 0 <= r, g, b < 256 into one single integer = 256**2*r+256*g+b, as expected by Meshcat.
+
+    >>> rgb2int(0, 0, 0)
+    0
+    >>> rgb2int(0, 0, 255)
+    255
+    >>> rgb2int(0, 255, 0) == 0x00FF00
+    True
+    >>> rgb2int(255, 0, 0) == 0xFF0000
+    True
+    >>> rgb2int(255, 255, 255) == 0xFFFFFF
+    True
+    """
+    return int((r << 16) + (g << 8) + b)
+
+
+def material(color, transparent=False):
+    mat = meshcat.geometry.MeshPhongMaterial()
+    mat.color = color
+    mat.transparent = transparent
+    return mat
+
+
+red = material(color=rgb2int(255, 0, 0), transparent=False)
+blue = material(color=rgb2int(0, 0, 255), transparent=False)
+green = material(color=rgb2int(0, 255, 0), transparent=False)
+yellow = material(color=rgb2int(255, 255, 0), transparent=False)
+magenta = material(color=rgb2int(255, 0, 255), transparent=False)
+cyan = material(color=rgb2int(0, 255, 255), transparent=False)
+white = material(color=rgb2int(250, 250, 250), transparent=False)
+black = material(color=rgb2int(5, 5, 5), transparent=False)
+grey = material(color=rgb2int(120, 120, 120), transparent=False)
+
+colormap = {
+    "red": red,
+    "blue": blue,
+    "green": green,
+    "yellow": yellow,
+    "magenta": magenta,
+    "cyan": cyan,
+    "black": black,
+    "white": white,
+    "grey": grey,
+}
diff --git a/python/ur_simple_control/visualize/meshcat_viewer_wrapper/visualizer.py b/python/ur_simple_control/visualize/meshcat_viewer_wrapper/visualizer.py
new file mode 100644
index 0000000..82ebdf4
--- /dev/null
+++ b/python/ur_simple_control/visualize/meshcat_viewer_wrapper/visualizer.py
@@ -0,0 +1,103 @@
+import random
+
+import meshcat
+import numpy as np
+import pinocchio as pin
+from pinocchio.visualize import MeshcatVisualizer as PMV
+
+from . import colors
+
+
+def materialFromColor(color):
+    if isinstance(color, meshcat.geometry.MeshPhongMaterial):
+        return color
+    elif isinstance(color, str):
+        material = colors.colormap[color]
+    elif isinstance(color, list):
+        material = meshcat.geometry.MeshPhongMaterial()
+        material.color = colors.rgb2int(*[int(c * 255) for c in color[:3]])
+        if len(color) == 3:
+            material.transparent = False
+        else:
+            material.transparent = color[3] < 1
+            material.opacity = float(color[3])
+    elif color is None:
+        material = random.sample(list(colors.colormap), 1)[0]
+    else:
+        material = colors.black
+    return material
+
+
+class MeshcatVisualizer(PMV):
+    def __init__(
+        self,
+        robot=None,
+        model=None,
+        collision_model=None,
+        visual_model=None,
+        url=None,
+        autoclean=False,
+    ):
+        if robot is not None:
+            super().__init__(robot.model, robot.collision_model, robot.visual_model)
+        elif model is not None:
+            super().__init__(model, collision_model, visual_model)
+
+        if url is not None:
+            if url == "classical":
+                url = "tcp://127.0.0.1:6000"
+            print("Wrapper tries to connect to server <%s>" % url)
+            server = meshcat.Visualizer(zmq_url=url)
+        else:
+            server = None
+
+        if robot is not None or model is not None:
+            self.initViewer(loadModel=True, viewer=server)
+        else:
+            self.viewer = server if server is not None else meshcat.Visualizer()
+
+        if autoclean:
+            self.clean()
+
+    def addSphere(self, name, radius, color):
+        material = materialFromColor(color)
+        self.viewer[name].set_object(meshcat.geometry.Sphere(radius), material)
+
+    def addCylinder(self, name, length, radius, color=None):
+        material = materialFromColor(color)
+        self.viewer[name].set_object(
+            meshcat.geometry.Cylinder(length, radius), material
+        )
+
+    def addBox(self, name, dims, color):
+        material = materialFromColor(color)
+        self.viewer[name].set_object(meshcat.geometry.Box(dims), material)
+
+    def addEllipsoid(self, name, dims, color):
+        material = materialFromColor(color)
+        self.viewer[name].set_object(meshcat.geometry.Ellipsoid(dims), material)
+
+    def applyConfiguration(self, name, placement):
+        if isinstance(placement, list) or isinstance(placement, tuple):
+            placement = np.array(placement)
+        if isinstance(placement, pin.SE3):
+            R, p = placement.rotation, placement.translation
+            T = np.r_[np.c_[R, p], [[0, 0, 0, 1]]]
+        elif isinstance(placement, np.ndarray):
+            if placement.shape == (7,):  # XYZ-quat
+                R = pin.Quaternion(np.reshape(placement[3:], [4, 1])).matrix()
+                p = placement[:3]
+                T = np.r_[np.c_[R, p], [[0, 0, 0, 1]]]
+            else:
+                print("Error, np.shape of placement is not accepted")
+                return False
+        else:
+            print("Error format of placement is not accepted")
+            return False
+        self.viewer[name].set_transform(T)
+
+    def delete(self, name):
+        self.viewer[name].delete()
+
+    def __getitem__(self, name):
+        return self.viewer[name]
diff --git a/python/ur_simple_control/visualize/visualize.py b/python/ur_simple_control/visualize/visualize.py
index 30221a7..55459a5 100644
--- a/python/ur_simple_control/visualize/visualize.py
+++ b/python/ur_simple_control/visualize/visualize.py
@@ -4,6 +4,8 @@ from collections import deque, namedtuple
 import time
 import copy
 from pinocchio.visualize import MeshcatVisualizer
+# TODO: use wrapped meshcat visualizer to have access to more nifty plotting
+#from ur_simple_control.visualize.meshcat_viewer_wrapper.visualizer import MeshcatVisualizer
 import meshcat_shapes
 
 # tkinter stuff for later reference
@@ -165,20 +167,9 @@ def manipulatorVisualizer(args, model, collision_model, visual_model, queue):
     # so we scale manually
     init_target_frame = False
     init_ee_frame = False
-    # if we go for manipulator end-effector
     #meshcat_shapes.frame(viewer["end_effector_target"], opacity=0.5)
-    for geom in visual_model.geometryObjects:
-        if "hand" in geom.name:
-            s = geom.meshScale
-            # this looks exactly correct lmao
-            s *= 0.001
-            geom.meshScale = s
-    for geom in collision_model.geometryObjects:
-        if "hand" in geom.name:
-            s = geom.meshScale
-            # this looks exactly correct lmao
-            s *= 0.001
-            geom.meshScale = s
+    # TODO: use wrapped meshcat visualizer to have access to more nifty plotting
+    #viz = MeshcatVisualizer(model=model, collision_model=collision_model, visual_model=visual_model)
     viz = MeshcatVisualizer(model, collision_model, visual_model)
     viz.initViewer(open=True)
     viz.loadViewerModel()
@@ -220,24 +211,9 @@ def manipulatorVisualizer(args, model, collision_model, visual_model, queue):
 # but they're different enough in usage to warrent a different function,
 # instead of polluting the above one with ifs
 def manipulatorComparisonVisualizer(args, model, collision_model, visual_model, cmd_queue, ack_queue):
-    # for whatever reason the hand-e files don't have/
-    # meshcat can't read scaling information.
-    # so we scale manually
     for geom in visual_model.geometryObjects:
         if "hand" in geom.name:
-            s = geom.meshScale
-            # this looks exactly correct lmao
-            s *= 0.001
-            geom.meshScale = s
-            # there has to be a way
-            # if not here than elsewhere
             geom.meshColor = np.array([0.2,0.2,0.2,0.2])
-    for geom in collision_model.geometryObjects:
-        if "hand" in geom.name:
-            s = geom.meshScale
-            # this looks exactly correct lmao
-            s *= 0.001
-            geom.meshScale = s
     viz = MeshcatVisualizer(model, collision_model, visual_model)
     viz.initViewer(open=True)
     # load the first one
-- 
GitLab