simulation-pendulum.py
Go to the documentation of this file.
1 # Parse input arguments
2 import argparse
3 import math
4 import sys
5 import time
6 
7 import hppfcl as fcl
8 import numpy as np
9 import pinocchio as pin
10 from pinocchio.visualize import MeshcatVisualizer as Visualizer
11 
12 parser = argparse.ArgumentParser()
13 parser.add_argument(
14  "--with-cart",
15  help="Add a cart at the base of the pendulum to simulate a cart pole system.",
16  action="store_true",
17 )
18 parser.add_argument(
19  "-N", help="Number of pendulums compositing the dynamical system.", type=int
20 )
21 args = parser.parse_args()
22 
23 if args.N:
24  N = args.N
25 else:
26  N = 1 # number of pendulums
27 
28 model = pin.Model()
29 geom_model = pin.GeometryModel()
30 
31 parent_id = 0
32 
33 if args.with_cart:
34  cart_radius = 0.1
35  cart_length = 5 * cart_radius
36  cart_mass = 2.0
37  joint_name = "joint_cart"
38 
39  geometry_placement = pin.SE3.Identity()
40  geometry_placement.rotation = pin.Quaternion(
41  np.array([0.0, 0.0, 1.0]), np.array([0.0, 1.0, 0.0])
43 
44  joint_id = model.addJoint(
45  parent_id, pin.JointModelPY(), pin.SE3.Identity(), joint_name
46  )
47 
48  body_inertia = pin.Inertia.FromCylinder(cart_mass, cart_radius, cart_length)
49  body_placement = geometry_placement
50  # We need to rotate the inertia as it is expressed in the LOCAL frame of the
51  # geometry.
52  model.appendBodyToJoint(joint_id, body_inertia, body_placement)
53 
54  shape_cart = fcl.Cylinder(cart_radius, cart_length)
55 
56  geom_cart = pin.GeometryObject(
57  "shape_cart", joint_id, geometry_placement, shape_cart
58  )
59  geom_cart.meshColor = np.array([1.0, 0.1, 0.1, 1.0])
60  geom_model.addGeometryObject(geom_cart)
61 
62  parent_id = joint_id
63 else:
64  base_radius = 0.2
65  shape_base = fcl.Sphere(base_radius)
66  geom_base = pin.GeometryObject("base", 0, pin.SE3.Identity(), shape_base)
67  geom_base.meshColor = np.array([1.0, 0.1, 0.1, 1.0])
68  geom_model.addGeometryObject(geom_base)
69 
70 joint_placement = pin.SE3.Identity()
71 body_mass = 1.0
72 body_radius = 0.1
73 
74 for k in range(N):
75  joint_name = "joint_" + str(k + 1)
76  joint_id = model.addJoint(
77  parent_id, pin.JointModelRX(), joint_placement, joint_name
78  )
79 
80  body_inertia = pin.Inertia.FromSphere(body_mass, body_radius)
81  body_placement = joint_placement.copy()
82  body_placement.translation[2] = 1.0
83  model.appendBodyToJoint(joint_id, body_inertia, body_placement)
84 
85  geom1_name = "ball_" + str(k + 1)
86  shape1 = fcl.Sphere(body_radius)
87  geom1_obj = pin.GeometryObject(geom1_name, joint_id, body_placement, shape1)
88  geom1_obj.meshColor = np.ones(4)
89  geom_model.addGeometryObject(geom1_obj)
90 
91  geom2_name = "bar_" + str(k + 1)
92  shape2 = fcl.Cylinder(body_radius / 4.0, body_placement.translation[2])
93  shape2_placement = body_placement.copy()
94  shape2_placement.translation[2] /= 2.0
95 
96  geom2_obj = pin.GeometryObject(geom2_name, joint_id, shape2_placement, shape2)
97  geom2_obj.meshColor = np.array([0.0, 0.0, 0.0, 1.0])
98  geom_model.addGeometryObject(geom2_obj)
99 
100  parent_id = joint_id
101  joint_placement = body_placement.copy()
102 
103 
104 visual_model = geom_model
105 # Initialize the viewer.
106 try:
107  viz = Visualizer(model, geom_model, visual_model)
108  viz.initViewer()
109 except ImportError as err:
110  print(
111  "Error while initializing the viewer. "
112  "It seems you should install gepetto-viewer"
113  )
114  print(err)
115  sys.exit(0)
116 
117 try:
118  viz.loadViewerModel("pinocchio")
119 except AttributeError as err:
120  print(
121  "Error while loading the viewer model. "
122  "It seems you should start gepetto-viewer"
123  )
124  print(err)
125  sys.exit(0)
126 
127 # Display a robot configuration.
128 q0 = pin.neutral(model)
129 viz.display(q0)
130 
131 # Play a bit with the simulation
132 dt = 0.01
133 T = 5
134 
135 N = math.floor(T / dt)
136 
137 model.lowerPositionLimit.fill(-math.pi)
138 model.upperPositionLimit.fill(+math.pi)
139 
140 if args.with_cart:
141  model.lowerPositionLimit[0] = model.upperPositionLimit[0] = 0.0
142 
143 data_sim = model.createData()
144 
145 t = 0.0
146 q = pin.randomConfiguration(model)
147 v = np.zeros(model.nv)
148 tau_control = np.zeros(model.nv)
149 damping_value = 0.1
150 for k in range(N):
151  tic = time.time()
152  tau_control = -damping_value * v # small damping
153  a = pin.aba(model, data_sim, q, v, tau_control) # Forward dynamics
154 
155  # Semi-explicit integration
156  v += a * dt
157  q = pin.integrate(model, q, v * dt) # Configuration integration
158 
159  viz.display(q)
160  toc = time.time()
161  ellapsed = toc - tic
162 
163  dt_sleep = max(0, dt - (ellapsed))
164  time.sleep(dt_sleep)
165  t += dt
pinocchio.visualize
Definition: bindings/python/pinocchio/visualize/__init__.py:1
pinocchio::toRotationMatrix
void toRotationMatrix(const Eigen::MatrixBase< Vector3 > &axis, const Scalar &cos_value, const Scalar &sin_value, const Eigen::MatrixBase< Matrix3 > &res)
Computes a rotation matrix from a vector and values of sin and cos orientations values.
Definition: rotation.hpp:26
CppAD::max
AD< Scalar > max(const AD< Scalar > &x, const AD< Scalar > &y)
Definition: autodiff/cppad.hpp:181


pinocchio
Author(s):
autogenerated on Fri Nov 1 2024 02:41:48