Skip to content

Commit 526e6df

Browse files
authored
Merge pull request #155 from TheoMF/topic/tmartinez/model_sensibility
add script to analyze panda model sensibility to inertia, center of mass, and mass of links
2 parents 851a34b + 8c79654 commit 526e6df

File tree

2 files changed

+278
-0
lines changed

2 files changed

+278
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
import crocoddyl
4+
import pinocchio as pin
5+
import yaml
6+
import example_robot_data
7+
8+
9+
def get_next_state_delta_inertia(model, x, u, dt, link_idx, row_idx, col_idx, delta):
10+
"""Integrate state to get next one, add small delta to link's inertia matrix."""
11+
curr_inertia = model.differential.pinocchio.inertias[link_idx].inertia.copy()
12+
new_inertia = curr_inertia.copy()
13+
new_inertia[row_idx, col_idx] += delta
14+
new_inertia[col_idx, row_idx] += delta
15+
model.differential.pinocchio.inertias[link_idx].inertia = new_inertia
16+
curr_dt = model.dt
17+
model.dt = dt
18+
d = model.createData()
19+
model.calc(d, x, u)
20+
model.dt = curr_dt
21+
model.differential.pinocchio.inertias[link_idx].inertia = curr_inertia
22+
return d.xnext.copy()
23+
24+
25+
def get_next_state_delta_com(model, x, u, dt, link_idx, com_idx, delta):
26+
"""Integrate state to get next one, add small delta to link's com pose."""
27+
curr_com = model.differential.pinocchio.inertias[link_idx].lever
28+
new_com = curr_com.copy()
29+
new_com[com_idx] += delta
30+
model.differential.pinocchio.inertias[link_idx].lever = new_com
31+
curr_dt = model.dt
32+
model.dt = dt
33+
d = model.createData()
34+
model.calc(d, x, u)
35+
model.dt = curr_dt
36+
model.differential.pinocchio.inertias[link_idx].lever = curr_com
37+
return d.xnext.copy()
38+
39+
40+
def get_next_state_delta_mass(model, x, u, dt, link_idx, delta):
41+
"""Integrate state to get next one, add small delta to link's mass."""
42+
model.differential.pinocchio.inertias[link_idx].mass += delta
43+
curr_dt = model.dt
44+
model.dt = dt
45+
d = model.createData()
46+
model.calc(d, x, u)
47+
model.dt = curr_dt
48+
model.differential.pinocchio.inertias[link_idx].mass -= delta
49+
return d.xnext.copy()
50+
51+
52+
def get_reduced_panda_robot_model(robot):
53+
"""Get pinocchio panda's reduced robot model."""
54+
q0 = np.zeros((9))
55+
locked_joints = [
56+
robot.model.getJointId("panda_finger_joint1"),
57+
robot.model.getJointId("panda_finger_joint2"),
58+
]
59+
return pin.buildReducedModel(robot.model, locked_joints, np.array(q0))
60+
61+
62+
if __name__ == "__main__":
63+
# retrieve x0 and u0 from real data on the robot
64+
with open("state_and_control_expe_data.yaml", "r") as file:
65+
state_control_expe_data = yaml.safe_load(file)
66+
67+
# get model and set parameters
68+
robot = example_robot_data.load("panda")
69+
rmodel = get_reduced_panda_robot_model(robot)
70+
dt = 0.01 # integration step
71+
delta_inertia = 0.01
72+
delta_com = 0.01
73+
delta_mass = 0.01
74+
nq = rmodel.nq
75+
nv = rmodel.nv
76+
armature = np.array([0.1] * nq)
77+
point_idx = 2 # range from 1 to 5
78+
79+
# get starting state and control
80+
point_data = state_control_expe_data[f"point_{point_idx}"]
81+
x0 = np.array(point_data["x0"])
82+
u0 = np.array(point_data["u0"])
83+
84+
# create crocoddyl model
85+
state = crocoddyl.StateMultibody(rmodel)
86+
actuation = crocoddyl.ActuationModelFull(state)
87+
cost_model = crocoddyl.CostModelSum(state)
88+
differential_model = crocoddyl.DifferentialActionModelFreeFwdDynamics(
89+
state, actuation, cost_model
90+
)
91+
differential_model.armature = armature
92+
model = crocoddyl.IntegratedActionModelEuler(differential_model, dt)
93+
94+
# compute sensibilities
95+
# for each link we have 10 values we're gonna test sensibility on,
96+
# 6 for inertia matrix, 3 for center of mass pose, 1 for mass
97+
model_sensibility = np.zeros(((nq + nv), nq * 10))
98+
x1_base = get_next_state_delta_inertia(model, x0, u0, dt, 0, 0, 0, 0)
99+
for link_idx in range(1, nq + 1):
100+
idx_link_inerta = (link_idx - 1) * 10
101+
for row_idx in range(3):
102+
for col_idx in range(0, row_idx + 1):
103+
x1 = get_next_state_delta_inertia(
104+
model, x0, u0, dt, link_idx, row_idx, col_idx, delta_inertia
105+
)
106+
sensi_inertia = (x1 - x1_base) / delta_inertia
107+
model_sensibility[:, idx_link_inerta] = abs(sensi_inertia)
108+
idx_link_inerta += 1
109+
110+
for link_idx in range(1, nq + 1):
111+
for com_idx in range(3):
112+
x1 = get_next_state_delta_com(
113+
model, x0, u0, dt, link_idx, com_idx, delta_com
114+
)
115+
sensi_com = (x1 - x1_base) / delta_com
116+
model_sensibility[:, 6 + (link_idx - 1) * 10 + com_idx] = abs(sensi_com)
117+
x1 = get_next_state_delta_mass(model, x0, u0, dt, link_idx, delta_mass)
118+
sensi_mass = (x1 - x1_base) / delta_mass
119+
model_sensibility[:, 9 + (link_idx - 1) * 10] = abs(sensi_mass)
120+
121+
# plots
122+
u, s, vh = np.linalg.svd(model_sensibility)
123+
plt.plot(s, "+")
124+
plt.title("eigen values of sensibility matrix")
125+
plt.show()
126+
plt.imshow(np.abs(u))
127+
128+
plt.colorbar()
129+
plt.title("eigen vectors on the left of sensibility matrix")
130+
plt.show()
131+
plt.imshow(np.abs(vh))
132+
plt.title("eigen vectors on the right of sensibility matrix")
133+
plt.colorbar()
134+
plt.show()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
point_1:
2+
x0:
3+
[
4+
-0.01234266,
5+
0.04483726,
6+
-0.01245294,
7+
-1.65970849,
8+
0.0053825,
9+
1.67475624,
10+
0.73647535,
11+
-0.03952127,
12+
0.09115266,
13+
-0.03780158,
14+
-0.19657774,
15+
0.0110891,
16+
0.30519501,
17+
-0.12058271,
18+
]
19+
u0:
20+
[
21+
-1.50062189,
22+
-32.96001341,
23+
-1.25585792,
24+
23.93996965,
25+
0.94498913,
26+
3.57828055,
27+
-0.51308917,
28+
]
29+
30+
point_2:
31+
x0:
32+
[
33+
-0.17150362,
34+
0.10615764,
35+
-0.16229535,
36+
-1.95177738,
37+
0.03691598,
38+
2.25664708,
39+
0.52969295,
40+
-0.08740141,
41+
0.23581081,
42+
-0.09771547,
43+
-0.26409425,
44+
0.00576253,
45+
0.1715259,
46+
-0.09583149,
47+
]
48+
u0:
49+
[
50+
0.51098499,
51+
-32.34277148,
52+
0.5212811,
53+
22.93049917,
54+
1.25434371,
55+
3.9713109,
56+
-0.78057266,
57+
]
58+
59+
point_3:
60+
x0:
61+
[
62+
0.13049612,
63+
0.16498611,
64+
0.11533246,
65+
-2.08334287,
66+
0.05353042,
67+
2.09693776,
68+
0.70178061,
69+
0.34143127,
70+
-0.11871808,
71+
0.31681011,
72+
0.03695333,
73+
0.00816043,
74+
0.0315556,
75+
0.23940798,
76+
]
77+
u0:
78+
[
79+
1.39650455,
80+
-36.29590193,
81+
2.34490956,
82+
23.19352057,
83+
0.99217375,
84+
3.18790063,
85+
0.97390622,
86+
]
87+
88+
point_4:
89+
x0:
90+
[
91+
0.97031325,
92+
-0.02127223,
93+
0.9304275,
94+
-2.16655581,
95+
0.13665267,
96+
2.19277893,
97+
1.37555517,
98+
0.45229686,
99+
-0.08920446,
100+
0.43320022,
101+
-0.06813646,
102+
0.04852861,
103+
0.05199259,
104+
0.38024724,
105+
]
106+
u0:
107+
[
108+
1.2735004,
109+
-18.00693956,
110+
0.93743486,
111+
21.89665671,
112+
1.0686884,
113+
3.29290768,
114+
0.81871872,
115+
]
116+
117+
point_5:
118+
x0:
119+
[
120+
1.0425574,
121+
-0.15902984,
122+
0.53682131,
123+
-1.86540792,
124+
0.17898847,
125+
1.76978178,
126+
1.32322549,
127+
-0.54787866,
128+
0.0933039,
129+
-0.27467942,
130+
0.12831353,
131+
-0.08944301,
132+
-0.08760853,
133+
-0.29462839,
134+
]
135+
u0:
136+
[
137+
-1.89533092,
138+
-20.87217118,
139+
-4.17067257,
140+
25.78918204,
141+
-0.29369269,
142+
1.60877,
143+
-0.8094384,
144+
]

0 commit comments

Comments
 (0)