From 7d24d7801a6a86495a1b3d86af92cf8c185e2454 Mon Sep 17 00:00:00 2001
From: m-guberina <gubi.guberina@gmail.com>
Date: Wed, 4 Dec 2024 01:50:12 +0100
Subject: [PATCH] now it's shared memory all the way. and the path generation
 itself got fixed. now we can actually just compute the reference for the
 gripper and be done with this part

---
 .../__pycache__/managers.cpython-312.pyc      | Bin 53810 -> 54489 bytes
 python/ur_simple_control/managers.py          |  40 ++++++++++++------
 .../optimal_control/crocoddyl_mpc.py          |   2 +-
 .../path_generation/planner.py                |  12 ++++--
 4 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/python/ur_simple_control/__pycache__/managers.cpython-312.pyc b/python/ur_simple_control/__pycache__/managers.cpython-312.pyc
index c2815be629cbe704bc81afe0a7c810441fb93951..0343be7262ccf487703d207bbfbaeb2cdb691335 100644
GIT binary patch
delta 1480
zcmdnAg!$%5X1>$Byj%<n3=HR&`KOECn#d=?7_d>DmC+}KA%!tVH%gb2Aw{5tAxe*l
z!JQ#Ru!SK-Xf+c^Jp)6OK3Gh+g&{=*E@l806K!Eg5rc~vZZ2R<5@B@Od|C9h0OQHc
z`_*=FGrrnfWyHwM=(f4WmYa!j-sTSb8ezr>n^}WTurTsZJ{P{4QD}2jgak9A=;q1M
zF^r5Fn?J+^u`+6Jc20W7&gj3{D2tzov3#>r&L<Yerp=~>YuFi=Zhlmu#mabPGjE+2
zGvl|-5se2K8Cf<<HLEf+@@#f!yUflgy;-F18Z)EM=GPOSGctxvem&8Dv(l7V+>9xk
z_s)-CWn8dXZ0QU}#&w(5FH2=)+&WojrP5^c6<-*4Z`N5^#Kd@T^8D3*8A~?LUGtBX
zNr-jx+)aIqEE5=u1U7qbkz-^_;i_dX;h!uxRaTZgg*}CP4aaI`NLbY{#0x`M3=Acj
zlWQ$x_)-{FGeU%FIchj2JC=%1{<lR~JcXe|7b48SP{RRJB0V`{tIlM;QsK$Vw@NbV
zPd>O+Sl9rjEL($tp-8QUDa&Z`MGN7{H+6(3%U6pD#7n~z<jK`AWtmKF^b%&`shZ?2
zi6m9STEh@8Gr4e^JfrpGi>Kr#Z`dX>`NIqmKIIa7nD!Ljn#mVgM47V8Ci|aJVbbKA
zti0Wyt0;wmfgw{soq=I;(RLk1g~{``r*N<rXXM5w=cY_%-{C5Eivz?<Ni0dc#a57+
zoSl<;i#4S*x1hL)iIIU}vd<1_X6~HC$=N$38967n?y!)&#S7CApO=`MdW*53n3I8l
zK|x{ip&eT6ubCMbiq)7Vf8McEn}>l%YDVB?Zn+2I3LPGIq&2Qfn_iSQ-H>sh<U&x~
z^`O*?L8(`y(>h#wd?w%DDN~<!F)8nQQqjevqAN<p9WGaR<Zq}NZd6<l-{EqdNB$y@
z{6fYHJW5a0wHKFxWK|x>D0TQgk<q*^V|G!-Y(wpdkP8v9S7hQkTzY(;2#8JRnaDFE
z<g$QLhvN-Rtqzxd-%j7_JhB&gWM`z$DPCYWyX*pw+7ku!6}30?jW@&`m~6I-kEi5f
zddUU7vM<bxiWQRscDb`lt9Gzl;gHxoZ`U*?M#ashdu7?#j2Rgiip(ZQ9Pwb(+r03|
z6lO-V$z~_Q7y~Ewo|rOuVzV?y3S+i814EJJ<bydzOvUn(59WwZKEG0U@`ET2mKuh5
zmdS};a+BqAxhG#{5uW^@U1YMsA}%Iys+6C+K1FzP|5TC5{Jz|bETBlA{OGjoWcd>L
z$$C>oC-eJq2nI7~GWiufVPIg;<SUW|Mbq7rl4?32SE+*tD-fZ{$iQ%mH77qYrMO4~
zB%lf+tS5gzX;+`b!oW~Goq>U&f#C)>|8;J;i`;Sx6fbcr-w+m`Za>lfy0FGYVT~)o
zS~rx{m)kG2zpiY1QQ7vgvi$^>D*_5=T6hGm^Qc_pQMt~ebCE~q3Xk3$dDZzfGiz43
ztoL2%dtJx&qK@rlc{@;)$=m=dRzy+FFWg_-Svw=-x~%R+S>4P0dKWnKCiBKhZ=QOJ
znVDM~<Z3w(VLEy7Sx?Ixkkh|ob2^VezfY&nbso8kJaSif6mG!ypp<ikM{%>_Ic`R7
z3y?`RAi{C7`FTZ&^Pu!<&cMLX!tjwvf|cX5nLeu@<A<Ed1?S~OIau{Si}12KGZukV
z6#0Sz+-UQX^Jf^DG#Mx7UNqneVPs$c6%fU3lb2r%WWLS7JNd^&O~EWCMrX!P3}6bZ
F7XY4z)baoT

delta 1082
zcmcb)l6lh-X1>$Byj%<n3=B!#{^@70P2`hc^w_A*%ILz$kRs5+5T(n+;LeaD*usz^
zw3-Q|j)5Uc4=g6!!jK{Y7t;reiMBALh{44SHdinvi7+~DzAgG%fbqoU<7&IO8DDO0
zGGgRrblu!y%gw|%ck=}M8ezu%&Ah=USQz;xUkhK&D7d*PLV}r5Wb^Fk7)D0*%|Bv-
zSQ)i8dndhPXY|`_mBr7*Shm?K=MxKK<7V5!HSCN_HovOSVr9I%S+vfJnepr9gvNu6
zY|P9I48_5decM7dS2v$wV&vZJ(RP`gQEIbH-!*1N@5#3(`)_udG=q^bbo1@WFS!|$
zHy@oJ!OA#)v)s}djErkHZ(o+m$hc**><TeP#$A(TS14@`TN%K_cwqAK)qfd_H!ofD
zkCmy3W%JTaeT*zcCrel-2j<GKrLfhqmGDn~a871&<d#2^uWuHdEVNB((iV})4%;Nu
z)gj@>z)-`qni0Y-(SXnl4A~kC3`J@+Oj%l!H<}4gPAC<doKP*y7cUM|kSABeG<l(g
z2y+To)#QuGk^%^+8rB+yc!|mRr{x)qCo@{gPww*;nLKHmFkg{!i8)Mv3iss3sp6CE
zb%ZDXIVZ%V$uoKPcK^vDJ9HRjCOhs(VPP)L$ep})hwEg4ozg5kIf=!S^>#`!vQPHd
zX~9~|&cMJhdFD<n_E(@_eZ@HW)Xts8Yz#b7GXgJh%iWPvo}J#|(&PU?T%p6`j=0Ko
zal?z^h8r{vn4HMD?w5GcFY$_aQin^A$K-XpWDK${CS_eu%Db49cSR|`!{rK({0&vZ
zjfxB6J6x{w$Y11<U&wfYN9m5b_Tn;-tjc7&-I6?I7t_lw=v91SW>l=2oV?qeT}G{g
z<qC)7=8e0jF)@m5_Sh%O&Zfu6z))m3Is2#wqw?l0N2f3|8cy~+8OG=~dBMpklNanW
zXDXJTT<9e}`9Y5K<h7f5C%@aoIhlh+WHM{L*yQ`CxfF{wGB7Y`vK1*XGBDg?P0cMR
zsl3INo>~&0mtUTkSyH4q+5C*1PdEz$L$M75149GD4SwPN`p)|6{3;juRj%->-B3_j
z&cBfVx`Ne31*^*nHXskk-r*PSukEaz5prEt@1m^UWq$n&9Qs9|m`P@wJkeBSv%y(r
zW^N6T<K;kv!DPD&o@_B7TRu<jy&x{((dp6e*XehKN9G2PKtG7*-|2saM|Sgp3*3y{
z#vncBAi{d`wTp@p=Rk1;GQEZ2Ba;Lx$7eHDRzJoM5tI2Z$%`_x8hqyBWp!o*+h61h
v@~`1$=Syc8CyQLs<?>@>U;w4f;^xWTR{|%`zoID^&BW-;_=y2bfi(dDXdYWS

diff --git a/python/ur_simple_control/managers.py b/python/ur_simple_control/managers.py
index c64cd26..f6731d0 100644
--- a/python/ur_simple_control/managers.py
+++ b/python/ur_simple_control/managers.py
@@ -25,6 +25,7 @@ from sys import exc_info
 from types import NoneType
 from os import getpid
 from functools import partial
+import pickle
 
 """
 general notes
@@ -1016,23 +1017,33 @@ class ProcessManager:
             self.data_queue = Queue()
             self.side_process = Process(target=side_function, 
                                                      args=(args, init_command, self.command_queue, self.data_queue,))
-        # both ways, with shared memory for commands
+        # shared memory both ways
+        # one lock because i'm lazy
+        # but also, it's just copy-pasting 
+        # we're in python, and NOW do we get picky with copy-pasting???????
         if comm_direction == 3:
-            self.data_queue = Queue()
             # "sending" the command via shared memory
             shm_name = "command"
-            self.shm = shared_memory.SharedMemory(shm_name, create=True, size=init_command.nbytes)
-            self.shared_command = np.ndarray(init_command.shape, dtype=init_command.dtype, buffer=self.shm.buf)
+            self.shm_cmd = shared_memory.SharedMemory(shm_name, create=True, size=init_command.nbytes)
+            self.shared_command = np.ndarray(init_command.shape, dtype=init_command.dtype, buffer=self.shm_cmd.buf)
             self.shared_command[:] = init_command[:]
+            # same lock for both
             self.shared_command_lock = Lock()
+            # getting data via different shared memory
+            shm_data_name = "data"
+            # size is chosen arbitrarily but 10k should be more than enough for anything really
+            self.shm_data = shared_memory.SharedMemory(shm_data_name, create=True, size=10000)
+            # initialize empty
+            p = pickle.dumps(None)
+            self.shm_data.buf[:len(p)] = p
             # the process has to create its shared memory
             self.side_process = Process(target=side_function, 
-                                         args=(args, init_command, shm_name, self.shared_command_lock, self.data_queue,))
+                                         args=(args, init_command, shm_name, self.shared_command_lock, self.shm_data,))
         if type(side_function) == partial:
             self.side_process.name = side_function.func.__name__
         else:
             self.side_process.name = side_function.__name__ + "_process"
-        self.lastest_data = init_value
+        self.latest_data = init_value
 
         self.side_process.start()
         if self.args.debug_prints:
@@ -1090,7 +1101,7 @@ class ProcessManager:
             #self.command_queue.get_nowait()
             self.command_queue.put_nowait(command)
 
-    # TODO: implement
+    # TODO merge with send command under if which depends on comm_direction
     def sendCommandViaSharedMemory(self, command):
         """ 
         sendCommandViaSharedMemory
@@ -1109,14 +1120,19 @@ class ProcessManager:
         self.shared_command_lock.release()
 
     def getData(self):
-        if not self.data_queue.empty():
-            self.lastest_data = self.data_queue.get_nowait()
-        return copy.deepcopy(self.lastest_data)
+        if self.comm_direction != 3:
+            if not self.data_queue.empty():
+                self.latest_data = self.data_queue.get_nowait()
+        if self.comm_direction == 3:
+            self.shared_command_lock.acquire()
+            self.latest_data = pickle.loads(self.shm_data.buf)
+            self.shared_command_lock.release()
+        return copy.deepcopy(self.latest_data)
 
     def terminateProcess(self):
         if self.comm_direction == 3:
-            self.shm.close()
-            self.shm.unlink()
+            self.shm_cmd.close()
+            self.shm_cmd.unlink()
         if self.args.debug_prints:
             print(f"i am putting befree in {self.side_process.name}'s command queue to stop it")
         self.command_queue.put_nowait("befree")
diff --git a/python/ur_simple_control/optimal_control/crocoddyl_mpc.py b/python/ur_simple_control/optimal_control/crocoddyl_mpc.py
index 078883c..d0a17c5 100644
--- a/python/ur_simple_control/optimal_control/crocoddyl_mpc.py
+++ b/python/ur_simple_control/optimal_control/crocoddyl_mpc.py
@@ -221,7 +221,7 @@ def BaseAndEEPathFollowingMPCControlLoop(args, robot : RobotManager, solver : cr
     T_w_e = robot.getT_w_e()
     #p = T_w_e.translation[:2]
     p = q[:2]
-    print("CTRL:", p)
+    #print("CTRL:", p)
     # NOTE: this is the actual position, not what the path suggested
     # whether this or path reference should be put in is debateable. 
     # this feels more correct to me.
diff --git a/python/ur_simple_control/path_generation/planner.py b/python/ur_simple_control/path_generation/planner.py
index 38eeaf2..a93d6d8 100644
--- a/python/ur_simple_control/path_generation/planner.py
+++ b/python/ur_simple_control/path_generation/planner.py
@@ -10,6 +10,7 @@ from ur_simple_control.path_generation.starworlds.obstacles import StarshapedPol
 import shapely
 import yaml
 import pinocchio as pin
+import pickle
 
 import matplotlib.pyplot as plt
 import matplotlib.collections as plt_col
@@ -721,7 +722,7 @@ def path2D_to_timed_SE3_base_and_ee(args, path_pol, path2D_untimed, max_base_v):
 # spitting out path points
 #def starPlanner(goal, args, init_cmd, cmd_queue : Queue, data_queue : Queue):
 # let's try shared memory
-def starPlanner(goal, args, init_cmd, shm_name, lock : Lock, data_queue : Queue):
+def starPlanner(goal, args, init_cmd, shm_name, lock : Lock, shm_data):
     """
     starPlanner
     ------------
@@ -778,8 +779,13 @@ def starPlanner(goal, args, init_cmd, shm_name, lock : Lock, data_queue : Queue)
             # compute the path
             path_pol, epsilon = path_gen.update(p, r0, rg, rho, obstacles_star)
             # TODO: this is stupid, just used shared memory bro
-            if data_queue.qsize() < 1:
-                data_queue.put((path_pol, path_gen.target_path))
+            #if data_queue.qsize() < 1:
+                #data_queue.put((path_pol, path_gen.target_path))
+            data_pickled = pickle.dumps((path_pol, path_gen.target_path))
+            lock.acquire()
+            shm_data.buf[:len(data_pickled)] = data_pickled
+            #shm_data.buf[len(data_pickled):] = bytes(0)
+            lock.release()
 
     except KeyboardInterrupt:
         shm.close()
-- 
GitLab