2 from __future__
import print_function, division
5 import pyexotica
as exo
8 __all__ = [
"check_dynamics_solver_derivatives"]
11 np.set_printoptions(4, suppress=
True, threshold=sys.maxsize, linewidth=500)
15 uvw = np.random.uniform(size=(3,))
16 return np.array([np.sqrt(1.0-uvw[0]) * np.sin(2.0*np.pi*uvw[1]),
17 np.sqrt(1.0-uvw[0]) * np.cos(2.0*np.pi*uvw[1]),
18 np.sqrt(uvw[0])*np.sin(2.0*np.pi*uvw[2]),
19 np.sqrt(uvw[0])*np.cos(2.0*np.pi*uvw[2])])
23 x = np.random.random((ds.nx,))
27 if ds.ndx != ds.nq + ds.nv:
29 x[3:7] /= np.linalg.norm(x[3:7])
40 raise RuntimeError(
"ds is None!")
44 dx_new = np.concatenate([dt * v + (dt*dt) * a, dt * a])
50 if urdf
is not None and srdf
is not None and joint_group
is not None:
51 my_scene_init = exo.Initializers.SceneInitializer()
52 my_scene_init[1][
'URDF'] = urdf
53 my_scene_init[1][
'SRDF'] = srdf
54 my_scene_init[1][
'JointGroup'] = joint_group
55 my_scene_init[1][
'DynamicsSolver'] = [(name, {
'Name':
u'MyDynamicsSolver'})]
56 if additional_args
is not None:
57 my_scene_init[1][
'DynamicsSolver'][0][1].update(additional_args)
58 scene = exo.Setup.create_scene(exo.Initializers.Initializer(my_scene_init))
59 ds = scene.get_dynamics_solver()
61 my_ds_init = (name, {
'Name':
u'MyDynamicsSolver'})
62 if additional_args
is not None:
63 my_ds_init.merge(additional_args)
64 ds = exo.Setup.create_dynamics_solver(my_ds_init)
68 u = np.random.random((ds.nu,))
71 np.testing.assert_equal(ds.f(x,u).shape[0], ds.ndx)
73 np.testing.assert_equal(ds.fx(x,u).shape[0], ds.ndx)
74 np.testing.assert_equal(ds.fx(x,u).shape[1], ds.ndx)
76 np.testing.assert_equal(ds.fu(x,u).shape[0], ds.ndx)
77 np.testing.assert_equal(ds.fu(x,u).shape[1], ds.nu)
81 np.testing.assert_array_equal(ds.simulate(x, u, 0.01), ds.integrate(x, dx, 0.01))
93 np.testing.assert_allclose(fu, fu_fd, rtol=1e-5, atol=1e-5)
98 if np.linalg.norm(fx-fx_fd) > 1e-3
or np.any(np.isnan(fx)):
100 fx_fd[fx_fd<1e-6] = 0.
103 print(
"fx_fd\n",fx_fd)
104 np.testing.assert_allclose(fx, fx_fd, rtol=1e-5, atol=1e-5, err_msg=
'fx does not match!')
107 ds.compute_derivatives(x, u)
108 fx_joint = ds.get_fx()
109 fu_joint = ds.get_fu()
110 np.testing.assert_allclose(fx, fx_joint, rtol=1e-5, atol=1e-5)
111 np.testing.assert_allclose(fu, fu_joint, rtol=1e-5, atol=1e-5)
114 if ds.nq == ds.nv
and do_test_integrators:
115 python_integrators = {
116 exo.Integrator.RK1: explicit_euler,
117 exo.Integrator.SymplecticEuler: semiimplicit_euler
119 for integrator
in [exo.Integrator.RK1, exo.Integrator.SymplecticEuler]:
120 ds.integrator = integrator
121 for dt
in [0.001, 0.01, 1.0]:
122 print(
"Testing integrator", integrator,
"dt=", dt)
123 np.testing.assert_allclose(ds.integrate(
124 x, dx, dt), python_integrators[integrator](x, dx, dt, ds))
127 for integrator
in [exo.Integrator.RK1, exo.Integrator.SymplecticEuler]:
128 print(
"Testing state transition for", integrator,
"dt=", ds.dt)
129 ds.integrator = integrator
131 Fx_fd = np.zeros((ds.ndx, ds.ndx))
132 for i
in range(ds.ndx):
133 dx = np.zeros((ds.ndx))
136 ds.integrator = exo.Integrator.RK1
137 x_plus = ds.integrate(x, dx, 1.0)
138 x_minus = ds.integrate(x, -dx, 1.0)
139 ds.integrator = integrator
140 F_plus = ds.F(x_plus, u)
141 F_minus = ds.F(x_minus, u)
142 Fx_fd[:,i] = ds.state_delta(F_plus, F_minus) / eps
144 Fu_fd = np.zeros((ds.ndx, ds.nu))
145 for i
in range(ds.nu):
146 du = np.zeros((ds.nu))
150 F_plus = ds.F(x, u_plus)
151 F_minus = ds.F(x, u_minus)
152 Fu_fd[:,i] = ds.state_delta(F_plus, F_minus) / eps
155 ds.compute_derivatives(x, u)
156 ds.compute_derivatives(x, u)
157 ds.compute_derivatives(x, u)
168 np.testing.assert_allclose(ds.get_Fx(), Fx_fd, rtol=1e-5, atol=1e-5)
169 np.testing.assert_allclose(ds.get_Fu(), Fu_fd, rtol=1e-5, atol=1e-5)
178 Jds = ds.state_delta_derivative(x1, x2, exo.ArgumentPosition.ARG0)
179 Jdiff = np.zeros((ds.ndx, ds.ndx))
181 integrator = ds.integrator
182 for i
in range(ds.ndx):
183 dx = np.zeros((ds.ndx))
185 ds.integrator = exo.Integrator.RK1
186 x1_plus = ds.integrate(x1, dx, 1.0)
187 x1_minus = ds.integrate(x1, -dx, 1.0)
188 ds.integrator = integrator
189 delta_plus = ds.state_delta(x1_plus, x2)
190 delta_minus = ds.state_delta(x1_minus, x2)
191 Jdiff[:,i] = (delta_plus - delta_minus) / eps
192 np.testing.assert_allclose(Jds, Jdiff, rtol=1e-5, atol=1e-5)
198 Hds = ds.state_delta_second_derivative(x1, x2, exo.ArgumentPosition.ARG0)
199 Hdiff = np.zeros((ds.ndx, ds.ndx, ds.ndx))
201 integrator = ds.integrator
202 for i
in range(ds.ndx):
203 dx = np.zeros((ds.ndx))
205 ds.integrator = exo.Integrator.RK1
206 x1_plus = ds.integrate(x1, dx, 1.0)
207 x1_minus = ds.integrate(x1, -dx, 1.0)
208 ds.integrator = integrator
209 Jdiff_plus = ds.state_delta_derivative(x1_plus, x2, exo.ArgumentPosition.ARG0)
210 Jdiff_minus = ds.state_delta_derivative(x1_minus, x2, exo.ArgumentPosition.ARG0)
211 Hdiff[:,:,i] = (Jdiff_plus - Jdiff_minus) / eps
212 np.testing.assert_allclose(Hds, Hdiff, rtol=1e-5, atol=1e-5)
def explicit_euler(x, dx, dt, ds=None)
def semiimplicit_euler(x, dx, dt, ds=None)
def check_dynamics_solver_derivatives(name, urdf=None, srdf=None, joint_group=None, additional_args=None, do_test_integrators=True)