From fbcd7a494a850bea191a359e6101aea6cbca302e Mon Sep 17 00:00:00 2001 From: Ale <alessandroassirell98@gmail.com> Date: Tue, 9 Aug 2022 14:26:43 +0200 Subject: [PATCH] working on rising foot --- config/walk_parameters.yaml | 2 +- .../quadruped_reactive_walking/Controller.py | 33 ++++++++------ .../WB_MPC/ProblemData.py | 18 ++++---- .../WB_MPC/Target.py | 8 ++-- .../tools/PyBulletSimulator.py | 45 +++++++++++++++++-- 5 files changed, 75 insertions(+), 31 deletions(-) diff --git a/config/walk_parameters.yaml b/config/walk_parameters.yaml index f670bd48..b6416697 100644 --- a/config/walk_parameters.yaml +++ b/config/walk_parameters.yaml @@ -7,7 +7,7 @@ robot: PLOTTING: true # Enable/disable automatic plotting at the end of the experiment DEMONSTRATION: false # Enable/disable demonstration functionalities SIMULATION: true # Enable/disable PyBullet simulation or running on real robot - enable_pyb_GUI: false # Enable/disable PyBullet GUI + enable_pyb_GUI: true # Enable/disable PyBullet GUI envID: 0 # Identifier of the environment to choose in which one the simulation will happen use_flat_plane: true # If True the ground is flat, otherwise it has bumps predefined_vel: true # If we are using a predefined reference velocity (True) or a joystick (False) diff --git a/python/quadruped_reactive_walking/Controller.py b/python/quadruped_reactive_walking/Controller.py index 190ef617..b6496bab 100644 --- a/python/quadruped_reactive_walking/Controller.py +++ b/python/quadruped_reactive_walking/Controller.py @@ -46,7 +46,8 @@ class Interpolator: self.beta = self.v1 self.gamma = self.q0 elif self.type == 1: # Quadratic fixed velocity - self.alpha = 2 * (self.q1 - self.q0 - self.v0 * self.dt) / self.dt**2 + self.alpha = 2 * (self.q1 - self.q0 - + self.v0 * self.dt) / self.dt**2 self.beta = self.v0 self.gamma = self.q0 elif self.type == 2: # Quadratic time variable @@ -102,7 +103,8 @@ class Interpolator: plt.scatter(y=self.q0[i], x=0.0, color="violet", marker="+") plt.scatter(y=self.q1[i], x=self.dt, color="violet", marker="+") if self.type == 3 and self.q2 is not None: - plt.scatter(y=self.q2[i], x=2 * self.dt, color="violet", marker="+") + plt.scatter(y=self.q2[i], x=2 * self.dt, + color="violet", marker="+") plt.subplot(3, 2, (i * 2) + 2) plt.title("Velocity interpolation") @@ -110,7 +112,8 @@ class Interpolator: plt.scatter(y=self.v0[i], x=0.0, color="violet", marker="+") plt.scatter(y=self.v1[i], x=self.dt, color="violet", marker="+") if self.type == 3 and self.v2 is not None: - plt.scatter(y=self.v2[i], x=2 * self.dt, color="violet", marker="+") + plt.scatter(y=self.v2[i], x=2 * self.dt, + color="violet", marker="+") plt.show() @@ -122,7 +125,7 @@ class DummyDevice: self.base_position = np.zeros(3) self.base_position[2] = 0.1944 self.b_base_velocity = np.zeros(3) - self.baseState = ((0.0, 0.0, 0.2607495), (0.0, 0.0, 0.0, 1.0)) + self.baseState = ((0.0, 0.0, 0.2607495), (0.0, 0.0, 0.0, 1.0)) self.baseVel = ((0.0, 0.0, 0.0), (0.0, 0.0, 0.0)) class IMU: @@ -138,7 +141,6 @@ class DummyDevice: self.velocities = np.zeros(12) - class Controller: def __init__(self, pd, params, q_init, t): """ @@ -153,7 +155,8 @@ class Controller: self.pd = pd self.params = params - self.gait = np.repeat(np.array([0, 0, 0, 0]).reshape((1, 4)), self.pd.T, axis=0) + self.gait = np.concatenate([np.repeat(np.array([1, 1, 1, 1]).reshape((1, 4)), self.pd.init_steps, axis=0), + np.repeat(np.array([1, 0, 1, 1]).reshape((1, 4)), self.pd.target_steps - 1, axis=0)]) self.q_init = pd.q0 self.k = 0 @@ -261,8 +264,8 @@ class Controller: # q, v = self.interpolator.interpolate(t) # else: # q, v = self.integrate_x(m) - q = xs[1][: self.pd.nq] - v = xs[1][self.pd.nq :] + q = xs[1][7: self.pd.nq] + v = xs[1][6 + self.pd.nq:] self.result.q_des = q[:] self.result.v_des = v[:] @@ -426,9 +429,10 @@ class Controller: pin.difference( self.pd.model, m["x_m"][: self.pd.nq], - self.mpc_result.xs[0][: self.pd.nq], + self.mpc_result.xs[0][: self.pd.nq] + ), - m["x_m"][self.pd.nq :] - self.mpc_result.xs[0][self.pd.nq :], + m["x_m"][self.pd.nq:] - self.mpc_result.xs[0][self.pd.nq:] ] ) # x_diff = self.mpc_result.xs[0] - m["x_m"] @@ -459,13 +463,16 @@ class Controller: legend = ["Hip", "Shoulder", "Knee"] fig, axs = plt.subplots(3) - [axs[0].plot(np.array(self.mpc_result.xs)[:, joint]) for joint in range(3)] + [axs[0].plot(np.array(self.mpc_result.xs)[:, joint]) + for joint in range(3)] axs[0].legend(legend) - [axs[1].plot(np.array(self.mpc_result.xs)[:, 3 + joint]) for joint in range(3)] + [axs[1].plot(np.array(self.mpc_result.xs)[:, 3 + joint]) + for joint in range(3)] axs[1].legend(legend) - [axs[2].plot(np.array(self.mpc_result.us)[:, joint]) for joint in range(3)] + [axs[2].plot(np.array(self.mpc_result.us)[:, joint]) + for joint in range(3)] axs[2].legend(legend) return axs diff --git a/python/quadruped_reactive_walking/WB_MPC/ProblemData.py b/python/quadruped_reactive_walking/WB_MPC/ProblemData.py index f2eeeadc..8e822e48 100644 --- a/python/quadruped_reactive_walking/WB_MPC/ProblemData.py +++ b/python/quadruped_reactive_walking/WB_MPC/ProblemData.py @@ -8,8 +8,8 @@ class problemDataAbstract: self.dt = param.dt_mpc # OCP dt self.dt_wbc = param.dt_wbc self.mpc_wbc_ratio = int(self.dt / self.dt_wbc) - self.init_steps = 0 - self.target_steps = 150 + self.init_steps = 10 + self.target_steps = 90 self.T = self.init_steps + self.target_steps - 1 self.robot = erd.load("solo12") @@ -89,25 +89,25 @@ class ProblemData(problemDataAbstract): # Cost function weights # Cost function weights self.mu = 0.7 - self.foot_tracking_w = 1e3 - # self.friction_cone_w = 1e3 * 0 + self.foot_tracking_w = 1e2 + self.friction_cone_w = 1e3 self.control_bound_w = 1e3 - self.control_reg_w = 1e0 + self.control_reg_w = 1e1 self.state_reg_w = np.array([0] * 3 + [1e1] * 3 + [1e0] * 3 - + [1e-5] * 3 + + [1e-3] * 3 + [1e0] * 6 + [0] * 6 + [1e1] * 3 - + [1e0] * 3 + + [1e-1] * 3 + [1e1] * 6 ) self.terminal_velocity_w = np.array( - [0] * self.nq + [1e3] * self.nv) + [0] * self.nv + [1e3] * self.nv) self.xref = self.x0 - self.uref = self.u0 + self.uref =self.u0 class ProblemDataFull(problemDataAbstract): diff --git a/python/quadruped_reactive_walking/WB_MPC/Target.py b/python/quadruped_reactive_walking/WB_MPC/Target.py index 90f34a01..d2cf603b 100644 --- a/python/quadruped_reactive_walking/WB_MPC/Target.py +++ b/python/quadruped_reactive_walking/WB_MPC/Target.py @@ -9,10 +9,10 @@ class Target: pin.forwardKinematics(pd.model, pd.rdata, pd.q0, pd.v0) pin.updateFramePlacements(pd.model, pd.rdata) self.foot_pose = pd.rdata.oMf[pd.rfFootId].translation.copy() - self.A = np.array([0, 0.03, 0.03]) - self.offset = np.array([0.05, -0.02, 0.06]) - self.freq = np.array([0, 0.5, 0.5]) - self.phase = np.array([0, np.pi / 2, 0]) + self.A = np.array([0, 0.05, 0.05]) + self.offset = np.array([0.05, 0, 0.06]) + self.freq = np.array([0, 0.5 * 0, 0.5*0]) + self.phase = np.array([0, 0, np.pi / 2]) self.t_offset = 0 def shift(self): diff --git a/python/quadruped_reactive_walking/tools/PyBulletSimulator.py b/python/quadruped_reactive_walking/tools/PyBulletSimulator.py index 07f59c9c..22e140b9 100644 --- a/python/quadruped_reactive_walking/tools/PyBulletSimulator.py +++ b/python/quadruped_reactive_walking/tools/PyBulletSimulator.py @@ -42,7 +42,8 @@ class pybullet_simulator: # Either use a flat ground or a rough terrain if use_flat_plane: - """ self.planeId = pyb.loadURDF("plane.urdf") # Flat plane + + self.planeId = pyb.loadURDF("plane.urdf") # Flat plane self.planeIdbis = pyb.loadURDF("plane.urdf") # Flat plane # Tune position and orientation of plane @@ -55,7 +56,7 @@ class pybullet_simulator: self.planeIdbis, [200.0, 0, -100.0 * np.sin(p_pitch)], pin.Quaternion(pin.rpy.rpyToMatrix(p_roll, p_pitch, 0.0)).coeffs(), - ) """ + ) else: import random @@ -269,12 +270,12 @@ class pybullet_simulator: pyb.setGravity(0, 0, -9.81) # Load Quadruped robot - robotStartPos = [0, 0, 0.2607495] + robotStartPos = [0, 0, 0] robotStartOrientation = pyb.getQuaternionFromEuler([0.0, 0.0, 0.0]) pyb.setAdditionalSearchPath( EXAMPLE_ROBOT_DATA_MODEL_DIR + "/solo_description/robots" ) - self.robotId = pyb.loadURDF("solo12.urdf", robotStartPos, robotStartOrientation, useFixedBase = 1) + self.robotId = pyb.loadURDF("solo12.urdf", robotStartPos, robotStartOrientation) # Disable default motor control for revolute joints self.revoluteJointIndices = [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14] @@ -301,6 +302,42 @@ class pybullet_simulator: forces=jointTorques, ) + # Get position of feet in world frame with base at (0, 0, 0) + feetLinksID = [3, 7, 11, 15] + linkStates = pyb.getLinkStates(self.robotId, feetLinksID) + + # Get minimum height of feet (they are in the ground since base is at 0, 0, 0) + z_min = linkStates[0][4][2] + i_min = 0 + i = 1 + for link in linkStates[1:]: + if link[4][2] < z_min: + z_min = link[4][2] + i_min = i + i += 1 + + # Set base at (0, 0, -z_min) so that the lowest foot is at z = 0 + pyb.resetBasePositionAndOrientation( + self.robotId, + [0.0, 0.0, -z_min], + pin.Quaternion(pin.rpy.rpyToMatrix(p_roll, p_pitch, 0.0)).coeffs(), + ) + + # Progressively raise the base to achieve proper contact (take into account radius of the foot) + while ( + pyb.getClosestPoints( + self.robotId, + self.planeId, + distance=0.005, + linkIndexA=feetLinksID[i_min], + ) + )[0][8] < -0.001: + z_min -= 0.001 + pyb.resetBasePositionAndOrientation( + self.robotId, + [0.0, 0.0, -z_min], + pin.Quaternion(pin.rpy.rpyToMatrix(p_roll, p_pitch, 0.0)).coeffs(), + ) # Fix the base in the world frame # pyb.createConstraint(self.robotId, -1, -1, -1, pyb.JOINT_FIXED, [0, 0, 0], [0, 0, 0], [0, 0, robotStartPos[2]]) -- GitLab