Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Q
quadruped-reactive-walking
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gepetto
quadruped-reactive-walking
Commits
8e7f1939
Commit
8e7f1939
authored
4 years ago
by
Pierre-Alexandre Leziart
Browse files
Options
Downloads
Patches
Plain Diff
Synchronize Estimator with solo-estimation repository
parent
2185762e
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
scripts/Estimator.py
+116
-10
116 additions, 10 deletions
scripts/Estimator.py
with
116 additions
and
10 deletions
scripts/Estimator.py
+
116
−
10
View file @
8e7f1939
...
@@ -85,6 +85,102 @@ class KFilter:
...
@@ -85,6 +85,102 @@ class KFilter:
self
.
P
=
self
.
P
-
self
.
K
@
self
.
H
@
self
.
P
self
.
P
=
self
.
P
-
self
.
K
@
self
.
H
@
self
.
P
class
KFilterBis
:
def
__init__
(
self
,
dt
):
self
.
dt
=
dt
self
.
n
=
3
+
3
+
4
*
3
# State = pos base + vel lin base + feet pos
self
.
m
=
4
*
3
+
4
# Measure = relative pos of IMU
# State transition matrix
self
.
A
=
np
.
eye
(
self
.
n
)
self
.
A
[
0
:
3
,
3
:
6
]
=
dt
*
np
.
eye
(
3
)
# Control matrix
self
.
B
=
np
.
zeros
((
self
.
n
,
3
))
for
i
in
range
(
3
):
self
.
B
[
i
,
i
]
=
0.5
*
dt
**
2
self
.
B
[
i
+
3
,
i
]
=
dt
# Observation matrix
self
.
H
=
np
.
zeros
((
self
.
m
,
self
.
n
))
for
i
in
range
(
4
):
for
j
in
range
(
3
):
self
.
H
[
3
*
i
+
j
,
j
]
=
1.0
self
.
H
[
3
*
i
+
j
,
j
+
6
+
3
*
i
]
=
-
1.0
self
.
H
[
12
+
i
,
6
+
3
*
i
+
2
]
=
1.0
# Z: m x 1 Measurement vector
# Covariance of the process noise
self
.
Q
=
np
.
zeros
((
self
.
n
,
self
.
n
))
# Covariance of the observation noise
self
.
R
=
np
.
zeros
((
self
.
m
,
self
.
m
))
# a posteriori estimate covariance
self
.
P
=
np
.
eye
(
self
.
n
)
# Optimal Kalman gain
self
.
K
=
np
.
zeros
((
self
.
n
,
self
.
m
))
# Updated (a posteriori) state estimate
self
.
X
=
np
.
zeros
((
self
.
n
,
1
))
# Initial state and covariance
self
.
X
=
np
.
zeros
((
self
.
n
,
1
))
# Parameters to tune
self
.
sigma_kin
=
0.1
self
.
sigma_h
=
1.0
self
.
sigma_a
=
0.1
self
.
sigma_dp
=
0.1
self
.
gamma
=
30
def
setFixed
(
self
,
A
,
H
,
Q
,
R
):
self
.
A
=
A
self
.
H
=
H
self
.
Q
=
Q
self
.
R
=
R
def
setInitial
(
self
,
X0
,
P0
):
# X : initial state of the system
# P : initial covariance
self
.
X
=
X0
self
.
P
=
P0
def
predict
(
self
,
U
):
# Make prediction based on physical system
# U : control vector (measured acceleration)
self
.
X
=
(
self
.
A
@
self
.
X
)
+
self
.
B
@
U
self
.
P
=
(
self
.
A
@
self
.
P
@
self
.
A
.
T
)
+
self
.
Q
def
correct
(
self
,
Z
):
# Correct the prediction, using measurement
# Z : measurement vector
self
.
K
=
self
.
P
@
self
.
H
.
T
@
np
.
linalg
.
inv
(
self
.
H
@
self
.
P
@
self
.
H
.
T
+
self
.
R
)
self
.
X
=
self
.
X
+
self
.
K
@
(
Z
-
self
.
H
@
self
.
X
)
self
.
P
=
self
.
P
-
self
.
K
@
self
.
H
@
self
.
P
def
updateCoeffs
(
self
,
status
):
# Update noise/covariance matrices depending on feet status
for
i
in
range
(
4
):
# Trust is between 1 and 0 (cliped to a very low value to avoid division by 0)
if
status
[
i
]
==
0
:
trust
=
0.01
else
:
trust
=
1.0
self
.
R
[(
3
*
i
):(
3
*
(
i
+
1
)),
(
3
*
i
):(
3
*
(
i
+
1
))]
=
self
.
sigma_kin
**
2
/
trust
*
np
.
eye
(
3
)
self
.
R
[
12
+
i
,
12
+
i
]
=
self
.
sigma_h
**
2
/
trust
self
.
Q
[(
6
+
3
*
i
):(
6
+
3
*
(
i
+
1
)),
(
6
+
3
*
i
):(
6
+
3
*
(
i
+
1
))]
=
self
.
sigma_dp
**
2
*
(
1
+
np
.
exp
(
self
.
gamma
*
(
0.5
-
trust
)))
*
np
.
eye
(
3
)
*
self
.
dt
**
2
self
.
Q
[
3
:
6
,
3
:
6
]
=
self
.
sigma_a
**
2
*
np
.
eye
(
3
)
*
self
.
dt
**
2
class
ComplementaryFilter
:
class
ComplementaryFilter
:
"""
Simple complementary filter
"""
Simple complementary filter
...
@@ -166,8 +262,8 @@ class Estimator:
...
@@ -166,8 +262,8 @@ class Estimator:
self
.
filter_xyz_vel
=
ComplementaryFilter
(
dt
,
3.0
)
self
.
filter_xyz_vel
=
ComplementaryFilter
(
dt
,
3.0
)
self
.
filter_xyz_pos
=
ComplementaryFilter
(
dt
,
500.0
)
self
.
filter_xyz_pos
=
ComplementaryFilter
(
dt
,
500.0
)
else
:
# Kalman filter for linear velocity and position
else
:
# Kalman filter for linear velocity and position
self
.
kf
=
KFilter
(
dt
)
self
.
kf
=
KFilter
Bis
(
dt
)
self
.
Z
=
np
.
zeros
((
6
,
1
))
self
.
Z
=
np
.
zeros
((
self
.
kf
.
m
,
1
))
# IMU data
# IMU data
self
.
IMU_lin_acc
=
np
.
zeros
((
3
,
))
# Linear acceleration (gravity debiased)
self
.
IMU_lin_acc
=
np
.
zeros
((
3
,
))
# Linear acceleration (gravity debiased)
...
@@ -328,11 +424,11 @@ class Estimator:
...
@@ -328,11 +424,11 @@ class Estimator:
vel_est
+=
vel_estimated_baseframe
[:,
0
]
# Linear velocity
vel_est
+=
vel_estimated_baseframe
[:,
0
]
# Linear velocity
xyz_est
+=
xyz_estimated
# Position
xyz_est
+=
xyz_estimated
# Position
r_foot
=
0.0155
# 31mm of diameter on meshlab
"""
r_foot = 0.0155 # 31mm of diameter on meshlab
if i <= 1:
if i <= 1:
vel_est[0] += r_foot * (self.actuators_vel[1+3*i] - self.actuators_vel[2+3*i])
vel_est[0] += r_foot * (self.actuators_vel[1+3*i] - self.actuators_vel[2+3*i])
else:
else:
vel_est
[
0
]
+=
r_foot
*
(
self
.
actuators_vel
[
1
+
3
*
i
]
+
self
.
actuators_vel
[
2
+
3
*
i
])
vel_est[0] += r_foot * (self.actuators_vel[1+3*i] + self.actuators_vel[2+3*i])
"""
# If at least one foot is in contact, we do the average of feet results
# If at least one foot is in contact, we do the average of feet results
if
cpt
>
0
:
if
cpt
>
0
:
...
@@ -396,7 +492,7 @@ class Estimator:
...
@@ -396,7 +492,7 @@ class Estimator:
# Tune alpha depending on the state of the gait (close to contact switch or not)
# Tune alpha depending on the state of the gait (close to contact switch or not)
a
=
np
.
ceil
(
np
.
max
(
self
.
k_since_contact
)
/
10
)
-
1
a
=
np
.
ceil
(
np
.
max
(
self
.
k_since_contact
)
/
10
)
-
1
b
=
remaining_steps
b
=
remaining_steps
n
=
1
# Nb of steps of margin around contact switch
n
=
1
0
# Nb of steps of margin around contact switch
v
=
0.0
# Minimum alpha value
v
=
0.0
# Minimum alpha value
c
=
((
a
+
b
)
-
2
*
n
)
*
0.5
c
=
((
a
+
b
)
-
2
*
n
)
*
0.5
if
(
a
<=
(
n
-
1
))
or
(
b
<=
n
):
# If we are close from contact switch
if
(
a
<=
(
n
-
1
))
or
(
b
<=
n
):
# If we are close from contact switch
...
@@ -404,7 +500,7 @@ class Estimator:
...
@@ -404,7 +500,7 @@ class Estimator:
self
.
close_from_contact
=
True
# Raise flag
self
.
close_from_contact
=
True
# Raise flag
else
:
else
:
self
.
alpha
=
v
+
(
1
-
v
)
*
np
.
abs
(
c
-
(
a
-
n
))
/
c
self
.
alpha
=
v
+
(
1
-
v
)
*
np
.
abs
(
c
-
(
a
-
n
))
/
c
self
.
alpha
=
0.99
self
.
alpha
=
0.99
7
self
.
close_from_contact
=
False
# Lower flag
self
.
close_from_contact
=
False
# Lower flag
if
not
self
.
kf_enabled
:
# Use cascade of complementary filters
if
not
self
.
kf_enabled
:
# Use cascade of complementary filters
...
@@ -448,17 +544,27 @@ class Estimator:
...
@@ -448,17 +544,27 @@ class Estimator:
# Rotation matrix to go from base frame to world frame
# Rotation matrix to go from base frame to world frame
oRb
=
pin
.
Quaternion
(
np
.
array
([
self
.
IMU_ang_pos
]).
T
).
toRotationMatrix
()
oRb
=
pin
.
Quaternion
(
np
.
array
([
self
.
IMU_ang_pos
]).
T
).
toRotationMatrix
()
# Update coefficients depending on feet status
self
.
kf
.
updateCoeffs
(
feet_status
)
# Prediction step of the Kalman filter with IMU acceleration
# Prediction step of the Kalman filter with IMU acceleration
self
.
kf
.
predict
(
oRb
@
self
.
IMU_lin_acc
.
reshape
((
3
,
1
)))
self
.
kf
.
predict
(
oRb
@
self
.
IMU_lin_acc
.
reshape
((
3
,
1
)))
# Get position of IMU relative to feet in base frame
for
i
in
range
(
4
):
framePlacement
=
-
pin
.
updateFramePlacement
(
self
.
model
,
self
.
data
,
self
.
indexes
[
i
]).
translation
self
.
Z
[(
3
*
i
):(
3
*
(
i
+
1
)),
0
:
1
]
=
oRb
@
(
framePlacement
+
self
.
_1Mi
.
translation
.
ravel
()).
reshape
((
3
,
1
))
self
.
Z
[
12
+
i
,
0
]
=
0.0
# (oRb @ framePlacement.reshape((3, 1)))[2, 0] + self.filt_lin_pos[2]
# Correction step of the Kalman filter with position and velocity estimations by FK
# Correction step of the Kalman filter with position and velocity estimations by FK
self
.
Z
[
0
:
3
,
0
]
=
self
.
FK_xyz
[:]
+
self
.
xyz_mean_feet
[:]
#
self.Z[0:3, 0] = self.FK_xyz[:] + self.xyz_mean_feet[:]
self
.
Z
[
3
:
6
,
0
]
=
oRb
.
T
@
self
.
FK_lin_vel
#
self.Z[3:6, 0] = oRb.T @ self.FK_lin_vel
self
.
kf
.
correct
(
self
.
Z
)
self
.
kf
.
correct
(
self
.
Z
)
# Retrieve and store results
# Retrieve and store results
self
.
filt_lin_pos
[:]
=
self
.
kf
.
X
[
0
:
3
,
0
]
cross_product
=
self
.
cross3
(
self
.
_1Mi
.
translation
.
ravel
(),
self
.
IMU_ang_vel
).
ravel
()
self
.
filt_lin_vel
[:]
=
oRb
@
self
.
kf
.
X
[
3
:
6
,
0
]
self
.
filt_lin_pos
[:]
=
self
.
kf
.
X
[
0
:
3
,
0
]
-
self
.
_1Mi
.
translation
.
ravel
()
# base position in world frame
self
.
filt_lin_vel
[:]
=
oRb
.
transpose
()
@
(
self
.
kf
.
X
[
3
:
6
,
0
]
-
cross_product
)
# base velocity in base frame
# Logging
# Logging
self
.
log_alpha
[
self
.
k_log
]
=
self
.
alpha
self
.
log_alpha
[
self
.
k_log
]
=
self
.
alpha
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment