Matrix<Scalar, Dynamic, DerivedPoints::ColsAtCompileTime> forwardJacDotTimesVTemp( const RigidBodyTree &tree, const KinematicsCache<Scalar> &cache, const MatrixBase<DerivedPoints> &points, int current_body_or_frame_ind, int new_body_or_frame_ind, int rotation_type) { auto Jtransdot_times_v = tree.transformPointsJacobianDotTimesV(cache, points, current_body_or_frame_ind, new_body_or_frame_ind); if (rotation_type == 0) { return Jtransdot_times_v; } else { Matrix<Scalar, Dynamic, 1> Jrotdot_times_v(rotationRepresentationSize(rotation_type)); if (rotation_type == 1) { Jrotdot_times_v = tree.relativeRollPitchYawJacobianDotTimesV(cache, current_body_or_frame_ind, new_body_or_frame_ind); } else if (rotation_type == 2) { Jrotdot_times_v = tree.relativeQuaternionJacobianDotTimesV(cache, current_body_or_frame_ind, new_body_or_frame_ind); } else { throw runtime_error("rotation type not recognized"); } Matrix<Scalar, Dynamic, 1> Jdot_times_v((3 + rotationRepresentationSize(rotation_type)) * points.cols(), 1); int row_start = 0; for (int i = 0; i < points.cols(); i++) { Jdot_times_v.template middleRows<3>(row_start) = Jtransdot_times_v.template middleRows<3>(3 * i); row_start += 3; Jdot_times_v.middleRows(row_start, Jrotdot_times_v.rows()) = Jrotdot_times_v; row_start += Jrotdot_times_v.rows(); } return Jdot_times_v; } };
int contactConstraintsBV( const RigidBodyTree<double>& r, const KinematicsCache<double>& cache, int nc, std::vector<double> support_mus, // TODO(#2274) Fix NOLINTNEXTLINE(runtime/references). drake::eigen_aligned_std_vector<SupportStateElement>& supp, MatrixXd& B, // TODO(#2274) Fix NOLINTNEXTLINE(runtime/references). MatrixXd& JB, MatrixXd& Jp, VectorXd& Jpdotv, MatrixXd& normals) { int j, k = 0, nq = r.get_num_positions(); B.resize(3, nc * 2 * m_surface_tangents); JB.resize(nq, nc * 2 * m_surface_tangents); Jp.resize(3 * nc, nq); Jpdotv.resize(3 * nc); normals.resize(3, nc); Vector3d contact_pos, pos, normal; MatrixXd J(3, nq); Matrix<double, 3, m_surface_tangents> d; for (auto iter = supp.begin(); iter != supp.end(); iter++) { double mu = support_mus[iter - supp.begin()]; double norm = sqrt(1 + mu * mu); // because normals and ds are orthogonal, // the norm has a simple form if (nc > 0) { for (auto pt_iter = iter->contact_pts.begin(); pt_iter != iter->contact_pts.end(); pt_iter++) { contact_pos = r.transformPoints(cache, *pt_iter, iter->body_idx, 0); J = r.transformPointsJacobian(cache, *pt_iter, iter->body_idx, 0, true); normal = iter->support_surface.head(3); surfaceTangents(normal, d); for (j = 0; j < m_surface_tangents; j++) { B.col(2 * k * m_surface_tangents + j) = (normal + mu * d.col(j)) / norm; B.col((2 * k + 1) * m_surface_tangents + j) = (normal - mu * d.col(j)) / norm; JB.col(2 * k * m_surface_tangents + j) = J.transpose() * B.col(2 * k * m_surface_tangents + j); JB.col((2 * k + 1) * m_surface_tangents + j) = J.transpose() * B.col((2 * k + 1) * m_surface_tangents + j); } // store away kin sols into Jp and Jpdotv // NOTE: I'm cheating and using a slightly different ordering of J and // Jdot here Jp.block(3 * k, 0, 3, nq) = J; Vector3d pt = (*pt_iter).head(3); Jpdotv.block(3 * k, 0, 3, 1) = r.transformPointsJacobianDotTimesV(cache, pt, iter->body_idx, 0); normals.col(k) = normal; k++; } } } return k; }