diff --git a/python/examples/.smc_yumi_challenge.py.swp b/python/examples/.smc_yumi_challenge.py.swp
new file mode 100644
index 0000000000000000000000000000000000000000..df6c5270b503b62a62ad1f626b8dd88eaca12a40
Binary files /dev/null and b/python/examples/.smc_yumi_challenge.py.swp differ
diff --git a/python/examples/dummy_cmds_pub.py b/python/examples/dummy_cmds_pub.py
index a3aa1517a82a9f95a16170b63e3e5cf5c52feec1..b77cb146e9c27f4feda135921c5b630b6479b85b 100755
--- a/python/examples/dummy_cmds_pub.py
+++ b/python/examples/dummy_cmds_pub.py
@@ -12,6 +12,24 @@
 # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 # WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+
+
+import rclpy
+from rclpy.node import Node
+from rclpy.executors import MultiThreadedExecutor
+from geometry_msgs.msg import Twist, PoseWithCovarianceStamped
+from sensor_msgs.msg import JointState
+from nav_msgs.msg import Odometry
+from abb_python_utilities.names import get_rosified_name
+
+import numpy as np
+import argparse
+from ur_simple_control.managers import getMinimalArgParser, ControlLoopManager, RobotManager
+from ur_simple_control.clik.clik import getClikArgs, getClikController, controlLoopClik, moveL, compliantMoveL, controlLoopCompliantClik, invKinmQP, moveLDualArm
+from ur_simple_control.optimal_control.get_ocp_args import get_OCP_args
+from ur_simple_control.optimal_control.crocoddyl_mpc import CrocoIKMPC
+import pinocchio as pin
+
 import numpy as np
 
 import rclpy
@@ -23,15 +41,33 @@ from rclpy.node import Node
 from abb_python_utilities.names import get_rosified_name
 
 
+# you will need to manually set everything here :(
+def get_args():
+    parser = getMinimalArgParser()
+    parser.description = 'Run closed loop inverse kinematics \
+    of various kinds. Make sure you know what the goal is before you run!'
+    parser = getClikArgs(parser)
+    parser = get_OCP_args(parser)
+    parser.add_argument('--ros-namespace', type=str, default="maskinn", help="you MUST put in ros namespace you're using")
+    #parser.add_argument('--ros-args', action='extend', nargs="+")
+    #parser.add_argument('-r',  action='extend', nargs="+")
+    parser.add_argument('--ros-args', action='append', nargs='*')
+    parser.add_argument('-r',  action='append', nargs='*')
+    parser.add_argument('-p',  action='append', nargs='*')
+    args = parser.parse_args()
+    args.robot = "yumi"
+    args.save_log = True
+    args.real_time_plotting = False
+    return args
+
+
 class DummyNode(Node):
-    def __init__(self):
+    def __init__(self, args, robot_manager : RobotManager, loop_manager : ControlLoopManager):
         super().__init__("dummy_cmds_pub_node")
 
         self._cb = ReentrantCallbackGroup()
 
         self._ns = get_rosified_name(self.get_namespace())
-        # test
-        self._ns = "maskinn"
 
         self._cmd_pub = self.create_publisher(JointState, f"{self._ns}/joints_cmd", 1)
 
@@ -48,26 +84,99 @@ class DummyNode(Node):
 
         self._pub_timer = self.create_timer(self._dt, self.send_cmd)
 
-    def send_cmd(self):
-        msg = self.empty_msg
-        msg.header.stamp = self.get_clock().now().to_msg()
-        msg.velocity[0] = 1.0
-        msg.velocity[1] = 1.0
-        msg.velocity[2] = 1.0
-        msg.velocity[3] = 1.0
-        msg.velocity[4] = 1.0
-        msg.velocity[5] = 1.0
-        msg.velocity[21] = self._A * np.sin(2 * np.pi / self._T * self._t)
-        msg.velocity[28] = self._A * np.sin(2 * np.pi / self._T * self._t)
-        self._cmd_pub.publish(msg)
-        #print("published")
-        self._t += self._dt
+########################################################
+# connect to smc
+###########################################################
+
+        robot_manager.set_publisher_joints_cmd(self._cmd_pub)
+        self.robot_manager = robot_manager
+        self.loop_manager = loop_manager
+        self.args = args
+        # give me the latest thing even if there wasn't an update
+        qos_prof = rclpy.qos.QoSProfile(
+            reliability=rclpy.qos.QoSReliabilityPolicy.RELIABLE,
+            durability = rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL,
+            history = rclpy.qos.HistoryPolicy.KEEP_LAST,
+            depth = 1)
+
+#        self.sub_base_odom = self.create_subscription(Odometry, f"{self._ns}platform/odometry", self.callback_base_odom, qos_prof)
+        # self.sub_amcl = self.create_subscription(PoseWithCovarianceStamped, '/amcl_pose', self.pose_callback, qos_prof)
+
+        # this qos is incompatible
+        #self.sub_joint_states = self.create_subscription(JointState, f"{self._ns}/joint_states", self.callback_arms_state, qos_prof)
+
+        qos_prof2 = rclpy.qos.QoSProfile(
+        #    reliability=rclpy.qos.QoSReliabilityPolicy.RELIABLE,
+        #    durability = rclpy.qos.DurabilityPolicy.TRANSIENT_LOCAL,
+        #    history = rclpy.qos.HistoryPolicy.KEEP_LAST,
+            depth = 1)
+        self.sub_joint_states = self.create_subscription(JointState, f"{self._ns}/joint_states", self.callback_arms_state, qos_prof2)
+
 
 
+##########
+# base is a twist which is constructed from the first 3 msg.velocities
+# 0 -> twist.linear.x
+# 1 -> twist.linear.y 
+# 2 -> twist.angular.z
+# left arm indeces are 15-21 (last included)
+# right arm indeces are 22-28 (last included)
+
+    def send_cmd(self):
+        breakFlag = self.loop_manager.run_one_iter(0)
+        #msg = self.empty_msg
+        #msg.header.stamp = self.get_clock().now().to_msg()
+        #msg.velocity[0] = self._A * np.sin(2 * np.pi / self._T * self._t)
+        #msg.velocity[1] = self._A * np.sin(2 * np.pi / self._T * self._t)
+        #msg.velocity[2] = self._A * np.sin(2 * np.pi / self._T * self._t)
+        #self._cmd_pub.publish(msg)
+        #self._t += self._dt
+
+
+    def callback_base_odom(self, msg : Odometry):
+        self.robot_manager.v_q[0] = msg.twist.twist.linear.x
+        self.robot_manager.v_q[1] = msg.twist.twist.linear.y
+        # TODO: check that z can be used as cos(theta) and w as sin(theta)
+        # (they could be defined some other way or theta could be offset of something)
+        self.robot_manager.v_q[2] = msg.twist.twist.angular.z
+        self.robot_manager.v_q[3] = 0  # for consistency
+        print("received /odom")
+
+    def callback_arms_state(self, msg : JointState):
+        self.robot_manager.q[0] = 0.0
+        self.robot_manager.q[1] = 0.0
+        self.robot_manager.q[2] = 1.0
+        self.robot_manager.q[3] = 0.0
+        self.robot_manager.q[-14:-7] = msg.position[-14:-7]
+        self.robot_manager.q[-7:] = msg.position[-7:]
+        self.get_logger().info('jebem ti mamu')
+
+
+#def main(args=None):
 def main(args=None):
+    # evil and makes args unusable but what can you do
+    args_smc = get_args()
+    #print(args_smc)
     rclpy.init(args=args)
+
+    robot = RobotManager(args_smc)
+# you can't do terminal input with ros
+    #goal = robot.defineGoalPointCLI()
+    goal = pin.SE3.Identity()
+    goal.translation = np.array([0.3,0.0,0.5])
+    if robot.robot_name == "yumi":
+        goal.rotation = np.eye(3)
+        goal_transform = pin.SE3.Identity()
+        goal_transform.translation[1] = 0.1
+        goal_left = goal_transform.act(goal)
+        goal_left = goal_transform.inverse().act(goal)
+#        goal = (goal_left, goal_right)
+    #loop_manager = CrocoIKMPC(args, robot, goal, run=False)
+    loop_manager = moveLDualArm(args_smc, robot, goal, goal_transform, run=False)
+
+
     executor = MultiThreadedExecutor()
-    node = DummyNode()
+    node = DummyNode(args, robot, loop_manager)
     executor.add_node(node)
     executor.spin()
 
diff --git a/python/examples/smc_yumi_challenge.py b/python/examples/smc_yumi_challenge.py
index 2af6a7c911be229f85c081adbf7beb389e99b317..d317f054684711ea3b6c5fc43c66bd25abada0d3 100644
--- a/python/examples/smc_yumi_challenge.py
+++ b/python/examples/smc_yumi_challenge.py
@@ -188,10 +188,3 @@ def main(args=None):
 
 if __name__ == "__main__":
     main()
-
-
-
-
-
-
-
diff --git a/python/ur_simple_control/.managers.py.swp b/python/ur_simple_control/.managers.py.swp
index d0587e1010aa996ade5bcbe92c010aa75a4c6838..e7d74c6d65fcc80968d7fb50b836b82eb7e3379c 100644
Binary files a/python/ur_simple_control/.managers.py.swp and b/python/ur_simple_control/.managers.py.swp differ
diff --git a/python/ur_simple_control/__pycache__/managers.cpython-310.pyc b/python/ur_simple_control/__pycache__/managers.cpython-310.pyc
index 8344427e05627676833671090b0d83c03dc1c605..1600e6db912b8abfba2f23fb2dcc1c45018cf938 100644
Binary files a/python/ur_simple_control/__pycache__/managers.cpython-310.pyc and b/python/ur_simple_control/__pycache__/managers.cpython-310.pyc differ
diff --git a/python/ur_simple_control/managers.py b/python/ur_simple_control/managers.py
index 48467bbdf32b98a0fbce034211a61f277ba5f70f..00c2447c8d0df5fa51009575d34759075b0ea940 100644
--- a/python/ur_simple_control/managers.py
+++ b/python/ur_simple_control/managers.py
@@ -32,6 +32,8 @@ import pickle
 import importlib.util
 if importlib.util.find_spec('rclpy'):
     from geometry_msgs import msg 
+    from sensor_msgs.msg import JointState
+    from rclpy.time import Time
 
 """
 general notes
@@ -934,17 +936,28 @@ class RobotManager:
                 self.q = pin.integrate(self.model, self.q, qd_cmd * self.dt)
 
         if self.robot_name == "yumi":
-            qd_cmd = np.clip(qd, -1 * self.model.velocityLimit, self.model.velocityLimit)
+            qd_cmd = np.clip(qd, -0.1 * self.model.velocityLimit, 0.1 *self.model.velocityLimit)
             self.v_q = qd_cmd
-            if self.args.pinocchio_only:
-                self.q = pin.integrate(self.model, self.q, qd_cmd * self.dt)
-            else:
-                qd_base = qd[:3]
-                qd_left = qd[3:10]
-                qd_right = qd[10:]
-                self.publisher_vel_base(qd_base)
-                self.publisher_vel_left(qd_left)
-                self.publisher_vel_right(qd_right)
+        #    if self.args.pinocchio_only:
+        #        self.q = pin.integrate(self.model, self.q, qd_cmd * self.dt)
+        #    else:
+        #        qd_base = qd[:3]
+        #        qd_left = qd[3:10]
+        #        qd_right = qd[10:]
+        #        self.publisher_vel_base(qd_base)
+        #        self.publisher_vel_left(qd_left)
+        #        self.publisher_vel_right(qd_right)
+            empty_msg = JointState()
+            for i in range(29):
+                empty_msg.velocity.append(0.0)
+            msg = empty_msg
+            msg.header.stamp = Time().to_msg()
+            for i in range(3):
+                msg.velocity[i] = qd_cmd[i] 
+            for i in range(15, 30):
+                msg.velocity[i] = qd_cmd[i - 12] 
+
+            self.publisher_joints_cmd.publish(msg)
 
             
 
@@ -1091,6 +1104,11 @@ class RobotManager:
     def set_publisher_vel_right(self, publisher_vel_right):
         self.publisher_vel_right = publisher_vel_right
         print("set vel_right_publisher into robotmanager")
+    
+    def set_publisher_joints_cmd(self, publisher_joints_cmd):
+        self.publisher_joints_cmd = publisher_joints_cmd
+        print("set publisher_joints_cmd into RobotManager")
+
 
 
 class ProcessManager:
diff --git a/python/ur_simple_control/robot_descriptions/urdf/__pycache__/__init__.cpython-310.pyc b/python/ur_simple_control/robot_descriptions/urdf/__pycache__/__init__.cpython-310.pyc
index b21ae860d8993fbb7c2b56d3cb77e67b296b9dff..90610d17abec485ff327a863a03e55b8bc09ef3f 100644
Binary files a/python/ur_simple_control/robot_descriptions/urdf/__pycache__/__init__.cpython-310.pyc and b/python/ur_simple_control/robot_descriptions/urdf/__pycache__/__init__.cpython-310.pyc differ