From d86b22047cef6620936aacb6fa0a7f199c46b9c4 Mon Sep 17 00:00:00 2001
From: paleziart <paleziart@laas.fr>
Date: Wed, 20 Oct 2021 11:45:26 +0200
Subject: [PATCH] Formatting MPC Wrapper

---
 include/qrw/FootTrajectoryGenerator.hpp |   2 +-
 include/qrw/MpcWrapper.hpp              |  97 +++++++++++++---
 src/MpcWrapper.cpp                      | 146 ++++++++----------------
 3 files changed, 129 insertions(+), 116 deletions(-)

diff --git a/include/qrw/FootTrajectoryGenerator.hpp b/include/qrw/FootTrajectoryGenerator.hpp
index 4121085b..543731ad 100644
--- a/include/qrw/FootTrajectoryGenerator.hpp
+++ b/include/qrw/FootTrajectoryGenerator.hpp
@@ -55,7 +55,7 @@ class FootTrajectoryGenerator {
   /// \brief Update the 3D desired position for feet in swing phase by using a 5-th order polynomial that lead them
   ///        to the desired position on the ground (computed by the footstep planner)
   ///
-  /// \param[in] k Number of time steps since the start of the simulation
+  /// \param[in] k Numero of the current loop
   /// \param[in] targetFootstep Desired target locations at the end of the swing phases
   ///
   ////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/include/qrw/MpcWrapper.hpp b/include/qrw/MpcWrapper.hpp
index eec79bc8..debe8ba4 100644
--- a/include/qrw/MpcWrapper.hpp
+++ b/include/qrw/MpcWrapper.hpp
@@ -9,10 +9,6 @@
 #ifndef MPCWRAPPER_H_INCLUDED
 #define MPCWRAPPER_H_INCLUDED
 
-// #include <string>
-// #include <boost/interprocess/managed_shared_memory.hpp>
-// #include <boost/interprocess/shared_memory_object.hpp>
-// #include <boost/interprocess/mapped_region.hpp>
 #include "pinocchio/math/rpy.hpp"
 #include <Eigen/Core>
 #include <Eigen/Dense>
@@ -22,16 +18,81 @@
 #include "qrw/Types.h"
 #include "qrw/MPC.hpp"
 
-// Functions acting on shared memory
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// Functions acting on shared memory
+///
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Stop the thread running the MPC in parallel
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
 void stop_thread();
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Check if the thread running the MPC in parallel should stop
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
 bool check_stop_thread();
-void write_in(int & k, MatrixN & xref, MatrixN & fsteps);
-bool read_in(int & k, MatrixN & xref, MatrixN & fsteps);
-void write_out(MatrixN & result);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Write data to shared memory (from main loop to MPC)
+///
+/// \param[in] k Numero of the current loop
+/// \param[in] xref Desired state vector for the whole prediction horizon
+/// \param[in] fsteps The [x, y, z]^T desired position of each foot for each time step of the horizon
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
+void write_in(int& k, MatrixN& xref, MatrixN& fsteps);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Read data in shared memory (from main loop to MPC)
+///
+/// \param[in] k Numero of the current loop
+/// \param[in] xref Desired state vector for the whole prediction horizon
+/// \param[in] fsteps The [x, y, z]^T desired position of each foot for each time step of the horizon
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
+bool read_in(int& k, MatrixN& xref, MatrixN& fsteps);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Write data to shared memory (from MPC to main loop)
+///
+/// \param[in] result Predicted state and desired contact forces resulting of the MPC. The first 12 rows contains the
+/// predicted position/orientation/velocity and the last 12 rows contains the 3D contact forces for each foot. The
+/// first column corresponds to the predicted state in dt_mpc seconds if the contact forces are applied. The second
+/// column is the predicted state in 2*dt_mpc seconds if the contact forces of the first column are applied during
+/// dt_mpc then those of the second column during dt_mpc. And so on...
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
+void write_out(MatrixN& result);
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Check if a new MPC result is available
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
 bool check_new_result();
+
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Read data in shared memory (from MPC to main loop)
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
 MatrixN read_out();
-void parallel_loop();
 
+////////////////////////////////////////////////////////////////////////////////////////////////
+///
+/// \brief Run the MPC in parallel (launched by a thread)
+///
+////////////////////////////////////////////////////////////////////////////////////////////////
+void parallel_loop();
 
 class MpcWrapper {
  public:
@@ -62,7 +123,10 @@ class MpcWrapper {
   ///
   /// \brief Send data to the MPC to solve one iteration of MPC
   ///
-  /// \param[in] robot Pointer to the robot interface
+  /// \param[in] k Numero of the current loop
+  /// \param[in] xref Desired state vector for the whole prediction horizon
+  /// \param[in] fsteps The [x, y, z]^T desired position of each foot for each time step of the horizon
+  /// \param[in] gait Current gait matrix
   ///
   ////////////////////////////////////////////////////////////////////////////////////////////////
   void solve(int k, MatrixN xref, MatrixN fsteps, MatrixN gait);
@@ -75,15 +139,12 @@ class MpcWrapper {
   Eigen::Matrix<double, 24, 2> get_latest_result();
 
  private:
-  
-  Params* params_;
-  MPC mpc_;
-
-  int test = 0;
-  Eigen::Matrix<double, 24, 2> last_available_result;
-  Matrix14 gait_past;
-  Matrix14 gait_next;
+  Params* params_;  // Object that stores parameters
+  MPC mpc_;         // MPC object used for synchronous solving (not in parallel loop)
 
+  Eigen::Matrix<double, 24, 2> last_available_result;  // Latest available result of the MPC
+  Matrix14 gait_past;                                  // Gait status of the previous MPC time step
+  Matrix14 gait_next;                                  // Gait status of the next MPC time step
 };
 
 #endif  // MPCWRAPPER_H_INCLUDED
diff --git a/src/MpcWrapper.cpp b/src/MpcWrapper.cpp
index 63ccb62d..090a3800 100644
--- a/src/MpcWrapper.cpp
+++ b/src/MpcWrapper.cpp
@@ -1,54 +1,41 @@
 #include "qrw/MpcWrapper.hpp"
 
 // Shared global variables
-Params* shared_params = nullptr;
-bool shared_running = true;
-bool shared_newIn = false;
-bool shared_newOut = false;
-int shared_k;
-MatrixN shared_xref;
-MatrixN shared_fsteps;
-MatrixN shared_result;
+Params* shared_params = nullptr;  // Shared pointer to object that stores parameters
+bool shared_running = true;       // Flag to stop the parallel thread
+bool shared_newIn = false;        // Flag to indicate new data has been written by main loop for MPC
+bool shared_newOut = false;       // Flag to indicate new data has been written by MPC for main loop
+int shared_k;                     // Numero of the current loop
+MatrixN shared_xref;              // Desired state vector for the whole prediction horizon
+MatrixN shared_fsteps;            // The [x, y, z]^T desired position of each foot for each time step of the horizon
+MatrixN shared_result;            // Predicted state and desired contact forces resulting of the MPC
 
 // Mutexes to protect the global variables
 std::mutex mutexStop;  // To check if the thread should still run
-std::mutex mutexIn;  // From main loop to MPC
-std::mutex mutexOut;  // From MPC to main loop
+std::mutex mutexIn;    // From main loop to MPC
+std::mutex mutexOut;   // From MPC to main loop
 
-void stop_thread()
-{
+void stop_thread() {
   const std::lock_guard<std::mutex> lockStop(mutexStop);
   shared_running = false;
 }
 
-bool check_stop_thread()
-{
+bool check_stop_thread() {
   const std::lock_guard<std::mutex> lockStop(mutexStop);
   return shared_running;
 }
 
-void write_in(int & k, MatrixN & xref, MatrixN & fsteps)
-{
+void write_in(int& k, MatrixN& xref, MatrixN& fsteps) {
   const std::lock_guard<std::mutex> lockIn(mutexIn);
   shared_k = k;
   shared_xref = xref;
   shared_fsteps = fsteps;
-  // std::cout << "Writing memory" << std::endl;
-  /*std::cout << "Shared k" << std::endl << shared_k << std::endl;
-  std::cout << "Shared xref" << std::endl << shared_xref << std::endl;
-  std::cout << "Shared fsteps" << std::endl << shared_fsteps << std::endl;*/
-  shared_newIn = true; // New data is available
+  shared_newIn = true;  // New data is available
 }
 
-bool read_in(int & k, MatrixN & xref, MatrixN & fsteps)
-{
+bool read_in(int& k, MatrixN& xref, MatrixN& fsteps) {
   const std::lock_guard<std::mutex> lockIn(mutexIn);
-  if (shared_newIn)
-  {
-    // std::cout << "Reading memory" << std::endl;
-    /*std::cout << "Shared k" << std::endl << shared_k << std::endl;
-    std::cout << "Shared xref" << std::endl << shared_xref << std::endl;
-    std::cout << "Shared fsteps" << std::endl << shared_fsteps << std::endl;*/
+  if (shared_newIn) {
     k = shared_k;
     xref = shared_xref;
     fsteps = shared_fsteps;
@@ -58,77 +45,63 @@ bool read_in(int & k, MatrixN & xref, MatrixN & fsteps)
   return false;
 }
 
-void write_out(MatrixN & result)
-{
+void write_out(MatrixN& result) {
   const std::lock_guard<std::mutex> lockOut(mutexOut);
-  // std::cout << "Writing result" << std::endl;
   shared_result = result;
-  // std::cout << "Shared result" << std::endl << shared_result << std::endl;
-  shared_newOut = true; // New data is available
+  shared_newOut = true;  // New data is available
 }
 
-bool check_new_result()
-{
+bool check_new_result() {
   const std::lock_guard<std::mutex> lockOut(mutexOut);
-  if (shared_newOut)
-  {
-    // std::cout << "NEW RESULT DETECTED" << std::endl;
+  if (shared_newOut) {
     shared_newOut = false;
     return true;
   }
   return false;
 }
 
-MatrixN read_out()
-{
+MatrixN read_out() {
   const std::lock_guard<std::mutex> lockOut(mutexOut);
-  // std::cout << "NEW RESULT OUTPUTTING" << std::endl;
   return shared_result;
 }
 
-void parallel_loop()
-{
+void parallel_loop() {
   int k;
   MatrixN xref;
   MatrixN fsteps;
   MatrixN result;
   MPC loop_mpc = MPC(*shared_params);  // Create the MPC object running in parallel
-  while (check_stop_thread())
-  {
+  while (check_stop_thread()) {
     // Checking if new data is available to trigger the asynchronous MPC
-    if (read_in(k, xref, fsteps))
-    {
-        // std::cout << "NEW DATA AVAILABLE, LAUNCHING MPC" << std::endl;
-
-        /*std::cout << "Parallel k" << std::endl << k << std::endl;
-        std::cout << "Parallel xref" << std::endl << xref << std::endl;
-        std::cout << "Parallel fsteps" << std::endl << fsteps << std::endl;*/
-
-        // Run the asynchronous MPC with the data that as been retrieved
-        loop_mpc.run(k, xref, fsteps);
-
-        // Store the result (predicted state + desired forces) in the shared memory
-        // MPC::get_latest_result() returns a matrix of size 24 x N and we want to
-        // retrieve only the 2 first columns i.e. dataOut.block(0, 0, 24, 2)
-        // std::cout << "NEW RESULT AVAILABLE, WRITING OUT" << std::endl;
-        result = loop_mpc.get_latest_result();
-        write_out(result);
-    }
-    else
-    {
+    if (read_in(k, xref, fsteps)) {
+      // std::cout << "NEW DATA AVAILABLE, LAUNCHING MPC" << std::endl;
+
+      /*std::cout << "Parallel k" << std::endl << k << std::endl;
+      std::cout << "Parallel xref" << std::endl << xref << std::endl;
+      std::cout << "Parallel fsteps" << std::endl << fsteps << std::endl;*/
+
+      // Run the asynchronous MPC with the data that as been retrieved
+      loop_mpc.run(k, xref, fsteps);
+
+      // Store the result (predicted state + desired forces) in the shared memory
+      // MPC::get_latest_result() returns a matrix of size 24 x N and we want to
+      // retrieve only the 2 first columns i.e. dataOut.block(0, 0, 24, 2)
+      // std::cout << "NEW RESULT AVAILABLE, WRITING OUT" << std::endl;
+      result = loop_mpc.get_latest_result();
+      write_out(result);
+    } else {
       std::this_thread::sleep_for(std::chrono::milliseconds(1));  // Wait a bit
     }
   }
 }
 
 MpcWrapper::MpcWrapper()
-  : test(0),
-    last_available_result(Eigen::Matrix<double, 24, 2>::Zero()),
-    gait_past(Matrix14::Zero()),
-    gait_next(Matrix14::Zero()) {}
+    : test(0),
+      last_available_result(Eigen::Matrix<double, 24, 2>::Zero()),
+      gait_past(Matrix14::Zero()),
+      gait_next(Matrix14::Zero()) {}
 
 void MpcWrapper::initialize(Params& params) {
-  
   params_ = &params;
   mpc_ = MPC(params);
 
@@ -141,27 +114,9 @@ void MpcWrapper::initialize(Params& params) {
   shared_k = 42;
   shared_xref = MatrixN::Zero(12, params.gait.rows() + 1);
   shared_fsteps = MatrixN::Zero(params.gait.rows(), 12);
-
 }
 
 void MpcWrapper::solve(int k, MatrixN xref, MatrixN fsteps, MatrixN gait) {
-  
-  /*std::cout << "SIZES" << std::endl;
-  std::cout << sizeof((int)5) << std::endl;
-  std::cout << sizeof(MatrixN::Zero(12, params_->gait.rows() + 1)) << std::endl;
-  std::cout << sizeof(MatrixN::Zero(params_->gait.rows(), 12)) << std::endl;
-  std::cout << params_->gait << std::endl;*/
-
-  /*double t = 0;
-  while (t < 15.0)
-  {
-    std::cout << "Waiting" << std::endl;
-    write_in(k, xref, fsteps);
-    k++;
-    t += 0.5;
-    std::this_thread::sleep_for(std::chrono::milliseconds(500));
-  }*/
-
   // std::cout << "NEW DATA AVAILABLE, WRITING IN" << std::endl;
   write_in(k, xref, fsteps);
 
@@ -171,12 +126,11 @@ void MpcWrapper::solve(int k, MatrixN xref, MatrixN fsteps, MatrixN gait) {
     if (gait_next.isApprox(gait.row(0)))  // If we're still doing what was planned the last time MPC was solved
     {
       last_available_result.col(0).tail(12) = last_available_result.col(1).tail(12);
-    }
-    else  // Otherwise use a default contact force command till we get the actual result of the MPC for this new sequence
+    } else  // Otherwise use a default contact force command till we get the actual result of the MPC for this new
+            // sequence
     {
       double F = 9.81 * params_->mass / gait.row(0).sum();
-      for (int i = 0; i < 4; i++) 
-      {
+      for (int i = 0; i < 4; i++) {
         last_available_result.block(12 + 3 * i, 0, 3, 1) << 0.0, 0.0, F;
       }
     }
@@ -186,11 +140,9 @@ void MpcWrapper::solve(int k, MatrixN xref, MatrixN fsteps, MatrixN gait) {
   gait_next = gait.row(1);
 }
 
-Eigen::Matrix<double, 24, 2> MpcWrapper::get_latest_result()
-{
+Eigen::Matrix<double, 24, 2> MpcWrapper::get_latest_result() {
   // Retrieve data from parallel process if a new result is available
-  if (check_new_result())
-  {
+  if (check_new_result()) {
     last_available_result = read_out().block(0, 0, 24, 2);
   }
   // std::cout << "get_latest_result: " << std::endl << last_available_result.transpose() << std::endl;
-- 
GitLab