RotationMatrix ForwardKinematics::calcChestFeetRotation(const KinematicChain& theKinematicChain)
{
  RotationMatrix calculatedRotation;

  // calculate rotation based on foot - torso transformation
  const Pose3D& footLeft = theKinematicChain.theLinks[KinematicChain::LFoot].M;
  const Pose3D& footRight = theKinematicChain.theLinks[KinematicChain::RFoot].M;
  const Pose3D& body = theKinematicChain.theLinks[KinematicChain::Torso].M;

  // local in chest
  Pose3D localFootLeft(body.local(footLeft));
  Pose3D localFootRight(body.local(footRight));
    
  if(abs(localFootLeft.translation.z - localFootRight.translation.z) < 3.f/* magic number */)
  {
    // use average of the calculated rotation of each leg
    double meanX = (localFootLeft.rotation.getXAngle() + localFootRight.rotation.getXAngle())*0.5;
    double meanY = (localFootLeft.rotation.getYAngle() + localFootRight.rotation.getYAngle())*0.5;

    //calculatedRotation.fromKardanRPY(0.0, meanY, meanX);
    calculatedRotation.rotateX(meanX).rotateY(meanY);
  }
  else if(localFootLeft.translation.z > localFootRight.translation.z)
  {
    // use left foot
    calculatedRotation = localFootLeft.rotation;
  }
  else
  {
    // use right foot
    calculatedRotation = localFootRight.rotation;
  }

  return calculatedRotation.invert();
}//end calcChestFeetRotation
void KickEngineData::calcLegJoints(const JointData::Joint& joint, JointRequest& jointRequest, const RobotDimensions& theRobotDimensions)
{
  float sign = joint == JointData::LHipYawPitch ? 1.f : -1.f;
  float leg0, leg1, leg2, leg3, leg4, leg5;

  const Vector3<>& footPos = (sign > 0) ? positions[Phase::leftFootTra] : positions[Phase::rightFootTra];
  const Vector3<>& footRotAng = (sign > 0) ? positions[Phase::leftFootRot] : positions[Phase::rightFootRot];

  RotationMatrix rotateBodyTilt = RotationMatrix().rotateX(comOffset.x);
  Vector3<> anklePos = rotateBodyTilt * Vector3<>(footPos.x, footPos.y, footPos.z);
  //we need just the leg length x and y have to stay the same
  anklePos.y = footPos.y;
  anklePos.x = footPos.x;
  // for the translation of the footpos we only need to translate the anklepoint, which is the intersection of the axis leg4 and leg5
  // the rotation of the foot will be made later by rotating the footpos around the anklepoint
  anklePos -= Vector3<>(0.f, sign * (theRobotDimensions.lengthBetweenLegs / 2), -theRobotDimensions.heightLeg5Joint);

  RotationMatrix rotateBecauseOfHip = RotationMatrix().rotateZ(footRotAng.z).rotateX(-sign * pi_4);

  anklePos = rotateBecauseOfHip * anklePos;

  float diagonal = anklePos.abs();

  // upperLegLength, lowerLegLength, and diagonal form a triangle, use cosine theorem
  float a1 = (theRobotDimensions.upperLegLength * theRobotDimensions.upperLegLength -
              theRobotDimensions.lowerLegLength * theRobotDimensions.lowerLegLength + diagonal * diagonal) /
             (2 * theRobotDimensions.upperLegLength * diagonal);
  //if(abs(a1) > 1.f) OUTPUT(idText, text, "clipped a1");
  a1 = abs(a1) > 1.f ? 0.f : acos(a1);

  float a2 = (theRobotDimensions.upperLegLength * theRobotDimensions.upperLegLength +
              theRobotDimensions.lowerLegLength * theRobotDimensions.lowerLegLength - diagonal * diagonal) /
             (2 * theRobotDimensions.upperLegLength * theRobotDimensions.lowerLegLength);
  //if(abs(a2) > 1.f) OUTPUT(idText, text, "clipped a2");
  a2 = abs(a2) > 1.f ? pi : acos(a2);

  leg0 = footRotAng.z * sign;
  leg2 = -a1 - atan2(anklePos.x, Vector2<>(anklePos.y, anklePos.z).abs() * -sgn(anklePos.z));

  leg1 = anklePos.z == 0.0f ? 0.0f : atan(anklePos.y / -anklePos.z) * -sign;
  leg3 = pi - a2;

  RotationMatrix footRot = RotationMatrix().rotateX(leg1 * -sign).rotateY(leg2 + leg3);
  footRot = footRot.invert() * rotateBecauseOfHip;

  leg5 = asin(-footRot[2].y) * sign * -1;
  leg4 = -atan2(footRot[2].x, footRot[2].z) * -1;

  leg4 += footRotAng.y;
  leg5 += footRotAng.x;

  jointRequest.angles[joint] = leg0;
  jointRequest.angles[joint + 1] = -pi_4 + leg1;
  jointRequest.angles[joint + 2] = leg2;
  jointRequest.angles[joint + 3] = leg3;
  jointRequest.angles[joint + 4] = leg4;
  jointRequest.angles[joint + 5] = leg5;
}
Esempio n. 3
0
bool ViewBikeMath::calcLegJoints(const Vector3<>& footPos, const Vector3<>& footRotAng, const bool& left, const RobotDimensions& robotDimensions, float& leg0, float& leg1, float& leg2, float& leg3, float& leg4, float& leg5)
{
  float sign = (left) ? 1.f : -1.f;
  bool legTooShort = false;

  Vector3<> anklePos; //FLOAT
  anklePos = Vector3<>(footPos.x,  footPos.y, footPos.z + robotDimensions.heightLeg5Joint);

  anklePos -= Vector3<>(0.f, sign * (robotDimensions.lengthBetweenLegs / 2.f), 0.f);

  RotationMatrix rotateBecauseOfHip = RotationMatrix().rotateZ(sign * footRotAng.z).rotateX(-sign * pi_4);
  Vector3<> rotatedFootRotAng;


  anklePos = rotateBecauseOfHip * anklePos;
  leg0 = footRotAng.z;
  rotatedFootRotAng = rotateBecauseOfHip * footRotAng;

  leg2 = -std::atan2(anklePos.x, Vector2<>(anklePos.y, anklePos.z).abs());

  float diagonal = anklePos.abs();

  // upperLegLength, lowerLegLength, and diagonal form a triangle, use cosine theorem
  float a1 = (robotDimensions.upperLegLength * robotDimensions.upperLegLength -
              robotDimensions.lowerLegLength * robotDimensions.lowerLegLength + diagonal * diagonal) /
             (2 * robotDimensions.upperLegLength * diagonal);
  a1 = std::abs(a1) > 1.f ? 0 : std::acos(a1);

  float a2 = (robotDimensions.upperLegLength * robotDimensions.upperLegLength +
              robotDimensions.lowerLegLength * robotDimensions.lowerLegLength - diagonal * diagonal) /
             (2 * robotDimensions.upperLegLength * robotDimensions.lowerLegLength);
  const Range<float> clipping(-1.f, 1.f);
  if(!clipping.isInside(a2))
  {
    legTooShort = true;
  }
  a2 = std::abs(a2) > 1.f ? pi : std::acos(a2);

  leg1 = (-sign * std::atan2(anklePos.y, std::abs(anklePos.z))) - (pi / 4);
  leg2 -= a1;
  leg3 = pi - a2;

  RotationMatrix footRot = RotationMatrix().rotateX(leg1 * -sign).rotateY(leg2 + leg3);
  footRot = footRot.invert() * rotateBecauseOfHip;
  leg5 = std::asin(-footRot[2].y) * -sign;
  leg4 = -std::atan2(footRot[2].x, footRot[2].z) * -1;
  leg4 += footRotAng.y;
  leg5 += footRotAng.x;

  return legTooShort;
}
Esempio n. 4
0
bool InverseKinematics::calcLegJoints(const Pose3D& position, Joints jointAngles, float joint0, bool left, const RobotDimensions& robotDimensions) {
  Pose3D target(position);
  Joint firstJoint(left ? LHipYawPitch : RHipYawPitch);
  const int sign(left ? -1 : 1);
  target.translation.y += robotDimensions.values_[RobotDimensions::lengthBetweenLegs] / 2 * sign; // translate to origin of leg
  target = Pose3D().rotateZ(joint0 * -sign).rotateX(M_PI_4 * sign).conc(target); // compute residual transformation with fixed joint0

  // use cosine theorem and arctan to compute first three joints
  float length = target.translation.abs();
  float sqrLength = length * length;
  float upperLeg = robotDimensions.values_[RobotDimensions::upperLegLength];
  float sqrUpperLeg = upperLeg * upperLeg;
  float lowerLeg = robotDimensions.values_[RobotDimensions::lowerLegLength];
  float sqrLowerLeg = lowerLeg * lowerLeg;
  float cosUpperLeg = (sqrUpperLeg + sqrLength - sqrLowerLeg) / (2 * upperLeg * length);
  float cosKnee = (sqrUpperLeg + sqrLowerLeg - sqrLength) / (2 * upperLeg * lowerLeg);
  // clip for the case that target position is not reachable
  const Range<float> clipping(-1.0f, 1.0f);
  bool reachable = true;
  if(!clipping.isInside(cosKnee) || clipping.isInside(upperLeg))
  {
    cosKnee = clipping.limit(cosKnee);
    cosUpperLeg = clipping.limit(cosUpperLeg);
    reachable = false;
  }
  float joint1 = target.translation.z == 0.0f ? 0.0f : atanf(target.translation.y / -target.translation.z) * sign;
  float joint2 = -acos(cosUpperLeg);
  joint2 -= atan2(target.translation.x, Vector2<float>(target.translation.y, target.translation.z).abs() * -sgn(target.translation.z));
  float joint3 = M_PI - acos(cosKnee);
  RotationMatrix beforeFoot = RotationMatrix().rotateX(joint1 * sign).rotateY(joint2 + joint3);
  joint1 -= M_PI_4; // because of the strange hip of Nao

  // compute joints from rotation matrix using theorem of euler angles
  // see http://www.geometrictools.com/Documentation/EulerAngles.pdf
  // this is possible because of the known order of joints (y, x, z) where z is left open and is seen as failure
  RotationMatrix foot = beforeFoot.invert() * target.rotation;
  float joint5 = asin(-foot[2].y) * -sign * -1;
  float joint4 = -atan2(foot[2].x, foot[2].z) * -1;
  //float failure = atan2(foot[0].y, foot[1].y) * sign;

  // set computed joints in jointAngles
  jointAngles[firstJoint + 0] = joint0;
  jointAngles[firstJoint + 1] = joint1;
  jointAngles[firstJoint + 2] = joint2;
  jointAngles[firstJoint + 3] = joint3;
  jointAngles[firstJoint + 4] = joint4;
  jointAngles[firstJoint + 5] = joint5;

  return reachable;
}
Esempio n. 5
0
bool Geometry::calculatePointByAngles
(
  const Vector2<>& angles,
  const CameraMatrix& cameraMatrix,
  const CameraInfo& cameraInfo,
  Vector2<int>& point
)
{
  Vector3<> vectorToPointWorld, vectorToPoint;
  vectorToPointWorld.x = (float) cos(angles.x);
  vectorToPointWorld.y = (float) sin(angles.x);
  vectorToPointWorld.z = (float) tan(angles.y);

  RotationMatrix rotationMatrix = cameraMatrix.rotation;
  vectorToPoint = rotationMatrix.invert() * vectorToPointWorld;

  float factor = cameraInfo.focalLength;

  float scale = factor / vectorToPoint.x;

  point.x = (int)(0.5f + cameraInfo.opticalCenter.x - vectorToPoint.y * scale);
  point.y = (int)(0.5f + cameraInfo.opticalCenter.y  - vectorToPoint.z * scale);
  return vectorToPoint.x > 0;
}
Esempio n. 6
0
bool InverseKinematics::calcLegJoints(const Pose3D& position, Joints jointAngles, bool left, const RobotDimensions& robotDimensions) {
  Pose3D target(position);
  Joint firstJoint(left ? LHipYawPitch : RHipYawPitch);
  int sign(left ? -1 : 1);
  target.translation.y += (float) robotDimensions.values_[RobotDimensions::lengthBetweenLegs] / 2.f * sign; // translate to origin of leg
  // rotate by 45° around origin for Nao
  // calculating sqrtf(2) is faster than calculating the resp. rotation matrix with getRotationX()
  static const float sqrt2_2 = sqrtf(2.0f) * 0.5f;
  RotationMatrix rotationX_pi_4 = RotationMatrix(Vector3<float>(1, 0, 0), Vector3<float>(0, sqrt2_2, sqrt2_2 * sign), Vector3<float>(0, sqrt2_2 * -sign, sqrt2_2));
  target.translation = rotationX_pi_4 * target.translation;
  target.rotation = rotationX_pi_4 * target.rotation;

  target = target.invert(); // invert pose to get position of body relative to foot

  // use geometrical solution to compute last three joints
  float length = target.translation.abs();
  float sqrLength = length * length;
  float upperLeg = robotDimensions.values_[RobotDimensions::upperLegLength];
  float sqrUpperLeg = upperLeg * upperLeg;
  float lowerLeg = robotDimensions.values_[RobotDimensions::lowerLegLength];
  float sqrLowerLeg = lowerLeg * lowerLeg;
  float cosLowerLeg = (sqrLowerLeg + sqrLength - sqrUpperLeg) / (2 * lowerLeg * length);
  float cosKnee = (sqrUpperLeg + sqrLowerLeg - sqrLength) / (2 * upperLeg * lowerLeg);

  // clip for the case of unreachable position
  const Range<float> clipping(-1.0f, 1.0f);
  bool reachable = true;
  if(!clipping.isInside(cosKnee) || clipping.isInside(cosLowerLeg))
  {
    cosKnee = clipping.limit(cosKnee);
    cosLowerLeg = clipping.limit(cosLowerLeg);
    reachable = false;
  }
  float joint3 = M_PI - acosf(cosKnee); // implicitly solve discrete ambiguousness (knee always moves forward)
  float joint4 = -acosf(cosLowerLeg);
  joint4 -= atan2f(target.translation.x, Vector2<float>(target.translation.y, target.translation.z).abs());
  float joint5 = atan2f(target.translation.y, target.translation.z) * sign;

  // calulate rotation matrix before hip joints
  RotationMatrix hipFromFoot;
  hipFromFoot.rotateX(joint5 * -sign);
  hipFromFoot.rotateY(-joint4 - joint3);

  // compute rotation matrix for hip from rotation before hip and desired rotation
  RotationMatrix hip = hipFromFoot.invert() * target.rotation;

  // compute joints from rotation matrix using theorem of euler angles
  // see http://www.geometrictools.com/Documentation/EulerAngles.pdf
  // this is possible because of the known order of joints (z, x, y seen from body resp. y, x, z seen from foot)
  float joint1 = asinf(-hip[2].y) * -sign;
  joint1 -= M_PI_4; // because of the 45°-rotational construction of the Nao legs
  float joint2 = -atan2f(hip[2].x, hip[2].z);
  float joint0 = atan2f(hip[0].y, hip[1].y) * -sign;

  // set computed joints in jointAngles
  jointAngles[firstJoint + 0] = joint0;
  jointAngles[firstJoint + 1] = joint1;
  jointAngles[firstJoint + 2] = joint2;
  jointAngles[firstJoint + 3] = joint3;
  jointAngles[firstJoint + 4] = joint4;
  jointAngles[firstJoint + 5] = joint5;

  return reachable;
}
Esempio n. 7
0
Vector2<double> AngleEstimator::RotationMatrix::operator-(const RotationMatrix& other) const
{
  //return ((const RotationMatrix&)(other.invert() * *this)).getAngleAxis();
  const Vector3<double>& result(other * ((const RotationMatrix&)(other.invert() * *this)).getAngleAxis());
  return Vector2<double>(result.x, result.y);
}