From db79e1621b28d567102c2037a41e1d9503c0765e Mon Sep 17 00:00:00 2001 From: thomascbrs <thomas.corberes@laposte.net> Date: Wed, 18 Aug 2021 17:24:37 +0100 Subject: [PATCH] New set of gains for MPCs (for h_ref), new velocities tests in joystick, scripts to eval RMSE, small fix in control cycle eval scripts --- scripts/Joystick.py | 77 ++-- scripts/crocoddyl_class/MPC_crocoddyl.py | 8 +- .../crocoddyl_class/MPC_crocoddyl_planner.py | 14 +- .../test_1/analyse_control_cycle.py | 18 +- .../test_3/analyse_control_cycle.py | 25 +- .../crocoddyl_eval/test_6/analyse_slalom.py | 338 ++++++++++++++++++ 6 files changed, 416 insertions(+), 64 deletions(-) create mode 100644 scripts/crocoddyl_eval/test_6/analyse_slalom.py diff --git a/scripts/Joystick.py b/scripts/Joystick.py index f12592fd..32fec77b 100644 --- a/scripts/Joystick.py +++ b/scripts/Joystick.py @@ -201,46 +201,45 @@ class Joystick: 0.0, 0.0, 0.0, 0.0, R_max, R_max, 0.0, 0.0, -R_max, 0.0]) elif velID == 2: - self.t_switch = np.array([0, 5, 8, 10, 12]) - self.v_switch = np.array([[0.0, 0.8, 0.8, 0.8, 0.8 ], - [0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0., 1., 0., -1. ]]) - elif velID == 3: - self.t_switch = np.array([0, 2, 6, 8, 12, 60]) - self.v_switch = np.array([[0.0, 0.0, 0.4, 0.4, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]) - elif velID == 4: - self.t_switch = np.array([0, 2, 6, 14, 18, 60]) - self.v_switch = np.array([[0.0, 0.0, 1.5, 1.5, 1.5, 1.5], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.4, 0.4]]) - elif velID == 5: - self.t_switch = np.array([0, 1, 3, 5.2, 10, 13, 14, 16, 18]) - self.v_switch = np.array([[0.0, 0.0, 0.5, 0.6, 0.3, 0.6, -0.5, 0.7, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.2, 0.7, 0.7, 0.0, -0.4, -0.6, 0.0]]) + self.t_switch = np.array([0, 3, 4, 5, 10,15]) + self.v_switch = np.array([[0.0, 0.6, 0.6, 0.6, 0., 0. ], + [0.0, 0.0, 0.0, 0.0, 0.5, 0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0., 0.4, -0.4, 0. ,0.]]) + elif velID == 3: # PLANNER > NL > LIN + self.t_switch = np.array([0, 3, 4, 5, 10,15]) + self.v_switch = np.array([[0.0, 0., 0., 0., 0., 0. ], + [0.0, 0.0, 0.0, 0.0, 0., 0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.8, 1.5, 1.8, 2.5 ,2.8]]) + elif velID == 4: # PLANNER > NL == LIN + self.t_switch = np.array([0, 3, 4, 5, 10,15]) + self.v_switch = np.array([[0.0, 0.4, 0.6, 0.6, 0., 0. ], + [0.0, 0.4, 0.6, 0.6, 0.6 ,0.6], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.5, 0.5 ,0.5]]) + elif velID == 5: # PLANNER GOOD ROLL / PITCH + self.t_switch = np.array([0, 3, 4, 5, 10,15]) + self.v_switch = np.array([[0.0, 0.4, 0.4, 0.4, 0.4, 0. ], + [0.0, 0.4, 0.4, 0.4, 0. ,0.4], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.7, 0.7 ,0.7]]) elif velID == 6: - self.t_switch = np.array([0, 2, 5, 10, 15, 16, 20]) - self.v_switch = np.array([[0.0, 0.0, 0.8, 0.4, 0.8, 0.8, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 0.55, 0.3, 0.0, 0.0]]) - + self.t_switch = np.array([0, 3, 4, 5, 10,15]) + self.v_switch = np.array([[0.0, 0.4, 0.5, 0.6, 0.6, 0.6 ], + [0.0, 0., 0., 0., 0. ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0.0, 0.0 ,0.], + [0.0, 0.0, 0.0, 0., 0. ,0.]]) self.k_switch = (self.t_switch / self.dt_wbc).astype(int) self.handle_v_switch(k_loop) return 0 diff --git a/scripts/crocoddyl_class/MPC_crocoddyl.py b/scripts/crocoddyl_class/MPC_crocoddyl.py index 346a2f49..c478763b 100644 --- a/scripts/crocoddyl_class/MPC_crocoddyl.py +++ b/scripts/crocoddyl_class/MPC_crocoddyl.py @@ -35,7 +35,7 @@ class MPC_crocoddyl: # Weights on the state vector self.w_x = 0.3 self.w_y = 0.3 - self.w_z = 2 + self.w_z = 20 self.w_roll = 0.9 self.w_pitch = 1. self.w_yaw = 0.4 @@ -44,20 +44,20 @@ class MPC_crocoddyl: self.w_vz = 2*np.sqrt(self.w_z) self.w_vroll = 0.05*np.sqrt(self.w_roll) self.w_vpitch = 0.07*np.sqrt(self.w_pitch) - self.w_vyaw = 0.05*np.sqrt(self.w_yaw) + self.w_vyaw = 0.08*np.sqrt(self.w_yaw) self.stateWeights = np.array([self.w_x, self.w_y, self.w_z, self.w_roll, self.w_pitch, self.w_yaw, self.w_vx, self.w_vy, self.w_vz, self.w_vroll, self.w_vpitch, self.w_vyaw]) - self.forceWeights = np.array(4*[0.007, 0.007, 0.007]) # Weight Vector : Force Norm + self.forceWeights = 1*np.array(4*[0.007, 0.007, 0.007]) # Weight Vector : Force Norm self.frictionWeights = 1.0 # Weight Vector : Friction cone cost self.min_fz = 0.2 # Minimum normal force (N) self.max_fz = 25 # Maximum normal force (N) self.shoulderWeights = 5. # Weight on the shoulder term : - self.shoulder_hlim = 0.23 # shoulder maximum height + self.shoulder_hlim = 0.235 # shoulder maximum height # Integration scheme self.implicit_integration = True diff --git a/scripts/crocoddyl_class/MPC_crocoddyl_planner.py b/scripts/crocoddyl_class/MPC_crocoddyl_planner.py index de68d695..8356cb8a 100644 --- a/scripts/crocoddyl_class/MPC_crocoddyl_planner.py +++ b/scripts/crocoddyl_class/MPC_crocoddyl_planner.py @@ -31,29 +31,29 @@ class MPC_crocoddyl_planner(): else: self.mu = mu - # self.stateWeight = np.sqrt([2.0, 2.0, 20.0, 0.25, 0.25, 0.25, 0.2, 0.2, 5., 0.0, 0.0, 0.3]) + # self.stateWeight = np.sqrt([0., 0., 20.0, 1., 1., 0., 0.5, 0.5, 0., 0.0, 0.0, 0.5]) # Weights Vector : States self.w_x = 0.3 self.w_y = 0.3 - self.w_z = 2 + self.w_z = 20 self.w_roll = 0.9 self.w_pitch = 1. - self.w_yaw = 0.4 + self.w_yaw = 0.5 self.w_vx = 1.5*np.sqrt(self.w_x) self.w_vy = 2*np.sqrt(self.w_y) self.w_vz = 1*np.sqrt(self.w_z) self.w_vroll = 0.05*np.sqrt(self.w_roll) self.w_vpitch = 0.07*np.sqrt(self.w_pitch) - self.w_vyaw = 0.05*np.sqrt(self.w_yaw) + self.w_vyaw = 0.08*np.sqrt(self.w_yaw) self.stateWeights = np.array([self.w_x, self.w_y, self.w_z, self.w_roll, self.w_pitch, self.w_yaw, self.w_vx, self.w_vy, self.w_vz, self.w_vroll, self.w_vpitch, self.w_vyaw]) - self.forceWeights = 2*np.array(4*[0.01, 0.01, 0.01]) # Weight Vector : Force Norm + self.forceWeights = 1*np.array(4*[0.007, 0.007, 0.007]) # Weight Vector : Force Norm self.frictionWeights = 1. # Weight Vector : Friction cone cost - self.heuristicWeights = np.array(4*[0.3, 0.4]) # Weights on the heuristic term + self.heuristicWeights = np.array(4*[0.03, 0.04]) # Weights on the heuristic term self.stepWeights = np.full(8, 0.005) # Weight on the step command (distance between steps) - self.stopWeights = 2.5*np.ones(8) # Weights to stop the optimisation at the end of the flying phase + self.stopWeights = 2.*np.ones(8) # Weights to stop the optimisation at the end of the flying phase self.shoulderContactWeight = 5. # Weight for shoulder-to-contact penalty self.shoulder_hlim = 0.235 diff --git a/scripts/crocoddyl_eval/test_1/analyse_control_cycle.py b/scripts/crocoddyl_eval/test_1/analyse_control_cycle.py index 8068739f..1a551658 100644 --- a/scripts/crocoddyl_eval/test_1/analyse_control_cycle.py +++ b/scripts/crocoddyl_eval/test_1/analyse_control_cycle.py @@ -15,7 +15,7 @@ import utils_mpc ############## # Parameters ############## -iteration_mpc = 250 # Control cycle +iteration_mpc = 2 # Control cycle Relaunch_DDP = True # Compare a third MPC with != parameters linear_mpc = True params = lqrw.Params() # Object that holds all controller parameters @@ -29,7 +29,7 @@ solo = utils_mpc.init_robot(q_init, params) ###################### # Recover Logged data ###################### -file_name = "crocoddyl_eval/logs/new_controller_test1.npz" +file_name = "crocoddyl_eval/logs/chute_mpc_nl_noShoulder.npz" logs = np.load(file_name) planner_gait = logs.get("planner_gait") planner_xref = logs.get("planner_xref") @@ -42,14 +42,14 @@ k = int( iteration_mpc * (params.dt_mpc / params.dt_wbc) ) # simulation iteratio mpc_osqp = lqrw.MPC(params) mpc_osqp.run(0, planner_xref[0] , planner_fsteps[0]) # Initialization of the matrix # mpc_osqp.run(1, planner_xref[1] , planner_fsteps[1]) -mpc_osqp.run(k, planner_xref[k] , planner_fsteps[k]) +# mpc_osqp.run(k, planner_xref[k] , planner_fsteps[k]) osqp_xs = mpc_osqp.get_latest_result()[:12,:] # States computed over the whole predicted horizon osqp_xs = np.vstack([planner_xref[k,:,0] , osqp_xs.transpose()]).transpose() # Add current state osqp_us = mpc_osqp.get_latest_result()[12:,:] # Forces computed over the whole predicted horizon # DDP MPC -mpc_ddp = MPC_crocoddyl.MPC_crocoddyl(params, mu=0.9, inner=False, linearModel=True) +mpc_ddp = MPC_crocoddyl.MPC_crocoddyl(params, mu=0.9, inner=False, linearModel=False) # Without warm-start : # mpc_ddp.warm_start = False # mpc_ddp.solve(k, planner_xref[k] , planner_fsteps[k] ) # Without warm-start @@ -90,7 +90,8 @@ ddp_us = mpc_ddp.get_latest_result()[12:,:] # Forces computed over the whole pre ###################################### mpc_ddp_2 = MPC_crocoddyl.MPC_crocoddyl(params, mu=0.9, inner=False , linearModel=False) # To modify the linear model if wanted, recreate a list with proper model - +mpc_ddp_2.implicit_integration = False +mpc_ddp_2.shoulderWeights = 0. # Weight Vector : State # w_x = 0.2 # w_y = 0.2 @@ -107,7 +108,7 @@ mpc_ddp_2 = MPC_crocoddyl.MPC_crocoddyl(params, mu=0.9, inner=False , linearMod # mpc_ddp.stateWeight = np.array([w_x,w_y,w_z,w_roll,w_pitch,w_yaw, # w_vx,w_vy,w_vz,w_vroll,w_vpitch,w_vyaw]) # OSQP values, in ddp formulation, terms are put in square -mpc_ddp_2.stateWeight = np.sqrt([2.0, 2.0, 20.0, 0.25, 0.25, 10.0, 0.2, 0.2, 0.2, 0.0, 0.0, 0.3]) +# mpc_ddp_2.stateWeight = np.sqrt([2.0, 2.0, 20.0, 0.25, 0.25, 10.0, 0.2, 0.2, 0.2, 0.0, 0.0, 0.3]) # Friction coefficient # mpc_ddp_2.mu = 0.9 @@ -136,8 +137,9 @@ mpc_ddp_2.stateWeight = np.sqrt([2.0, 2.0, 20.0, 0.25, 0.25, 10.0, 0.2, 0.2, 0.2 # mpc_ddp_2.relative_forces = False # Update weights and params inside the models -# mpc_ddp_2.updateActionModel() - +mpc_ddp_2.updateActionModels() +mpc_ddp_2.problem = crocoddyl.ShootingProblem(np.zeros(12), mpc_ddp_2.ListAction, mpc_ddp_2.terminalModel) +mpc_ddp_2.ddp = crocoddyl.SolverDDP(mpc_ddp_2.problem) # Run ddp solver # Update the dynamic depending on the predicted feet position if Relaunch_DDP : diff --git a/scripts/crocoddyl_eval/test_3/analyse_control_cycle.py b/scripts/crocoddyl_eval/test_3/analyse_control_cycle.py index 9dbcac1b..a3d77924 100644 --- a/scripts/crocoddyl_eval/test_3/analyse_control_cycle.py +++ b/scripts/crocoddyl_eval/test_3/analyse_control_cycle.py @@ -10,19 +10,27 @@ import matplotlib.pylab as plt import libquadruped_reactive_walking as lqrw import crocoddyl_class.MPC_crocoddyl_planner as MPC_crocoddyl_planner import time +import utils_mpc + ############## # Parameters ############## -iteration_mpc = 62 # Control cycle +iteration_mpc = 45 # Control cycle Relaunch_DDP = False # Compare a third MPC with != parameters linear_mpc = True params = lqrw.Params() # Object that holds all controller parameters +# Default position after calibration +q_init = np.array(params.q_init.tolist()) + +# Update I_mat, etc... +solo = utils_mpc.init_robot(q_init, params) + ###################### # Recover Logged data ###################### -file_name = "crocoddyl_eval/logs/data_2021_07_12_09_25.npz" +file_name = "crocoddyl_eval/logs/data_2021_08_18_13_23.npz" logs = np.load(file_name) planner_gait = logs.get("planner_gait") planner_xref = logs.get("planner_xref") @@ -55,17 +63,22 @@ mpc_ddp = MPC_crocoddyl_planner.MPC_crocoddyl_planner(params, mu=0.9, inner=Fals mpc_ddp.heuristicWeights = np.array(4*[0.3, 0.4]) mpc_ddp.stepWeights = np.full(8, 0.5) mpc_ddp.stateWeights = np.sqrt([2.0, 2.0, 20.0, 0.25, 0.25, 10.0, 0.2, 0.2, 0.2, 0.0, 0.0, 0.3]) # fit osqp gains -mpc_ddp.initializeModels(params) # re-initialize the model list with the new gains +mpc_ddp.initialize_models(params) # re-initialize the model list with the new gains mpc_ddp.gait = planner_gait[k_previous].copy() # gait_old will be initialised with that + +print(mpc_ddp.gait) mpc_ddp.updateProblem(k , planner_xref[k] , planner_fsteps[k], planner_goals[k]) mpc_ddp.ddp.solve(mpc_ddp.x_init, mpc_ddp.u_init, mpc_ddp.max_iteration) -ddp_xs = mpc_ddp.get_latest_result()[:12,:] # States computed over the whole predicted horizon +oRh = np.eye(3) +oTh = np.zeros((3,1)) + +ddp_xs = mpc_ddp.get_latest_result(oRh, oTh)[:12,:] # States computed over the whole predicted horizon ddp_xs = np.vstack([planner_xref[k,:,0] , ddp_xs.transpose()]).transpose() # Add current state -ddp_us = mpc_ddp.get_latest_result()[12:,:] # Forces computed over the whole predicted horizon -ddp_fsteps = mpc_ddp.get_latest_result()[24:,:] +ddp_us = mpc_ddp.get_latest_result(oRh, oTh)[12:,:] # Forces computed over the whole predicted horizon +ddp_fsteps = mpc_ddp.get_latest_result(oRh, oTh)[24:,:] ddp_fsteps = np.vstack([planner_fsteps[k,0,:][[0,1,3,4,6,7,9,10]] , ddp_fsteps.transpose()]).transpose() # Add current state diff --git a/scripts/crocoddyl_eval/test_6/analyse_slalom.py b/scripts/crocoddyl_eval/test_6/analyse_slalom.py new file mode 100644 index 00000000..bc47ff5a --- /dev/null +++ b/scripts/crocoddyl_eval/test_6/analyse_slalom.py @@ -0,0 +1,338 @@ +# coding: utf8 + +import sys +import os +from sys import argv +sys.path.insert(0, os.getcwd()) # adds current directory to python path + +import numpy as np +import matplotlib.pylab as plt +import pinocchio as pin +import libquadruped_reactive_walking as lqrw + + +###################### +# Recover Logged data, mpc lin +###################### +file_name = "crocoddyl_eval/logs/vel6/data_lin_vel6.npz" +logs = np.load(file_name) + + +# Common data + +joy_v_ref = logs.get('joy_v_ref') +planner_xref = logs.get("planner_xref") + + + +mocapPosition = logs.get("mocapPosition") +mocapOrientationQuat = logs.get("mocapOrientationQuat") +mocapOrientationMat9 = logs.get("mocapOrientationMat9") +mocapVelocity = logs.get("mocapVelocity") +mocapAngularVelocity = logs.get('mocapAngularVelocity') + +params = lqrw.Params() # Object that holds all controller parameters + + +N = mocapPosition.shape[0] + +mocap_pos_mpc_lin = np.zeros([N, 3]) +mocap_h_v_mpc_lin = np.zeros([N, 3]) +mocap_b_w_mpc_lin = np.zeros([N, 3]) +mocap_RPY_mpc_lin = np.zeros([N, 3]) + +for i in range(N): + mocap_RPY_mpc_lin[i] = pin.rpy.matrixToRpy(pin.Quaternion(mocapOrientationQuat[i]).toRotationMatrix()) + +# Robot world to Mocap initial translationa and rotation +mTo = np.array([mocapPosition[0, 0], mocapPosition[0, 1], 0.02]) +mRo = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_lin[0, 2]) + +for i in range(N): + oRb = mocapOrientationMat9[i] + + oRh = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_lin[i, 2] - mocap_RPY_mpc_lin[0, 2]) + + mocap_h_v_mpc_lin[i] = (oRh.transpose() @ mRo.transpose() @ mocapVelocity[i].reshape((3, 1))).ravel() + mocap_b_w_mpc_lin[i] = (oRb.transpose() @ mocapAngularVelocity[i].reshape((3, 1))).ravel() + mocap_pos_mpc_lin[i] = (mRo.transpose() @ (mocapPosition[i, :] - mTo).reshape((3, 1))).ravel() + + +###################### +# Recover Logged data, mpc non linear +###################### +file_name = "crocoddyl_eval/logs/vel6/data_nl_vel6.npz" +logs = np.load(file_name) + +mocapPosition = logs.get("mocapPosition") +mocapOrientationQuat = logs.get("mocapOrientationQuat") +mocapOrientationMat9 = logs.get("mocapOrientationMat9") +mocapVelocity = logs.get("mocapVelocity") +mocapAngularVelocity = logs.get('mocapAngularVelocity') + +params = lqrw.Params() # Object that holds all controller parameters + + +N = mocapPosition.shape[0] + +mocap_pos_mpc_nl = np.zeros([N, 3]) +mocap_h_v_mpc_nl = np.zeros([N, 3]) +mocap_b_w_mpc_nl = np.zeros([N, 3]) +mocap_RPY_mpc_nl = np.zeros([N, 3]) + +for i in range(N): + mocap_RPY_mpc_nl[i] = pin.rpy.matrixToRpy(pin.Quaternion(mocapOrientationQuat[i]).toRotationMatrix()) + +# Robot world to Mocap initial translationa and rotation +mTo = np.array([mocapPosition[0, 0], mocapPosition[0, 1], 0.02]) +mRo = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_nl[0, 2]) + +for i in range(N): + oRb = mocapOrientationMat9[i] + + oRh = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_nl[i, 2] - mocap_RPY_mpc_nl[0, 2]) + + mocap_h_v_mpc_nl[i] = (oRh.transpose() @ mRo.transpose() @ mocapVelocity[i].reshape((3, 1))).ravel() + mocap_b_w_mpc_nl[i] = (oRb.transpose() @ mocapAngularVelocity[i].reshape((3, 1))).ravel() + mocap_pos_mpc_nl[i] = (mRo.transpose() @ (mocapPosition[i, :] - mTo).reshape((3, 1))).ravel() + + +###################### +# Recover Logged data, mpc planner +###################### +file_name = "crocoddyl_eval/logs/vel6/data_planner_vel6.npz" +logs = np.load(file_name) + +mocapPosition = logs.get("mocapPosition") +mocapOrientationQuat = logs.get("mocapOrientationQuat") +mocapOrientationMat9 = logs.get("mocapOrientationMat9") +mocapVelocity = logs.get("mocapVelocity") +mocapAngularVelocity = logs.get('mocapAngularVelocity') + +params = lqrw.Params() # Object that holds all controller parameters + + +N = mocapPosition.shape[0] + +mocap_pos_mpc_planner = np.zeros([N, 3]) +mocap_h_v_mpc_planner = np.zeros([N, 3]) +mocap_b_w_mpc_planner = np.zeros([N, 3]) +mocap_RPY_mpc_planner = np.zeros([N, 3]) + +for i in range(N): + mocap_RPY_mpc_planner[i] = pin.rpy.matrixToRpy(pin.Quaternion(mocapOrientationQuat[i]).toRotationMatrix()) + +# Robot world to Mocap initial translationa and rotation +mTo = np.array([mocapPosition[0, 0], mocapPosition[0, 1], 0.02]) +mRo = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_planner[0, 2]) + +for i in range(N): + oRb = mocapOrientationMat9[i] + + oRh = pin.rpy.rpyToMatrix(0.0, 0.0, mocap_RPY_mpc_planner[i, 2] - mocap_RPY_mpc_planner[0, 2]) + + mocap_h_v_mpc_planner[i] = (oRh.transpose() @ mRo.transpose() @ mocapVelocity[i].reshape((3, 1))).ravel() + mocap_b_w_mpc_planner[i] = (oRb.transpose() @ mocapAngularVelocity[i].reshape((3, 1))).ravel() + mocap_pos_mpc_planner[i] = (mRo.transpose() @ (mocapPosition[i, :] - mTo).reshape((3, 1))).ravel() + + + +lgd = ["Position X", "Position Y", "Position Z", "Position Roll", "Position Pitch", "Position Yaw"] +index6 = [1, 3, 5, 2, 4, 6] +t_range = np.array([k*params.dt_wbc for k in range(N)]) + +plt.figure() +for i in range(6): + if i == 0: + ax0 = plt.subplot(3, 2, index6[i]) + else: + plt.subplot(3, 2, index6[i], sharex=ax0) + + if i < 3: + plt.plot(t_range, mocap_pos_mpc_lin[:, i], "k", linewidth=3) + plt.plot(t_range, mocap_pos_mpc_nl[:, i], "b", linewidth=3) + plt.plot(t_range, mocap_pos_mpc_planner[:, i], "r", linewidth=3) + else: + plt.plot(t_range, mocap_RPY_mpc_lin[:, i-3], "k", linewidth=3) + plt.plot(t_range, mocap_RPY_mpc_nl[:, i-3], "b", linewidth=3) + plt.plot(t_range, mocap_RPY_mpc_planner[:, i-3], "r", linewidth=3) + + plt.legend(["MOCAP LIN", "MOCAP NL", "MOCAP PLANNER"], prop={'size': 8}) + plt.ylabel(lgd[i]) +plt.suptitle("Measured & Reference position and orientation") + +lgd = ["Linear vel X", "Linear vel Y", "Linear vel Z", + "Andiff_pos_lingular vel Roll", "Angular vel Pitch", "Angular vel Yaw"] +plt.figure() +for i in range(6): + if i == 0: + ax0 = plt.subplot(3, 2, index6[i]) + else: + plt.subplot(3, 2, index6[i], sharex=ax0) + + if i < 3: + plt.plot(t_range, mocap_h_v_mpc_lin[:, i], "k", linewidth=3) + plt.plot(t_range, mocap_h_v_mpc_nl[:, i], "b", linewidth=3) + plt.plot(t_range, mocap_h_v_mpc_planner[:, i], "r", linewidth=3) + else: + plt.plot(t_range, mocap_b_w_mpc_lin[:, i-3], "k", linewidth=3) + plt.plot(t_range, mocap_b_w_mpc_nl[:, i-3], "b", linewidth=3) + plt.plot(t_range, mocap_b_w_mpc_planner[:, i-3], "r", linewidth=3) + + """N = 2000 + y = np.convolve(self.mocap_b_w[:, i-3], np.ones(N)/N, mode='valid') + plt.plot(t_range[int(N/2)-1:-int(N/2)], y, linewidth=3, linestyle="--")""" + + # plt.plot(t_range, self.log_dq[i, :], "g", linewidth=2) + # plt.plot(t_range[:-2], self.log_dx_invkin[i, :-2], "g", linewidth=2) + # plt.plot(t_range[:-2], self.log_dx_ref_invkin[i, :-2], "violet", linewidth=2, linestyle="--") + plt.legend(["MOCAP LIN", "MOCAP NL", "MOCAP PLANNER"], prop={'size': 8}) + plt.ylabel(lgd[i]) +plt.suptitle("Measured & Reference linear and angular velocities") + + +diff_vel_lin = abs(mocap_h_v_mpc_lin[:,:] - joy_v_ref[:,:3]) +diff_vel_nl = abs(mocap_h_v_mpc_nl[:,:] - joy_v_ref[:,:3]) +diff_vel_planner = abs(mocap_h_v_mpc_planner[:,:] - joy_v_ref[:,:3]) + +diff_ang_lin = abs(mocap_b_w_mpc_lin[:,:] - joy_v_ref[:,3:6]) +diff_ang_nl = abs(mocap_b_w_mpc_nl[:,:] - joy_v_ref[:,3:6]) +diff_ang_planner = abs(mocap_b_w_mpc_planner[:,:] - joy_v_ref[:,3:6]) + +diff_rpy_lin = abs(mocap_RPY_mpc_lin[:,:] - planner_xref[:, 3:6, 1] ) +diff_rpy_nl = abs(mocap_RPY_mpc_nl[:,:] - planner_xref[:, 3:6, 1] ) +diff_rpy_planner = abs(mocap_RPY_mpc_planner[:,:] - planner_xref[:, 3:6, 1] ) + +diff_pos_lin = abs(mocap_pos_mpc_lin[:,:] - planner_xref[:, :3, 1] ) +diff_pos_nl = abs(mocap_pos_mpc_nl[:,:] - planner_xref[:, :3, 1] ) +diff_pos_planner = abs(mocap_pos_mpc_planner[:,:] - planner_xref[:, :3, 1] ) + +# print('RMSE Vx [Lin, Nl, PLanner]: ', np.linalg.norm(diff_vel_lin)) + +lgd = ["Linear vel X", "Linear vel Y", "POsition Z", + "Position Roll", "Position Pitch", "Ang vel Yaw"] +plt.figure() +for i in range(6): + if i == 0: + ax0 = plt.subplot(3, 2, index6[i]) + else: + plt.subplot(3, 2, index6[i], sharex=ax0) + + if i < 2: + plt.plot(t_range, diff_vel_lin[:, i], "k", linewidth=3) + plt.plot(t_range, diff_vel_nl[:, i], "b", linewidth=3) + plt.plot(t_range, diff_vel_planner[:, i], "r", linewidth=3) + + elif i == 2 : + plt.plot(t_range, diff_pos_lin[:, i], "k", linewidth=3) + plt.plot(t_range, diff_pos_nl[:, i], "b", linewidth=3) + plt.plot(t_range, diff_pos_planner[:, i], "r", linewidth=3) + + + elif i == 3 or i == 4: + plt.plot(t_range, diff_rpy_lin[:, i-3], "k", linewidth=3) + plt.plot(t_range, diff_rpy_nl[:, i-3], "b", linewidth=3) + plt.plot(t_range, diff_rpy_planner[:, i-3], "r", linewidth=3) + + else : + + plt.plot(t_range, diff_ang_lin[:, i-3], "k", linewidth=3) + plt.plot(t_range, diff_ang_nl[:, i-3], "b", linewidth=3) + plt.plot(t_range, diff_ang_planner[:, i-3], "r", linewidth=3) + + """N = 2000 + y = np.convolve(self.mocap_b_w[:, i-3], np.ones(N)/N, mode='valid') + plt.plot(t_range[int(N/2)-1:-int(N/2)], y, linewidth=3, linestyle="--")""" + + # plt.plot(t_range, self.log_dq[i, :], "g", linewidth=2) + # plt.plot(t_range[:-2], self.log_dx_invkin[i, :-2], "g", linewidth=2) + # plt.plot(t_range[:-2], self.log_dx_ref_invkin[i, :-2], "violet", linewidth=2, linestyle="--") + plt.legend(["LIN", "NL", "PLANNER"], prop={'size': 8}) + plt.ylabel(lgd[i]) +plt.suptitle("Measured & Reference linear and angular velocities (ABS ERROR) ") + + + +# Diff with reference +diff_pos_lin = (mocap_pos_mpc_lin[:,:] - planner_xref[:, :3, 1] ) +diff_pos_nl = (mocap_pos_mpc_nl[:,:] - planner_xref[:, :3, 1] ) +diff_pos_planner = (mocap_pos_mpc_planner[:,:] - planner_xref[:, :3, 1] ) + +diff_rpy_lin = (mocap_RPY_mpc_lin[:,:] - planner_xref[:, 3:6, 1] ) +diff_rpy_nl = (mocap_RPY_mpc_nl[:,:] - planner_xref[:, 3:6, 1] ) +diff_rpy_planner = (mocap_RPY_mpc_planner[:,:] - planner_xref[:, 3:6, 1] ) + +diff_vel_lin = (mocap_h_v_mpc_lin[:,:] - joy_v_ref[:,:3]) +diff_vel_nl = (mocap_h_v_mpc_nl[:,:] - joy_v_ref[:,:3]) +diff_vel_planner = (mocap_h_v_mpc_planner[:,:] - joy_v_ref[:,:3]) + +diff_ang_lin = (mocap_b_w_mpc_lin[:,:] - joy_v_ref[:,3:6]) +diff_ang_nl = (mocap_b_w_mpc_nl[:,:] - joy_v_ref[:,3:6]) +diff_ang_planner = (mocap_b_w_mpc_planner[:,:] - joy_v_ref[:,3:6]) + + +# Max measures +max_pos_lin = abs(np.max(mocap_pos_mpc_lin, axis = 0)) +max_pos_nl = abs(np.max(mocap_pos_mpc_nl, axis = 0)) +max_pos_planner = abs(np.max(mocap_pos_mpc_planner, axis = 0)) + +max_rpy_lin = abs(np.max(mocap_RPY_mpc_lin, axis = 0)) +max_rpy_nl = abs(np.max(mocap_RPY_mpc_nl, axis = 0)) +max_rpy_planner = abs(np.max(mocap_RPY_mpc_planner, axis = 0)) + +max_vel_lin = abs(np.max(mocap_h_v_mpc_lin, axis = 0)) +max_vel_nl = abs(np.max(mocap_h_v_mpc_nl, axis = 0)) +max_vel_planner = abs(np.max(mocap_h_v_mpc_planner, axis = 0)) + +max_ang_lin = abs(np.max(mocap_b_w_mpc_lin, axis = 0)) +max_ang_nl = abs(np.max(mocap_b_w_mpc_nl, axis = 0)) +max_ang_planner = abs(np.max(mocap_b_w_mpc_planner, axis = 0)) + +# RMSE normalized +RMSE_pos_lin = np.sqrt((diff_pos_lin**2).mean(axis=0)) / max_pos_lin +RMSE_pos_nl = np.sqrt((diff_pos_nl**2).mean(axis=0)) / max_pos_lin +RMSE_pos_planner = np.sqrt((diff_pos_planner**2).mean(axis=0)) / max_pos_lin + +RMSE_rpy_lin = np.sqrt((diff_rpy_lin**2).mean(axis=0)) / max_rpy_lin +RMSE_rpy_nl = np.sqrt((diff_rpy_nl**2).mean(axis=0)) / max_rpy_lin +RMSE_rpy_planner = np.sqrt((diff_rpy_planner**2).mean(axis=0)) / max_rpy_lin + +RMSE_vel_lin = np.sqrt((diff_vel_lin**2).mean(axis=0)) / max_vel_lin +RMSE_vel_nl = np.sqrt((diff_vel_nl**2).mean(axis=0)) / max_vel_lin +RMSE_vel_planner = np.sqrt((diff_vel_planner**2).mean(axis=0)) / max_vel_lin + +RMSE_ang_lin = np.sqrt((diff_ang_lin**2).mean(axis=0)) / max_ang_lin +RMSE_ang_nl = np.sqrt((diff_ang_nl**2).mean(axis=0)) / max_ang_lin +RMSE_ang_planner = np.sqrt((diff_ang_planner**2).mean(axis=0)) / max_ang_lin + +print("NORMALIZED RMSE : sqrt( (measures - ref**2).mean() ) / measure_max ") + +print('RMSE Velocity : [Vx, Vy] ') +print(RMSE_vel_lin[:2], ' : LINEAR') +print(RMSE_vel_nl[:2], ' : NON LINEAR') +print(RMSE_vel_planner[:2], ' : PLANNER') + +print("\n\n") +print('RMSE POSITION : [Z] ') +print(RMSE_pos_lin[2], ' : LINEAR') +print(RMSE_pos_nl[2], ' : NON LINEAR') +print(RMSE_pos_planner[2], ' : PLANNER') + +print("\n\n") +print('RMSE Roll / Pitch : ') +print(RMSE_rpy_lin[:2], ' : LINEAR') +print(RMSE_rpy_nl[:2], ' : NON LINEAR') +print(RMSE_rpy_planner[:2], ' : PLANNER') + +print("\n\n") +print('RMSE Yaw Velocity : ') +print(RMSE_ang_lin[2], ' : LINEAR') +print(RMSE_ang_nl[2], ' : NON LINEAR') +print(RMSE_ang_planner[2], ' : PLANNER') + + + + + + # Display all graphs and wait +plt.show(block=True) \ No newline at end of file -- GitLab