/// Evaluates the time derivative of the constraint void Joint::evaluate_constraints_dot(Real C[6]) { Real Cx[6]; // get the inboard and outboard links RigidBodyPtr in = get_inboard_link(); RigidBodyPtr out = get_outboard_link(); // get the linear angular velocities const Vector3& lvi = in->get_lvel(); const Vector3& lvo = out->get_lvel(); const Vector3& avi = in->get_avel(); const Vector3& avo = out->get_avel(); // compute const unsigned NEQ = num_constraint_eqns(); for (unsigned i=0; i< NEQ; i++) { calc_constraint_jacobian(DynamicBody::eAxisAngle, in, i, Cx); Vector3 lv(Cx[0], Cx[1], Cx[2]); Vector3 av(Cx[3], Cx[4], Cx[5]); C[i] = lv.dot(lvi) + av.dot(avi); calc_constraint_jacobian(DynamicBody::eAxisAngle, out, i, Cx); lv = Vector3(Cx[0], Cx[1], Cx[2]); av = Vector3(Cx[3], Cx[4], Cx[5]); C[i] += -lv.dot(lvo) - av.dot(avo); } }
/// Computes the time derivative of the constraint jacobian with respect to a body void SphericalJoint::calc_constraint_jacobian_dot_rodrigues(RigidBodyPtr body, unsigned index, Real Cq[7]) { const unsigned X = 0, Y = 1, Z = 2, SPATIAL_DIM = 7; // get the two links RigidBodyPtr inner = get_inboard_link(); RigidBodyPtr outer = get_outboard_link(); // mke sure that body is one of the links if (inner != body && outer != body) { for (unsigned i=0; i< SPATIAL_DIM; i++) Cq[i] = (Real) 0.0; return; } // setup the constraint equations (from Shabana, p. 432) if (body == inner) { // get the information necessary to compute the constraint equations const Quat& q = inner->get_orientation(); const Vector3& p = inner->get_outer_joint_data(outer).com_to_joint_vec; const Real px = p[X]; const Real py = p[Y]; const Real pz = p[Z]; Quat qd = Quat::deriv(q, inner->get_avel()); const Real dqw = qd.w; const Real dqx = qd.x; const Real dqy = qd.y; const Real dqz = qd.z; switch (index) { case 0: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = 4*px*dqw + 2*pz*dqy - 2*py*dqz; Cq[4] = 4*dqx*px + 2*dqy*py + 2*dqz*pz; Cq[5] = 2*pz*dqw + 2*py*dqx; Cq[6] = 2*pz*dqx - 2*py*dqw; break; case 1: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = 4*py*dqw - 2*pz*dqx + 2*px*dqz; Cq[4] = 2*dqy*px - 2*dqw*pz; Cq[5] = 2*px*dqx + 4*py*dqy + 2*pz*dqz; Cq[6] = 2*px*dqw + 2*pz*dqy; break; case 2: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = 4*pz*dqw + 2*py*dqx - 2*px*dqy; Cq[4] = 2*dqz*px + 2*dqw*py; Cq[5] = 2*py*dqz - 2*px*dqw; Cq[6] = 4*pz*dqz + 2*py*dqy + 2*px*dqx; break; default: throw std::runtime_error("Invalid joint constraint index!"); } } else { // get the information necessary to compute the constraint equations const Quat& q = outer->get_orientation(); const Vector3& p = body->get_inner_joint_data(inner).joint_to_com_vec_of; const Real px = -p[X]; const Real py = -p[Y]; const Real pz = -p[Z]; Quat qd = Quat::deriv(q, outer->get_avel()); const Real dqw = qd.w; const Real dqx = qd.x; const Real dqy = qd.y; const Real dqz = qd.z; switch (index) { case 0: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = -(4*px*dqw + 2*pz*dqy - 2*py*dqz); Cq[4] = -(4*dqx*px + 2*dqy*py + 2*dqz*pz); Cq[5] = -(2*pz*dqw + 2*py*dqx); Cq[6] = -(2*pz*dqx - 2*py*dqw); break; case 1: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = -(4*py*dqw - 2*pz*dqx + 2*px*dqz); Cq[4] = -(2*dqy*px - 2*dqw*pz); Cq[5] = -(2*px*dqx + 4*py*dqy + 2*pz*dqz); Cq[6] = -(2*px*dqw + 2*pz*dqy); break; case 2: Cq[0] = 0.0; Cq[1] = 0.0; Cq[2] = 0.0; Cq[3] = -(4*pz*dqw + 2*py*dqx - 2*px*dqy); Cq[4] = -(2*dqz*px + 2*dqw*py); Cq[5] = -(2*py*dqz - 2*px*dqw); Cq[6] = -(4*pz*dqz + 2*py*dqy + 2*px*dqx); break; default: throw std::runtime_error("Invalid joint constraint index!"); } } }