cartpole-casadi.py
Go to the documentation of this file.
1 import casadi
2 import numpy as np
3 import pinocchio as pin
4 import pinocchio.casadi as cpin
5 import hppfcl as fcl
6 
7 
8 def make_cartpole(ub=True):
9  model = pin.Model()
10 
11  m1 = 1.0
12  m2 = 0.1
13  length = 0.5
14  base_sizes = (0.4, 0.2, 0.05)
15 
16  base = pin.JointModelPX()
17  base_id = model.addJoint(0, base, pin.SE3.Identity(), "base")
18 
19  if ub:
20  pole = pin.JointModelRUBY()
21  else:
22  pole = pin.JointModelRY()
23  pole_id = model.addJoint(1, pole, pin.SE3.Identity(), "pole")
24 
25  base_inertia = pin.Inertia.FromBox(m1, *base_sizes)
26  pole_inertia = pin.Inertia(
27  m2,
28  np.array([0.0, 0.0, length / 2]),
29  m2 / 5 * np.diagflat([1e-2, length**2, 1e-2]),
30  )
31 
32  base_body_pl = pin.SE3.Identity()
33  pole_body_pl = pin.SE3.Identity()
34  pole_body_pl.translation = np.array([0.0, 0.0, length / 2])
35 
36  model.appendBodyToJoint(base_id, base_inertia, base_body_pl)
37  model.appendBodyToJoint(pole_id, pole_inertia, pole_body_pl)
38 
39  # make visual/collision models
40  collision_model = pin.GeometryModel()
41  shape_base = fcl.Box(*base_sizes)
42  radius = 0.01
43  shape_pole = fcl.Capsule(radius, length)
44  RED_COLOR = np.array([1, 0.0, 0.0, 1.0])
45  WHITE_COLOR = np.array([1, 1.0, 1.0, 1.0])
46  geom_base = pin.GeometryObject("link_base", base_id, shape_base, base_body_pl)
47  geom_base.meshColor = WHITE_COLOR
48  geom_pole = pin.GeometryObject("link_pole", pole_id, shape_pole, pole_body_pl)
49  geom_pole.meshColor = RED_COLOR
50 
51  collision_model.addGeometryObject(geom_base)
52  collision_model.addGeometryObject(geom_pole)
53  visual_model = collision_model
54  return model, collision_model, visual_model
55 
56 
58  """Take a Pinocchio model, turn it into a Casadi model
59  and define the appropriate graphs.
60  """
61 
62  def __init__(self, model: pin.Model, timestep=0.05):
63  self.model = model
64  self.cmodel = cpin.Model(model) # cast to CasADi model
65  self.cdata = self.cmodel.createData()
66  self.timestep = timestep
67  self.create_dynamics()
69 
70  def create_dynamics(self):
71  """Create the acceleration expression and acceleration function."""
72  nq = self.model.nq
73  nu = 1
74  nv = self.model.nv
75  q = casadi.SX.sym("q", nq)
76  v = casadi.SX.sym("v", nv)
77  u = casadi.SX.sym("u", nu)
78  dq_ = casadi.SX.sym("dq_", nv)
79  self.u_node = u
80  self.q_node = q
81  self.v_node = v
82  self.dq_ = dq_
83 
84  B = np.array([1, 0])
85  tau = B @ u
86  a = cpin.aba(self.cmodel, self.cdata, q, v, tau)
87  self.acc = a
88  self.acc_func = casadi.Function("acc", [q, v, u], [a], ["q", "v", "u"], ["a"])
89 
91  """Create the map `(q,v) -> (qnext, vnext)` using semi-implicit Euler integration."""
92  nv = self.model.nv
93  nq = self.model.nq
94  q = self.q_node
95  v = self.v_node
96  u = self.u_node
97  dq_ = self.dq_
98  # q' = q + dq
99  q_dq = cpin.integrate(self.cmodel, q, dq_)
100  self.q_dq = q_dq
101  # express acceleration using q' = q + dq
102  a = self.acc_func(q_dq, v, u)
103 
104  dt = self.timestep
105  vnext = v + a * dt
106  qnext = cpin.integrate(self.cmodel, self.q_dq, dt * vnext)
107 
108  self.dyn_qv_fn_ = casadi.Function(
109  "discrete_dyn",
110  [q, dq_, v, u],
111  [qnext, vnext],
112  ["q", "dq_", "v", "u"],
113  ["qnext", "vnext"],
114  )
115 
117  q=q, dq_=casadi.SX.zeros(nv), v=v, u=u
118  )
119  self.dyn_jac_expr = self.dyn_jac_expr["jac"][:, nq:]
120  print("dyn jac expr:", self.dyn_jac_expr.shape)
121  self.dyn_jac_fn = casadi.Function("Ddyn", [q, v, u], [self.dyn_jac_expr])
122 
124 
126  nq = self.model.nq
127  nv = self.model.nv
128  dt = self.timestep
129  u = self.u_node
130  model = self.cmodel
131 
132  # discrete dynamics in terms of x:
133  state = casadi.SX.sym("x", nq + nv)
134  self.x_node = state
135  q, v = casadi.vertsplit(state, nq)
136  dq_ = self.dq_
137  q_dq = self.q_dq
138 
139  a = self.acc_func(q_dq, v, u)
140  vnext = v + a * dt
141 
142  # implicit form
143  next_state = casadi.SX.sym("xnext", nq + nv)
144  qn, vn = casadi.vertsplit(next_state, nq)
145  dqn_ = casadi.SX.sym("dqn_", nv)
146  qn_dq = cpin.integrate(model, qn, dqn_)
147 
148  res_q = cpin.difference(model, q_dq, qn_dq) - dt * vnext
149  res_v = (vn - v) - dt * a
150 
151  residual = casadi.vertcat(res_q, res_v)
152  self.dyn_residual = casadi.Function(
153  "residual",
154  [state, u, next_state, dq_, dqn_],
155  [residual],
156  ["x", "u", "xnext", "dq_", "dqn_"],
157  ["r"],
158  )
159 
160  def forward(self, x, u):
161  nq = self.model.nq
162  nv = self.model.nv
163  q = x[:nq]
164  v = x[nq:]
165  dq_ = np.zeros(nv)
166  qnext, vnext = self.dyn_qv_fn_(q, dq_, v, u)
167  xnext = np.concatenate((qnext, vnext))
168  return xnext
169 
170  def residual_fwd(self, x, u, xnext):
171  nv = self.model.nv
172  dq = np.zeros(nv)
173  dqn = dq
174  res = self.dyn_residual(x, u, xnext, dq, dqn)
175  return res
176 
177 
179  def __init__(self, timestep=0.05):
180  model, collision_model, visual_model = make_cartpole()
181  self.collision_model = collision_model
182  self.visual_model = visual_model
183  super().__init__(model=model, timestep=timestep)
184 
185 
186 dt = 0.02
187 cartpole = CartpoleDynamics(timestep=dt)
188 model = cartpole.model
189 
190 print(model)
191 
192 q0 = np.array([0.0, 0.95, 0.01])
193 q0 = pin.normalize(model, q0)
194 v = np.zeros(model.nv)
195 u = np.zeros(1)
196 a0 = cartpole.acc_func(q0, v, u)
197 
198 print("a0:", a0)
199 
200 x0 = np.append(q0, v)
201 xnext = cartpole.forward(x0, u)
202 
203 
204 def integrate_no_control(x0, nsteps):
205  states_ = [x0.copy()]
206  for t in range(nsteps):
207  u = np.zeros(1)
208  xnext = cartpole.forward(states_[t], u).ravel()
209  states_.append(xnext)
210  return states_
211 
212 
213 states_ = integrate_no_control(x0, nsteps=400)
214 states_ = np.stack(states_).T
215 
216 
217 from pinocchio import visualize
218 
219 viz = visualize.MeshcatVisualizer(
220  model=model,
221  collision_model=cartpole.collision_model,
222  visual_model=cartpole.visual_model,
223 )
224 
225 viz.initViewer()
226 viz.loadViewerModel("pinocchio")
227 
228 qs_ = states_[: model.nq, :]
229 viz.play(q_trajectory=qs_, dt=dt)
cartpole-casadi.integrate_no_control
def integrate_no_control(x0, nsteps)
Definition: cartpole-casadi.py:204
cartpole-casadi.PinocchioCasadi.q_node
q_node
Definition: cartpole-casadi.py:80
cartpole-casadi.PinocchioCasadi.model
model
Definition: cartpole-casadi.py:63
cartpole-casadi.PinocchioCasadi.dyn_qv_fn_
dyn_qv_fn_
Definition: cartpole-casadi.py:108
cartpole-casadi.PinocchioCasadi.dyn_jac_expr
dyn_jac_expr
Definition: cartpole-casadi.py:116
cartpole-casadi.PinocchioCasadi.x_node
x_node
Definition: cartpole-casadi.py:134
cartpole-casadi.PinocchioCasadi.dyn_jac_fn
dyn_jac_fn
Definition: cartpole-casadi.py:121
cartpole-casadi.PinocchioCasadi.dyn_residual
dyn_residual
Definition: cartpole-casadi.py:152
cartpole-casadi.PinocchioCasadi.dq_
dq_
Definition: cartpole-casadi.py:82
cartpole-casadi.PinocchioCasadi.cmodel
cmodel
Definition: cartpole-casadi.py:64
cartpole-casadi.PinocchioCasadi.q_dq
q_dq
Definition: cartpole-casadi.py:100
pinocchio.casadi
Definition: bindings/python/pinocchio/casadi/__init__.py:1
cartpole-casadi.CartpoleDynamics.visual_model
visual_model
Definition: cartpole-casadi.py:182
cartpole-casadi.PinocchioCasadi.create_discrete_dynamics_state
def create_discrete_dynamics_state(self)
Definition: cartpole-casadi.py:125
cartpole-casadi.PinocchioCasadi.__init__
def __init__(self, pin.Model model, timestep=0.05)
Definition: cartpole-casadi.py:62
cartpole-casadi.PinocchioCasadi.create_discrete_dynamics
def create_discrete_dynamics(self)
Definition: cartpole-casadi.py:90
cartpole-casadi.PinocchioCasadi.create_dynamics
def create_dynamics(self)
Definition: cartpole-casadi.py:70
cartpole-casadi.make_cartpole
def make_cartpole(ub=True)
Definition: cartpole-casadi.py:8
pinocchio::createData
ConstraintDataTpl< Scalar, Options, ConstraintCollectionTpl > createData(const ConstraintModelTpl< Scalar, Options, ConstraintCollectionTpl > &cmodel)
Definition: constraint-model-visitor.hpp:248
cartpole-casadi.CartpoleDynamics.__init__
def __init__(self, timestep=0.05)
Definition: cartpole-casadi.py:179
pinocchio::jacobian
void jacobian(const ConstraintModelTpl< Scalar, Options, ConstraintCollectionTpl > &cmodel, ConstraintDataTpl< Scalar, Options, ConstraintCollectionTpl > &cdata, const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const DataTpl< Scalar, Options, JointCollectionTpl > &data, const Eigen::MatrixBase< JacobianMatrix > &jacobian_matrix)
Definition: constraint-model-visitor.hpp:208
cartpole-casadi.PinocchioCasadi.u_node
u_node
Definition: cartpole-casadi.py:79
cartpole-casadi.PinocchioCasadi.acc
acc
Definition: cartpole-casadi.py:87
cartpole-casadi.PinocchioCasadi.timestep
timestep
Definition: cartpole-casadi.py:66
cartpole-casadi.PinocchioCasadi.v_node
v_node
Definition: cartpole-casadi.py:81
cartpole-casadi.CartpoleDynamics
Definition: cartpole-casadi.py:178
cartpole-casadi.PinocchioCasadi.cdata
cdata
Definition: cartpole-casadi.py:65
cartpole-casadi.PinocchioCasadi.forward
def forward(self, x, u)
Definition: cartpole-casadi.py:160
cartpole-casadi.PinocchioCasadi.acc_func
acc_func
Definition: cartpole-casadi.py:88
cartpole-casadi.PinocchioCasadi.residual_fwd
def residual_fwd(self, x, u, xnext)
Definition: cartpole-casadi.py:170
cartpole-casadi.CartpoleDynamics.collision_model
collision_model
Definition: cartpole-casadi.py:181
cartpole-casadi.PinocchioCasadi
Definition: cartpole-casadi.py:57


pinocchio
Author(s):
autogenerated on Tue Jun 25 2024 02:42:34