Esempio n. 1
0
void InverseKinematics::calcArmJoints(const Vector3<float>& position, const float elbowYaw, Joints jointAngles, bool left, const RobotDimensions& robotDimensions) {
  Joint firstJoint(left ? LShoulderPitch : RShoulderPitch);
  const int sign(left ? -1 : 1);
  const Vector3<float> pos(position - Vector3<float>(robotDimensions.values_[RobotDimensions::armOffset1], robotDimensions.values_[RobotDimensions::armOffset2] * -sign, robotDimensions.values_[RobotDimensions::armOffset3]));
  float& joint0 = jointAngles[firstJoint + 0];
  float& joint1 = jointAngles[firstJoint + 1];
  const float& joint2 = jointAngles[firstJoint + 2] = elbowYaw;
  float& joint3 = jointAngles[firstJoint + 3];

  // distance of the end effector position to the origin
  const float positionAbs = pos.abs();

  // the upper and lower arm form a triangle with the air line to the end effector position being the third edge. Elbow angle can be computed using cosine theorem
  const float actualUpperArmLength = Vector2<float>(robotDimensions.values_[RobotDimensions::upperArmLength], robotDimensions.values_[RobotDimensions::elbowOffsetY]).abs();
  float cosElbow = (sqr(actualUpperArmLength) + sqr(robotDimensions.values_[RobotDimensions::lowerArmLength]) - sqr(positionAbs)) / (2.0f * robotDimensions.values_[RobotDimensions::upperArmLength] * robotDimensions.values_[RobotDimensions::lowerArmLength]);
  // clip for the case of unreachable position
  cosElbow = Range<float>(-1.0f, 1.0f).limit(cosElbow);
  // elbow is streched in zero-position, hence M_PI - innerAngle
  joint3 = -(M_PI - acos(cosElbow));
  // compute temporary end effector position from known third and fourth joint angle
  const Pose3D tempPose = Pose3D(robotDimensions.values_[RobotDimensions::upperArmLength], robotDimensions.values_[RobotDimensions::elbowOffsetY] * -sign, 0).rotateX(joint2 * -sign).rotateZ(joint3 * -sign).translate(robotDimensions.values_[RobotDimensions::lowerArmLength], 0, 0);

  /* offset caused by third and fourth joint angle */                /* angle needed to realise y-component of target position */
  joint1 = atan2(tempPose.translation.y * sign, tempPose.translation.x) + asin(pos.y / Vector2<float>(tempPose.translation.x, tempPose.translation.y).abs()) * -sign;
  // refresh temporary endeffector position with known joint1
  const Pose3D tempPose2 = Pose3D().rotateZ(joint1 * -sign).conc(tempPose);

  /* first compensate offset from temporary position */       /* angle from target x- and z-component of target position */
  joint0 = -atan2(tempPose2.translation.z, tempPose2.translation.x) + atan2(pos.z, pos.x);
}
Esempio n. 2
0
RotationMatrix::RotationMatrix(const Vector3<>& a, float angle)
{
  Vector3<> axis = a;
  const float axisLen = axis.abs();
  if(axisLen != 0.f)
    axis *= 1.f / axisLen; // normalize a, rotation is only possible with unit vectors
  const float& x = axis.x, &y = axis.y, &z = axis.z;
  //compute sine and cosine of angle because it is needed quite often for complete matrix
  const float si = sin(angle), co = cos(angle);
  //compute all components needed more than once for complete matrix
  const float v = 1 - co;
  const float xyv = x * y * v;
  const float xzv = x * z * v;
  const float yzv = y * z * v;
  const float xs = x * si;
  const float ys = y * si;
  const float zs = z * si;
  //compute matrix
  c0.x = x * x * v + co;
  c1.x = xyv - zs;
  c2.x = xzv + ys;
  c0.y = xyv + zs;
  c1.y = y * y * v + co;
  c2.y = yzv - xs;
  c0.z = xzv - ys;
  c1.z = yzv + xs;
  c2.z = z * z * v + co;
}
Esempio n. 3
0
void BoxShapeSW::_setup(const Vector3& p_half_extents)  {

	half_extents=p_half_extents.abs();

	configure(AABB(-half_extents,half_extents*2));


}
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. 5
0
void SimObjectRenderer::rotateCamera(float x, float y)
{
  if(cameraMode == SimRobotCore2::Renderer::targetCam)
  {
    Vector3<> v = cameraPos - cameraTarget;
    Matrix3x3<> rotateY(Vector3<>(0.f, y, 0.f));
    Matrix3x3<> rotateZ(Vector3<>(0.f, 0.f, x));
    Vector3<> v2(sqrtf(v.x * v.x + v.y * v.y), 0.f, v.z);
    v2 = rotateY * v2;
    if(v2.x < 0.001f)
    {
      v2.x = 0.001f;
      v2.normalize(v.abs());
    }
    Vector3<> v3(v.x, v.y, 0.f);
    v3.normalize(v2.x);
    v3.z = v2.z;
    v = rotateZ * v3;
    cameraPos = cameraTarget + v;
  }
  else // if(cameraMode == SimRobotCore2::Renderer::freeCam)
  {
    Vector3<> v = cameraTarget - cameraPos;
    Matrix3x3<> rotateY(Vector3<>(0.f, y, 0.f));
    Matrix3x3<> rotateZ(Vector3<>(0.f, 0.f, -x));
    Vector3<> v2(sqrtf(v.x * v.x + v.y * v.y), 0.f, v.z);
    v2 = rotateY * v2;
    if(v2.x < 0.001f)
    {
      v2.x = 0.001f;
      v2.normalize(v.abs());
    }
    Vector3<> v3(v.x, v.y, 0.f);
    v3.normalize(v2.x);
    v3.z = v2.z;
    v = rotateZ * v3;
    cameraTarget = cameraPos + v;
  }
  updateCameraTransformation();
}
Esempio n. 6
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. 7
0
void CameraObject::focus_at (const Vector3 &to, const Vector3 &up, const DTfloat radius)
{
    look_at (to, up);
    
    Vector3 diff;
    DTfloat dist;
    
    diff = to - translation();
    dist = diff.abs();
    
    _angle = RAD_TO_DEG * 2.0F * std::atan(radius / dist);
    
    // Keep from getting too small
    if (_angle < 0.1F)  _angle = 0.1F;
}
Esempio n. 8
0
// Decomposes a Basis into a rotation-reflection matrix (an element of the group O(3)) and a positive scaling matrix as B = O.S.
// Returns the rotation-reflection matrix via reference argument, and scaling information is returned as a Vector3.
// This (internal) function is too specific and named too ugly to expose to users, and probably there's no need to do so.
Vector3 Basis::rotref_posscale_decomposition(Basis &rotref) const {
#ifdef MATH_CHECKS
	ERR_FAIL_COND_V(determinant() == 0, Vector3());

	Basis m = transposed() * (*this);
	ERR_FAIL_COND_V(!m.is_diagonal(), Vector3());
#endif
	Vector3 scale = get_scale();
	Basis inv_scale = Basis().scaled(scale.inverse()); // this will also absorb the sign of scale
	rotref = (*this) * inv_scale;

#ifdef MATH_CHECKS
	ERR_FAIL_COND_V(!rotref.is_orthogonal(), Vector3());
#endif
	return scale.abs();
}
Esempio n. 9
0
AngleEstimator::RotationMatrix::RotationMatrix(const Vector3<>& angleAxis)
{
  const double angle = angleAxis.abs();
  const Vector3<> axis(angleAxis / angle);
  //rotation is only possible with unit vectors
  const double &x = axis.x, &y = axis.y, &z = axis.z;
  //compute sine and cosine of angle because it is needed quite often for complete matrix
  const double si = sin(angle), co = cos(angle);
  //compute all components needed more than once for complete matrix
  const double v = 1 - co;
  const double xyv = x * y * v;
  const double xzv = x * z * v;
  const double yzv = y * z * v;
  const double xs = x * si;
  const double ys = y * si;
  const double zs = z * si;
  c[0].x = x * x * v + co; c[1].x = xyv - zs;       c[2].x = xzv + ys;
  c[0].y = xyv + zs;       c[1].y = y * y * v + co; c[2].y = yzv - xs;
  c[0].z = xzv - ys;       c[1].z = yzv + xs;       c[2].z = z * z * v + co;
}
Esempio n. 10
0
template <class V> Matrix3x3<V>::Matrix3x3(const Vector3<V>& a)
{
  const V angle = a.abs();
  Vector3<V> axis = a;
  if(angle != V())
    axis /= angle; // normalize a, rotation is only possible with unit vectors
  const V &x = axis.x, &y = axis.y, &z = axis.z;
  //compute sine and cosine of angle because it is needed quite often for complete matrix
  const V si = sin(angle), co = cos(angle);
  //compute all components needed more than once for complete matrix
  const V v = 1 - co;
  const V xyv = x * y * v;
  const V xzv = x * z * v;
  const V yzv = y * z * v;
  const V xs = x * si;
  const V ys = y * si;
  const V zs = z * si;
  //compute matrix
  c0.x = x * x * v + co; c1.x = xyv - zs;       c2.x = xzv + ys;
  c0.y = xyv + zs;       c1.y = y * y * v + co; c2.y = yzv - xs;
  c0.z = xzv - ys;       c1.z = yzv + xs;       c2.z = z * z * v + co;
}
void InverseKinematics::calcJointsForElbowPos(const Vector3<float> &elbow, const Vector3<float> &target, Joints jointAngles, int offset, const RobotDimensions &theRobotDimensions)
{
    //set elbow position with the pitch/yaw unit in the shoulder
    jointAngles[offset + 0] = atan2f(elbow.z, elbow.x);
    jointAngles[offset + 1] = atan2f(elbow.y, sqrtf(sqr(elbow.x)+sqr(elbow.z)));

    //calculate desired elbow "klapp"-angle
    const float c = target.abs(),
                a = theRobotDimensions.upperArmLength,
                b = theRobotDimensions.lowerArmLength;

    //cosine theorem
    float cosAngle = (-sqr(c) + sqr(b) + sqr(a))/(2.0f*a*b);
    if(cosAngle < -1.0f)
    {
        assert(cosAngle > -1.1);
        cosAngle = -1.0f;
    }
    else if(cosAngle > 1.0f)
    {
        assert(cosAngle < 1.1);
        cosAngle = 1.0f;
    }
    jointAngles[offset + 3] = acosf(cosAngle)-M_PI;

    //calculate hand in elbow coordinate system and calculate last angle
    Pose3D shoulder2Elbow;
    shoulder2Elbow.translate(0, -theRobotDimensions.upperArmLength, 0);
    shoulder2Elbow.rotateX(-(jointAngles[offset + 1] - M_PI/2.0f));
    shoulder2Elbow.rotateY(jointAngles[offset + 0] + M_PI/2.0f);
    const Vector3<float> handInEllbow = shoulder2Elbow * target;

    jointAngles[offset + 2] = -(atan2f(handInEllbow.z, handInEllbow.x)+M_PI/2);
    while(jointAngles[offset + 2] > M_PI)
        jointAngles[offset + 2] -= 2*M_PI;
    while(jointAngles[offset + 2] < -M_PI)
        jointAngles[offset + 2] += 2*M_PI;
}
Esempio n. 12
0
void SimObjectRenderer::moveCamera(float x, float y)
{
  if(cameraMode == SimRobotCore2::Renderer::targetCam)
  {
    if(x != 0.f)
      rotateCamera(x, 0);
    if(y != 0.f)
    {
      Vector3<> v = cameraPos - cameraTarget;
      float len = v.abs() + y;
      if(len < 0.0001f)
        len = 0.0001f;
      v.normalize(len);
      cameraPos = cameraTarget + v;
    }
  }
  else // if(cameraMode == SimRobotCore2::Renderer::FREECAM)
  {
    if(x != 0.f)
    {
      Vector3<> v = cameraTarget - cameraPos;
      Vector3<> v2 = v ^ Vector3<>(0.f, 0.f, 1.f);
      v2.normalize(x);
      cameraTarget += v2;
      cameraPos += v2;
    }
    if(y != 0.f)
    {
      Vector3<> v = cameraTarget - cameraPos;
      v.normalize(y);
      cameraTarget -= v;
      cameraPos -= v;
    }
  }
  updateCameraTransformation();
}
Esempio n. 13
0
void SimObjectRenderer::zoom(float change)
{
  Vector3<> v = cameraPos - cameraTarget;
  moveCamera(0.f, v.abs() * change * 0.0005f);
}
Esempio n. 14
0
void Simulation::staticCollisionCallback(Simulation* simulation, dGeomID geomId1, dGeomID geomId2)
{
  ASSERT(!dGeomIsSpace(geomId1));
  ASSERT(!dGeomIsSpace(geomId2));

#ifndef NDEBUG
  {
    dBodyID bodyId1 = dGeomGetBody(geomId1);
    dBodyID bodyId2 = dGeomGetBody(geomId2);
    ASSERT(bodyId1 || bodyId2);

    Body* body1 = bodyId1 ? (Body*)dBodyGetData(bodyId1) : 0;
    Body* body2 = bodyId2 ? (Body*)dBodyGetData(bodyId2) : 0;
    ASSERT(!body1 || !body2 || body1->rootBody != body2->rootBody);
  }
#endif

  dContact contact[32];
  int collisions = dCollide(geomId1, geomId2, 32, &contact[0].geom, sizeof(dContact));
  if(collisions <= 0)
    return;

  Geometry* geometry1 = (Geometry*)dGeomGetData(geomId1);
  Geometry* geometry2 = (Geometry*)dGeomGetData(geomId2);

  if(geometry1->collisionCallbacks && !geometry2->immaterial)
  {
    for(std::list<SimRobotCore2::CollisionCallback*>::iterator i = geometry1->collisionCallbacks->begin(), end = geometry1->collisionCallbacks->end(); i != end; ++i)
      (*i)->collided(*geometry1, *geometry2);
    if(geometry1->immaterial)
      return;
  }
  if(geometry2->collisionCallbacks && !geometry1->immaterial)
  {
    for(std::list<SimRobotCore2::CollisionCallback*>::iterator i = geometry2->collisionCallbacks->begin(), end = geometry2->collisionCallbacks->end(); i != end; ++i)
      (*i)->collided(*geometry2, *geometry1);
    if(geometry2->immaterial)
      return;
  }

  dBodyID bodyId1 = dGeomGetBody(geomId1);
  dBodyID bodyId2 = dGeomGetBody(geomId2);
  ASSERT(bodyId1 || bodyId2);

  float friction = 1.f;
  if(geometry1->material && geometry2->material)
  {
    if(!geometry1->material->getFriction(*geometry2->material, friction))
      friction = 1.f;

    float rollingFriction;
    if(bodyId1)
      switch(dGeomGetClass(geomId1))
      {
        case dSphereClass:
        case dCCylinderClass:
        case dCylinderClass:
          if(geometry1->material->getRollingFriction(*geometry2->material, rollingFriction))
          {
            dBodySetAngularDamping(bodyId1, 0.2);
            Vector3<> linearVel;
            ODETools::convertVector(dBodyGetLinearVel(bodyId1), linearVel);
            linearVel -= Vector3<>(linearVel).normalize(std::min(linearVel.abs(), rollingFriction * simulation->scene->stepLength));
            dBodySetLinearVel(bodyId1, linearVel.x, linearVel.y, linearVel.z);
          }
          break;
      }
    if(bodyId2)
      switch(dGeomGetClass(geomId2))
      {
        case dSphereClass:
        case dCCylinderClass:
        case dCylinderClass:
          if(geometry2->material->getRollingFriction(*geometry1->material, rollingFriction))
          {
            dBodySetAngularDamping(bodyId2, 0.2);
            Vector3<> linearVel;
            ODETools::convertVector(dBodyGetLinearVel(bodyId2), linearVel);
            linearVel -= Vector3<>(linearVel).normalize(std::min(linearVel.abs(), rollingFriction * simulation->scene->stepLength));
            dBodySetLinearVel(bodyId2, linearVel.x, linearVel.y, linearVel.z);
          }
          break;
      }
  }

  for(dContact* cont = contact, * end = contact + collisions; cont < end; ++cont)
  {
    cont->surface.mode = simulation->scene->contactMode | dContactApprox1;
    cont->surface.mu = friction;

    /*
    cont->surface.bounce = 0.f;
    cont->surface.bounce_vel = 0.001f;
    cont->surface.slip1 = 0.f;
    cont->surface.slip2 = 0.f;
    */
    cont->surface.soft_erp = simulation->scene->contactSoftERP;
    cont->surface.soft_cfm = simulation->scene->contactSoftCFM;

    dJointID c = dJointCreateContact(simulation->physicalWorld, simulation->contactGroup, cont);
    ASSERT(bodyId1 == dGeomGetBody(cont->geom.g1));
    ASSERT(bodyId2 == dGeomGetBody(cont->geom.g2));
    dJointAttach(c, bodyId1, bodyId2);
  }
  ++simulation->collisions;
  simulation->contactPoints += collisions;
}