From ca5890e77cb8d5f91330354b9b61d64db4d65149 Mon Sep 17 00:00:00 2001
From: Ale <alessandroassirell98@gmail.com>
Date: Tue, 12 Jul 2022 17:10:04 +0200
Subject: [PATCH] working on walking

it's floating in the air
---
 .../WB_MPC/CasadiOCP.py                       | 28 +++++++++----
 .../WB_MPC/ProblemData.py                     | 18 ++++-----
 .../WB_MPC/ShootingNode.py                    | 30 ++++++++++----
 .../WB_MPC/Target.py                          | 39 ++++++-------------
 4 files changed, 62 insertions(+), 53 deletions(-)

diff --git a/python/quadruped_reactive_walking/WB_MPC/CasadiOCP.py b/python/quadruped_reactive_walking/WB_MPC/CasadiOCP.py
index 9107783c..b1b15392 100644
--- a/python/quadruped_reactive_walking/WB_MPC/CasadiOCP.py
+++ b/python/quadruped_reactive_walking/WB_MPC/CasadiOCP.py
@@ -58,10 +58,11 @@ class CasadiOCP:
                 self.datas += [NodeData()]
 
         self.make_opti_variables(x0)
-        self.cost, eq_constraints = self.make_ocp()
+        self.cost, eq_constraints, ineq_constraints = self.make_ocp()
 
         self.opti.minimize(self.cost)
         self.opti.subject_to(eq_constraints == 0)
+        self.opti.subject_to(ineq_constraints <= 0)
 
         p_opts = {"expand": False}
         s_opts = {"tol": 1e-8,
@@ -104,6 +105,7 @@ class CasadiOCP:
     def make_ocp(self):
         totalcost = 0
         eq = []
+        ineq = []
 
         eq.append(self.dxs[0])
         for t in range(self.pd.T):
@@ -111,25 +113,35 @@ class CasadiOCP:
             self.runningModels[t].init(self.datas[t], self.xs[t], self.acs[t], self.us[t], self.fs[t], False)
 
             # If it is landing
-            """ if (self.target.contactSequence[t] != self.target.contactSequence[t-1] and t >= 1):
-                print('Contact on ', str(self.runningModels[t].contactIds)) """
+            if (self.target.contactSequence[t] != self.target.contactSequence[t-1] and t >= 1):
+                print('Contact on ', str(self.runningModels[t].contactIds))
+                self.runningModels[t].constraint_landing_feet_eq(self.pd.xref)
 
             xnext, rcost = self.runningModels[t].calc(x_ref=self.pd.xref,
                                                       u_ref=self.pd.uref,
-                                                      target=self.target.evaluate_in_t(t))
+                                                      target=self.target.target)
 
             # Constraints
             eq.append(self.runningModels[t].constraint_standing_feet_eq())
             eq.append(self.runningModels[t].constraint_dynamics_eq())
             eq.append(self.runningModels[t].difference(self.xs[t + 1], xnext) - np.zeros(self.pd.ndx))
 
-            totalcost += rcost
-        eq_constraints = casadi.vertcat(*eq)
+            ineq.append(self.runningModels[t].constraint_swing_feet_ineq(self.pd.xref, k = self.pd.k)) 
+            ineq.append(self.runningModels[t].constraint_standing_feet_ineq())
 
+            totalcost += rcost
+        
+        eq.append(self.xs[self.pd.T][self.pd.nq :])
         self.terminalModel.init(data=self.datas[self.pd.T], x=self.xs[self.pd.T],  isTerminal=True)
-        totalcost += self.terminalModel.calc(x_ref=self.pd.xref)[1]
+        _, rcost = self.terminalModel.calc(x_ref=self.pd.xref)
+        #totalcost += self.terminalModel.calc(x_ref=self.pd.xref)[1]
+        totalcost += rcost
+
+        eq_constraints = casadi.vertcat(*eq)
+        ineq_constraints = casadi.vertcat(*ineq)
+        
 
-        return totalcost, eq_constraints
+        return totalcost, eq_constraints, ineq_constraints
 
     def warmstart(self, x0, guess=None):
         for g in guess:
diff --git a/python/quadruped_reactive_walking/WB_MPC/ProblemData.py b/python/quadruped_reactive_walking/WB_MPC/ProblemData.py
index d31df5c2..91826bcd 100644
--- a/python/quadruped_reactive_walking/WB_MPC/ProblemData.py
+++ b/python/quadruped_reactive_walking/WB_MPC/ProblemData.py
@@ -9,9 +9,9 @@ class problemDataAbstract:
         self.dt_bldc = 0.0005
         self.r1 = int(self.dt / self.dt_sim)
         self.r2 = int(self.dt_sim / self.dt_bldc)
-        self.init_steps = 10 # full stand phase
-        self.target_steps = 30 # manipulation steps
-        self.T = self.init_steps + self.target_steps -1
+        self.t_step = 12 # timestep for each contact phase
+        self.repetitions = 3
+        self.T = (2*self.t_step) * self.repetitions -1
 
         self.robot = erd.load("solo12")
         self.q0 = self.robot.q0
@@ -50,6 +50,7 @@ class problemDataAbstract:
         self.rfFootId = self.model.getFrameId(self.rfFoot)
         self.lhFootId = self.model.getFrameId(self.lhFoot)
         self.rhFootId = self.model.getFrameId(self.rhFoot)
+        self.baseId = self.model.getFrameId("base_link")
 
         self.Rsurf = np.eye(3)
 
@@ -77,15 +78,14 @@ class ProblemData(problemDataAbstract):
         self.control_reg_w = 1e1
         self.state_reg_w = np.array([0] * 3 \
                             + [1e1] * 3 \
-                            + [1e0] * 3 \
-                            + [1e-3] * 3\
-                            + [1e0] * 6
+                            + [1e0] * 12 \
                             + [0] * 6 \
-                            + [1e1] * 3 \
-                            + [1e-1] * 3\
-                            + [1e1] * 6 ) 
+                            + [1e1] * 12 ) 
         self.terminal_velocity_w = np.array([0] * 18 + [1e3] * 18 )
         self.control_bound_w = 1e3
+        self.k = np.array([2,2])
+        self.linear_velocity_weight = np.array([10, 10, 10])
+        self.angular_velocity_weight = np.array([10, 10, 10])
 
         self.x0 = np.array([ 0.0, 0.0, 0.2607495, 0, 0, 0, 1,
                              0,  0.7, -1.4,  
diff --git a/python/quadruped_reactive_walking/WB_MPC/ShootingNode.py b/python/quadruped_reactive_walking/WB_MPC/ShootingNode.py
index 3cf0d8da..61c72f54 100644
--- a/python/quadruped_reactive_walking/WB_MPC/ShootingNode.py
+++ b/python/quadruped_reactive_walking/WB_MPC/ShootingNode.py
@@ -164,6 +164,21 @@ class ShootingNode():
 
         return(casadi.vertcat(*eq))
 
+    def constraint_standing_feet_ineq(self):
+        # Friction cone
+        ineq = []
+        for i, stFoot in enumerate(self.contactIds):
+            R = self.Rfeet[stFoot](self.x)
+            f_ = self.fs[i]
+            fw = R @ f_
+            ineq.append(-fw[2])
+            """ ineq.append( fw[0] - conf.mu*fw[2] )
+            ineq.append( -fw[0] - conf.mu*fw[2] )
+            ineq.append(  fw[1] - conf.mu*fw[2] )
+            ineq.append( -fw[1] - conf.mu*fw[2] ) """
+
+        return (casadi.vertcat(*ineq))
+
     def constraint_standing_feet_cost(self):
         # Friction cone
         for i, stFoot in enumerate(self.contactIds):
@@ -188,11 +203,11 @@ class ShootingNode():
         eq.append(self.acc(self.x, self.tau, *self.fs) - self.a)
         return(casadi.vertcat(*eq))
 
-    def constraint_swing_feet_ineq(self, x_ref):
+    def constraint_swing_feet_ineq(self, x_ref, k):
         ineq = []
         for sw_foot in self.freeIds:
-            ineq.append(-self.feet[sw_foot](self.x)
-                        [2] + self.feet[sw_foot](x_ref)[2])
+            ineq.append(-self.feet[sw_foot](self.x)[2] + self.feet[sw_foot](x_ref)[2])
+            ineq.append(self.vfeet[sw_foot](self.x)[0:2] - k[0]* self.feet[sw_foot](self.x)[2])
         return(casadi.vertcat(*ineq))
 
     def force_reg_cost(self):
@@ -222,16 +237,15 @@ class ShootingNode():
 
     def target_cost(self, target):
         # I am Assuming just FR FOOt to be free
-        for sw_foot in self.freeIds:
-
-            self.cost += 1/2 * self.pd.foot_tracking_w * casadi.sumsqr(self.feet[sw_foot](self.x) - target[sw_foot]) * self.pd.dt
+        for obj in target:
+            self.cost += casadi.sumsqr(self.pd.linear_velocity_weight*(self.baseVelocityLin(self.x) - target[obj]["linear_velocity"])) * self.pd.dt
+            self.cost += casadi.sumsqr(self.pd.angular_velocity_weight*(self.baseVelocityAng(self.x) - target[obj]["angular_velocity"])) * self.pd.dt
 
     def compute_cost(self, x_ref, u_ref, target):
         self.cost = 0
         if not self.isTerminal:
-            self.constraint_standing_feet_cost()
             self.control_cost(u_ref)
-            self.constraint_control_cost()
+            #self.constraint_control_cost()
             self.target_cost(target)
 
         self.body_reg_cost(x_ref=x_ref)
diff --git a/python/quadruped_reactive_walking/WB_MPC/Target.py b/python/quadruped_reactive_walking/WB_MPC/Target.py
index cc7ce001..ca1d639c 100644
--- a/python/quadruped_reactive_walking/WB_MPC/Target.py
+++ b/python/quadruped_reactive_walking/WB_MPC/Target.py
@@ -7,45 +7,28 @@ class Target:
         self.pd = pd
         self.dt = pd.dt
 
-        if pd.useFixedBase == 0:
-            self.gait = [] \
-                + [ [ 1,1,1,1 ] ] * pd.init_steps \
-                + [ [ 1,0,1,1 ] ] * pd.target_steps
-        elif pd.useFixedBase == 1:
-            self.gait = [] \
-                + [ [ 0,0,0,0 ] ] * pd.init_steps \
-                + [ [ 0,0,0,0 ] ] * pd.target_steps
-        else:
-            print("'useFixedBase' can be either 0 or 1 !")
+        self.gait = [] \
+            + [ [ 0,1,1,0 ] ] * pd.t_step \
+            + [ [ 1,0,0,1 ] ] * pd.t_step
+
+        self.gait = self.gait * pd.repetitions
 
         self.T = pd.T
         self.contactSequence = [ self.patternToId(p) for p in self.gait]
 
-        self.target = {pd.rfFootId: []}
-        q = pd.x0[: pd.nq]
-        v = pd.x0[pd.nq :]
-        pin.forwardKinematics(pd.model, pd.rdata, q, v)
-        pin.updateFramePlacements(pd.model, pd.rdata)
-        self.FR_foot0 = pd.rdata.oMf[pd.rfFootId].translation.copy()
-        self.A = np.array([0, 0.05, 0.05])
-        self.offset = np.array([0.05, 0., 0.06])
-        self.freq = np.array([0, 2.5, 2.5])
-        self.phase = np.array([0, 0, np.pi/2])
+        self.target = {pd.baseId: {"linear_velocity" :[1,0,0], "angular_velocity": [0,0,0]}}
+
 
     def patternToId(self, gait):
             return tuple(self.pd.allContactIds[i] for i,c in enumerate(gait) if c==1 )
         
     def shift_gait(self):
-        self.gait.pop(0)
-        self.gait += [self.gait[-1]]
+        g0 = self.gait.pop(0)
+        self.gait += [g0]
         self.contactSequence = [ self.patternToId(p) for p in self.gait]    
 
     def update(self, t):
-        target = []
-        for n in range(self.T+1):
-            target += [self.FR_foot0 + self.offset + self.A *
-                       np.sin(2*np.pi*self.freq * (n+t) * self.dt + self.phase)]
-        self.target[self.pd.rfFootId] = np.array(target)
+        pass
     
     def evaluate_in_t(self, t):
-        return {e: self.target[e][t] for e in self.target}
\ No newline at end of file
+        pass
\ No newline at end of file
-- 
GitLab