1 |
|
|
/* |
2 |
|
|
* Copyright 2017, Thomas Flayols, LAAS-CNRS |
3 |
|
|
* |
4 |
|
|
*/ |
5 |
|
|
|
6 |
|
|
#ifndef __sot_torque_control_base_estimator_H__ |
7 |
|
|
#define __sot_torque_control_base_estimator_H__ |
8 |
|
|
|
9 |
|
|
/* --------------------------------------------------------------------- */ |
10 |
|
|
/* --- API ------------------------------------------------------------- */ |
11 |
|
|
/* --------------------------------------------------------------------- */ |
12 |
|
|
|
13 |
|
|
#if defined(WIN32) |
14 |
|
|
#if defined(base_estimator_EXPORTS) |
15 |
|
|
#define SOTBASEESTIMATOR_EXPORT __declspec(dllexport) |
16 |
|
|
#else |
17 |
|
|
#define SOTBASEESTIMATOR_EXPORT __declspec(dllimport) |
18 |
|
|
#endif |
19 |
|
|
#else |
20 |
|
|
#define SOTBASEESTIMATOR_EXPORT |
21 |
|
|
#endif |
22 |
|
|
|
23 |
|
|
/* --------------------------------------------------------------------- */ |
24 |
|
|
/* --- INCLUDE --------------------------------------------------------- */ |
25 |
|
|
/* --------------------------------------------------------------------- */ |
26 |
|
|
|
27 |
|
|
#include <pinocchio/fwd.hpp> |
28 |
|
|
|
29 |
|
|
// include pinocchio first |
30 |
|
|
|
31 |
|
|
#include <map> |
32 |
|
|
|
33 |
|
|
#include "boost/assign.hpp" |
34 |
|
|
// #include <boost/random/normal_distribution.hpp> |
35 |
|
|
#include <boost/math/distributions/normal.hpp> // for normal_distribution |
36 |
|
|
|
37 |
|
|
/* Pinocchio */ |
38 |
|
|
#include <pinocchio/algorithm/kinematics.hpp> |
39 |
|
|
#include <pinocchio/multibody/model.hpp> |
40 |
|
|
#include <pinocchio/parsers/urdf.hpp> |
41 |
|
|
|
42 |
|
|
/* HELPER */ |
43 |
|
|
#include <dynamic-graph/signal-helper.h> |
44 |
|
|
|
45 |
|
|
#include <sot/core/matrix-geometry.hh> |
46 |
|
|
#include <sot/core/robot-utils.hh> |
47 |
|
|
#include <sot/torque_control/utils/vector-conversions.hh> |
48 |
|
|
|
49 |
|
|
namespace dynamicgraph { |
50 |
|
|
namespace sot { |
51 |
|
|
namespace torque_control { |
52 |
|
|
|
53 |
|
|
/* --------------------------------------------------------------------- */ |
54 |
|
|
/* --- CLASS ----------------------------------------------------------- */ |
55 |
|
|
/* --------------------------------------------------------------------- */ |
56 |
|
|
|
57 |
|
|
/** Compute s12 as an intermediate transform between s1 and s2 SE3 transforms**/ |
58 |
|
|
void se3Interp(const pinocchio::SE3& s1, const pinocchio::SE3& s2, |
59 |
|
|
const double alpha, pinocchio::SE3& s12); |
60 |
|
|
|
61 |
|
|
/** Convert from Roll, Pitch, Yaw to transformation Matrix. */ |
62 |
|
|
void rpyToMatrix(double r, double p, double y, Eigen::Matrix3d& R); |
63 |
|
|
|
64 |
|
|
/** Convert from Roll, Pitch, Yaw to transformation Matrix. */ |
65 |
|
|
void rpyToMatrix(const Eigen::Vector3d& rpy, Eigen::Matrix3d& R); |
66 |
|
|
|
67 |
|
|
/** Convert from Transformation Matrix to Roll, Pitch, Yaw */ |
68 |
|
|
void matrixToRpy(const Eigen::Matrix3d& M, Eigen::Vector3d& rpy); |
69 |
|
|
|
70 |
|
|
/** Multiply to quaternions stored in (w,x,y,z) format */ |
71 |
|
|
void quanternionMult(const Eigen::Vector4d& q1, const Eigen::Vector4d& q2, |
72 |
|
|
Eigen::Vector4d& q12); |
73 |
|
|
|
74 |
|
|
/** Rotate a point or a vector by a quaternion stored in (w,x,y,z) format */ |
75 |
|
|
void pointRotationByQuaternion(const Eigen::Vector3d& point, |
76 |
|
|
const Eigen::Vector4d& quat, |
77 |
|
|
Eigen::Vector3d& rotatedPoint); |
78 |
|
|
|
79 |
|
|
class SOTBASEESTIMATOR_EXPORT BaseEstimator : public ::dynamicgraph::Entity { |
80 |
|
|
typedef BaseEstimator EntityClassName; |
81 |
|
|
typedef pinocchio::SE3 SE3; |
82 |
|
|
typedef Eigen::Vector2d Vector2; |
83 |
|
|
typedef Eigen::Vector3d Vector3; |
84 |
|
|
typedef Eigen::Vector4d Vector4; |
85 |
|
|
typedef dynamicgraph::sot::Vector6d Vector6; |
86 |
|
|
typedef dynamicgraph::sot::Vector7d Vector7; |
87 |
|
|
typedef Eigen::Matrix3d Matrix3; |
88 |
|
|
typedef boost::math::normal normal; |
89 |
|
|
|
90 |
|
|
DYNAMIC_GRAPH_ENTITY_DECL(); |
91 |
|
|
|
92 |
|
|
public: |
93 |
|
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW |
94 |
|
|
|
95 |
|
|
/* --- CONSTRUCTOR ---- */ |
96 |
|
|
BaseEstimator(const std::string& name); |
97 |
|
|
|
98 |
|
|
void init(const double& dt, const std::string& urdfFile); |
99 |
|
|
|
100 |
|
|
void set_fz_stable_windows_size(const int& ws); |
101 |
|
|
void set_alpha_w_filter(const double& a); |
102 |
|
|
void set_alpha_DC_acc(const double& a); |
103 |
|
|
void set_alpha_DC_vel(const double& a); |
104 |
|
|
void reset_foot_positions(); |
105 |
|
|
void set_imu_weight(const double& w); |
106 |
|
|
void set_zmp_std_dev_right_foot(const double& std_dev); |
107 |
|
|
void set_zmp_std_dev_left_foot(const double& std_dev); |
108 |
|
|
void set_normal_force_std_dev_right_foot(const double& std_dev); |
109 |
|
|
void set_normal_force_std_dev_left_foot(const double& std_dev); |
110 |
|
|
void set_stiffness_right_foot(const dynamicgraph::Vector& k); |
111 |
|
|
void set_stiffness_left_foot(const dynamicgraph::Vector& k); |
112 |
|
|
void set_right_foot_sizes(const dynamicgraph::Vector& s); |
113 |
|
|
void set_left_foot_sizes(const dynamicgraph::Vector& s); |
114 |
|
|
void set_zmp_margin_right_foot(const double& margin); |
115 |
|
|
void set_zmp_margin_left_foot(const double& margin); |
116 |
|
|
void set_normal_force_margin_right_foot(const double& margin); |
117 |
|
|
void set_normal_force_margin_left_foot(const double& margin); |
118 |
|
|
|
119 |
|
|
void reset_foot_positions_impl(const Vector6& ftlf, const Vector6& ftrf); |
120 |
|
|
void compute_zmp(const Vector6& w, Vector2& zmp); |
121 |
|
|
double compute_zmp_weight(const Vector2& zmp, const Vector4& foot_sizes, |
122 |
|
|
double std_dev, double margin); |
123 |
|
|
double compute_force_weight(double fz, double std_dev, double margin); |
124 |
|
|
void kinematics_estimation(const Vector6& ft, const Vector6& K, |
125 |
|
|
const SE3& oMfs, const int foot_id, SE3& oMff, |
126 |
|
|
SE3& oMfa, SE3& fsMff); |
127 |
|
|
|
128 |
|
|
/* --- SIGNALS --- */ |
129 |
|
|
DECLARE_SIGNAL_IN(joint_positions, dynamicgraph::Vector); |
130 |
|
|
DECLARE_SIGNAL_IN(joint_velocities, dynamicgraph::Vector); |
131 |
|
|
DECLARE_SIGNAL_IN(imu_quaternion, dynamicgraph::Vector); |
132 |
|
|
DECLARE_SIGNAL_IN(forceLLEG, dynamicgraph::Vector); |
133 |
|
|
DECLARE_SIGNAL_IN(forceRLEG, dynamicgraph::Vector); |
134 |
|
|
DECLARE_SIGNAL_IN( |
135 |
|
|
dforceLLEG, |
136 |
|
|
dynamicgraph::Vector); /// derivative of left force torque sensor |
137 |
|
|
DECLARE_SIGNAL_IN( |
138 |
|
|
dforceRLEG, |
139 |
|
|
dynamicgraph::Vector); /// derivative of right force torque sensor |
140 |
|
|
DECLARE_SIGNAL_IN( |
141 |
|
|
w_lf_in, double); /// weight of the estimation coming from the left foot |
142 |
|
|
DECLARE_SIGNAL_IN( |
143 |
|
|
w_rf_in, double); /// weight of the estimation coming from the right foot |
144 |
|
|
DECLARE_SIGNAL_IN( |
145 |
|
|
K_fb_feet_poses, |
146 |
|
|
double); /// feed back gain to correct feet position according to last |
147 |
|
|
/// base estimation and kinematic |
148 |
|
|
DECLARE_SIGNAL_IN(lf_ref_xyzquat, dynamicgraph::Vector); |
149 |
|
|
DECLARE_SIGNAL_IN(rf_ref_xyzquat, dynamicgraph::Vector); |
150 |
|
|
DECLARE_SIGNAL_IN(accelerometer, dynamicgraph::Vector); |
151 |
|
|
DECLARE_SIGNAL_IN(gyroscope, dynamicgraph::Vector); |
152 |
|
|
|
153 |
|
|
DECLARE_SIGNAL_INNER(kinematics_computations, dynamicgraph::Vector); |
154 |
|
|
|
155 |
|
|
DECLARE_SIGNAL_OUT( |
156 |
|
|
q, dynamicgraph::Vector); /// n+6 robot configuration with base6d in RPY |
157 |
|
|
DECLARE_SIGNAL_OUT(v, dynamicgraph::Vector); /// n+6 robot velocities |
158 |
|
|
DECLARE_SIGNAL_OUT( |
159 |
|
|
v_kin, dynamicgraph::Vector); /// 6d robot velocities from kinematic only |
160 |
|
|
/// (encoders derivative) |
161 |
|
|
DECLARE_SIGNAL_OUT( |
162 |
|
|
v_flex, |
163 |
|
|
dynamicgraph::Vector); /// 6d robot velocities from flexibility only |
164 |
|
|
/// (force sensor derivative) |
165 |
|
|
DECLARE_SIGNAL_OUT( |
166 |
|
|
v_imu, |
167 |
|
|
dynamicgraph::Vector); /// 6d robot velocities form imu only |
168 |
|
|
/// (accelerometer integration + gyro) |
169 |
|
|
DECLARE_SIGNAL_OUT( |
170 |
|
|
v_gyr, dynamicgraph::Vector); /// 6d robot velocities form gyroscope only |
171 |
|
|
/// (as if gyro measured the pure angular |
172 |
|
|
/// ankle velocities) |
173 |
|
|
DECLARE_SIGNAL_OUT(lf_xyzquat, dynamicgraph::Vector); /// left foot pose |
174 |
|
|
DECLARE_SIGNAL_OUT(rf_xyzquat, dynamicgraph::Vector); /// right foot pose |
175 |
|
|
DECLARE_SIGNAL_OUT(a_ac, |
176 |
|
|
dynamicgraph::Vector); /// acceleration of the base in the |
177 |
|
|
/// world with DC component removed |
178 |
|
|
DECLARE_SIGNAL_OUT(v_ac, |
179 |
|
|
dynamicgraph::Vector); /// velocity of the base in the |
180 |
|
|
/// world with DC component removed |
181 |
|
|
|
182 |
|
|
DECLARE_SIGNAL_OUT( |
183 |
|
|
q_lf, |
184 |
|
|
dynamicgraph::Vector); /// n+6 robot configuration with base6d in RPY |
185 |
|
|
DECLARE_SIGNAL_OUT( |
186 |
|
|
q_rf, |
187 |
|
|
dynamicgraph::Vector); /// n+6 robot configuration with base6d in RPY |
188 |
|
|
DECLARE_SIGNAL_OUT( |
189 |
|
|
q_imu, |
190 |
|
|
dynamicgraph::Vector); /// n+6 robot configuration with base6d in RPY |
191 |
|
|
DECLARE_SIGNAL_OUT( |
192 |
|
|
w_lf, double); /// weight of the estimation coming from the left foot |
193 |
|
|
DECLARE_SIGNAL_OUT( |
194 |
|
|
w_rf, double); /// weight of the estimation coming from the right foot |
195 |
|
|
DECLARE_SIGNAL_OUT( |
196 |
|
|
w_lf_filtered, |
197 |
|
|
double); /// filtered weight of the estimation coming from the left foot |
198 |
|
|
DECLARE_SIGNAL_OUT( |
199 |
|
|
w_rf_filtered, |
200 |
|
|
double); /// filtered weight of the estimation coming from the right foot |
201 |
|
|
|
202 |
|
|
/* --- COMMANDS --- */ |
203 |
|
|
/* --- ENTITY INHERITANCE --- */ |
204 |
|
|
virtual void display(std::ostream& os) const; |
205 |
|
|
|
206 |
|
|
void sendMsg(const std::string& msg, MsgType t = MSG_TYPE_INFO, |
207 |
|
|
const char* = "", int = 0) { |
208 |
|
|
logger_.stream(t) << ("[" + name + "] " + msg) << '\n'; |
209 |
|
|
} |
210 |
|
|
|
211 |
|
|
protected: |
212 |
|
|
bool |
213 |
|
|
m_initSucceeded; /// true if the entity has been successfully initialized |
214 |
|
|
bool |
215 |
|
|
m_reset_foot_pos; /// true after the command resetFootPositions is called |
216 |
|
|
double m_dt; /// sampling time step |
217 |
|
|
RobotUtilShrPtr m_robot_util; |
218 |
|
|
|
219 |
|
|
bool m_left_foot_is_stable; /// True if left foot as been stable for the last |
220 |
|
|
/// 'm_fz_stable_windows_size' samples |
221 |
|
|
bool m_right_foot_is_stable; /// True if right foot as been stable for the |
222 |
|
|
/// last 'm_fz_stable_windows_size' samples |
223 |
|
|
int m_fz_stable_windows_size; /// size of the windows used to detect that |
224 |
|
|
/// feet did not leave the ground |
225 |
|
|
int m_lf_fz_stable_cpt; /// counter for detecting for how long the feet has |
226 |
|
|
/// been stable |
227 |
|
|
int m_rf_fz_stable_cpt; /// counter for detecting for how long the feet has |
228 |
|
|
/// been stable |
229 |
|
|
|
230 |
|
|
/* Estimator parameters */ |
231 |
|
|
double m_w_imu; /// weight of IMU for sensor fusion |
232 |
|
|
double m_zmp_std_dev_rf; /// standard deviation of ZMP measurement errors for |
233 |
|
|
/// right foot |
234 |
|
|
double m_zmp_std_dev_lf; /// standard deviation of ZMP measurement errors for |
235 |
|
|
/// left foot |
236 |
|
|
double m_fz_std_dev_rf; /// standard deviation of normal force measurement |
237 |
|
|
/// errors for right foot |
238 |
|
|
double m_fz_std_dev_lf; /// standard deviation of normal force measurement |
239 |
|
|
/// errors for left foot |
240 |
|
|
Vector4 m_left_foot_sizes; /// sizes of the left foot (pos x, neg x, pos y, |
241 |
|
|
/// neg y) |
242 |
|
|
Vector4 m_right_foot_sizes; /// sizes of the left foot (pos x, neg x, pos y, |
243 |
|
|
/// neg y) |
244 |
|
|
double m_zmp_margin_lf; /// margin used for computing zmp weight |
245 |
|
|
double m_zmp_margin_rf; /// margin used for computing zmp weight |
246 |
|
|
double m_fz_margin_lf; /// margin used for computing normal force weight |
247 |
|
|
double m_fz_margin_rf; /// margin used for computing normal force weight |
248 |
|
|
Vector6 m_K_rf; /// 6d stiffness of right foot spring |
249 |
|
|
Vector6 m_K_lf; /// 6d stiffness of left foot spring |
250 |
|
|
|
251 |
|
|
Eigen::VectorXd m_v_kin; /// 6d robot velocities from kinematic only |
252 |
|
|
/// (encoders derivative) |
253 |
|
|
Eigen::VectorXd m_v_flex; /// 6d robot velocities from flexibility only |
254 |
|
|
/// (force sensor derivative) |
255 |
|
|
Eigen::VectorXd m_v_imu; /// 6d robot velocities form imu only (accelerometer |
256 |
|
|
/// integration + gyro) |
257 |
|
|
Eigen::VectorXd m_v_gyr; /// 6d robot velocities form gyroscope only (as if |
258 |
|
|
/// gyro measured the pure angular ankle velocities) |
259 |
|
|
|
260 |
|
|
Vector3 |
261 |
|
|
m_v_ac; /// velocity of the base in the world with DC component removed |
262 |
|
|
Vector3 m_a_ac; /// acceleration of the base in the world with DC component |
263 |
|
|
/// removed |
264 |
|
|
|
265 |
|
|
double m_alpha_DC_acc; /// alpha parameter for DC blocker filter on |
266 |
|
|
/// acceleration data |
267 |
|
|
double m_alpha_DC_vel; /// alpha parameter for DC blocker filter on velocity |
268 |
|
|
/// data |
269 |
|
|
|
270 |
|
|
double m_alpha_w_filter; /// filter parameter to filter weights (1st order |
271 |
|
|
/// low pass filter) |
272 |
|
|
|
273 |
|
|
double m_w_lf_filtered; /// filtered weight of the estimation coming from the |
274 |
|
|
/// left foot |
275 |
|
|
double m_w_rf_filtered; /// filtered weight of the estimation coming from the |
276 |
|
|
/// right foot |
277 |
|
|
|
278 |
|
|
pinocchio::Model m_model; /// Pinocchio robot model |
279 |
|
|
pinocchio::Data* m_data; /// Pinocchio robot data |
280 |
|
|
pinocchio::SE3 |
281 |
|
|
m_oMff_lf; /// world-to-base transformation obtained through left foot |
282 |
|
|
pinocchio::SE3 |
283 |
|
|
m_oMff_rf; /// world-to-base transformation obtained through right foot |
284 |
|
|
SE3 m_oMlfs; /// transformation from world to left foot sole |
285 |
|
|
SE3 m_oMrfs; /// transformation from world to right foot sole |
286 |
|
|
Vector7 m_oMlfs_xyzquat; |
287 |
|
|
Vector7 m_oMrfs_xyzquat; |
288 |
|
|
SE3 m_oMlfs_default_ref; /// Default reference for left foot pose to use if |
289 |
|
|
/// no ref is pluged |
290 |
|
|
SE3 m_oMrfs_default_ref; /// Default reference for right foot pose to use if |
291 |
|
|
/// no ref is pluged |
292 |
|
|
normal m_normal; /// Normal distribution |
293 |
|
|
|
294 |
|
|
bool m_isFirstIterFlag; /// flag to detect first iteration and initialise |
295 |
|
|
/// velocity filters |
296 |
|
|
|
297 |
|
|
SE3 m_sole_M_ftSens; /// foot sole to F/T sensor transformation |
298 |
|
|
|
299 |
|
|
pinocchio::FrameIndex m_right_foot_id; |
300 |
|
|
pinocchio::FrameIndex m_left_foot_id; |
301 |
|
|
pinocchio::FrameIndex m_IMU_body_id; |
302 |
|
|
|
303 |
|
|
Eigen::VectorXd |
304 |
|
|
m_q_pin; /// robot configuration according to pinocchio convention |
305 |
|
|
Eigen::VectorXd m_q_sot; /// robot configuration according to SoT convention |
306 |
|
|
Eigen::VectorXd |
307 |
|
|
m_v_pin; /// robot velocities according to pinocchio convention |
308 |
|
|
Eigen::VectorXd m_v_sot; /// robot velocities according to SoT convention |
309 |
|
|
Matrix3 m_oRchest; /// chest orientation in the world from angular fusion |
310 |
|
|
Matrix3 m_oRff; /// base orientation in the world |
311 |
|
|
|
312 |
|
|
/* Filter buffers*/ |
313 |
|
|
Vector3 m_last_vel; |
314 |
|
|
Vector3 m_last_DCvel; |
315 |
|
|
Vector3 m_last_DCacc; |
316 |
|
|
|
317 |
|
|
}; // class BaseEstimator |
318 |
|
|
|
319 |
|
|
} // namespace torque_control |
320 |
|
|
} // namespace sot |
321 |
|
|
} // namespace dynamicgraph |
322 |
|
|
|
323 |
|
|
#endif // #ifndef __sot_torque_control_free_flyer_locator_H__ |