From d6d1bbf9d529990fbb81fe54adb558f6606e0f74 Mon Sep 17 00:00:00 2001
From: Fanny Risbourg <frisbourg@laas.fr>
Date: Fri, 18 Mar 2022 14:41:02 +0100
Subject: [PATCH] solve_mpc fucnction

---
 .../quadruped_reactive_walking/Controller.py  | 199 ++++++++++--------
 .../tools/LoggerControl.py                    |   2 +-
 2 files changed, 107 insertions(+), 94 deletions(-)

diff --git a/python/quadruped_reactive_walking/Controller.py b/python/quadruped_reactive_walking/Controller.py
index 130e1082..6633831e 100644
--- a/python/quadruped_reactive_walking/Controller.py
+++ b/python/quadruped_reactive_walking/Controller.py
@@ -88,7 +88,6 @@ class Controller:
         self.o_targetFootstep = np.zeros((3, 4))
 
         self.enable_multiprocessing_mip = params.enable_multiprocessing_mip
-        self.update_mip = False
         if params.solo3D:
             from .solo3D.SurfacePlannerWrapper import Surface_planner_wrapper
 
@@ -116,7 +115,7 @@ class Controller:
                     self.footstepPlanner,
                     self.footTrajectoryGenerator,
                 )
-
+            self.update_mip = False
         else:
             self.statePlanner = qrw.StatePlanner()
             self.statePlanner.initialize(params)
@@ -175,22 +174,10 @@ class Controller:
         self.t_filter = t_filter - t_start
 
         self.gait.update(self.k, self.k_mpc, self.joystick.get_joystick_code())
+        gait_matrix = self.gait.matrix
 
-        self.update_mip = self.k % self.k_mpc == 0 and self.gait.is_new_step()
         if self.solo3D:
-            if self.update_mip:
-                self.statePlanner.update_surface(
-                    self.q_filtered[:6], self.vref_filtered
-                )
-                if self.surfacePlanner.initialized:
-                    self.error = self.surfacePlanner.get_latest_results()
-
-            self.footstepPlanner.update_surfaces(
-                self.surfacePlanner.potential_surfaces,
-                self.surfacePlanner.selected_surfaces,
-                self.surfacePlanner.mip_success,
-                self.surfacePlanner.mip_iteration,
-            )
+            self.retrieve_surfaces()
 
         self.o_targetFootstep = self.footstepPlanner.update_footsteps(
             self.k % self.k_mpc == 0 and self.k != 0,
@@ -199,73 +186,24 @@ class Controller:
             self.h_v_windowed,
             self.v_ref,
         )
+        footsteps = self.footstepPlanner.get_footsteps()
 
         self.statePlanner.compute_reference_states(
-            self.q_filtered[:6],
-            self.h_v_filtered,
-            self.vref_filtered,
+            self.q_filtered[:6], self.h_v_filtered, self.vref_filtered
         )
+        reference_state = self.statePlanner.get_reference_states()
 
-        xref = self.statePlanner.get_reference_states()
-        fsteps = self.footstepPlanner.get_footsteps()
-        gait_matrix = self.gait.matrix
-
-        if self.update_mip and self.solo3D:
-            configs = self.statePlanner.get_configurations().transpose()
-            self.surfacePlanner.run(
-                configs, gait_matrix, self.o_targetFootstep, self.vref_filtered[:3]
-            )
-            self.surfacePlanner.initialized = True
-            if not self.enable_multiprocessing_mip and self.SIMULATION:
-                self.pybEnvironment3D.update_target_SL1M(
-                    self.surfacePlanner.all_feet_pos_syn
-                )
+        if self.solo3D and self.update_mip:
+            self.call_planner()
 
         t_planner = time.time()
         self.t_planner = t_planner - t_filter
 
-        # Solve MPC
-        if (self.k % self.k_mpc) == 0:
-            try:
-                if self.type_MPC == 3:
-                    l_targetFootstep = oRh.transpose() @ (self.o_targetFootstep - oTh)
-                    self.mpc_wrapper.solve(
-                        self.k,
-                        xref,
-                        fsteps,
-                        gait_matrix,
-                        l_targetFootstep,
-                        oRh,
-                        oTh,
-                        self.footTrajectoryGenerator.get_foot_position(),
-                        self.footTrajectoryGenerator.get_foot_velocity(),
-                        self.footTrajectoryGenerator.get_foot_acceleration(),
-                        self.footTrajectoryGenerator.get_foot_jerk(),
-                        self.footTrajectoryGenerator.get_phase_durations()
-                        - self.footTrajectoryGenerator.get_elapsed_durations(),
-                    )
-                else:
-                    self.mpc_wrapper.solve(
-                        self.k, xref, fsteps, gait_matrix, np.zeros((3, 4))
-                    )
-            except ValueError:
-                print("MPC Problem")
-        self.x_f_mpc, self.mpc_cost = self.mpc_wrapper.get_latest_result()
+        self.solve_MPC(reference_state, footsteps, oRh, oTh)
 
         t_mpc = time.time()
         self.t_mpc = t_mpc - t_planner
 
-        if self.k > 100 and self.type_MPC == 3:
-            for foot in range(4):
-                if gait_matrix[0, foot] == 0:
-                    id = 0
-                    while gait_matrix[id, foot] == 0:
-                        id += 1
-                    self.o_targetFootstep[:2, foot] = self.x_f_mpc[
-                        24 + 2 * foot : 24 + 2 * foot + 2, id + 1
-                    ]
-
-        # Update pos, vel and acc references for feet
         if self.solo3D:
             self.footTrajectoryGenerator.update(
                 self.k,
@@ -288,12 +226,12 @@ class Controller:
                 self.h_ref = p_ref[2]
                 hRb = pin.rpy.rpyToMatrix(0.0, 0.0, self.p_ref[5])
             else:
-                self.xgoals[[3, 4]] = xref[[3, 4], 1]
+                self.xgoals[[3, 4]] = reference_state[[3, 4], 1]
                 self.h_ref = self.q_init[2]
 
             # If the four feet are in contact then we do not listen to MPC
             if self.DEMONSTRATION and self.gait.is_static():
-                self.x_f_mpc[12:24, 0] = [0.0, 0.0, 9.81 * 2.5 / 4.0] * 4
+                self.mpc_result[12:24, 0] = [0.0, 0.0, 9.81 * 2.5 / 4.0] * 4
 
             # Wbc uses filtered roll and pitch and reference angular positions of previous loop
             self.q_wbc[3:5] = self.q_filtered[3:5]
@@ -319,7 +257,7 @@ class Controller:
                 self.feet_p_cmd = (
                     self.footTrajectoryGenerator.get_foot_position_base_frame(
                         oRh_3d.transpose(),
-                        oTh_3d + np.array([[0.0], [0.0], [xref[2, 1]]]),
+                        oTh_3d + np.array([[0.0], [0.0], [reference_state[2, 1]]]),
                     )
                 )
             else:  # Use ideal base frame
@@ -346,7 +284,7 @@ class Controller:
             self.wbcWrapper.compute(
                 self.q_wbc,
                 self.dq_wbc,
-                (self.x_f_mpc[12:24, 0:1]).copy(),
+                (self.mpc_result[12:24, 0:1]).copy(),
                 np.array([gait_matrix[0, :]]),
                 self.feet_p_cmd,
                 self.feet_v_cmd,
@@ -375,23 +313,23 @@ class Controller:
         if self.error or self.joystick.get_stop():
             self.set_null_control()
 
-        # Update PyBullet camera
         if not self.solo3D:
-            self.pyb_camera(device, 0.0)
-        else:  # Update 3D Environment
+            self.pyb_camera(device)
+        else:
             if self.SIMULATION:
                 self.pybEnvironment3D.update(self.k)
 
-        self.pyb_debug(device, fsteps, gait_matrix, xref)
+        self.pyb_debug(device, footsteps, gait_matrix, reference_state)
 
         self.t_loop = time.time() - t_start
         self.k += 1
 
         return self.error
 
-    def pyb_camera(self, device, yaw):
+    def pyb_camera(self, device):
         """
-        Update position of PyBullet camera on the robot position to do as if it was attached to the robot
+        Update position of PyBullet camera on the robot position to do as if it was
+        attached to the robot
         """
         if self.k > 10 and self.enable_pyb_GUI:
             pyb.resetDebugVisualizerCamera(
@@ -405,7 +343,7 @@ class Controller:
                 ],
             )
 
-    def pyb_debug(self, device, fsteps, gait_matrix, xref):
+    def pyb_debug(self, device, footsteps, gait_matrix, xref):
 
         if self.k > 1 and self.enable_pyb_GUI:
             # Display desired feet positions in WBC as green spheres
@@ -438,7 +376,9 @@ class Controller:
                         if status:
                             pos = (
                                 oRh_pyb
-                                @ fsteps[cpt, (3 * i) : (3 * (i + 1))].reshape((-1, 1))
+                                @ footsteps[cpt, (3 * i) : (3 * (i + 1))].reshape(
+                                    (-1, 1)
+                                )
                                 + oTh_pyb
                                 - np.array([[0.0], [0.0], [oTh_pyb[2, 0]]])
                             )
@@ -491,29 +431,29 @@ class Controller:
                     )
 
             # Display predicted trajectory
-            x_f_mpc_rot = np.zeros((3, self.x_f_mpc.shape[1]))
-            for i in range(self.x_f_mpc.shape[1]):
-                x_f_mpc_rot[:, i : (i + 1)] = (
-                    oRh_pyb @ self.x_f_mpc[:3, i : (i + 1)]
+            mpc_result_rot = np.zeros((3, self.mpc_result.shape[1]))
+            for i in range(self.mpc_result.shape[1]):
+                mpc_result_rot[:, i : (i + 1)] = (
+                    oRh_pyb @ self.mpc_result[:3, i : (i + 1)]
                     + oTh_pyb
                     + np.array([[0.0], [0.0], [0.05 - self.h_ref]])
                 )
 
             if len(device.pyb_sim.lineId_blue) == 0:
-                for i in range(self.x_f_mpc.shape[1] - 1):
+                for i in range(self.mpc_result.shape[1] - 1):
                     device.pyb_sim.lineId_blue.append(
                         pyb.addUserDebugLine(
-                            x_f_mpc_rot[:3, i].tolist(),
-                            x_f_mpc_rot[:3, i + 1].tolist(),
+                            mpc_result_rot[:3, i].tolist(),
+                            mpc_result_rot[:3, i + 1].tolist(),
                             lineColorRGB=[0.0, 0.0, 1.0],
                             lineWidth=8,
                         )
                     )
             else:
-                for i in range(self.x_f_mpc.shape[1] - 1):
+                for i in range(self.mpc_result.shape[1] - 1):
                     device.pyb_sim.lineId_blue[i] = pyb.addUserDebugLine(
-                        x_f_mpc_rot[:3, i].tolist(),
-                        x_f_mpc_rot[:3, i + 1].tolist(),
+                        mpc_result_rot[:3, i].tolist(),
+                        mpc_result_rot[:3, i + 1].tolist(),
                         lineColorRGB=[0.0, 0.0, 1.0],
                         lineWidth=8,
                         replaceItemUniqueId=device.pyb_sim.lineId_blue[i],
@@ -610,6 +550,79 @@ class Controller:
 
         return oRh, hRb, oTh
 
+    def retrieve_surfaces(self):
+        """
+        Get last surfaces computed by the planner and send them to the footstep adapter
+        """
+        self.update_mip = self.k % self.k_mpc == 0 and self.gait.is_new_step()
+        if self.update_mip:
+            self.statePlanner.update_surface(self.q_filtered[:6], self.vref_filtered)
+            if self.surfacePlanner.initialized:
+                self.error = self.surfacePlanner.get_latest_results()
+
+        self.footstepPlanner.update_surfaces(
+            self.surfacePlanner.potential_surfaces,
+            self.surfacePlanner.selected_surfaces,
+            self.surfacePlanner.mip_success,
+            self.surfacePlanner.mip_iteration,
+        )
+
+    def call_planner(self):
+        """
+        Call the planner and show the result in simulation
+        """
+        configs = self.statePlanner.get_configurations().transpose()
+        self.surfacePlanner.run(
+            configs, self.gait.matrix, self.o_targetFootstep, self.vref_filtered[:3]
+        )
+        self.surfacePlanner.initialized = True
+        if not self.enable_multiprocessing_mip and self.SIMULATION:
+            self.pybEnvironment3D.update_target_SL1M(
+                self.surfacePlanner.all_feet_pos_syn
+            )
+
+    def solve_MPC(self, reference_state, footsteps, oRh, oTh):
+        if (self.k % self.k_mpc) == 0:
+            try:
+                if self.type_MPC == 3:
+                    l_targetFootstep = oRh.transpose() @ (self.o_targetFootstep - oTh)
+                    self.mpc_wrapper.solve(
+                        self.k,
+                        reference_state,
+                        footsteps,
+                        self.gait.matrix,
+                        l_targetFootstep,
+                        oRh,
+                        oTh,
+                        self.footTrajectoryGenerator.get_foot_position(),
+                        self.footTrajectoryGenerator.get_foot_velocity(),
+                        self.footTrajectoryGenerator.get_foot_acceleration(),
+                        self.footTrajectoryGenerator.get_foot_jerk(),
+                        self.footTrajectoryGenerator.get_phase_durations()
+                        - self.footTrajectoryGenerator.get_elapsed_durations(),
+                    )
+                else:
+                    self.mpc_wrapper.solve(
+                        self.k,
+                        reference_state,
+                        footsteps,
+                        self.gait.matrix,
+                        np.zeros((3, 4)),
+                    )
+            except ValueError:
+                print("MPC Problem")
+        self.mpc_result, self.mpc_cost = self.mpc_wrapper.get_latest_result()
+
+        if self.k > 100 and self.type_MPC == 3:
+            for foot in range(4):
+                if self.gait.matrix[0, foot] == 0:
+                    id = 0
+                    while self.gait.matrix[id, foot] == 0:
+                        id += 1
+                    self.o_targetFootstep[:2, foot] = self.mpc_result[
+                        24 + 2 * foot : 24 + 2 * foot + 2, id + 1
+                    ]
+
     def security_check(self):
         """
         Check if the command is fine and set the command to zero in case of error
diff --git a/python/quadruped_reactive_walking/tools/LoggerControl.py b/python/quadruped_reactive_walking/tools/LoggerControl.py
index b73229c6..08bb91e3 100644
--- a/python/quadruped_reactive_walking/tools/LoggerControl.py
+++ b/python/quadruped_reactive_walking/tools/LoggerControl.py
@@ -296,7 +296,7 @@ class LoggerControl:
         self.planner_h_ref[self.i] = controller.h_ref
 
         # Logging from model predictive control
-        self.mpc_x_f[self.i] = controller.x_f_mpc
+        self.mpc_x_f[self.i] = controller.mpc_result
         self.mpc_solving_duration[
             self.i
         ] = controller.mpc_wrapper.t_mpc_solving_duration
-- 
GitLab