From c22e0f2c7eba67a9c7686550efed2b8a91df8f4e Mon Sep 17 00:00:00 2001
From: paleziart <paleziart@laas.fr>
Date: Tue, 13 Jul 2021 18:15:02 +0200
Subject: [PATCH] Replace python estimator by C++ version + Adapt logger for
 new estimator

---
 include/qrw/Estimator.hpp | 30 ++++++++++++---
 python/gepadd.cpp         | 14 +++++++
 scripts/Controller.py     | 79 +++++++++++----------------------------
 scripts/LoggerControl.py  | 43 ++++++++++-----------
 scripts/utils_mpc.py      |  6 +--
 src/Estimator.cpp         | 44 ++++++++++------------
 6 files changed, 101 insertions(+), 115 deletions(-)

diff --git a/include/qrw/Estimator.hpp b/include/qrw/Estimator.hpp
index ad50a3e2..254400dc 100644
--- a/include/qrw/Estimator.hpp
+++ b/include/qrw/Estimator.hpp
@@ -63,12 +63,13 @@ public:
     Vector3 getDX() { return dx_; }         ///< Get the derivative of the input quantity
     Vector3 getHpX() { return HP_x_; }      ///< Get the high-passed internal quantity
     Vector3 getLpX() { return LP_x_; }      ///< Get the low-passed internal quantity
+    Vector3 getAlpha() {return alpha_; }     ///< Get the alpha coefficient of the filter
     Vector3 getFiltX() { return filt_x_; }  ///< Get the filtered output
 
 private:
     
     double dt_;
-    Vector3 x_, dx_, HP_x_, LP_x_, filt_x_;
+    Vector3 x_, dx_, HP_x_, LP_x_, alpha_, filt_x_;
    
 };
 
@@ -108,7 +109,7 @@ public:
     /// \param[in] baseOrientation Quaternion orientation of the IMU
     ///
     ////////////////////////////////////////////////////////////////////////////////////////////////
-    void get_data_IMU(Vector3 baseLinearAcceleration, Vector3 baseAngularVelocity, Vector4 baseOrientation);
+    void get_data_IMU(Vector3 const& baseLinearAcceleration, Vector3 const& baseAngularVelocity, Vector4 const& baseOrientation);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     ///
@@ -118,7 +119,7 @@ public:
     /// \param[in] v_mes velocity of the 12 actuators
     ///
     ////////////////////////////////////////////////////////////////////////////////////////////////
-    void get_data_joints(Vector12 q_mes, Vector12 v_mes);
+    void get_data_joints(Vector12 const& q_mes, Vector12 const& v_mes);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     ///
@@ -127,7 +128,7 @@ public:
     /// \param[in] feet_status contact status of the four feet
     ///
     ////////////////////////////////////////////////////////////////////////////////////////////////
-    void get_data_FK(Eigen::Matrix<double, 1, 4> feet_status);
+    void get_data_FK(Eigen::Matrix<double, 1, 4> const& feet_status);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     ///
@@ -137,7 +138,7 @@ public:
     /// \param[in] goals target positions of the four feet
     ///
     ////////////////////////////////////////////////////////////////////////////////////////////////
-    void get_xyz_feet(Eigen::Matrix<double, 1, 4> feet_status, Matrix34 goals);
+    void get_xyz_feet(Eigen::Matrix<double, 1, 4> const& feet_status, Matrix34 const& goals);
 
     ////////////////////////////////////////////////////////////////////////////////////////////////
     ///
@@ -172,6 +173,22 @@ public:
     MatrixN getVFilt() { return v_filt_dyn_; }
     MatrixN getVSecu() { return v_secu_dyn_; }
     Vector3 getRPY() { return IMU_RPY_; }
+    MatrixN getFeetStatus() { return feet_status_;}
+    MatrixN getFeetGoals() { return feet_goals_; }
+    Vector3 getFKLinVel() { return FK_lin_vel_; }
+    Vector3 getFKXYZ() { return FK_xyz_; }
+    Vector3 getXYZMeanFeet() { return xyz_mean_feet_; }
+    Vector3 getFiltLinVel() { return b_filt_lin_vel_; }
+
+    Vector3 getFilterVelX() { return filter_xyz_vel_.getX(); }
+    Vector3 getFilterVelDX() { return filter_xyz_vel_.getDX(); }
+    Vector3 getFilterVelAlpha() { return filter_xyz_vel_.getAlpha(); }
+    Vector3 getFilterVelFiltX() { return filter_xyz_vel_.getFiltX(); }
+
+    Vector3 getFilterPosX() { return filter_xyz_pos_.getX(); }
+    Vector3 getFilterPosDX() { return filter_xyz_pos_.getDX(); }
+    Vector3 getFilterPosAlpha() { return filter_xyz_pos_.getAlpha(); }
+    Vector3 getFilterPosFiltX() { return filter_xyz_pos_.getFiltX(); }
 
 private:
 
@@ -195,8 +212,11 @@ private:
 
     Vector19 q_FK_;  // Configuration vector for Forward Kinematics
     Vector18 v_FK_;  // Velocity vector for Forward Kinematics
+    MatrixN feet_status_;  // Contact status of the four feet
+    MatrixN feet_goals_;  // Target positions of the four feet
     Vector3 FK_lin_vel_;  // Base linear velocity estimated by Forward Kinematics
     Vector3 FK_xyz_;  // Base position estimated by Forward Kinematics
+    Vector3 b_filt_lin_vel_;  // Filtered estimated velocity at center base (base frame)
 
     Vector3 xyz_mean_feet_;  // Barycenter of feet in contact
 
diff --git a/python/gepadd.cpp b/python/gepadd.cpp
index ebf779f1..5d5bd30d 100644
--- a/python/gepadd.cpp
+++ b/python/gepadd.cpp
@@ -260,6 +260,20 @@ struct EstimatorPythonVisitor : public bp::def_visitor<EstimatorPythonVisitor<Es
             .def("getVFilt", &Estimator::getVFilt, "Get filtered velocity.\n")
             .def("getVSecu", &Estimator::getVSecu, "Get filtered velocity for security check.\n")
             .def("getRPY", &Estimator::getRPY, "Get Roll Pitch Yaw.\n")
+            .def("getFeetStatus", &Estimator::getFeetStatus, "")
+            .def("getFeetGoals", &Estimator::getFeetGoals, "")
+            .def("getFKLinVel", &Estimator::getFKLinVel, "")
+            .def("getFKXYZ", &Estimator::getFKXYZ, "")
+            .def("getXYZMeanFeet", &Estimator::getXYZMeanFeet, "")
+            .def("getFiltLinVel", &Estimator::getFiltLinVel, "")
+            .def("getFilterVelX", &Estimator::getFilterVelX, "")
+            .def("getFilterVelDX", &Estimator::getFilterVelDX, "")
+            .def("getFilterVelAlpha", &Estimator::getFilterVelAlpha, "")
+            .def("getFilterVelFiltX", &Estimator::getFilterVelFiltX, "")
+            .def("getFilterPosX", &Estimator::getFilterPosX, "")
+            .def("getFilterPosDX", &Estimator::getFilterPosDX, "")
+            .def("getFilterPosAlpha", &Estimator::getFilterPosAlpha, "")
+            .def("getFilterPosFiltX", &Estimator::getFilterPosFiltX, "")
 
             // Run Estimator from Python
             .def("run_filter", &Estimator::run_filter, bp::args("gait", "goals", "baseLinearAcceleration",
diff --git a/scripts/Controller.py b/scripts/Controller.py
index ef8d7a46..3f906b34 100644
--- a/scripts/Controller.py
+++ b/scripts/Controller.py
@@ -105,8 +105,8 @@ class Controller:
         # Initialisation of the solo model/data and of the Gepetto viewer
         self.solo = utils_mpc.init_robot(q_init, params, self.enable_gepetto_viewer)
 
-        # Create Joystick, FootstepPlanner, Logger and Interface objects
-        self.joystick, self.estimator = utils_mpc.init_objects(params)
+        # Create Joystick object
+        self.joystick = utils_mpc.init_objects(params)
 
         # Enable/Disable hybrid control
         self.enable_hybrid_control = True
@@ -131,8 +131,8 @@ class Controller:
         self.footTrajectoryGenerator = lqrw.FootTrajectoryGenerator()
         self.footTrajectoryGenerator.initialize(params, self.gait)
 
-        self.estimator_bis = lqrw.Estimator()
-        self.estimator_bis.initialize(params)
+        self.estimator = lqrw.Estimator()
+        self.estimator.initialize(params)
 
         # Wrapper that makes the link with the solver that you want to use for the MPC
         self.mpc_wrapper = MPC_Wrapper.MPC_Wrapper(params, self.q)
@@ -202,47 +202,16 @@ class Controller:
         # Update the reference velocity coming from the gamepad
         self.joystick.update_v_ref(self.k, self.velID)
 
-        self.estimator_bis.run_filter(self.gait.getCurrentGait(),
-                                      self.footTrajectoryGenerator.getFootPosition(),
-                                      device.baseLinearAcceleration.reshape((-1, 1)),
-                                      device.baseAngularVelocity.reshape((-1, 1)),
-                                      device.baseOrientation.reshape((-1, 1)),
-                                      device.q_mes.reshape((-1, 1)),
-                                      device.v_mes.reshape((-1, 1)),
-                                      device.dummyPos.reshape((-1, 1)),
-                                      device.b_baseVel.reshape((-1, 1)))
-
         # Process state estimator
-        """self.estimator.run_filter(self.k, self.gait.getCurrentGait(),
-                                  device, self.footTrajectoryGenerator.getFootPosition())"""
-        """, self.estimator_bis.getVFilt()[0:3]),
-                                  self.estimator_bis.debug2(), self.estimator_bis.debug3(), self.estimator_bis.debug4(), self.estimator_bis.debug5(),
-                                  self.estimator_bis.debug6(), self.estimator_bis.debug7(),
-                                  self.estimator_bis.debug8(), self.estimator_bis.debug9())"""
-
-        self.estimator.q_filt[:, 0] = self.estimator_bis.getQFilt()
-        self.estimator.v_filt[:, 0] = self.estimator_bis.getVFilt()
-        self.estimator.v_secu[:] = self.estimator_bis.getVSecu()
-        self.estimator.RPY = self.estimator_bis.getRPY()
-
-        """from IPython import embed
-        embed()"""
-
-        """if self.k % 10 == 0:
-            print("q_filt: ", np.allclose(self.estimator.q_filt.ravel(), self.estimator_bis.getQFilt()))
-            print("v_filt: ", np.allclose(self.estimator.v_filt.ravel(), self.estimator_bis.getVFilt()))
-            print("v_secu: ", np.allclose(self.estimator.v_secu.ravel(), self.estimator_bis.getVSecu()))
-            print("RPY: ", np.allclose(self.estimator.RPY.ravel(), self.estimator_bis.getRPY()))
-
-            from IPython import embed
-            embed()"""
-        """if self.k == 50:
-            print("q_filt: ", self.estimator.q_filt.ravel())
-            print("v_filt: ", self.estimator.v_filt.ravel())
-            print("v_secu: ", self.estimator.v_secu.ravel())
-            print("RPY: ", self.estimator.RPY.ravel())
-            from IPython import embed
-            embed()"""
+        self.estimator.run_filter(self.gait.getCurrentGait(),
+                                  self.footTrajectoryGenerator.getFootPosition(),
+                                  device.baseLinearAcceleration.reshape((-1, 1)),
+                                  device.baseAngularVelocity.reshape((-1, 1)),
+                                  device.baseOrientation.reshape((-1, 1)),
+                                  device.q_mes.reshape((-1, 1)),
+                                  device.v_mes.reshape((-1, 1)),
+                                  device.dummyPos.reshape((-1, 1)),
+                                  device.b_baseVel.reshape((-1, 1)))
 
         t_filter = time.time()
 
@@ -385,14 +354,14 @@ class Controller:
     def security_check(self):
 
         if (self.error_flag == 0) and (not self.myController.error) and (not self.joystick.stop):
-            if np.any(np.abs(self.estimator.q_filt[7:, 0]) > self.q_security):
+            if np.any(np.abs(self.estimator.getQFilt()[7:]) > self.q_security):
                 self.myController.error = True
                 self.error_flag = 1
-                self.error_value = self.estimator.q_filt[7:, 0] * 180 / 3.1415
-            if np.any(np.abs(self.estimator.v_secu) > 50):
+                self.error_value = self.estimator.getQFilt()[7:] * 180 / 3.1415
+            if np.any(np.abs(self.estimator.getVSecu()) > 50):
                 self.myController.error = True
                 self.error_flag = 2
-                self.error_value = self.estimator.v_secu
+                self.error_value = self.estimator.getVSecu()
             if np.any(np.abs(self.myController.tau_ff) > 8):
                 print(self.result.P)
                 print(self.result.D)
@@ -415,10 +384,6 @@ class Controller:
 
     def log_misc(self, tic, t_filter, t_planner, t_mpc, t_wbc):
 
-        # Log joystick command
-        if self.joystick is not None:
-            self.estimator.v_ref = self.joystick.v_ref
-
         self.t_list_filter[self.k] = t_filter - tic
         self.t_list_planner[self.k] = t_planner - t_filter
         self.t_list_mpc[self.k] = t_mpc - t_planner
@@ -443,18 +408,18 @@ class Controller:
             self.q[0:2, 0:1] = self.q[0:2, 0:1] + Ryaw @ self.v_ref[0:2, 0:1] * self.myController.dt
 
             # Mix perfect x and y with height measurement
-            self.q[2, 0] = self.estimator.q_filt[2, 0]
+            self.q[2, 0] = self.estimator.getQFilt()[2]
 
             # Mix perfect yaw with pitch and roll measurements
             self.yaw_estim += self.v_ref[5, 0] * self.myController.dt
-            self.q[3:7, 0] = pin.Quaternion(pin.rpy.rpyToMatrix(self.estimator.RPY[0], self.estimator.RPY[1], self.yaw_estim)).coeffs()
+            self.q[3:7, 0] = pin.Quaternion(pin.rpy.rpyToMatrix(self.estimator.getRPY()[0], self.estimator.getRPY()[1], self.yaw_estim)).coeffs()
 
             # Actuators measurements
-            self.q[7:, 0] = self.estimator.q_filt[7:, 0]
+            self.q[7:, 0] = self.estimator.getQFilt()[7:]
 
             # Velocities are the one estimated by the estimator
-            self.v = self.estimator.v_filt.copy()
-            hRb = pin.rpy.rpyToMatrix(self.estimator.RPY[0], self.estimator.RPY[1], 0.0)
+            self.v = self.estimator.getVFilt().reshape((-1, 1))
+            hRb = pin.rpy.rpyToMatrix(self.estimator.getRPY()[0], self.estimator.getRPY()[1], 0.0)
 
             self.h_v[0:3, 0:1] = hRb @ self.v[0:3, 0:1]
             self.h_v[3:6, 0:1] = hRb @ self.v[3:6, 0:1]
diff --git a/scripts/LoggerControl.py b/scripts/LoggerControl.py
index af1a27f8..a22fcffa 100644
--- a/scripts/LoggerControl.py
+++ b/scripts/LoggerControl.py
@@ -109,29 +109,26 @@ class LoggerControl():
         self.joy_v_ref[self.i] = joystick.v_ref[:, 0]
 
         # Logging from estimator
-        self.esti_feet_status[self.i] = estimator.feet_status[:]
-        self.esti_feet_goals[self.i] = estimator.feet_goals
-        self.esti_q_filt[self.i] = estimator.q_filt[:, 0]
-        self.esti_v_filt[self.i] = estimator.v_filt[:, 0]
-        self.esti_v_secu[self.i] = estimator.v_secu[:]
-
-        self.esti_FK_lin_vel[self.i] = estimator.FK_lin_vel[:]
-        self.esti_FK_xyz[self.i] = estimator.FK_xyz[:]
-        self.esti_xyz_mean_feet[self.i] = estimator.xyz_mean_feet[:]
-        self.esti_filt_lin_vel[self.i] = estimator.filt_lin_vel[:]
-        if not estimator.kf_enabled:
-            self.esti_HP_x[self.i] = estimator.filter_xyz_vel.x
-            self.esti_HP_dx[self.i] = estimator.filter_xyz_vel.dx
-            self.esti_HP_alpha[self.i] = estimator.filter_xyz_vel.alpha
-            self.esti_HP_filt_x[self.i] = estimator.filter_xyz_vel.filt_x
-
-            self.esti_LP_x[self.i] = estimator.filter_xyz_pos.x
-            self.esti_LP_dx[self.i] = estimator.filter_xyz_pos.dx
-            self.esti_LP_alpha[self.i] = estimator.filter_xyz_pos.alpha
-            self.esti_LP_filt_x[self.i] = estimator.filter_xyz_pos.filt_x
-        else:
-            self.esti_kf_X[self.i] = estimator.kf.X[:, 0]
-            self.esti_kf_Z[self.i] = estimator.Z[:, 0]
+        self.esti_feet_status[self.i] = estimator.getFeetStatus()
+        self.esti_feet_goals[self.i] = estimator.getFeetGoals()
+        self.esti_q_filt[self.i] = estimator.getQFilt()
+        self.esti_v_filt[self.i] = estimator.getVFilt()
+        self.esti_v_secu[self.i] = estimator.getVSecu()
+
+        self.esti_FK_lin_vel[self.i] = estimator.getFKLinVel()
+        self.esti_FK_xyz[self.i] = estimator.getFKXYZ()
+        self.esti_xyz_mean_feet[self.i] = estimator.getXYZMeanFeet()
+        self.esti_filt_lin_vel[self.i] = estimator.getFiltLinVel()
+
+        self.esti_HP_x[self.i] = estimator.getFilterVelX()
+        self.esti_HP_dx[self.i] = estimator.getFilterVelDX()
+        self.esti_HP_alpha[self.i] = estimator.getFilterVelAlpha()
+        self.esti_HP_filt_x[self.i] = estimator.getFilterVelFiltX()
+
+        self.esti_LP_x[self.i] = estimator.getFilterPosX()
+        self.esti_LP_dx[self.i] = estimator.getFilterPosDX()
+        self.esti_LP_alpha[self.i] = estimator.getFilterPosAlpha()
+        self.esti_LP_filt_x[self.i] = estimator.getFilterPosFiltX()
 
         # Logging from the main loop
         self.loop_o_q_int[self.i] = loop.q[:, 0]
diff --git a/scripts/utils_mpc.py b/scripts/utils_mpc.py
index 43a87308..563cae75 100644
--- a/scripts/utils_mpc.py
+++ b/scripts/utils_mpc.py
@@ -201,11 +201,7 @@ def init_objects(params):
     # Create Joystick object
     joystick = Joystick.Joystick(params.predefined_vel)
 
-    # Create Estimator object
-    estimator = Estimator.Estimator(params.dt_wbc, params.N_SIMULATION, params.h_ref, params.kf_enabled,
-                                    params.perfect_estimator)
-
-    return joystick, estimator
+    return joystick
 
 
 def display_all(solo, k, sequencer, fstep_planner, ftraj_gen, mpc):
diff --git a/src/Estimator.cpp b/src/Estimator.cpp
index 14c8b84f..3bb1b2fa 100644
--- a/src/Estimator.cpp
+++ b/src/Estimator.cpp
@@ -9,6 +9,7 @@ ComplementaryFilter::ComplementaryFilter()
     , dx_(Vector3::Zero())
     , HP_x_(Vector3::Zero())
     , LP_x_(Vector3::Zero())
+    , alpha_(Vector3::Zero())
     , filt_x_(Vector3::Zero())
 {
 }
@@ -27,6 +28,7 @@ Vector3 ComplementaryFilter::compute(Vector3 const& x, Vector3 const& dx, Vector
     // For logging
     x_ = x;
     dx_ = dx;
+    alpha_ = alpha;
 
     // Process high pass filter
     HP_x_ = alpha.cwiseProduct(HP_x_ + dx_ * dt_);
@@ -60,8 +62,11 @@ Estimator::Estimator()
     , actuators_vel_(Vector12::Zero())
     , q_FK_(Vector19::Zero())
     , v_FK_(Vector18::Zero())
+    , feet_status_(MatrixN::Zero(1, 4))
+    , feet_goals_(MatrixN::Zero(3, 4))
     , FK_lin_vel_(Vector3::Zero())
     , FK_xyz_(Vector3::Zero())
+    , b_filt_lin_vel_(Vector3::Zero())
     , xyz_mean_feet_(Vector3::Zero())
     , k_since_contact_(Eigen::Matrix<double, 1, 4>::Zero())
     , q_filt_(Vector19::Zero())
@@ -118,7 +123,7 @@ void Estimator::initialize(Params& params)
 }
 
 
-void Estimator::get_data_IMU(Vector3 baseLinearAcceleration, Vector3 baseAngularVelocity, Vector4 baseOrientation)
+void Estimator::get_data_IMU(Vector3 const& baseLinearAcceleration, Vector3 const& baseAngularVelocity, Vector4 const& baseOrientation)
 {
     // Linear acceleration of the trunk (base frame)
     IMU_lin_acc_ = baseLinearAcceleration;
@@ -142,14 +147,14 @@ void Estimator::get_data_IMU(Vector3 baseLinearAcceleration, Vector3 baseAngular
 }
 
 
-void Estimator::get_data_joints(Vector12 q_mes, Vector12 v_mes) 
+void Estimator::get_data_joints(Vector12 const& q_mes, Vector12 const& v_mes) 
 {
     actuators_pos_ = q_mes;
     actuators_vel_ = v_mes;
 }
 
       
-void Estimator::get_data_FK(Eigen::Matrix<double, 1, 4> feet_status)
+void Estimator::get_data_FK(Eigen::Matrix<double, 1, 4> const& feet_status)
 {
     // Update estimator FK model
     q_FK_.tail(12) = actuators_pos_; // Position of actuators
@@ -209,7 +214,7 @@ void Estimator::get_data_FK(Eigen::Matrix<double, 1, 4> feet_status)
 }
 
 
-void Estimator::get_xyz_feet(Eigen::Matrix<double, 1, 4> feet_status, Matrix34 goals)
+void Estimator::get_xyz_feet(Eigen::Matrix<double, 1, 4> const& feet_status, Matrix34 const& goals)
 {
     int cpt = 0;
     Vector3 xyz_feet = Vector3::Zero();
@@ -256,6 +261,9 @@ void Estimator::run_filter(MatrixN const& gait, MatrixN const& goals, VectorN co
                            VectorN const& baseAngularVelocity, VectorN const& baseOrientation, VectorN const& q_mes,
                            VectorN const& v_mes, VectorN const& dummyPos, VectorN const& b_baseVel)
 {
+    feet_status_ = gait.block(0, 0, 1, 4);
+    feet_goals_ = goals;
+
     int remaining_steps = 1;  // Remaining MPC steps for the current gait phase
     while((gait.block(0, 0, 1, 4)).isApprox(gait.row(remaining_steps))) {
         remaining_steps++;
@@ -274,14 +282,14 @@ void Estimator::run_filter(MatrixN const& gait, MatrixN const& goals, VectorN co
     get_data_joints(q_mes, v_mes);
 
     // Update nb of iterations since contact
-    k_since_contact_ += gait.block(0, 0, 1, 4);  // Increment feet in stance phase
-    k_since_contact_ = k_since_contact_.cwiseProduct(gait.block(0, 0, 1, 4));  // Reset feet in swing phase
+    k_since_contact_ += feet_status_;  // Increment feet in stance phase
+    k_since_contact_ = k_since_contact_.cwiseProduct(feet_status_);  // Reset feet in swing phase
 
     // Update forward kinematics data
-    get_data_FK(gait.block(0, 0, 1, 4));
+    get_data_FK(feet_status_);
 
     // Update forward geometry data
-    get_xyz_feet(gait.block(0, 0, 1, 4), goals);
+    get_xyz_feet(feet_status_, goals);
 
     // Tune alpha depending on the state of the gait (close to contact switch or not)
     double a = std::ceil(k_since_contact_.maxCoeff() * 0.1) - 1;
@@ -321,29 +329,15 @@ void Estimator::run_filter(MatrixN const& gait, MatrixN const& goals, VectorN co
     Vector3 i_filt_lin_vel = oRb.transpose() * oi_filt_lin_vel;
 
     // Filtered estimated velocity at center base (base frame)
-    Vector3 b_filt_lin_vel = i_filt_lin_vel - cross_product;
+    b_filt_lin_vel_ = i_filt_lin_vel - cross_product;
 
     // Filtered estimated velocity at center base (world frame)
-    Vector3 ob_filt_lin_vel = oRb * b_filt_lin_vel;
+    Vector3 ob_filt_lin_vel = oRb * b_filt_lin_vel_;
 
     // Position of the center of the base from FGeometry and filtered velocity (world frame)
     Vector3 filt_lin_pos = filter_xyz_pos_.compute(FK_xyz_ + xyz_mean_feet_, ob_filt_lin_vel, 
                                                    Vector3(0.995, 0.995, 0.9));
 
-    // Velocity of the center of the base (base frame)
-    Vector3 filt_lin_vel = b_filt_lin_vel;
-
-    // Logging
-    /*self.log_alpha[self.k_log] = self.alpha
-    self.feet_status[:] = feet_status  // Save contact status sent to the estimator for logging
-    self.feet_goals[:, :] = goals.copy()  // Save feet goals sent to the estimator for logging
-    self.log_IMU_lin_acc[:, self.k_log] = self.IMU_lin_acc[:]
-    self.log_HP_lin_vel[:, self.k_log] = self.HP_lin_vel[:]
-    self.log_LP_lin_vel[:, self.k_log] = self.LP_lin_vel[:]
-    self.log_FK_lin_vel[:, self.k_log] = self.FK_lin_vel[:]
-    self.log_filt_lin_vel[:, self.k_log] = self.filt_lin_vel[:]
-    self.log_o_filt_lin_vel[:, self.k_log] = self.o_filt_lin_vel[:, 0]*/
-
     // Output filtered position vector (19 x 1)
     q_filt_.head(3) = filt_lin_pos;
     if(perfect_estimator) {  // Base height directly from PyBullet
@@ -357,7 +351,7 @@ void Estimator::run_filter(MatrixN const& gait, MatrixN const& goals, VectorN co
         v_filt_.head(3) = (1 - alpha_v_) * v_filt_.head(3) + alpha_v_ * b_baseVel;
     }
     else {
-        v_filt_.head(3) = (1 - alpha_v_) * v_filt_.head(3) + alpha_v_ * filt_lin_vel;
+        v_filt_.head(3) = (1 - alpha_v_) * v_filt_.head(3) + alpha_v_ * b_filt_lin_vel_;
     }
     v_filt_.block(3, 0, 3, 1) = filt_ang_vel;  // Angular velocities are already directly from PyBullet
     v_filt_.tail(12) = actuators_vel_;  // Actuators velocities are already directly from PyBullet
-- 
GitLab