1#ifndef TR_FORWARDKINEMATICS_HPP
2#define TR_FORWARDKINEMATICS_HPP
5#include <Eigen/Geometry>
13namespace tinyrobotics {
25 template <
typename Scalar,
int nq,
typename TargetLink>
27 if constexpr (std::is_integral<TargetLink>::value) {
28 return static_cast<int>(target_link);
30 else if constexpr (std::is_same<TargetLink, std::string>::value) {
31 return model.
get_link(target_link).idx;
34 throw std::invalid_argument(
"Invalid target_link type. Must be int or std::string.");
46 template <
typename Scalar,
int nq>
49 const Eigen::Matrix<Scalar, nq, 1>& q) {
50 model.
data.forward_kinematics.resize(model.
n_links, Eigen::Transform<Scalar, 3, Eigen::Isometry>::Identity());
51 for (
auto const link : model.
links) {
52 model.
data.forward_kinematics[link.idx] = link.joint.parent_transform;
53 if (link.joint.idx != -1) {
54 model.
data.forward_kinematics[link.idx] =
55 model.
data.forward_kinematics[link.idx] * link.joint.get_joint_transform(q[link.joint.idx]);
57 if (link.parent != -1) {
58 model.
data.forward_kinematics[link.idx] =
59 model.
data.forward_kinematics[link.parent] * model.
data.forward_kinematics[link.idx];
62 return model.
data.forward_kinematics;
75 template <
typename Scalar,
int nq,
typename TargetLink>
77 const Eigen::Matrix<Scalar, nq, 1>& q,
78 const TargetLink& target_link) {
80 const int target_link_idx =
get_link_idx(model, target_link);
84 Eigen::Transform<Scalar, 3, Eigen::Isometry> Htb = Eigen::Transform<Scalar, 3, Eigen::Isometry>::Identity();
86 Eigen::Transform<Scalar, 3, Eigen::Isometry> H = Eigen::Transform<Scalar, 3, Eigen::Isometry>::Identity();
87 if (current_link.
joint.idx != -1) {
89 H = current_link.
joint.get_joint_transform(q[current_link.
joint.idx]);
91 Htb = Htb * H.inverse();
93 Htb = Htb * current_link.
joint.parent_transform.inverse();
113 template <
typename Scalar,
int nq,
typename TargetLink,
typename SourceLink>
115 const Eigen::Matrix<Scalar, nq, 1>& q,
116 const TargetLink& target_link,
117 const SourceLink& source_link) {
118 const int target_link_idx =
get_link_idx(model, target_link);
119 const int source_link_idx =
get_link_idx(model, source_link);
122 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hbs =
forward_kinematics(model, q, source_link_idx);
123 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hsb = Hbs.inverse();
125 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hbt =
forward_kinematics(model, q, target_link_idx);
127 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hst = Hsb * Hbt;
139 template <
typename Scalar,
int nq>
142 const Eigen::Matrix<Scalar, nq, 1>& q) {
146 for (
auto const link : model.
links) {
147 model.
data.forward_kinematics_com[link.idx] =
148 model.
data.forward_kinematics[link.idx] * model.
links[link.idx].centre_of_mass;
150 return model.
data.forward_kinematics_com;
165 template <
typename Scalar,
int nq,
typename TargetLink,
typename SourceLink =
int>
167 const Eigen::Matrix<Scalar, nq, 1>& q,
168 const TargetLink& target_link,
169 const SourceLink& source_link = 0) {
170 const int target_link_idx =
get_link_idx(model, target_link);
171 const int source_link_idx =
get_link_idx(model, source_link);
174 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hst =
177 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hsc = Hst * model.
links[target_link_idx].centre_of_mass;
194 template <
typename Scalar,
int nq,
typename TargetLink,
typename SourceLink =
int>
196 const Eigen::Matrix<Scalar, nq, 1>& q,
197 const TargetLink& target_link,
198 const SourceLink& source_link = 0) {
199 const int source_link_idx =
get_link_idx(model, source_link);
200 const int target_link_idx =
get_link_idx(model, target_link);
202 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hst =
204 Eigen::Matrix<Scalar, 3, 1> rTSs(Hst.translation());
220 template <
typename Scalar,
int nq,
typename TargetLink,
typename SourceLink =
int>
222 const Eigen::Matrix<Scalar, nq, 1>& q,
223 const TargetLink& target_link,
224 const SourceLink& source_link = 0) {
228 Eigen::Transform<Scalar, 3, Eigen::Isometry> Hst =
243 template <
typename Scalar,
int nq,
typename TargetLink>
245 const Eigen::Matrix<Scalar, nq, 1>& q,
246 const TargetLink& target_link) {
248 const int target_link_idx =
get_link_idx(model, target_link);
255 Eigen::Matrix<Scalar, 3, 1> rTBb =
translation(model, q, current_link.
idx, base_link.idx);
258 Eigen::Matrix<Scalar, 6, nq> J = Eigen::Matrix<Scalar, 6, nq>::Zero();
260 auto current_joint = current_link.
joint;
261 if (current_joint.idx != -1) {
265 auto zIBb = Hbi.linear() * current_joint.axis;
267 auto rIBb = Hbi.translation();
268 if (current_joint.type == JointType::PRISMATIC) {
269 J.block(0, current_joint.idx, 3, 1) = zIBb;
270 J.block(3, current_joint.idx, 3, 1) = Eigen::Matrix<Scalar, 3, 1>::Zero();
272 else if (current_joint.type == JointType::REVOLUTE) {
273 J.block(0, current_joint.idx, 3, 1) = (zIBb).cross(rTBb - rIBb);
274 J.block(3, current_joint.idx, 3, 1) = zIBb;
293 template <
typename Scalar,
int nq,
typename TargetLink>
295 const Eigen::Matrix<Scalar, nq, 1>& q,
296 const TargetLink& target_link) {
298 const int target_link_idx =
get_link_idx(model, target_link);
308 Eigen::Matrix<Scalar, 6, nq> J = Eigen::Matrix<Scalar, 6, nq>::Zero();
310 auto current_joint = current_link.
joint;
311 if (current_joint.idx != -1) {
315 auto zIBb = Hbi.linear() * current_joint.axis;
317 auto rIBb = Hbi.translation();
318 if (current_joint.type == JointType::PRISMATIC) {
319 J.block(0, current_joint.idx, 3, 1) = zIBb;
320 J.block(3, current_joint.idx, 3, 1) = Eigen::Matrix<Scalar, 3, 1>::Zero();
322 else if (current_joint.type == JointType::REVOLUTE) {
323 J.block(0, current_joint.idx, 3, 1) = (zIBb).cross(rTcBb - rIBb);
324 J.block(3, current_joint.idx, 3, 1) = zIBb;
344 template <
typename Scalar,
int nq,
typename SourceLink =
int>
346 const Eigen::Matrix<Scalar, nq, 1>& q,
347 const SourceLink& source_link = 0) {
349 Eigen::Matrix<Scalar, 3, 1> rCSs = Eigen::Matrix<Scalar, 3, 1>::Zero();
350 for (
auto link : model.
links) {
354 rCSs = rCSs + Hsc.translation() * link.mass;
357 return rCSs / model.
mass;
Eigen::Matrix< Scalar, 6, nq > geometric_jacobian(const Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q, const TargetLink &target_link)
Computes the geometric jacobian of the target link from the base link in the base link frame.
Definition: Kinematics.hpp:244
Eigen::Matrix< Scalar, 6, nq > geometric_jacobian_com(const Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q, const TargetLink &target_link)
Computes the geometric jacobian relative to the base for the specified target link's center of mass.
Definition: Kinematics.hpp:294
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 to centre of mass of all the links in the tinyrobotics model.
Definition: Kinematics.hpp:140
Eigen::Matrix< Scalar, 3, 3 > rotation(const Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q, const TargetLink &target_link, const SourceLink &source_link=0)
Computes the rotation matrix between the target link and the source link in the source link frame.
Definition: Kinematics.hpp:221
const int get_link_idx(const Model< Scalar, nq > &model, const TargetLink &target_link)
Retrieves the index of the target link in the tinyrobotics model.
Definition: Kinematics.hpp:26
std::vector< Eigen::Transform< Scalar, 3, Eigen::Isometry > > forward_kinematics(Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q)
Computes the transform to all the links in the tinyrobotics model.
Definition: Kinematics.hpp:47
Eigen::Matrix< Scalar, 3, 1 > centre_of_mass(const Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q, const SourceLink &source_link=0)
Computes the centre of mass expressed in source link frame.
Definition: Kinematics.hpp:345
Eigen::Matrix< Scalar, 3, 1 > translation(const Model< Scalar, nq > &model, const Eigen::Matrix< Scalar, nq, 1 > &q, const TargetLink &target_link, const SourceLink &source_link=0)
Computes the translation of the target link from the source link in the source link frame.
Definition: Kinematics.hpp:195
Contains various math related functions.
Contains struct for representing a tinyrobotics model.
Represents a link in a tinyrobotics model.
Definition: Link.hpp:16
std::string name
Name of the link.
Definition: Link.hpp:19
int idx
Index of the link in the model's link vector.
Definition: Link.hpp:22
Joint< Scalar > joint
Joint connecting the link to its parent link.
Definition: Link.hpp:41
int parent
Index of the link's parent link in the model's link vector.
Definition: Link.hpp:25
A tinyrobotics model.
Definition: Model.hpp:30
int n_links
Number of links in the model.
Definition: Model.hpp:35
Data< Scalar, nq > data
Stores the results of the models algorithms.
Definition: Model.hpp:65
Scalar mass
Total mass of the model.
Definition: Model.hpp:62
Link< Scalar > get_link(const std::string &name) const
Get a link in the model by name.
Definition: Model.hpp:72
std::string name
Name of the model.
Definition: Model.hpp:32
int base_link_idx
Index of the base link in the models links vector.
Definition: Model.hpp:50
std::vector< Link< Scalar > > links
Vector of links in the model.
Definition: Model.hpp:44