diff --git a/examples/optimal_control/dual_arm_ik_mpc.py b/examples/optimal_control/dual_arm_ik_mpc.py index 7b0031825a7d33ce3723ae590450d5d6dee56b1f..82a3cc27a7b348efc16945186a6dda93f156a528 100644 --- a/examples/optimal_control/dual_arm_ik_mpc.py +++ b/examples/optimal_control/dual_arm_ik_mpc.py @@ -21,7 +21,7 @@ def get_args(): if __name__ == "__main__": args = get_args() robot = getRobotFromArgs(args) - T_w_goal = getRandomlyGeneratedGoal(args) + T_w_absgoal = getRandomlyGeneratedGoal(args) T_absgoal_lgoal = pin.SE3.Identity() T_absgoal_lgoal.translation[1] = 0.1 T_absgoal_rgoal = pin.SE3.Identity() @@ -29,9 +29,9 @@ if __name__ == "__main__": if args.visualizer: # TODO: document this somewhere - robot.visualizer_manager.sendCommand({"Mgoal": T_w_goal}) + robot.visualizer_manager.sendCommand({"Mgoal": T_w_absgoal}) - CrocoDualEEP2PMPC(args, robot, T_w_goal) + CrocoDualEEP2PMPC(args, robot, T_w_absgoal, T_absgoal_lgoal, T_absgoal_rgoal) if args.real: robot.stopRobot() diff --git a/python/smc/control/optimal_control/abstract_croco_ocp.py b/python/smc/control/optimal_control/abstract_croco_ocp.py index e2551af9dd86faa346d107d208d10fe1492a943b..26127244403d396c6cbb99b8441428bab036295d 100644 --- a/python/smc/control/optimal_control/abstract_croco_ocp.py +++ b/python/smc/control/optimal_control/abstract_croco_ocp.py @@ -1,4 +1,4 @@ -from smc.robots.robotmanager_abstract import AbstractRobotManager +from smc.robots.abstract_robotmanager import AbstractRobotManager import numpy as np import crocoddyl @@ -84,8 +84,12 @@ class CrocoOCP(abc.ABC): # put these costs into the running costs for i in range(self.args.n_knots): - self.runningCostModels[i].addCost("xReg", self.xRegCost, self.args.u_reg_cost) - self.runningCostModels[i].addCost("uReg", self.uRegCost, self.args.x_reg_cost) + self.runningCostModels[i].addCost( + "xReg", self.xRegCost, self.args.u_reg_cost + ) + self.runningCostModels[i].addCost( + "uReg", self.uRegCost, self.args.x_reg_cost + ) # and add the terminal cost, which is the distance to the goal # NOTE: shouldn't there be a final velocity = 0 here? # --> no if you're not stopping at the last knot! @@ -123,12 +127,7 @@ class CrocoOCP(abc.ABC): # TODO: replace this with subclass or whatever call # to check if the robot has mobilebase interface - if ( - self.robot.robot_name == "heron" - or self.robot.robot_name == "heronros" - or self.robot.robot_name == "mirros" - or self.robot.robot_name == "yumi" - ): + if self.robot.robot_name == "heron" or self.robot.robot_name == "myumi": self.xlb = self.xlb[1:] self.xub = self.xub[1:] diff --git a/python/smc/control/optimal_control/croco_mpc_path_following.py b/python/smc/control/optimal_control/croco_mpc_path_following.py index c2aa9cf6b1fddd7c02fd6e3cbf3776c76e5e4406..5e0fb60542795bc809249e236dd44f2438c33e56 100644 --- a/python/smc/control/optimal_control/croco_mpc_path_following.py +++ b/python/smc/control/optimal_control/croco_mpc_path_following.py @@ -393,7 +393,6 @@ def BaseAndEEPathFollowingMPC( # TODO: the robot put in is a whole body robot, # which you need to implement -THIS IS THE STILL BROKEN ONE def BaseAndDualArmEEPathFollowingMPCControlLoop( args, robot, @@ -413,6 +412,7 @@ def BaseAndDualArmEEPathFollowingMPCControlLoop( or an instance of ProcessManager which spits out path points by calling ProcessManager.getData() """ + raise NotImplementedError breakFlag = False log_item = {} save_past_dict = {} @@ -530,7 +530,6 @@ def BaseAndDualArmEEPathFollowingMPCControlLoop( return breakFlag, save_past_dict, log_item -NOT TEMPLETIZED YET def BaseAndDualArmEEPathFollowingMPC(args, robot, path_planner): """ CrocoEndEffectorPathFollowingMPC @@ -540,7 +539,7 @@ def BaseAndDualArmEEPathFollowingMPC(args, robot, path_planner): a dynamics level, and velocities we command are actually extracted from the state x(q,dq). """ - + raise NotImplementedError("this has to be templetized like the previous cases") x0 = np.concatenate([robot.q, robot.v]) ocp = BaseAndDualArmEEPathFollowingOCP(args, robot, x0) ocp.solveInitialOCP(x0) diff --git a/python/smc/control/optimal_control/croco_mpc_point_to_point.py b/python/smc/control/optimal_control/croco_mpc_point_to_point.py index 8d4b489135c644568645d468fbe27ca512a1ba1b..d79472566a2f9bdeda9e74dc0cac8c9fe218fcc1 100644 --- a/python/smc/control/optimal_control/croco_mpc_point_to_point.py +++ b/python/smc/control/optimal_control/croco_mpc_point_to_point.py @@ -121,7 +121,10 @@ def CrocoDualEEP2PMPC( are actually extracted from the state x(q,dq) """ x0 = np.concatenate([robot.q, robot.v]) - ocp = DualArmIKOCP(args, robot, x0, T_w_absgoal) + T_w_lgoal = T_absgoal_l.act(T_w_absgoal) + T_w_rgoal = T_absgoal_r.act(T_w_absgoal) + + ocp = DualArmIKOCP(args, robot, x0, (T_w_lgoal, T_w_rgoal)) ocp.solveInitialOCP(x0) controlLoop = partial( @@ -136,9 +139,10 @@ def CrocoDualEEP2PMPC( ) log_item = { "qs": np.zeros(robot.nq), - "err_norm": np.zeros(1), "dqs": np.zeros(robot.nv), "dqs_cmd": np.zeros(robot.nv), + "l_err_norm": np.zeros(1), + "r_err_norm": np.zeros(1), } save_past_dict = {} loop_manager = ControlLoopManager( diff --git a/python/smc/control/optimal_control/path_following_croco_ocp.py b/python/smc/control/optimal_control/path_following_croco_ocp.py index d91b9794979d3a499296b19881dca6469adf210b..698bf71ea0b5b8c25d157c6c1739199bc5bbee1f 100644 --- a/python/smc/control/optimal_control/path_following_croco_ocp.py +++ b/python/smc/control/optimal_control/path_following_croco_ocp.py @@ -2,7 +2,10 @@ from smc.control.optimal_control.abstract_croco_ocp import CrocoOCP from smc.robots.interfaces.mobile_base_interface import MobileBaseInterface from smc.robots.interfaces.single_arm_interface import SingleArmInterface from smc.robots.interfaces.dual_arm_interface import DualArmInterface -from smc.robots.interfaces.whole_body_interface import SingleArmWholeBodyInterface, DualArmWholeBodyInterface +from smc.robots.interfaces.whole_body_interface import ( + SingleArmWholeBodyInterface, + DualArmWholeBodyInterface, +) import numpy as np import crocoddyl @@ -178,8 +181,12 @@ class BaseAndEEPathFollowingOCP(CrocoOCP): ].cost.residual.reference = pathSE3[-1] +class DualArmEEPathFollowingOCP(CrocoOCP): + def __init__(self, args, robot: DualArmInterface, x0): + goal = None + raise NotImplementedError + super().__init__(args, robot, x0, goal) -JUST THE DUAL ARM IS MISSING class BaseAndDualArmEEPathFollowingOCP(CrocoOCP): def __init__(self, args, robot: DualArmWholeBodyInterface, x0): diff --git a/python/smc/control/optimal_control/point_to_point_croco_ocp.py b/python/smc/control/optimal_control/point_to_point_croco_ocp.py index d4042997061d0f567150e23d0daa17737740cf5e..1b9625dc447bb6e835c8919bf14357e8e0fb0216 100644 --- a/python/smc/control/optimal_control/point_to_point_croco_ocp.py +++ b/python/smc/control/optimal_control/point_to_point_croco_ocp.py @@ -33,15 +33,17 @@ class SingleArmIKOCP(CrocoOCP): goalTrackingCost = crocoddyl.CostModelResidual( self.state, framePlacementResidual ) - frameVelocityResidual = crocoddyl.ResidualModelFrameVelocity( - self.state, - self.robot.ee_frame_id, - pin.Motion(np.zeros(6)), - pin.ReferenceFrame.WORLD, - ) - frameVelocityCost = crocoddyl.CostModelResidual( - self.state, frameVelocityResidual - ) + # TODO: final velocity costs only make sense if you're running a single ocp, but not mpc!! + # TODO: have an argument or something to include or not include them! + # frameVelocityResidual = crocoddyl.ResidualModelFrameVelocity( + # self.state, + # self.robot.ee_frame_id, + # pin.Motion(np.zeros(6)), + # pin.ReferenceFrame.WORLD, + # ) + # frameVelocityCost = crocoddyl.CostModelResidual( + # self.state, frameVelocityResidual + # ) for i in range(self.args.n_knots): self.runningCostModels[i].addCost( "gripperPose" + str(i), goalTrackingCost, 1e2 @@ -49,7 +51,7 @@ class SingleArmIKOCP(CrocoOCP): self.terminalCostModel.addCost( "gripperPose" + str(self.args.n_knots), goalTrackingCost, 1e2 ) - self.terminalCostModel.addCost("velFinal", frameVelocityCost, 1e3) + # self.terminalCostModel.addCost("velFinal", frameVelocityCost, 1e3) # there is nothing to update in a point-to-point task def updateCosts(self, data): @@ -76,13 +78,13 @@ class DualArmIKOCP(CrocoOCP): T_w_lgoal, T_w_rgoal = goal framePlacementResidual_l = crocoddyl.ResidualModelFramePlacement( self.state, - self.robot.model.l_ee_frame_id, + self.robot.l_ee_frame_id, T_w_lgoal.copy(), self.state.nv, ) framePlacementResidual_r = crocoddyl.ResidualModelFramePlacement( self.state, - self.robot.model.r_ee_frame_id, + self.robot.r_ee_frame_id, T_w_rgoal.copy(), self.state.nv, ) @@ -92,24 +94,27 @@ class DualArmIKOCP(CrocoOCP): goalTrackingCost_r = crocoddyl.CostModelResidual( self.state, framePlacementResidual_r ) - frameVelocityResidual_l = crocoddyl.ResidualModelFrameVelocity( - self.state, - self.robot.model.l_ee_frame_id, - pin.Motion(np.zeros(6)), - pin.ReferenceFrame.WORLD, - ) - frameVelocityResidual_r = crocoddyl.ResidualModelFrameVelocity( - self.state, - self.robot.model.r_ee_frame_id, - pin.Motion(np.zeros(6)), - pin.ReferenceFrame.WORLD, - ) - frameVelocityCost_l = crocoddyl.CostModelResidual( - self.state, frameVelocityResidual_l - ) - frameVelocityCost_r = crocoddyl.CostModelResidual( - self.state, frameVelocityResidual_r - ) + # TODO: final velocity costs only make sense if you're running a single ocp, but not mpc!! + # TODO: have an argument or something to include or not include them! + + # frameVelocityCost_l = crocoddyl.CostModelResidual( + # self.state, frameVelocityResidual_l + # frameVelocityResidual_l = crocoddyl.ResidualModelFrameVelocity( + # self.state, + # self.robot.l_ee_frame_id, + # pin.Motion(np.zeros(6)), + # pin.ReferenceFrame.WORLD, + # ) + # frameVelocityResidual_r = crocoddyl.ResidualModelFrameVelocity( + # self.state, + # self.robot.r_ee_frame_id, + # pin.Motion(np.zeros(6)), + # pin.ReferenceFrame.WORLD, + # ) + # ) + # frameVelocityCost_r = crocoddyl.CostModelResidual( + # self.state, frameVelocityResidual_r + # ) for i in range(self.args.n_knots): self.runningCostModels[i].addCost( "gripperPose_l" + str(i), goalTrackingCost_l, 1e2 @@ -123,8 +128,8 @@ class DualArmIKOCP(CrocoOCP): self.terminalCostModel.addCost( "gripperPose_r" + str(self.args.n_knots), goalTrackingCost_r, 1e2 ) - self.terminalCostModel.addCost("velFinal_l", frameVelocityCost_l, 1e3) - self.terminalCostModel.addCost("velFinal_r", frameVelocityCost_r, 1e3) + # self.terminalCostModel.addCost("velFinal_l", frameVelocityCost_l, 1e3) + # self.terminalCostModel.addCost("velFinal_r", frameVelocityCost_r, 1e3) # there is nothing to update in a point-to-point task def updateCosts(self, data):