From 18661828e5676845f3f8d4e8e7e009a99b5bf58c Mon Sep 17 00:00:00 2001
From: m-guberina <gubi.guberina@gmail.com>
Date: Fri, 17 Nov 2023 18:45:21 +0100
Subject: [PATCH] need to fix package first, but i just got a mini heart attack
 thinking i deleted something

---
 python/UNKNOWN.egg-info/PKG-INFO              |  11 -
 python/UNKNOWN.egg-info/SOURCES.txt           |   8 -
 python/UNKNOWN.egg-info/dependency_links.txt  |   1 -
 python/UNKNOWN.egg-info/top_level.txt         |   1 -
 .../pyproject.toml                            |   0
 .../setup.cfg                                 |   0
 .../.measuring_stick.py.swp                   | Bin 0 -> 12288 bytes
 python/ur_simple_control.egg-info/PKG-INFO    |  39 ---
 python/ur_simple_control.egg-info/SOURCES.txt |  20 --
 .../dependency_links.txt                      |   1 -
 .../ur_simple_control.egg-info/requires.txt   |   1 -
 .../ur_simple_control.egg-info/top_level.txt  |   1 -
 python/ur_simple_control/clik/.clik.py.swp    | Bin 0 -> 28672 bytes
 python/ur_simple_control/clik/clik.py         | 204 +++++++-------
 .../util/.boilerplate_wrapper.py.swp          | Bin 0 -> 28672 bytes
 .../util/boilerplate_wrapper.py               | 261 +++++++++++++++---
 16 files changed, 316 insertions(+), 232 deletions(-)
 delete mode 100644 python/UNKNOWN.egg-info/PKG-INFO
 delete mode 100644 python/UNKNOWN.egg-info/SOURCES.txt
 delete mode 100644 python/UNKNOWN.egg-info/dependency_links.txt
 delete mode 100644 python/UNKNOWN.egg-info/top_level.txt
 rename python/{ => alternative_packaging_BROKEN_atm}/pyproject.toml (100%)
 create mode 100644 python/alternative_packaging_BROKEN_atm/setup.cfg
 create mode 100644 python/convenience_tool_box/.measuring_stick.py.swp
 delete mode 100644 python/ur_simple_control.egg-info/PKG-INFO
 delete mode 100644 python/ur_simple_control.egg-info/SOURCES.txt
 delete mode 100644 python/ur_simple_control.egg-info/dependency_links.txt
 delete mode 100644 python/ur_simple_control.egg-info/requires.txt
 delete mode 100644 python/ur_simple_control.egg-info/top_level.txt
 create mode 100644 python/ur_simple_control/clik/.clik.py.swp
 create mode 100644 python/ur_simple_control/util/.boilerplate_wrapper.py.swp

diff --git a/python/UNKNOWN.egg-info/PKG-INFO b/python/UNKNOWN.egg-info/PKG-INFO
deleted file mode 100644
index aed30b2..0000000
--- a/python/UNKNOWN.egg-info/PKG-INFO
+++ /dev/null
@@ -1,11 +0,0 @@
-Metadata-Version: 2.1
-Name: UNKNOWN
-Version: 0.0.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-License: UNKNOWN
-Platform: UNKNOWN
-License-File: LICENSE.txt
-
-UNKNOWN
-
diff --git a/python/UNKNOWN.egg-info/SOURCES.txt b/python/UNKNOWN.egg-info/SOURCES.txt
deleted file mode 100644
index 4130086..0000000
--- a/python/UNKNOWN.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-LICENSE.txt
-README.md
-pyproject.toml
-setup.cfg
-UNKNOWN.egg-info/PKG-INFO
-UNKNOWN.egg-info/SOURCES.txt
-UNKNOWN.egg-info/dependency_links.txt
-UNKNOWN.egg-info/top_level.txt
\ No newline at end of file
diff --git a/python/UNKNOWN.egg-info/dependency_links.txt b/python/UNKNOWN.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/python/UNKNOWN.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/python/UNKNOWN.egg-info/top_level.txt b/python/UNKNOWN.egg-info/top_level.txt
deleted file mode 100644
index 8b13789..0000000
--- a/python/UNKNOWN.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/python/pyproject.toml b/python/alternative_packaging_BROKEN_atm/pyproject.toml
similarity index 100%
rename from python/pyproject.toml
rename to python/alternative_packaging_BROKEN_atm/pyproject.toml
diff --git a/python/alternative_packaging_BROKEN_atm/setup.cfg b/python/alternative_packaging_BROKEN_atm/setup.cfg
new file mode 100644
index 0000000..e69de29
diff --git a/python/convenience_tool_box/.measuring_stick.py.swp b/python/convenience_tool_box/.measuring_stick.py.swp
new file mode 100644
index 0000000000000000000000000000000000000000..565f0d5acdeb8db8100b7857fee177e575e0ce70
GIT binary patch
literal 12288
zcmYc?2=nw+u+TGNU|?VnU|{Hc<C9vZS;Jr<!N`!FUtEx%l2`<i!iRGci?cKH@Tq{v
z)xiwZ&&bbBHPVN3b4v44^b3j-D>94qON-)*Gjj`aQsa~J^Gb^HbMy-;OEU8F^po@R
z%2M+(Q}dEj<4f}MbK;ZoEA(?y6N^iWGV{{oi%T+-v-JupAy$o&qaiRF0vI8{%V2C|
zXaEvcR#H?D777J1NAYL~jE2By2#kinXb6mkz-S1JhQMeDjE2An34xLVMuvI@1_mam
ze|4cWBN`3mj#8r`Fd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0z)ta5>pr$
z4stRuOyq*h|HJzKFZdZ4uJSW5oZ@F-IKa=qFqNNyp_8A1A)KFq!G@oK;XfY(!y!Hf
zh8=ti3~Trp80PUYFl6&FFl6yDF!=E?FevjeF#P9bVEDqz!0?%uf#DM`1H&<128LO@
z3=Ac_3=HYK3=AQ>3=F}%3=C$x3=9Ii3=I6d3=9W&7#P}l7#Nay7#K`>7#O~BGcbJR
zW?*>9&A@P+n}J~~Hv_|BZU%;YZU%-3ZU%;TTnr4$xghSJ0P@2SjDt}pkA}c#2#kin
zXb6mkz-S1JhQNpp0R;sGg_6wNRK4Py)YJkE13d!+Q%wetXhBhCUWtZMX_2Xwl8%B_
zUV&a>QBh*0Mo~#hYJ5>@a%yH-s$P0(iDPm}X<|-@b3j0TajJ%<re0BgX<mwki6)9M
z1(|tZV^R`J67}+ZGo#I7^-78o^NMp4OEUBG;F@$4v<fow^oj~9^>PzSiZUxg@`DO0
zHITIx<(Gi<V7CcLCDZ|#d3tI2MdgV_Dc+fRskw<InaRZ(x%nxnIXVg;)jA4rzZF6q
zU8t8>P>`CJ0tyd^DOf}lY!$GFMWBWzLwQDKPO3skQE93b0|Sy}3bqRAsU`7X5slKK
zl(hJQ#FC8o#H8Z<oYIn19fjP~;*9u|%p$muCIg0$f~`V+u^vdHUSd))h}M9qL8w-+
zRZ!B?(=W<T$}fpeNi9w;$}9i{b+Nt@1E$4Tj6^6ZN(IGIS*j+IMwl3GYe4$-ON&fX
z<I6KkGUCAw$t;Y|NX$z~)dNW?F)$QorspN*=s_qA2&EV7>F((lqN4y(nUh+i$p8*!
z==x;6w4&71l%mYCRNwrRR1HlA253S}&d<wBO)g1IQG&!6NPT8rX(}`-^72a{(FGDO
z%FofuEOv(J(9pDk*a1z}3bqPCAug^#kVLMbWN2xmXJ}@jXQ*drV5EfV9;jMp$m(fK
zwG80Qlv<Hlq5*Liif2;uQryt|gUEa8nF{5ZIXMccc_|8TUn?Z$r6_=mQ`cljNlk+V
z5;*Kib9EHbiV|~EHLVyJ(u(qP71A@yQsZ+|<4ZD9<C7C}GLwoDOHxxH$xk6Ow;;c$
z1d$#YpaPI+fbo*^3o2pk{9=f)U_ZbD3#tn##60s#Qj5|OlT#HEi;+VTNi#GSU~T|u
zh6W*qW~eyK4e6-`sU;=(ddc}kNr}a&MP;c)5OWJM^YW9EGcxn_$})>f6LT`FQenos
zL-d5f#EW2tfr>teZfJ&r=}5^e%1g{m)ltaG&&<<NfMzq8w)|oktGE)*%qz_;s08^q
QuK*?scM?drATy5v09^+*ivR!s

literal 0
HcmV?d00001

diff --git a/python/ur_simple_control.egg-info/PKG-INFO b/python/ur_simple_control.egg-info/PKG-INFO
deleted file mode 100644
index 5f07aec..0000000
--- a/python/ur_simple_control.egg-info/PKG-INFO
+++ /dev/null
@@ -1,39 +0,0 @@
-Metadata-Version: 2.1
-Name: ur-simple-control
-Version: 0.0.1
-Summary: Collection of control algorithms for the UR5e arm based on the ur_rtde interface for communication and pinocchio for calculations.
-Author-email: Marko Guberina <marko.guberina@control.lth.se>
-Maintainer-email: Marko Guberina <marko.guberina@control.lth.se>
-License: Do whatever you want at your own risk.
-        
-Project-URL: Homepage, https://gitlab.control.lth.se/marko-g/ur_simple_control
-Project-URL: Documentation, https://gitlab.control.lth.se/marko-g/ur_simple_control
-Project-URL: Repository, https://gitlab.control.lth.se/marko-g/ur_simple_control
-Project-URL: Bug Tracker, https://gitlab.control.lth.se/marko-g/ur_simple_control
-Project-URL: Changelog, https://gitlab.control.lth.se/marko-g/ur_simple_control
-Keywords: manipulator,control algorithm
-Description-Content-Type: text/markdown
-License-File: LICENSE.txt
-Requires-Dist: ur_rtde
-
-# installation
-------------
-first you MUST update pip, otherwise it won't work:
-python3 -m pip install --upgrade pip setuptools wheel build
-then install with 
-pip install --user -e . 
-from this directory. now the package is editable, which there's a chance you'd want
-
-# description
----------
-- organized as a library called ur_simple_control, made into a python package. the hope is that if this
-  is done well enough, you could mix-and-match different components
-  and just have them work as intended. on the other hand,
-  the code should still be simple enough to afford the quickest possible prototyping,
-  which is the point of having it all in python anyway
-- initial python solution is age-old code which needs to be remapped into the 
-  libraries used here. it will sit here until everything it offers has been translated.
-
-# runnable things
----------------
-are in the examples folder
diff --git a/python/ur_simple_control.egg-info/SOURCES.txt b/python/ur_simple_control.egg-info/SOURCES.txt
deleted file mode 100644
index c8df780..0000000
--- a/python/ur_simple_control.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-LICENSE.txt
-README.md
-pyproject.toml
-setup.py
-ur_simple_control/__init__.py
-ur_simple_control.egg-info/PKG-INFO
-ur_simple_control.egg-info/SOURCES.txt
-ur_simple_control.egg-info/dependency_links.txt
-ur_simple_control.egg-info/requires.txt
-ur_simple_control.egg-info/top_level.txt
-ur_simple_control/clik/__init__.py
-ur_simple_control/clik/clik.py
-ur_simple_control/dmp/__init__.py
-ur_simple_control/dmp/notes.md
-ur_simple_control/dmp/robotiq_gripper.py
-ur_simple_control/dmp/run_dmp.py
-ur_simple_control/util/__init__.py
-ur_simple_control/util/calib_board_hacks.py
-ur_simple_control/util/give_me_the_calibrated_model.py
-ur_simple_control/util/robotiq_gripper.py
\ No newline at end of file
diff --git a/python/ur_simple_control.egg-info/dependency_links.txt b/python/ur_simple_control.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/python/ur_simple_control.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/python/ur_simple_control.egg-info/requires.txt b/python/ur_simple_control.egg-info/requires.txt
deleted file mode 100644
index e95a92e..0000000
--- a/python/ur_simple_control.egg-info/requires.txt
+++ /dev/null
@@ -1 +0,0 @@
-ur_rtde
diff --git a/python/ur_simple_control.egg-info/top_level.txt b/python/ur_simple_control.egg-info/top_level.txt
deleted file mode 100644
index 8b13789..0000000
--- a/python/ur_simple_control.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/python/ur_simple_control/clik/.clik.py.swp b/python/ur_simple_control/clik/.clik.py.swp
new file mode 100644
index 0000000000000000000000000000000000000000..7e2d03a88b0a8fd17bdc30aa40008b6dee547ff7
GIT binary patch
literal 28672
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

literal 0
HcmV?d00001

diff --git a/python/ur_simple_control/clik/clik.py b/python/ur_simple_control/clik/clik.py
index 0f5dcca..7f40d33 100644
--- a/python/ur_simple_control/clik/clik.py
+++ b/python/ur_simple_control/clik/clik.py
@@ -1,25 +1,22 @@
 import pinocchio as pin
 import numpy as np
-import sys
-import os
-from os.path import dirname, join, abspath
-import time
-from pinocchio.visualize import GepettoVisualizer
-#import gepetto.corbaserver
-from rtde_control import RTDEControlInterface as RTDEControl
-from rtde_receive import RTDEReceiveInterface as RTDEReceive
-from rtde_io import RTDEIOInterface
-from robotiq_gripper import RobotiqGripper
-import os
 import copy
-import signal
-sys.path.insert(0, '../util')
-from give_me_the_calibrated_model import get_model
 import argparse
 from functools import partial
-from ur_simple_control.util.boilerplate_wrapper import controlLoopTiming, RobotManager
-
+from ur_simple_control.util.boilerplate_wrapper import ControlLoopManager, RobotManager
 
+"""
+Every imaginable magic number, flag and setting is put in here.
+This way the rest of the code is clean.
+If you want to know what these various arguments do, just grep 
+though the code to find them (but replace '-' with '_' in multi-word arguments).
+All the sane defaults are here, and you can change any number of them as an argument
+when running your program. If you want to change a drastic amount of them, and
+not have to run a super long commands, just copy-paste this function and put your
+own parameters as default ones.
+NOTE: the args object obtained from args = parser.get_args()
+is pushed all around the rest of the code (because it's tidy), so don't change their names.
+"""
 def get_args():
     parser = argparse.ArgumentParser(description='Run closed loop inverse kinematics \
             of various kinds. Make sure you know what the goal is before you run!',
@@ -30,112 +27,111 @@ def get_args():
             help="whether you want to just integrate with pinocchio", default=False)
     parser.add_argument('--visualize', action=argparse.BooleanOptionalAction, 
             help="whether you want to visualize with gepetto, but NOTE: not implemented yet", default=False)
-    parser.add_argument('--gripper', action=argparse.BooleanOptionalAction, 
+    parser.add_argument('--gripper', action=argparse.BooleanOptionalAction, \
             help="whether you're using the gripper", default=False)
-    parser.add_argument('--goal-error', type=float, 
+    parser.add_argument('--goal-error', type=float, \
             help="the final position error you are happy with", default=1e-3)
-    parser.add_argument('--max-iterations', type=int, 
+    parser.add_argument('--max-iterations', type=int, \
             help="maximum allowable iteration number (it runs at 500Hz)", default=100000)
-    parser.add_argument('--acceleration', type=float, 
-            help="robot's acceleration, positive constant, max 1.7, 0.2 by default. \
-                   BE CAREFUL WITH THIS.", default=0.4)
-    parser.add_argument('--speed-slider', type=float,
+    parser.add_argument('--acceleration', type=float, \
+            help="robot's joints acceleration. scalar positive constant, max 1.7, and default 0.4. \
+                   BE CAREFUL WITH THIS. the urscript doc says this is 'lead axis acceleration'.\
+                   TODO: check what this means", default=0.4)
+    parser.add_argument('--speed-slider', type=float,\
             help="cap robot's speed with the speed slider \
                     to something between 0 and 1, 0.25 by default \
                     BE CAREFUL WITH THIS.", default=0.25)
-    parser.add_argument('--tikhonov-damp', type=float, 
-            help="damping scalar in tiknohov regularization", default=1e-6)
+    parser.add_argument('--tikhonov-damp', type=float, \
+            help="damping scalar in tiknohov regularization", default=1e-2)
+    # TODO add the rest
+    parser.add_argument('--controller', type=str, \
+            help="select which click algorithm you want", \
+            default='dampedPseudoinverse', choices=['dampedPseudoinverse', 'jacobianTranspose'])
 
-#    parser.add_argument(
-#        '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu'
-#    )
     args = parser.parse_args()
     if args.gripper and args.simulation:
         raise NotImplementedError('Did not figure out how to put the gripper in \
                 the simulation yet, sorry :/ . You can have only 1 these flags right now')
-    if success: 
-        print("Convergence achieved!")
-    else:
-        print("Warning: the iterative algorithm has not reached convergence to the desired precision")
-
-    print("final error", err_vector.transpose()) 
     return args
 
-def clik(robot_manager):
-    # define goal
-    # TODO this should be handled in some better way, but one step at a time
-    q = robot.rtde_receive.getActualQ()
-    # urdf treats gripper as two prismatic joints, 
-    # but they do not affect the overall movement
-    # of the robot, so we add or remove 2 items to the joint list.
-    # also, the gripper is controlled separately so we'd need to do this somehow anyway 
-    q.append(0.0)
-    q.append(0.0)
-    pin.forwardKinematics(robot.model, robot.data, np.array(q))
-    Mtool = robot.data.oMi[JOINT_ID]
-    print("pos", Mtool)
-    #SEerror = pin.SE3(np.zeros((3,3)), np.array([0.0, 0.0, 0.1])
-    Mgoal = copy.deepcopy(Mtool)
-    Mgoal.translation = Mgoal.translation + np.array([0.0, 0.0, -0.1])
-    print("goal", Mgoal)
-    success = False
-    def controlLoop():
-        q = rtde_receive.getActualQ()
-        if not SIMULATION:
-            gripper_pos = gripper.get_current_position()
-            # all 3 are between 0 and 255
-            #gripper.move(i % 255, 100, 100)
-            # just padding to fill q, which is only needed for forward kinematics
-            #q.append(gripper_pos)
-            #q.append(gripper_pos)
-            q.append(0.0)
-            q.append(0.0)
-            # pinocchio wants an ndarray
-            q = np.array(q)
-        pin.forwardKinematics(model, data, q)
-        SEerror = data.oMi[JOINT_ID].actInv(Mgoal)
-        err_vector = pin.log6(SEerror).vector 
-        if np.linalg.norm(err_vector) < eps:
-          success = True
-          print("reached destionation")
-          break
-        if i >= IT_MAX: 
-            success = false
-            print("FAIL: did not succed in IT_MAX iterations")
-            break
-        # this does the whole thing unlike the C++ version lel
-        J = pin.computeJointJacobian(model, data, q, JOINT_ID)
-        #J = J + np.eye(J.shape[0], J.shape[1]) * 10**-4
-        # idk what i was thinking here lol
-        #v = np.matmul(np.linalg.pinv(J), pin.log(SEerror.inverse() * Mgoal).vector)
-        #v = J.T @ err_vector
-        #v = np.linalg.pinv(J) @ err_vector
-        v = J.T @ np.linalg.inv(J @ J.T + np.eye(J.shape[0], J.shape[0]) * 10**-2) @ err_vector
-        v_cmd = v[:6]
-        v_cmd = v_cmd * 5
-        v_cmd = np.clip(v_cmd, -2, 2)
-        if not SIMULATION:
-            rtde_control.speedJ(v_cmd, acceleration, dt)
-        else:
-            q = pin.integrate(model, q, v * dt)
-        if not i % 1000:
-            print("pos", data.oMi[JOINT_ID])
-            print("linear error = ", pin.log6(SEerror).linear)
-            print("angular error = ", pin.log6(SEerror).angular)
-            print(" error = ", err_vector.transpose())
+#######################################################################
+#                             controllers                             #
+#######################################################################
+def dampedPseudoinverse(tiknonov_damp, J, err_vector):
+    qd = J.T @ np.linalg.inv(J @ J.T + np.eye(J.shape[0], J.shape[0]) * tiknonov_damp) @ err_vector
+    return qd
+
+def jacobianTranspose(J, err_vector):
+    qd = J.T @ err_vector
+    return qd
+
+"""
+A string argument is used to select one of these.
+It's a bit ugly, bit totally functional and OK solution.
+we want all of theme to accept the same arguments, i.e. the jacobian and the error vector.
+if they have extra stuff, just map it in the beginning with partial
+NOTE: this could be changed to something else if it proves inappropriate later
+TODO: write out other algorithms
+"""
+def getController(args):
+    if args.controller == "dampedPseudoinverse":
+        return partial(dampedPseudoinverse, args.tiknonov_damp)
+    if args.controller == "jacobianTranspose":
+        return jacobianTranspose
+    # TODO implement and add in the rest
+    #if controller_name == "invKinmQPSingAvoidE_kI":
+    #    return invKinmQPSingAvoidE_kI
+    #if controller_name == "invKinm_PseudoInv":
+    #    return invKinm_PseudoInv
+    #if controller_name == "invKinm_PseudoInv_half":
+    #    return invKinm_PseudoInv_half
+    #if controller_name == "invKinmQP":
+    #    return invKinmQP
+    #if controller_name == "invKinmQPSingAvoidE_kI":
+    #    return invKinmQPSingAvoidE_kI
+    #if controller_name == "invKinmQPSingAvoidE_kM":
+    #    return invKinmQPSingAvoidE_kM
+    #if controller_name == "invKinmQPSingAvoidManipMax":
+    #    return invKinmQPSingAvoidManipMax
+
+    # default
+    return partial(dampedPseudoinverse, args.tiknonov_damp)
 
-    for i in range(robot.args.max_iterations):
-        controlLoopTiming(partial(clik, robot))
 
-    if success: 
-        print("Convergence achieved!")
-    else:
-        print("Warning: the iterative algorithm has not reached convergence to the desired precision")
+# modularity yo
+def controlLoopClik(robot, controller, i):
+    breakFlag = False
+    # know where you are, i.e. do forward kinematics
+    q = robot.getQ()
+    pin.forwardKinematics(robot.model, robot.data, q)
+    # first check whether we're at the goal
+    SEerror = robot.data.oMi[robot.JOINT_ID].actInv(robot.Mgoal)
+    err_vector = pin.log6(SEerror).vector 
+    if np.linalg.norm(err_vector) < eps:
+      print("Convergence achieved, reached destionation!")
+      breakFlag = True
+    # pin.computeJointJacobian is much different than the C++ version lel
+    J = pin.computeJointJacobian(model, data, q, JOINT_ID)
+    # compute the joint velocities.
+    # just plug and play different ones
+    qd = controller(J, err_vector)
+    robot.sendQd(qd)
+    # we do the printing here because controlLoopManager should be general.
+    # and these prints are click specific (although i'm not 100% happy with the arrangement)
+    if not i % 1000:
+        print("pos", data.oMi[JOINT_ID])
+        print("linear error = ", pin.log6(SEerror).linear)
+        print("angular error = ", pin.log6(SEerror).angular)
+        print(" error = ", err_vector.transpose())
+    return breakFlag
 
-    print("final error", err_vector.transpose()) 
-    handler(None, None)
 
 
 if __name__ == "__main__": 
     args = get_args()
     robot = RobotManager(args)
+    Mgoal = robot.defineGoalPoint()
+    controller = getController(args)
+    controlLoop = partial(controlLoopClik, robot, controller)
+    controlLoopManager(controlLoop, args)
+    controlLoopManager.run()
diff --git a/python/ur_simple_control/util/.boilerplate_wrapper.py.swp b/python/ur_simple_control/util/.boilerplate_wrapper.py.swp
new file mode 100644
index 0000000000000000000000000000000000000000..d0befeb34512b3259ffe76f42513039b4404548a
GIT binary patch
literal 28672
zcmYc?2=nw+u+TGNU|?VnU|<lK8=h(&TEk!=!N`!FUtEx%l2`<i!iRGci?cKH@Tq{v
z)xiwZ&&bbBHPVN3b4v44^b3j-D>94qON-)*Gjj`aQsa~J^Gb^HbMy-;OEU8Fut=1a
zWaj86<!9!k78T?qmZZj)7bO-Hq!#HFR6;BqB}YSGGz1_aP+F3vYr)H4Y-DHv5>QrB
zR1g*l1u;kQXb6mkz-S1JhQMeDjE2By2#kinXb6mkzz7L}k^)wSdIkmtCa8aXpfn>I
z%?9NMKxuI(4O7Pq<=a8&NGJ`HXNB^?oeu^Eh6X4fCeH%pb3^G_P#Pu=<&ILLAut*O
zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Ukd5Kw=65!%1ca22oH4U4VfB*8jiF
z&%kh)pMhZmKLf)Oeg=jjeg=jxeg*~&eg=kLd<+cN_!t;g^D!{Y=VM@)$j87?!pFd1
z%g4a*o0oy%H7^6hD_#bMXS@symw6c&_VY3@RPZt|81XVNJm+Cx*v-Sh(8a^R5WvI0
z;KRefAkV|V@QRy(VFxz@!$fWdh6&sZ3=Z533<}%~3`e;b82Y#v7<#!F7*e?y7&y2X
z818d2FihfPU<lx3U{K{`V7SD=z_5mcfnhZV1H)nt28PKT3=GX23=F;;3=H4d85pjz
zGcasmXJA;t&cHB@oq?f<oq@raoq<7&oq^#C8w0~`HU@?@Yzz#m*%%lWvoSEtW@BKO
z%*Mb_!p6Yh#m2z!hn0chCMyHOMOFreeXI-&6ImG;3RxK#Tv-_yv{@lxXTZY1z{SGA
z@Qj&(;RZ7U!!%|Fh7e{3hG1p}24-dkhQ~|{3>{1i41r7x3_45<4A&SL7&bF9F!Ue|
za40}QacWMQUP_6At%9L~z5<w6T95)-;82uUlF9&8g(0C}t6*wiprGtgg{s8M-_tK7
z-qS_FR>4d`Ss^E}xI`f<KQpgHAt^OEv9vf<p&&CaKRG!gGhZPwC8by)DX}<JA+0De
zH&r3ASiztq1EL&ms<J|9kwS4nYI0^;X0k$VVtQt>LSAWZQfg7L0$fpXW_n&?jvj>4
zfKYnDp6;H0AvzGJ7nkH0cqHbf<fIm9!nG+Ylw_n9rK%SzB<2+7D<tMABqo=XCgv!B
zR4XLs=jJBnrRXRmm6j+Jr{<+(=A|nb6f2bH7iAYK6z3~ss^==?<(DWVXC&sOgCsLc
zP>qIozqlYZH6=?SCpR%)4@o{VO`$TsR3WRhxCCNfW(mkS3I#>^=|zdT3gww484AuN
zMLD|8ItrO33gwwOISQa<Dw%nusR~7<d3l+6=?riKK@kOxy`qwo)cB&*<kZZvR0Ugw
zpb!_=APCPhuOzi7EipM&L&?y{T+cwyK+jMK5gMo_fNUzt&w-lY3|SsSz=YJC;#4b4
z7o`_vf>+8UCYNNEC6=UWpxOzFh0J1w%wmN^g`}MP<ZMt-CMV|PpqK=A9n7@k{Jgx>
z<Pr@fLrWt)Lo*9KLp?(SBPAULGh<^@BUCFg(-abm(u?(=da<|>9BP^QQ15#BBl{G^
zd{l!;2yr~7fcyr>NkyrN*(hGmOj7_0y5%IMqdFZftY8aC=FnL4$<Hs)$V78$Nn#Nw
zo0nwfrs{zRq-aRXFH*=<$jnnHO3X`7)d2e{H?bl<vm~`Bu_QA;uUHdeaY||$DCvP!
zK!uc)l)$bn$$&&+N`79dLRn@aI5EQ=2v(9=qFxLZMslWlu|iR5aY24wab{9xPG(7^
zLP<Wvy9$|Upmd*@oROJYmYSjf)}5Z8m{SbNM&LY~0nXE4Lm{PtLOw_r%-Il?DftQ|
znYo~3Rgw>KzCvONsPyuvf=KJ?>VlnDRGJ5-K|TUAKyi{<ky(NiQXnC4T7h~&51hNb
zG|EzQ;*)bzbQBEq40RL?^$ZmBK~|tf0aTHKtwLUbUR7#QezArbLIqkR7#bKrLl|Ud
zK~ZL2iH16?7&0_402PX<DOtq|X{9+iAYX$GR7lKAQ2@C)GcR2oVm2twKm{7K_yZS@
zrMWtgLKkX<LvcxBNoI0xYDq?Z3fS+UKmb{+3@+(F5eHGC11g}Ba#C{@it}^IQXz_!
z6>?HRN|I6)lJkp-Qj<$SkyoCokerwYafGr0q*PXbL|BnRMq)82rZW=DQbDm-oT^|1
z%A=*Zsd**E3L2?psd)+|8TqB@86fFO^`cY-P+41AoC+zC!H!f0S)g8`05%1bYC&~K
zT4qsk3EV6lc*RqakqW6XbP)h-3R2*J`5>=@84&-Mr>f`VC={orDwJoW<|&k?Dx{~D
zfZUE!+-IhtxHB1)pi@$d6f*NNQj0Q6K#30&HQ<^oF(<PMBmmAb`9%uFB^e6EnYo!c
ziA6d{7MEnC7N;sC7NsgA=H!4(S11NmlN!1C#U(kFnvlc`abqzk7&A-23N!N*5*1Q1
zlR^15v8WQ1H1bjsi;5B}i@~X*D7B=t2o$)9$kkPTnnH4ZX;E=1Brw5FE6oG>02FQ@
z^WzJ0@=J;p(sB~h6+n*82c;H}H=s^Oa(SXcaW2@+nYpRD<(YXY`Q-|UMfs(9pj?dX
z?#vQU3@YU3<y0ypfvg7A&?yR_S{WtYpt(&UCqKUcqB=RTD79E2F)6<kR&Ayhr{<OD
zBe^2P-^CxA-V{<2OA-}|6U#vE1(~jgs5v1Cb3`{DKv_o*8pfcyL%|l@(kRN$0rB8L
z3RZ?%FDTf8a$2z-swh|osN9K<&&<m#iH`?Y7&^#?>L{RU(X?Vn&PgmTR)97&Ko<KZ
z<|U@57HJ^4Ob2Y8rWFGylR_#8P)U+llnyC5bQF>jv%w`wE~q{OH=@!?^O8&Q^K**z
z3KEM-G81$382tQ0T&=+EuXIo|37pzN>AWa4F{M&BH!%fNkbzeOgOi*dLr!LPDw>OR
z6v{IaOCTw$Bp;NxQWa85lJyuoK}BJr0>nG8W^ZPRLUw9uL9s$!ex7bhCa8?esnmt~
zOc#`{b&FC#3yV_}3KBuh;gZy%Vg}DVg?vyO71ZcVDF(Fzp*3hyetxzt$UsnnhGs30
z2cQjDsJT$b2j^s_XO!erDx@XmC1<7<fr@ZY8xvL~g37Z*1?YliSVjezhH4C=*o3nf
zpem4J3mh{HnYjh|Mc`7nAhD=8l_9MtKUV=`xwRf>RkdDGeo}r(W??+Eb*2E-8w3${
zhqNB?nvkAa5}%u&l9~h43m0HeRsa_RxzJRhP>`6MotT~q3eaqrD<LHSjF+5WPzkY(
z1c!m!1ey6T`$4U4q(&svIOLW&%#&D}=SZrd!HaAxG=IPws0_+bqta6gQcFtm^^)_8
zK%J_hveY7oN$?(*URh>wDX8*Eg&F7$(Gvy}FM<UEsDTJ$=auFbRDx>OyaJdI+(?jc
zL1rE-n3Ho-6N?l;WpXK~b)H&W461=34lHH>_5T%E7#K{T{eRf}{Uv?|hS~fK44M24
z4Ced{3@`W?80z>K7?SxI81(rV7)1FP7#{F4Fl^yvU|7w|z_6H?fngRe1H%Mf28K9Z
z1_nJ|28Oph3=GqF7#R9^7#ON}7#RF`7#IwA7#KcrGcX+BW?)#%&A<@D&A_0_&A{-E
zi-F+*7X!lvE(V5aTnr2~Tnr34Tnr4aIT;u(b22a-;ACJ}&&j~Bj+23587Bk7Y)%G-
ziJS}!R-6nBk2x3^x;Ypa@;De6(l{6xd^i{wzOpkgY-49&n8(h*kjc)#V9L(G@P>_n
zVILa<Lme9fLmV3egE$)l!(~<mhNG+u3?;0PFgV7_z%YxIfkBLwf#EF+1H*h41_pl?
z1_mJ(28LhE3=9*P85pXW85rW285s1K85n*sF)$opVqjRo#K6$V#K2&{#K0iT#K7>C
zk%3_+BLl;HMh1o)XdfTcE&yRrTad{1D@Zvy1~=fr#W}i+FQ_T5S5lOiSDXXxBS4z9
z;D&|<NG?7nv$zD(`a{;6nWm7cU~8+Ol%K5x=~N)gg4mF@ZYri$grrhPMyf()UO{OI
zsNV=`7-oW6G^q-y6$PouC8;S2Y57IDi6wdpAw`u6iRp=%d3tDFU65fQ4C*8oR~GA~
zRwTz~=B4GM1r}IIMRICE33kUSC@8=^8=V=eV5^Xplb=|E2!ZI#SnNJQYwzcz<{>m`
zYGStyZk2*9*jl~ff}G3}4Rsx8TOZ_FWDN2gD4;Q7u%xIG(*}^~3bv4N)ldq^Nd=9~
zq=H5bz^%`c#3E2lkqYWzq@|@Mm*f{I6yz6Yf*P8j$`({(ROnUcRO(ggROwYgqrgf5
zE#S*DGILTDLW)Y!#tM`bQt}lN6(G`}3Q?gnuOt)H@P%|N!4*jgtb>tLiQ*?^Y{?N*
zOdHhmf+W#s13d#!cg;XYLDxXf5G|6B2PKM96N~fn5|eUL70MIA{nM0uP|vg^KOfYJ
zsZ0VFr#Y#ht_w&URErm(xDM<PaHFcAQZFSnwE$GdX!wE}C8%jb8QfZj4sU^mhw_kP
z6WsnPRImk&q3LDjm87PF#^^M_H6L`Gt58RwFhxNNG8&MAmi?ff0(H<!60<?g=bRh`
z3x!mO(~CiN7p5o_XXYiRDwL;!x?II2pi!sHJdll$Q9HQ5Fb8|Ubs)6Hg7u3FQy|@9
zu+tNhlT&k`U2~{=F`WqRP-kfrrsyaXCnx447RBeJCZ@!L_G`r_CMWBFTJ-6q1@WL7
zDn36i9y&~i2*=Dca8D6zV{v9~DWr5lq;`mtAf;7uPG*4yL_kMD*ANzPpr$F<0ieNA
z2nS)lvVsO^L=Y4^$)F)a(9j{c6$$Ep<tczu7qaTS0zHs5pn@tt8#1hy1nLSED<q|Y
zT5k|vg4%WpDfy|zkXB`8i9&HkerXP*e+^0m5LYVLBE>H>taDO};=!R74>AfgDhN^!
z!paJ{iJ;^Oa%*{F9=O*EQUh)v!&>9eo;f^Xkt~X~GK+<aD<k*Fic-O?XNVi~)Jqid
zQd3hvo#O1g{Bi|wdpa?%vOE!yOO>HXDkBp-kP0d+QY%V|5*3UT3W_p|b3x+|kg;Ed
z;*8Y1#JtS(#Jpk!aKjO#80uMt@*>cv6xdau9tLPcBrpZqzbH(BmYbm70Vn_<ZSXu$
zw;9}=g!U*P(F5uSBKav3G&Yr)mtL%pl3D;N<nkd^3cPOtDw>irz#Z~jNY4b)QPs#u
z1?3o!Bf-w9%r6DyoqSL~yeKs>M*-Z9)Byz;NE|wJt5BSuo2rnPS`O;^gA!?ekwQ`q
zXb3b>4-$Zx#h|pFk^>!NNy$u0OD#$T#bO57nXn*FN(B#3L!AvuQu%qHu?ld<0qPi-
zrHL@xGV}8wV-4W8JlNfkpae5P;Rj}b0uef3PzV<QXDv`Ugb)Jp@(T38iC?1-622h4
z$_k(^RU&j~4?M;T@;A8WR9u>rl?oaYPE{xbHA_n>6%x}*Qj0*N7;w8_LrdUsa_~4$
zQhrH>LVf|L)+q+nF`(fX@c2q0C=aO@Lx$876)aL9Rj~r79RfEG<fuYD(ALeo6b%DC
z1B6rY%P2#PO#_#Qpwak}3<b!D8@Pj3o>`m<w*#|igxd&CsIYP9_=5am1$_l0Q&UX^
zEd>KT10z!$&LK@3sGKhaC7vAcpp-&-Vgac10b7s@9s?>*g^Z%4<SP_sDwO7BmK1~2
zGTaNGzyKMO3e#+woQp+L-^kPyWOPYBC>B7KUrJ_fYF=?>eqK&$aWRSxaH@g!@xVT}
zRe<vJK;5<E(jrje2FZY16iDr`%rr=ShJ6ell=Q$kOb=WEL8m@IW;%jra{{3zfl7<?
z)RI7OSfZ5^ps{2fa3crmB#@_|B~DIiib8QJs8e2&no|iH4lPerPk|SBpuuI(&^IVq
zXMo1Jz{MV9q%j{7{$SVXKy-p;y+FffMX9;@WuQUN%#zex@K7kI{D4fAff6ialnhkS
zlw_n<f|^F4R&FA=-34}NepzY}Xp9YH45;M+4(rmQlr)8sqSVBaVp!mUdT1r(`RIjg
zu@1zEi0lsv8?Ygu%nyox5C#i?7~t50hX`7Q1DZY5Gk~iltJ(ou0I6#gY!wXjOp%O(
z4A*2TWF)3QipCO92?!d-Hv%<0!8uSNIX?xF1(8fk0lUr|$+*mvY*4Y3lT!(q+yl=n
zB&C*s%AS&Zqyf+zaD1jHB$XBwWkNa?3dM<Osi2Z7F9lMrE9B(orKgsGW-cHNMMSE{
z77pMdtRy2fS0N)aJp-H>lM@TTF<O*b3@uo|wYfrZPG(AKkv)>bK|>i<AhqyuVbEBx
zLUL+RNn$2w3>9Q%Dx&QP4+T(_3GSp7;~B7nM>9AdW#;P@r<MeRCNG1*4$%N-Kd{r{
zAx=XSR$z;en|Cm4kj23L{~Npv3<`XZ{r}w1H3Xo!|E>HC3<>-U3|#yS3<vla7<%~_
z7=rj17|i(?7?k)J7!>&+`ULqH7(ixh<7Hr&$;-eH#mm58#>>E<!pp!Q!^^<%ori(p
zDh~rgJr4teCl3RIB@Y9GCJzIHA`jHEQED^<MnhmU1V%$(Gz3ONU^E0qLtr!nMnhn5
zgaD`qf{f88uL$uK6coUH7id2fHV6${cLg;X-4y(~Kyw86mUKZ41uwdSjx@l8pl*S2
z@!AVh1fww(V~QX=i(3~$O;LUhT7ba4hF3dY$rRAhX@pgPmr`Kbj;0Z@CI>p?2%a~A
z_kY2iOt6rGtpb>aODTgF>6U=jW8{L?I)D}vfyPq`ic-^3i;6%))1VOp9ncswWHA?#
zR?z4Id@(O<b_O(z3LeJJ&r>KUEh@-I8sCFC8$^Q^b-||9A$n55GjovTb$SZH`9(#Q
zdJ4|@;Kdfj`T2QzIOgh-QWerND?m=oR{$-P2HOr^%%-Q{2%2PojrYP<2t%hlA${>;
zg&4S(K<+9^%q&h-@XIgp1f6dO8X!tdaV;v!FVavCNG!=H292A5LI^x!gtD9qG<pdi
z-9i`&5=Km-fUJPb(<*`8nOO|+H7J}w1KkQKscD&csVP=5c}hBv$kGJ&|4*<oFf0LW
z@E2fUfbGx!&(FZ{kDr0z8$ScXBYp;k)BFq!b^Htr_WTSC;`|H@xA_<tX7DjE1n@C1
zF!C`lY~*ENDB)#b$l+yR@a1J-Fy&=nkmqG!xXZ)9uz`nxp@)Zo!JUVJ;XXG5!#!>W
zh8f%p3_9El3^%wK7?yD{FnDk=Fi3MTFnr=<U|7P*z!1X8z#z`a!0?}gfnh2K149D`
z14A+g1A{RK1H*rI28N^T3=C`885r82bNdqP3=F@Z^ZQ`G435%s)D@#4Fd71*Aut*O
z6ode%VnfHHi=Y$~6jDbQL4n#!ql=&hU=b8_ZAnRG0ch19N;?;_zSjyotqPig1<wpZ
zHmM{g<y0yZ6;y&33FH@Lrsjb*x#Z`;*L;BI{XmflTIp7z0NFr<W_nR-ZenI0WZ4c#
zDRi1z0m(cR9neN`Xpm{DLWpyKm6DEv7JOj@xI>6BK^@{85RhM-s-dZ=2i_y0VWNqc
zSwk+1v_QKU^zwZ(qs?NGS6;%k=_qIwWajA=6;$fwCYBUsR)pjS6;x^<Yb(l!1OhI*
zpza5)Ack~d6jJk2bW_3e&XDzfpzWIZxrh~EkS2Z%qVooFGSnCk$o9%|@KPI4@PVho
z!ISHd>HeHbJq6di;!@~(BJk=V@Zu1VVkAdo7AruyLTHN#q4q@Pmm)TjfcMy>Rf6V8
z6_D4b7J++)dHLnYOF@xWi-9LNVVyao)rsJRdax~a@W2FjM`8P25zC}N5s;Q&RGwIr
z;+>h73SQS#tN~VxyigBhj1FQoVj)tLD?>X^;2sq`ae<aOfK36-(?bUuKua1R9WD3#
z#GC-oK3lL&Xsa8b9mQnOa!%-aAeb*R^U^_U7(t5x^YTH<h>BAoI}YFrT0lz>K+7W_
zy}En_*g7)sL^kqT96g2nq_WKX(&C&-u-f!|aK-~gB(#eP_6s=EfmidCq*jzb7Mp?<
zf)<V;c1wWvIpmil=Hyf=loo^5Ug|&=;DA;^6qgpH79~MeNPwoq6+p{ULH0m=1zIAI
zmkxGAN@fbEqnlZl4BGPmT5SZ$$xsJ@_x(c50VP_HS3yhVz}^L$nXgcmnOY8>rBBRD
z%&Dw`tegX_69z3W&dkq)BulW*Kt_N&!=P27Aam04i;^K4K&29RUu#loT7D5kEH@vt
z8wt7$1Ee=MF|QQtVd%o<63`;9JkW+k&{kiBGc)rPz~LSmq)?Jv0L`VKaR~5k7o?^6
zc`2~945_)W)gE>VN#JD$kcF&}-FV=f0$%(JS_7A_P?8GWZ&q5IS_E<g)WwLkF<}3K
zmyVziU}3Zb2^Iq_DPaKj|CJaS80wfH^Z&5({Xl(w&>Dc1(7peW{0t24{0t0=(Ea}>
z_!t;=@i8#u^D!`Z@i8!X@-Z;DLe~bU^D!{I<Yizu%FDnok(YrXl9z!&mY0EnftP{d
zAP)n>OdbY?Fdha5X&wfKuiOj_JGmJcYPcB~D!3UKQlR?*esD1`?BQZyn8(Gy(8|TY
zP{75&pvJ|(aGR5XVGAb%!%R*F1{Y2ShJPFk3~xCY7`AXQFtl(mFl2HtFvxK*Ffed1
zFx+KlU^u|ez_6U1fuWk6fx(-dfkBa-fq{`7vgf~)je)_Eje$Xije+4lD+9w$RtAQt
ztPBk8(7pZ4tPBiHtPBiySr`}&voJ8!u`n>0voJ8cVP;^s#LU33o|%E6gPDOLnwfz?
zotc5*2@?auOeSbpQqbNVD6OCb55lneJ2@jYIa>iVf(K485GlwaWN?;GtOSj&feVkq
zloX^YTp_a<wEh&N0fh0G2a;A$P{5-CwnmjG8)2Kc6f_bG3KBtU*K#Tm^>$)$aVlg3
zRIwiNA{Yf51w%b^NQna4l8z#0r(mFmyo?Hzso|##<YX2UK*9jNlr$}~0wRJGW}t!x
zx|Rv#4e-k3+*F0+qQt67h2oOZv^2P4aCJhPvmfAgfcFoBq7_`oKnLa(Qc^*Cu2PG@
zE1p5o2OHZ27nIO#oyDce845|r%c(%&0a>12k^$KiP@0#SS5lf;l3A7t8r%gp13@(b
zWJy?AVo@fj?ocSn&qs0**{4z<%3yHN<;8>7>w(r(nIRdE=fDcMDo|Pkn}OUUR2V(3
z0TeEvz2o4f7_`1Y9d$;8+CUxGfN%jUIYZ(NeP^Bq+R+q<!U5Xo1bY(O76q^k2npC?
zI)n&39Vsh-HrQrDHuZtB2lQABaBc%_5h(&4_<_hnpzsBo4h>sSl0(^N32j+|)Zslf
zL%A%oN-rg|xF9F7Qlk)U88uikCqFSIEHkw{wa6E=H518Tkl|n@Ah$!5V3Ad@RlwMu
z2;1wDoS&1E30h?g+4iZU0BQL_c!+QYTLjuDqF0=gnp&V?j3$L;%cNd0=$wrB;#AQ7
zNpx3%+G0?vGOJRHAe$3F>rNFkKxHlHWEfC+oLG{JYEeNV+FEFk!$26{oKG;pnIo#t
z@xWpn5}KJ+NPQrXYeDU7NDxETg2I&{d<#xn$o(9Qm;$SS=!BRB+X)2Pp>K;ci>0gp
z*9)#LA$k<Rh8Kf(VdQ~!GGVwGw7JkNF$ZbBPFVqz79l#}IS1?xP!5FVF0cfsLxr|y
z9i#->pHfzUPcDMb{7Fqw0Ppnz6<FXZt~eF6mOB^J!cQzHD9SG=%7h)F1g-}mXI|uH
z=4Iw)Lc0=)x%s7eC7`WWIhlE>(4$SDn+-t82DBLhBnzt45Ia%8{b^8kFD?OD23}8`
z2s%Rtx``fnvkPReyaITJ6x@D-R=(gpk_u^w#U-E)L1s#7B53~(_&O}mbRl@TumWg<
znI3~Ks7nPh9@L9U0*|YJ(mTjax%tJQ%|GS3;J!i{Xp|)dyh=W&6tqJFw8sRpCml2v
zQ<?`_vu$c%;86vRQjj5_&;r$~NSoMU#VU9cV0lJnat3rGOfl>nm*RYIQxVk1V^9Da
zRRTJjBc&+60JI4qGp_`sAhTEj<nq*_RM3b6VuyPg=s<wX{5+6$g@V!&23;_#9JI3t
z#43Vqjmk+aLR$I{@=JaZq#IhCkzbw)YHfh`DkOq;DT1~RW#)ml5kT4|kh{cC_OyU|
zXt{}bpq5x_L9vbk_*{XM+yYPtfV!WcAO%MSq$dVFJp|+@&~{N!Sb@%^D#*!9P6X|8
z1vQt_iy3r5!3u5?6_<cEw}Yb@+{aE-NJ89MrcjicQVKp71ade5g90R8!ADCafi};U
zq~@ihrYPh?_cKAx#)3=+gY3^N0l5?P5H8U9Bw(vRn{i7(8zVvK1wPgSayn?+PjPW+
zZfXiBbdmQ!f!&;+rvM%<E6xY+iDE$MQtIk56oD!z=#DE$Vg~0`P>BT2#7O72X!zyl
zrRpevNJN<gQV1O<a&z?bu~Gny3V@PcacOcg=wP8d9VLvj9h4AD=8=Y+a881QjVcDs
zsw?RzWa=m&X;(zjpP8nRsbB-y%>vr%fUrbC*ATUx19CM|)s<4BpsN7d0*2}@Ob3DV
zfih5LUMXTb1V|8sp}~-wSzMf&qL7lBm;x$w6p|{Hbijs#>_FQznwh4MQlel3mPU0U
f$TbSKpz%QkT?KHp36B?$U7#&=wxA3PKW+*DE>7pG

literal 0
HcmV?d00001

diff --git a/python/ur_simple_control/util/boilerplate_wrapper.py b/python/ur_simple_control/util/boilerplate_wrapper.py
index 9441085..99e0492 100644
--- a/python/ur_simple_control/util/boilerplate_wrapper.py
+++ b/python/ur_simple_control/util/boilerplate_wrapper.py
@@ -15,33 +15,95 @@ from ur_simple_control.util.get_model import get_model
 from ur_simple_control.util.robotiq_gripper import RobotiqGripper
 import argparse
 
-# slightly fancier programming to get a timing wrapper around the control loop
-def controlLoopTiming(controlLoop):
-    start = time.time()
-    controlLoop()
-    end = time.time()
-    diff = end - start
-    if dt < diff:
-        print("missed deadline by", diff - dt)
-        continue
-    else:
-        time.sleep(dt - diff)
+"""
+controlLoopManager
+-------------------
+Slightly fancier programming to get a wrapper around the control loop.
+In other words, it's the book-keeping around the actual control loop.
+It's a class because it keeps non-directly-control-loop-related parameters
+like max_iterations, what data to save etc.
+NOTE: you give this the ready-made control loop.
+if it has arguments, bake them in with functools.partial.
+"""
+class ControlLoopManager(controlLoop, args):
+    def __init__(self, controlLoop, max_iterations):
+        self.max_iterations = args.max_iterations
+        self.controlLoop = controlLoop
 
-# robotmanager:
-# ---------------
-# - right now it is assumed you're running this on UR5e so some
-#   magic numbers are just put to it.
-#   this will be extended once there's a need for it.
-# - at this stage it's just a boilerplate reduction class
-#   but the idea is to inherit it for more complicated things
-#   with many steps, like dmp.
-#   or just showe additional things in, this is python after all
-# - you write your controller separately,
-#   and then drop it into this - there is a wrapper function you put
-#   around the control loop which handles timing so that you
-#   actually run at 500Hz and not more.
-# - this is probably not the most new-user friendly solution,
-#   but it's designed for fastest idea to implementation rate.
+        # if you just stop it the program with Ctrl-C, it will continue running
+        # the last speedj lmao.
+        # there's also an actual stop command, but sending 0s works so i'm not changing it
+        signal.signal(signal.SIGINT, self.stopHandler)
+
+        # TODO handle data saving here.
+        # it can only be handled here because the control loop only cares about the present/
+        # a small time-window around it.
+        # of course have this under the save_plots flag or something similar
+        # save it all in a dictionary of ndarrays and return that
+        # these are all the same (mostly).
+        # if they're not consider inheriting and specializing this or sth similar,
+        # we'll see when we get to it
+
+    """
+    stopHandler
+    -----------
+    # can't have self as first argument, because the 
+    # signal handler has to have these 2 arguments (even though they're not used, but
+    # let's be correct if we can)
+    # so it's static, problem solved
+    """
+    @staticmethod
+    def stopHandler(signum, frame):
+        print('sending 100 speedjs full of zeros and exiting')
+        for i in range(100):
+            vel_cmd = np.zeros(6)
+            rtde_control.speedJ(vel_cmd, 0.1, 1.0 / 500)
+        exit()
+
+    """
+    run
+    ---
+    do timing to run at 500Hz.
+    also handle the number of iterations.
+    it's the controlLoop's responsibility to break if it achieved it's goals.
+    this is done via the breakFlag
+    """
+    def run(self):
+        for i in range(self.max_iterations):
+            start = time.time()
+            breakFlag = self.controlLoop(i)
+            if breakFlag:
+                break
+            end = time.time()
+            diff = end - start
+            if dt < diff:
+                print("missed deadline by", diff - dt)
+                continue
+            else:
+                time.sleep(dt - diff)
+        if i < self.max_iterations -1:
+            print("success in", i, "iterations!")
+        else:
+            print("FAIL: did not succed in," max_iterations, "iterations")
+        self.stopHandler(None, None)
+
+"""
+robotmanager:
+---------------
+- right now it is assumed you're running this on UR5e so some
+  magic numbers are just put to it.
+  this will be extended once there's a need for it.
+- at this stage it's just a boilerplate reduction class
+  but the idea is to inherit it for more complicated things
+  with many steps, like dmp.
+  or just showe additional things in, this is python after all
+- you write your controller separately,
+  and then drop it into this - there is a wrapper function you put
+  around the control loop which handles timing so that you
+  actually run at 500Hz and not more.
+- this is probably not the most new-user friendly solution,
+  but it's designed for fastest idea to implementation rate.
+"""
 class RobotManager:
     # just pass all of the arguments here and store them as is
     # so as to minimize the amount of lines.
@@ -66,6 +128,7 @@ class RobotManager:
         if args.gripper:
             self.gripper = RobotiqGripper()
         # initialize and connect the interfaces
+        self.simulation = args.simulation
         if not args.simulation:
             self.rtde_control = RTDEControlInterface("192.168.1.102")
             self.rtde_receive = RTDEReceiveInterface("192.168.1.102")
@@ -78,29 +141,137 @@ class RobotManager:
             self.rtde_control = RTDEControlInterface("127.0.0.1")
             self.rtde_receive = RTDEReceiveInterface("127.0.0.1")
 
-        # if you just stop it the program with Ctrl-C, it will continue running
-        # the last speedj lmao.
-        # there's also an actual stop command, but sending 0s works so i'm not changing it
-        signal.signal(signal.SIGINT, self.stopHandler)
         # ur specific magic numbers 
-        self.JOINT_ID = 6 # last joint because pinocchio adds base frame as 0th joint
+        self.n_joints = 6
+        # last joint because pinocchio adds base frame as 0th joint.
+        # and since this is unintuitive, we add the other variable too
+        # so that the control designer doesn't need to think about such bs
+        self.JOINT_ID = 6
         self.update_rate = 500 #Hz
         self.dt = 1 / self.update_rate
+        # you better not give me crazy stuff
+        # and i'm not clipping it, you're fixing it
+        assert args.acceleration < 1.7 and args.acceleration > 0.0
+        # we're not saying it's qdd because it isn't directly (apparently)
+        # TODO: check that
         self.acceleration = args.acceleration
-        rtde_io.setSpeedSlider(args.speed_slider)
+        self.rtde_io.setSpeedSlider(args.speed_slider)
+        self.max_iterations = args.max_iterations
+        # TODO: these are almost certainly higher
+        # maybe you want to have them high and cap the rest with speed slider?
+        # idk really, but it's better to have this low and burried for safety and robot longevity reasons
+        self.max_qdd = 1.7
+        # NOTE: i had this thing at 2 in other code
+        self.max_qd = 0.5
+        # maybe you want to scale the control signal
+        self.controller_speed_scaling = 1.0
+        
+    """
+    getQ
+    -----
+    urdf treats gripper as two prismatic joints, 
+    but they do not affect the overall movement
+    of the robot, so we add or remove 2 items to the joint list.
+    also, the gripper is controlled separately so we'd need to do this somehow anyway 
+    """
+    def getQ(self):
+        q = robot.rtde_receive.getActualQ()
+        if self.args.gripper:
+            self.gripper_pos = gripper.get_current_position()
+            # the /255 is to get it dimensionless
+            # the gap is 5cm
+            # thus half the gap is 0.025m and we only do si units here
+            q.append((self.gripper_pos / 255) * 0.025)
+            q.append((self.gripper_pos / 255) * 0.025)
+        else:
+            # just fill it with zeros otherwise
+            q.append(0.0)
+            q.append(0.0)
+        # let's just have both options for getting q, it's just a 8d float list
+        # readability is a somewhat subjective quality after all
+        q = np.array(q)
+        self.q = q
+        return q
 
+    """
+    sendQd
+    -----
+    different things need to be send depending on whether you're running a simulation,
+    you're on a real robot, you're running some new simulator bla bla. this is handled
+    here because this things depend on the arguments which are manager here (hence the 
+    class name RobotManager)
+    """
+    def sendQd(self, qd):
+        # we're hiding the extra 2 prismatic joint shenanigans from the control writer
+        # because there you shouldn't need to know this anyway
+        qd_cmd = qd[:6]
+        # maybe you want to scale the control signal
+        qd_cmd = qd * self.controller_speed_scaling
+        # np.clip is ok with bounds being scalar, it does what it should
+        # (but you can also give it an array)
+        qd_cmd = np.clip(qd_cmd, -1 * self.max_qd, self.max_qd)
+        if not self.simulation:
+            # speedj(qd, scalar_lead_axis_acc, hangup_time_on_command)
+            rtde_control.speedJ(qd_cmd, self.acceleration, self.dt)
+        else:
+            # this one takes all 8 elements of qd since we're still in pinocchio
+            self.q = pin.integrate(model, self.q, qd * self.dt)
+
+
+    """
+    defineGoalPoint
+    ------------------
+    --> best way to handle the goal is to tell the user where the gripper is
+        in both UR tcp frame and with pinocchio and have them 
+        manually input it when running.
+        this way you force the thinking before the moving, 
+        but you also get to view and analyze the information first
+    TODO get the visual thing you did in ivc project with sliders also.
+    it's just text input for now because it's totally usable, just not superb.
+    but also you do want to have both options. obviously you go for the sliders
+    in the case you're visualizing, makes no sense otherwise
+    """
+    def defineGoalPoint(self):
+        q = self.getQ()
+        # define goal
+        pin.forwardKinematics(self.model, self.data, np.array(q))
+        Mtool = self.data.oMi[self.JOINT_ID]
+        if not self.args.visualize:
+            print("You can only specify the translation right now.")
+            print("Here's where the robot is currently. Ensure you know what the base frame is first.")
+
+            print("base frame end-effector pose from pinocchio:\n", \
+                    *data.oMi[6].translation.round(4), *pin.rpy.matrixToRpy(data.oMi[6].rotation).round(4))
+            print("UR5e TCP:", *np.array(rtde_receive.getActualTCPPose()).round(4))
+            # remain with the current orientation
+            # TODO: add something, probably rpy for orientation because it's the least number
+            # of numbers you need to type in
+            Mgoal = copy.deepcopy(Mtool)
+            # this is a reasonable way to do it too, maybe implement it later
+            #Mgoal.translation = Mgoal.translation + np.array([0.0, 0.0, -0.1])
+            # do a while loop until this is parsed correctly
+            while True:
+                goal = input("Please enter the target end effector position in the x.x,y.y,z.z format: ")
+                try:
+                    e = "ok"
+                    goal_list = goal.split(',')
+                    for i in range(len(goal_list)):
+                       goal_list[i] = float(goal_list[i])
+                except:
+                    e = sys.exc_info()
+                    print("The input is not in the expected format. Try again.")
+                    print(e)
+                if e == "ok":
+                    Mgoal.translation = np.array(goal_list)
+                    break
+            print("this is goal pose you defined:\n", Mgoal)
+        else:
+            raise NotImplementedError('Paths in the urdf or something else need to \
+                    be fixed to use this first. Also need to program in the sliders \
+                    and visualizing the goal frame. Sorry. Coming soon.')
+        # NOTE i'm not deepcopying this on purpose
+        # but that might be the preferred thing, we'll see
+        self.Mgoal = Mgoal
+        return Mgoal
 
-        # this does not need to be kept here
-        self.q = rtde_receive.getActualQ()
 
-    # can't have self as first argument, because the 
-    # signal handler has to have these 2 arguments (even though they're not used, but
-    # let's be correct if we can)
-    # so it's static, problem solved
-    @staticmethod
-    def stopHandler(signum, frame):
-        print('sending 100 speedjs full of zeros and exiting')
-        for i in range(100):
-            vel_cmd = np.zeros(6)
-            rtde_control.speedJ(vel_cmd, 0.1, 1.0 / 500)
-        exit()
-- 
GitLab