Drake
cylindrical.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cmath>
4 
5 #include <Eigen/Dense>
6 
8 #include "drake/drakeMath_export.h"
11 
12 namespace drake {
13 namespace math {
14 
15 namespace internal {
17 DRAKEMATH_EXPORT Eigen::Matrix3d rotz(double theta);
18 
22 DRAKEMATH_EXPORT void rotz(double theta, Eigen::Matrix3d* M,
23  Eigen::Matrix3d* dM, Eigen::Matrix3d* ddM);
24 } // namespace internal
25 
26 template <typename Scalar>
27 void cylindrical2cartesian(const Vector3<Scalar>& m_cylinder_axis,
28  const Vector3<Scalar>& m_cylinder_x_dir,
29  const Vector3<Scalar>& cylinder_origin,
30  const Vector6<Scalar>& x_cylinder,
31  const Vector6<Scalar>& v_cylinder,
32  Vector6<Scalar>& x_cartesian,
33  Vector6<Scalar>& v_cartesian, Matrix6<Scalar>& J,
34  Vector6<Scalar>& Jdotv) {
35  using std::cos;
36  using std::sin;
37  Vector3<Scalar> cylinder_axis = m_cylinder_axis / m_cylinder_axis.norm();
38  Vector3<Scalar> cylinder_x_dir = m_cylinder_x_dir / m_cylinder_x_dir.norm();
39  Matrix3<Scalar> R_cylinder2cartesian;
40  R_cylinder2cartesian.col(0) = cylinder_x_dir;
41  R_cylinder2cartesian.col(1) = cylinder_axis.cross(cylinder_x_dir);
42  R_cylinder2cartesian.col(2) = cylinder_axis;
43  double radius = x_cylinder(0);
44  double theta = x_cylinder(1);
45  double c_theta = cos(theta);
46  double s_theta = sin(theta);
47  double height = x_cylinder(2);
48  double radius_dot = v_cylinder(0);
49  double theta_dot = v_cylinder(1);
50  double height_dot = v_cylinder(2);
51  Vector3<Scalar> x_pos_cartesian;
52  x_pos_cartesian << radius * c_theta, radius * s_theta, height;
53  x_pos_cartesian = R_cylinder2cartesian * x_pos_cartesian + cylinder_origin;
54  Vector3<Scalar> v_pos_cartesian;
55  v_pos_cartesian << radius * -s_theta * theta_dot + radius_dot * c_theta,
56  radius * c_theta * theta_dot + radius_dot * s_theta, height_dot;
57  v_pos_cartesian = R_cylinder2cartesian * v_pos_cartesian;
58  Eigen::Vector3d x_rpy_cylinder = x_cylinder.block(3, 0, 3, 1);
59  Matrix3<Scalar> R_tangent = rpy2rotmat(x_rpy_cylinder);
60  Matrix3<Scalar> R_tangent2cylinder;
61  Matrix3<Scalar> dR_tangent2cylinder;
62  Matrix3<Scalar> ddR_tangent2cylinder;
63  internal::rotz(theta - M_PI / 2, &R_tangent2cylinder, &dR_tangent2cylinder,
64  &ddR_tangent2cylinder);
65  Matrix3<Scalar> dR_tangent2cylinder_dtheta = dR_tangent2cylinder;
66  Matrix3<Scalar> R_cylinder = R_tangent2cylinder * R_tangent;
67  Matrix3<Scalar> R_cartesian = R_cylinder2cartesian * R_cylinder;
68  Vector3<Scalar> x_rpy_cartesian = rotmat2rpy(R_cartesian);
69  x_cartesian.block(0, 0, 3, 1) = x_pos_cartesian;
70  x_cartesian.block(3, 0, 3, 1) = x_rpy_cartesian;
71  v_cartesian.block(0, 0, 3, 1) = v_pos_cartesian;
72  v_cartesian.block(3, 0, 3, 1) =
73  theta_dot * R_cylinder2cartesian.col(2) +
74  R_cylinder2cartesian * R_tangent2cylinder * v_cylinder.block(3, 0, 3, 1);
76  J.block(0, 0, 3, 1) << c_theta, s_theta, 0;
77  J.block(0, 1, 3, 1) << radius * -s_theta, radius * c_theta, 0;
78  J.block(0, 2, 3, 1) << 0, 0, 1;
79  J.block(0, 0, 3, 3) = R_cylinder2cartesian * J.block(0, 0, 3, 3);
80  J.block(3, 1, 3, 1) = R_cylinder2cartesian.col(2);
81  J.block(3, 3, 3, 3) = R_cylinder2cartesian * R_tangent2cylinder;
82  Matrix3<Scalar> dJ1_dradius = Matrix3<Scalar>::Zero();
83  dJ1_dradius(0, 1) = -s_theta;
84  dJ1_dradius(1, 1) = c_theta;
86  dJ1_dtheta(0, 0) = -s_theta;
87  dJ1_dtheta(0, 1) = -radius * c_theta;
88  dJ1_dtheta(1, 0) = c_theta;
89  dJ1_dtheta(1, 1) = -radius * s_theta;
90  Jdotv.block(0, 0, 3, 1) = R_cylinder2cartesian * (dJ1_dradius * radius_dot +
91  dJ1_dtheta * theta_dot) *
92  v_cylinder.block(0, 0, 3, 1);
93  Jdotv.block(3, 0, 3, 1) = R_cylinder2cartesian * dR_tangent2cylinder_dtheta *
94  theta_dot * v_cylinder.block(3, 0, 3, 1);
95 }
96 
97 template <typename Scalar>
98 void cartesian2cylindrical(const Vector3<Scalar>& m_cylinder_axis,
99  const Vector3<Scalar>& m_cylinder_x_dir,
100  const Vector3<Scalar>& cylinder_origin,
101  const Vector6<Scalar>& x_cartesian,
102  const Vector6<Scalar>& v_cartesian,
103  Vector6<Scalar>& x_cylinder,
104  Vector6<Scalar>& v_cylinder, Matrix6<Scalar>& J,
105  Vector6<Scalar>& Jdotv) {
106  using std::atan2;
107  using std::pow;
108  using std::sqrt;
109  Vector3<Scalar> cylinder_axis = m_cylinder_axis / m_cylinder_axis.norm();
110  Vector3<Scalar> cylinder_x_dir = m_cylinder_x_dir / m_cylinder_x_dir.norm();
111  Matrix3<Scalar> R_cylinder2cartesian;
112  R_cylinder2cartesian.col(0) = cylinder_x_dir;
113  R_cylinder2cartesian.col(1) = cylinder_axis.cross(cylinder_x_dir);
114  R_cylinder2cartesian.col(2) = cylinder_axis;
115  Matrix3<Scalar> R_cartesian2cylinder = R_cylinder2cartesian.transpose();
116  Vector3<Scalar> x_pos_cylinder =
117  R_cartesian2cylinder * (x_cartesian.block(0, 0, 3, 1) - cylinder_origin);
118  Vector3<Scalar> v_pos_cylinder =
119  R_cartesian2cylinder * v_cartesian.block(0, 0, 3, 1);
120  double radius = sqrt(pow(x_pos_cylinder(0), 2) + pow(x_pos_cylinder(1), 2));
121  double radius_dot = (x_pos_cylinder(0) * v_pos_cylinder(0) +
122  x_pos_cylinder(1) * v_pos_cylinder(1)) /
123  radius;
124  double theta = atan2(x_pos_cylinder(1), x_pos_cylinder(0));
125  double radius_square = pow(radius, 2);
126  double radius_cubic = pow(radius, 3);
127  double radius_quad = pow(radius, 4);
128  double theta_dot = (-x_pos_cylinder(1) * v_pos_cylinder(0) +
129  x_pos_cylinder(0) * v_pos_cylinder(1)) /
130  radius_square;
131  double height = x_pos_cylinder(2);
132  double height_dot = v_pos_cylinder(2);
133  x_cylinder(0) = radius;
134  x_cylinder(1) = theta;
135  x_cylinder(2) = height;
136  v_cylinder(0) = radius_dot;
137  v_cylinder(1) = theta_dot;
138  v_cylinder(2) = height_dot;
139  Matrix3<Scalar> R_tangent2cylinder;
140  Matrix3<Scalar> dR_tangent2cylinder;
141  Matrix3<Scalar> ddR_tangent2cylinder;
142  internal::rotz(theta - M_PI / 2, &R_tangent2cylinder, &dR_tangent2cylinder,
143  &ddR_tangent2cylinder);
144  Matrix3<Scalar> R_cylinder2tangent = R_tangent2cylinder.transpose();
145  Eigen::Vector3d x_rpy_cartesian = x_cartesian.block(3, 0, 3, 1);
146  Matrix3<Scalar> R_cartesian = rpy2rotmat(x_rpy_cartesian);
147  x_cylinder.block(3, 0, 3, 1) =
148  rotmat2rpy(R_cylinder2tangent * R_cartesian2cylinder * R_cartesian);
149  J = Matrix6<Scalar>::Zero();
151  J(0, 0) = x_pos_cylinder(0) / radius;
152  J(0, 1) = x_pos_cylinder(1) / radius;
153  J(1, 0) = -x_pos_cylinder(1) / radius_square;
154  J(1, 1) = x_pos_cylinder(0) / radius_square;
155  J(2, 2) = 1.0;
156  J.block(0, 0, 3, 3) = J.block(0, 0, 3, 3) * R_cartesian2cylinder;
157  Jdot(0, 0) =
158  pow(x_pos_cylinder(1), 2) / radius_cubic * v_pos_cylinder(0) -
159  x_pos_cylinder(0) * x_pos_cylinder(1) / radius_cubic * v_pos_cylinder(1);
160  Jdot(0, 1) = -x_pos_cylinder(0) * x_pos_cylinder(1) / radius_cubic *
161  v_pos_cylinder(0) +
162  pow(x_pos_cylinder(0), 2) / radius_cubic * v_pos_cylinder(1);
163  Jdot(1, 0) = 2 * x_pos_cylinder(0) * x_pos_cylinder(1) / radius_quad *
164  v_pos_cylinder(0) +
165  (pow(x_pos_cylinder(1), 2) - pow(x_pos_cylinder(0), 2)) /
166  radius_quad * v_pos_cylinder(1);
167  Jdot(1, 1) = (pow(x_pos_cylinder(1), 2) - pow(x_pos_cylinder(0), 2)) /
168  radius_quad * v_pos_cylinder(0) -
169  2 * x_pos_cylinder(0) * x_pos_cylinder(1) / radius_quad *
170  v_pos_cylinder(1);
171  Jdot.block(0, 0, 3, 3) = Jdot.block(0, 0, 3, 3) * R_cartesian2cylinder;
172  v_cylinder.block(3, 0, 3, 1) = R_cylinder2tangent * R_cartesian2cylinder *
173  v_cartesian.block(3, 0, 3, 1) -
174  theta_dot * R_cylinder2tangent.col(2);
175  J.block(3, 0, 3, 3) = R_cylinder2tangent.col(2) * -J.block(1, 0, 1, 3);
176  J.block(3, 3, 3, 3) = R_cylinder2tangent * R_cartesian2cylinder;
177  Jdot.block(3, 0, 3, 3) = dR_tangent2cylinder.row(2).transpose() *
178  -J.block(1, 0, 1, 3) * theta_dot +
179  R_cylinder2tangent.col(2) * -Jdot.block(1, 0, 1, 3);
180  Jdot.block(3, 3, 3, 3) =
181  dR_tangent2cylinder.transpose() * theta_dot * R_cartesian2cylinder;
182  Jdotv = Jdot * v_cartesian;
183 }
184 
185 } // namespace math
186 } // namespace drake
This file contains abbreviated definitions for certain specializations of Eigen::Matrix that are comm...
Eigen::Matrix< Scalar, 6, 6 > Matrix6
A matrix of 3 rows and 3 columns, templated on scalar type.
Definition: eigen_types.h:44
static const double radius
Definition: ptToPolyBullet_mex.cpp:35
void cylindrical2cartesian(const Vector3< Scalar > &m_cylinder_axis, const Vector3< Scalar > &m_cylinder_x_dir, const Vector3< Scalar > &cylinder_origin, const Vector6< Scalar > &x_cylinder, const Vector6< Scalar > &v_cylinder, Vector6< Scalar > &x_cartesian, Vector6< Scalar > &v_cartesian, Matrix6< Scalar > &J, Vector6< Scalar > &Jdotv)
Definition: cylindrical.h:27
Definition: constants.h:3
FunctionalForm cos(FunctionalForm const &x)
Definition: functional_form.cc:188
Matrix3d rotz(double theta)
Returns a 3D rotation matrix by theta about the z axis.
Definition: cylindrical.cc:12
FunctionalForm sqrt(FunctionalForm const &x)
Definition: functional_form.cc:208
Eigen::Matrix< Scalar, 3, 1 > Vector3
A column vector of size 3, templated on scalar type.
Definition: eigen_types.h:24
Vector3< typename Derived::Scalar > rotmat2rpy(const Eigen::MatrixBase< Derived > &R)
Definition: rotation_matrix.h:91
void cartesian2cylindrical(const Vector3< Scalar > &m_cylinder_axis, const Vector3< Scalar > &m_cylinder_x_dir, const Vector3< Scalar > &cylinder_origin, const Vector6< Scalar > &x_cartesian, const Vector6< Scalar > &v_cartesian, Vector6< Scalar > &x_cylinder, Vector6< Scalar > &v_cylinder, Matrix6< Scalar > &J, Vector6< Scalar > &Jdotv)
Definition: cylindrical.h:98
Eigen::Matrix< Scalar, 6, 1 > Vector6
A column vector of size 6.
Definition: eigen_types.h:32
Eigen::Matrix< Scalar, 3, 3 > Matrix3
A matrix of 3 rows and 3 columns, templated on scalar type.
Definition: eigen_types.h:40
Matrix3< typename Derived::Scalar > rpy2rotmat(const Eigen::MatrixBase< Derived > &rpy)
Definition: roll_pitch_yaw.h:37
FunctionalForm sin(FunctionalForm const &x)
Definition: functional_form.cc:203