tinyrobotics
Loading...
Searching...
No Matches
dynamics.hpp
Go to the documentation of this file.
1#ifndef TR_DYNAMICS_HPP
2#define TR_DYNAMICS_HPP
3
4#include <Eigen/Core>
5#include <Eigen/Dense>
6#include <Eigen/Geometry>
7
8#include "kinematics.hpp"
9#include "model.hpp"
10
14namespace tinyrobotics {
15
23 template <typename Scalar, int nq>
24 Eigen::Matrix<Scalar, nq, nq> mass_matrix(Model<Scalar, nq>& m, const Eigen::Matrix<Scalar, nq, 1>& q) {
25 m.mass_matrix.setZero();
26
27 for (int i = 0; i < nq; i++) {
28 m.Xup[i] = homogeneous_to_spatial(m.links[m.q_map[i]].joint.get_parent_to_child_transform(q(i)).inverse());
29 m.IC[i] = m.links[m.q_map[i]].I;
30 }
31
32 for (int i = nq - 1; i >= 0; i--) {
33 if (m.parent[i] != -1) {
34 m.IC[m.parent[i]] = m.IC[m.parent[i]] + m.Xup[i].transpose() * m.IC[i] * m.Xup[i];
35 }
36 }
37
38 for (int i = 0; i < nq; i++) {
39 m.fh = m.IC[i] * m.links[m.q_map[i]].joint.S;
40 m.mass_matrix(i, i) = m.links[m.q_map[i]].joint.S.transpose() * m.fh;
41 int j = i;
42 while (m.parent[j] > -1) {
43 m.fh = m.Xup[j].transpose() * m.fh;
44 j = m.parent[j];
45 m.mass_matrix(i, j) = m.links[m.q_map[j]].joint.S.transpose() * m.fh;
46 m.mass_matrix(j, i) = m.mass_matrix(i, j);
47 }
48 }
49
50 return m.mass_matrix;
51 }
52
59 template <typename Scalar, int nq>
61 const Eigen::Matrix<Scalar, nq, 1>& q,
62 const Eigen::Matrix<Scalar, nq, 1>& dq) {
63 return Scalar(0.5) * dq.transpose() * mass_matrix<Scalar, nq>(m, q) * dq;
64 }
65
73 template <typename Scalar, int nq>
74 Scalar potential_energy(Model<Scalar, nq>& m, const Eigen::Matrix<Scalar, nq, 1>& q) {
75 // Compute the forward kinematics to center of mass of all links
77
78 m.potential_energy = Scalar(0.0);
79 for (auto const link : m.links) {
80 m.potential_energy += -link.mass * m.gravity.transpose() * m.forward_kinematics_com[link.idx].translation();
81 }
82 return m.potential_energy;
83 }
84
93 template <typename Scalar, int nq>
95 const Eigen::Matrix<Scalar, nq, 1>& q,
96 const Eigen::Matrix<Scalar, nq, 1>& dq) {
97 return kinetic_energy(m, q, dq) + potential_energy(m, q);
98 }
99
108 template <typename Scalar, int nq>
109 std::vector<Eigen::Matrix<Scalar, 6, 1>> apply_external_forces(
110 const Model<Scalar, nq>& m,
111 const std::vector<Eigen::Matrix<Scalar, 6, 6>>& Xup,
112 const std::vector<Eigen::Matrix<Scalar, 6, 1>>& f_in,
113 const std::vector<Eigen::Matrix<Scalar, 6, 1>>& f_ext) {
114 std::vector<Eigen::Matrix<Scalar, 6, 1>> f_out(nq, Eigen::Matrix<Scalar, 6, 1>::Zero());
115 std::vector<Eigen::Matrix<Scalar, 6, 6>> Xa(nq, Eigen::Matrix<Scalar, 6, 6>::Zero());
116 f_out = f_in;
117
118 for (int i = 0; i < nq; i++) {
119 const auto link = m.links[m.q_map[i]];
120 if (m.parent[i] == -1) {
121 Xa[i] = Xup[i];
122 }
123 else {
124 Xa[i] = Xup[i] * Xa[m.parent[i]];
125 }
126 f_out[i] += Xa[i].transpose().inverse() * f_ext[i];
127 }
128 return f_out;
129 }
130
140 template <typename Scalar, int nq>
141 Eigen::Matrix<Scalar, nq, 1> forward_dynamics(Model<Scalar, nq>& m,
142 const Eigen::Matrix<Scalar, nq, 1>& q,
143 const Eigen::Matrix<Scalar, nq, 1>& dq,
144 const Eigen::Matrix<Scalar, nq, 1>& tau,
145 const std::vector<Eigen::Matrix<Scalar, 6, 1>>& f_ext = {}) {
146 for (int i = 0; i < nq; i++) {
147 // Compute the joint transform and motion subspace matrices
148 m.vJ = m.links[m.q_map[i]].joint.S * dq(i);
149 // Compute the spatial transform from the parent to the current body
150 m.Xup[i] = homogeneous_to_spatial(m.links[m.q_map[i]].joint.get_parent_to_child_transform(q(i)).inverse());
151 // Check if the m.parent link is the base link
152 if (m.parent[i] == -1) {
153 m.v[i] = m.vJ;
154 m.c[i] = Eigen::Matrix<Scalar, 6, 1>::Zero();
155 }
156 else {
157 m.v[i] = m.Xup[i] * m.v[m.parent[i]] + m.vJ;
158 m.c[i] = cross_spatial(m.v[i]) * m.vJ;
159 }
160 m.IA[i] = m.links[m.q_map[i]].I;
161 m.pA[i] = cross_motion(m.v[i]) * m.IA[i] * m.v[i];
162 }
163
164 // Apply external forces if non-zero
165 if (!f_ext.empty()) {
166 m.pA = apply_external_forces(m, m.Xup, m.pA, f_ext);
167 }
168
169 for (int i = nq - 1; i >= 0; i--) {
170 m.U[i] = m.IA[i] * m.links[m.q_map[i]].joint.S;
171 m.d[i] = m.links[m.q_map[i]].joint.S.transpose() * m.U[i];
172 m.u[i] = Scalar(tau(i) - m.links[m.q_map[i]].joint.S.transpose() * m.pA[i]);
173 if (m.parent[i] != -1) {
174 Eigen::Matrix<Scalar, 6, 6> Ia = m.IA[i] - (m.U[i] / m.d[i]) * m.U[i].transpose();
175 Eigen::Matrix<Scalar, 6, 1> pa = m.pA[i] + Ia * m.c[i] + m.U[i] * (m.u[i] / m.d[i]);
176 m.IA[m.parent[i]] += m.Xup[i].transpose() * Ia * m.Xup[i];
177 m.pA[m.parent[i]] += m.Xup[i].transpose() * pa;
178 }
179 }
180
181 for (int i = 0; i < nq; i++) {
182 if (m.parent[i] == -1) {
183 m.a[i] = m.Xup[i] * -m.spatial_gravity + m.c[i];
184 }
185 else {
186 m.a[i] = m.Xup[i] * m.a[m.parent[i]] + m.c[i];
187 }
188 m.ddq(i) = (m.u[i] - m.U[i].transpose() * m.a[i]) / m.d[i];
189 m.a[i] = m.a[i] + m.links[m.q_map[i]].joint.S * m.ddq(i);
190 }
191 return m.ddq;
192 }
193
203 template <typename Scalar, int nq>
204 Eigen::Matrix<Scalar, nq, 1> forward_dynamics_crb(Model<Scalar, nq>& m,
205 const Eigen::Matrix<Scalar, nq, 1>& q,
206 const Eigen::Matrix<Scalar, nq, 1>& dq,
207 const Eigen::Matrix<Scalar, nq, 1>& tau,
208 const std::vector<Eigen::Matrix<Scalar, 6, 1>>& f_ext = {}) {
209 for (int i = 0; i < nq; i++) {
210 // Compute the joint transform and motion subspace matrices
211 m.vJ = m.links[m.q_map[i]].joint.S * dq(i);
212 // Compute the spatial transform from the parent to the current body
213 m.Xup[i] = homogeneous_to_spatial(m.links[m.q_map[i]].joint.get_parent_to_child_transform(q(i)).inverse());
214 // Check if the m.parent link is the base link
215 if (m.parent[i] == -1) {
216 m.v[i] = m.vJ;
217 m.a[i] = m.Xup[i] * -m.spatial_gravity;
218 }
219 else {
220 m.v[i] = m.Xup[i] * m.v[m.parent[i]] + m.vJ;
221 m.a[i] = m.Xup[i] * m.a[m.parent[i]] + cross_spatial(m.v[i]) * m.vJ;
222 }
223 m.fvp[i] = m.links[m.q_map[i]].I * m.a[i] + cross_motion(m.v[i]) * m.links[m.q_map[i]].I * m.v[i];
224 m.IC[i] = m.links[m.q_map[i]].I;
225 }
226
227 // Apply external forces if non-zero
228 if (!f_ext.empty()) {
229 m.fvp = apply_external_forces(m, m.Xup, m.pA, f_ext);
230 }
231
232 for (int i = nq - 1; i >= 0; i--) {
233 m.C(i, 0) = m.links[m.q_map[i]].joint.S.transpose() * m.fvp[i];
234 if (m.parent[i] != -1) {
235 m.fvp[m.parent[i]] = m.fvp[m.parent[i]] + m.Xup[i].transpose() * m.fvp[i];
236 }
237 }
238
239 for (int i = nq - 1; i >= 0; i--) {
240 if (m.parent[i] != -1) {
241 m.IC[m.parent[i]] = m.IC[m.parent[i]] + m.Xup[i].transpose() * m.IC[i] * m.Xup[i];
242 }
243 }
244
245 for (int i = 0; i < nq; i++) {
246 m.fh = m.IC[i] * m.links[m.q_map[i]].joint.S;
247 m.mass_matrix(i, i) = m.links[m.q_map[i]].joint.S.transpose() * m.fh;
248 int j = i;
249 while (m.parent[j] != -1) {
250 m.fh = m.Xup[j].transpose() * m.fh;
251 j = m.parent[j];
252 m.mass_matrix(i, j) = m.links[m.q_map[j]].joint.S.transpose() * m.fh;
253 m.mass_matrix(j, i) = m.mass_matrix(i, j);
254 }
255 }
256
257 return m.mass_matrix.ldlt().solve(tau - m.C);
258 }
259
268 template <typename Scalar, int nq>
269 Eigen::Matrix<Scalar, nq, 1> inverse_dynamics(Model<Scalar, nq>& m,
270 const Eigen::Matrix<Scalar, nq, 1>& q,
271 const Eigen::Matrix<Scalar, nq, 1>& dq,
272 const Eigen::Matrix<Scalar, nq, 1>& ddq,
273 const std::vector<Eigen::Matrix<Scalar, 6, 1>>& f_ext = {}) {
274 for (int i = 0; i < nq; i++) {
275 // Compute the joint transform and motion subspace matrices
276 m.vJ = m.links[m.q_map[i]].joint.S * dq(i);
277 // Compute the spatial transform from the parent to the current body
278 m.Xup[i] = homogeneous_to_spatial(m.links[m.q_map[i]].joint.get_parent_to_child_transform(q(i)).inverse());
279 // Check if the m.parent link is the base link
280 if (m.parent[i] == -1) {
281 m.v[i] = m.vJ;
282 m.a[i] = m.Xup[i] * -m.spatial_gravity + m.links[m.q_map[i]].joint.S * ddq(i);
283 }
284 else {
285 m.v[i] = m.Xup[i] * m.v[m.parent[i]] + m.vJ;
286 m.a[i] =
287 m.Xup[i] * m.a[m.parent[i]] + m.links[m.q_map[i]].joint.S * ddq(i) + cross_spatial(m.v[i]) * m.vJ;
288 }
289 m.fvp[i] = m.links[m.q_map[i]].I * m.a[i] + cross_motion(m.v[i]) * m.links[m.q_map[i]].I * m.v[i];
290 }
291
292 // Apply external forces if non-zero
293 if (!f_ext.empty()) {
294 m.fvp = apply_external_forces(m, m.Xup, m.pA, f_ext);
295 }
296
297 for (int i = nq - 1; i >= 0; i--) {
298 m.tau(i, 0) = m.links[m.q_map[i]].joint.S.transpose() * m.fvp[i];
299 if (m.parent[i] != -1) {
300 m.fvp[m.parent[i]] = m.fvp[m.parent[i]] + m.Xup[i].transpose() * m.fvp[i];
301 }
302 }
303 return m.tau;
304 }
305
306} // namespace tinyrobotics
307
308#endif
Scalar total_energy(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q, const Eigen::Matrix< Scalar, nq, 1 > &dq)
Compute the total energy of the tinyrobotics model.
Definition: dynamics.hpp:94
Scalar kinetic_energy(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q, const Eigen::Matrix< Scalar, nq, 1 > &dq)
Compute the kinetic_energy of the tinyrobotics model.
Definition: dynamics.hpp:60
Scalar potential_energy(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q)
Compute the potential_energy of the tinyrobotics model.
Definition: dynamics.hpp:74
Eigen::Matrix< Scalar, nq, nq > mass_matrix(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q)
Compute the mass matrix of the tinyrobotics model.
Definition: dynamics.hpp:24
std::vector< Eigen::Matrix< Scalar, 6, 1 > > apply_external_forces(const Model< Scalar, nq > &m, const std::vector< Eigen::Matrix< Scalar, 6, 6 > > &Xup, const std::vector< Eigen::Matrix< Scalar, 6, 1 > > &f_in, const std::vector< Eigen::Matrix< Scalar, 6, 1 > > &f_ext)
Apply external forces to the tinyrobotics model.
Definition: dynamics.hpp:109
Eigen::Matrix< Scalar, nq, 1 > forward_dynamics(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q, const Eigen::Matrix< Scalar, nq, 1 > &dq, const Eigen::Matrix< Scalar, nq, 1 > &tau, const std::vector< Eigen::Matrix< Scalar, 6, 1 > > &f_ext={})
Compute the forward dynamics of the tinyrobotics model via Articulated-Body Algorithm.
Definition: dynamics.hpp:141
Eigen::Matrix< Scalar, nq, 1 > forward_dynamics_crb(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q, const Eigen::Matrix< Scalar, nq, 1 > &dq, const Eigen::Matrix< Scalar, nq, 1 > &tau, const std::vector< Eigen::Matrix< Scalar, 6, 1 > > &f_ext={})
Compute the forward dynamics of the tinyrobotics model via Composite-Rigid-Body Algorithm.
Definition: dynamics.hpp:204
Eigen::Matrix< Scalar, nq, 1 > inverse_dynamics(Model< Scalar, nq > &m, const Eigen::Matrix< Scalar, nq, 1 > &q, const Eigen::Matrix< Scalar, nq, 1 > &dq, const Eigen::Matrix< Scalar, nq, 1 > &ddq, const std::vector< Eigen::Matrix< Scalar, 6, 1 > > &f_ext={})
Compute the inverse dynamics of a tinyrobotics model.
Definition: dynamics.hpp:269
Contains functions for computing various kinematic quantities of a tinyrobotics model.
std::vector< Eigen::Transform< Scalar, 3, Eigen::Isometry > > forward_kinematics_com(Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q)
Computes the transform between center of mass of each link and the source link.
Definition: kinematics.hpp:126
Eigen::Matrix< Scalar, 6, 6 > homogeneous_to_spatial(const Eigen::Transform< Scalar, 3, Eigen::Isometry > &H)
Spatial coordinate transform from homogeneous transformation matrix.
Definition: math.hpp:95
Eigen::Matrix< Scalar, 6, 6 > cross_motion(const Eigen::Matrix< Scalar, 6, 1 > &v)
Computes the 6x6 cross-product matrix for a motion vector and a force vector.
Definition: math.hpp:57
Eigen::Matrix< Scalar, 6, 6 > cross_spatial(const Eigen::Matrix< Scalar, 6, 1 > &v)
Computes the 6x6 cross-product matrix for a 6D spatial vector.
Definition: math.hpp:43
Contains struct for representing a tinyrobotics model.
A tinyrobotics model.
Definition: model.hpp:25
std::vector< int > parent
Vector of parent link indices of the links which have a non-fixed joints.
Definition: model.hpp:42
std::vector< int > q_map
Map to indices of links in the models link vector that have a non-fixed joints.
Definition: model.hpp:39
Scalar potential_energy
Potential energy.
Definition: model.hpp:59
std::vector< Eigen::Matrix< Scalar, 6, 6 > > Xup
**************** Pre-allcoated variables for dynamics algorithms ****************
Definition: model.hpp:73
std::vector< Scalar > d
Joint force inertia terms for the robot links.
Definition: model.hpp:101
std::vector< Eigen::Matrix< Scalar, 6, 1 > > v
Spatial velocities of the robot links.
Definition: model.hpp:81
std::vector< Eigen::Transform< Scalar, 3, Eigen::Isometry > > forward_kinematics_com
Vector of forward kinematics com data.
Definition: model.hpp:65
std::vector< Eigen::Matrix< Scalar, 6, 1 > > U
Spatial force projections for the joints.
Definition: model.hpp:97
Eigen::Matrix< Scalar, 6, 1 > fh
Force term for intermediately storing the result.
Definition: model.hpp:121
Eigen::Matrix< Scalar, 6, 1 > spatial_gravity
Gravity vector in spatial coordinates.
Definition: model.hpp:128
Eigen::Matrix< Scalar, nq, 1 > ddq
Joint acceleration.
Definition: model.hpp:134
std::vector< Eigen::Matrix< Scalar, 6, 1 > > c
Spatial acceleration bias terms for the robot links.
Definition: model.hpp:85
Eigen::Matrix< Scalar, nq, nq > mass_matrix
**************** Pre-allcoated variables for kinematics algorithms ****************
Definition: model.hpp:56
std::vector< Eigen::Matrix< Scalar, 6, 6 > > IA
Articulated-body inertia matrices for the robot links.
Definition: model.hpp:89
Eigen::Matrix< Scalar, 3, 1 > gravity
Gravitational acceleration vector experienced by model.
Definition: model.hpp:45
std::vector< Eigen::Matrix< Scalar, 6, 1 > > fvp
Joint spatial forces.
Definition: model.hpp:114
Eigen::Matrix< Scalar, nq, 1 > tau
Joint torque/force.
Definition: model.hpp:137
std::vector< Eigen::Matrix< Scalar, 6, 1 > > pA
Articulated-body forces for the robot links.
Definition: model.hpp:93
Eigen::Matrix< Scalar, nq, 1 > C
Bias force vector.
Definition: model.hpp:118
std::vector< Scalar > u
Joint force bias terms for the robot links.
Definition: model.hpp:104
Eigen::Matrix< Scalar, 6, 1 > vJ
Joint spatial velocities.
Definition: model.hpp:111
std::vector< Eigen::Matrix< Scalar, 6, 1 > > a
Spatial accelerations of the robot links.
Definition: model.hpp:107
std::vector< Eigen::Matrix< Scalar, 6, 6 > > IC
Articulated-body inertias.
Definition: model.hpp:124
std::vector< Link< Scalar > > links
Vector of links in the model.
Definition: model.hpp:51