TEST(rosToEigen, transform) {
	Eigen::Isometry3d transform1 = toEigen(makeTransform(makeVector3(0, 1.5, 2), makeQuaternion(1, 0, 0, 0)));
	Eigen::Isometry3d transform2 = toEigen(makeTransform(makeVector3(-1.5, -2.6, -3.7), makeQuaternion(0, 0, 0, 1)));

	Eigen::Vector3d const & p1 = transform1.translation();
	Eigen::Vector3d const & p2 = transform2.translation();
	Eigen::Quaterniond const & q1 = Eigen::Quaterniond{transform1.rotation()};
	Eigen::Quaterniond const & q2 = Eigen::Quaterniond{transform2.rotation()};

	ASSERT_NEAR(0.0, p1.x(), 1e-5);
	ASSERT_NEAR(1.5, p1.y(), 1e-5);
	ASSERT_NEAR(2.0, p1.z(), 1e-5);
	ASSERT_NEAR(-1.5, p2.x(), 1e-5);
	ASSERT_NEAR(-2.6, p2.y(), 1e-5);
	ASSERT_NEAR(-3.7, p2.z(), 1e-5);

	ASSERT_NEAR(1, q1.x(), 1e-5);
	ASSERT_NEAR(0, q1.y(), 1e-5);
	ASSERT_NEAR(0, q1.z(), 1e-5);
	ASSERT_NEAR(0, q1.w(), 1e-5);
	ASSERT_NEAR(0, q2.x(), 1e-5);
	ASSERT_NEAR(0, q2.y(), 1e-5);
	ASSERT_NEAR(0, q2.z(), 1e-5);
	ASSERT_NEAR(1, q2.w(), 1e-5);
}
TEST(rosToEigen, pose) {
	Eigen::Isometry3d pose1 = toEigen(makePose(makePoint(0, 1.5, 2), makeQuaternion(1, 0, 0, 0)));
	Eigen::Isometry3d pose2 = toEigen(makePose(makePoint(-1.5, -2.6, -3.7), makeQuaternion(0, 0, 0, 1)));

	Eigen::Vector3d const & p1 = pose1.translation();
	Eigen::Vector3d const & p2 = pose2.translation();
	Eigen::Quaterniond const & q1 = Eigen::Quaterniond{pose1.rotation()};
	Eigen::Quaterniond const & q2 = Eigen::Quaterniond{pose2.rotation()};

	ASSERT_NEAR(0.0, p1.x(), 1e-5);
	ASSERT_NEAR(1.5, p1.y(), 1e-5);
	ASSERT_NEAR(2.0, p1.z(), 1e-5);
	ASSERT_NEAR(-1.5, p2.x(), 1e-5);
	ASSERT_NEAR(-2.6, p2.y(), 1e-5);
	ASSERT_NEAR(-3.7, p2.z(), 1e-5);

	ASSERT_NEAR(1, q1.x(), 1e-5);
	ASSERT_NEAR(0, q1.y(), 1e-5);
	ASSERT_NEAR(0, q1.z(), 1e-5);
	ASSERT_NEAR(0, q1.w(), 1e-5);
	ASSERT_NEAR(0, q2.x(), 1e-5);
	ASSERT_NEAR(0, q2.y(), 1e-5);
	ASSERT_NEAR(0, q2.z(), 1e-5);
	ASSERT_NEAR(1, q2.w(), 1e-5);
}
SpatialMotionVector SpatialMotionVector::operator*(const double scalar) const
{
    SpatialMotionVector scaledVec;

    toEigen(scaledVec.linearVec3)  = scalar*toEigen(this->linearVec3);
    toEigen(scaledVec.angularVec3) = scalar*toEigen(this->angularVec3);

    return scaledVec;
}
TEST(rosToEigen, point32) {
	Eigen::Vector3f p1 = toEigen(makePoint32(0, 1.5, 2));
	Eigen::Vector3f p2 = toEigen(makePoint32(-1.5, -2.6, -3.7));

	ASSERT_NEAR(0.0, p1.x(), 1e-5);
	ASSERT_NEAR(1.5, p1.y(), 1e-5);
	ASSERT_NEAR(2.0, p1.z(), 1e-5);
	ASSERT_NEAR(-1.5, p2.x(), 1e-5);
	ASSERT_NEAR(-2.6, p2.y(), 1e-5);
	ASSERT_NEAR(-3.7, p2.z(), 1e-5);
}
TEST(rosToEigen, vector3) {
	Eigen::Vector3d p1 = toEigen(makeVector3(0, 1.5, 2));
	Eigen::Vector3d p2 = toEigen(makeVector3(-1.5, -2.6, -3.7));

	ASSERT_NEAR(0.0, p1.x(), 1e-5);
	ASSERT_NEAR(1.5, p1.y(), 1e-5);
	ASSERT_NEAR(2.0, p1.z(), 1e-5);
	ASSERT_NEAR(-1.5, p2.x(), 1e-5);
	ASSERT_NEAR(-2.6, p2.y(), 1e-5);
	ASSERT_NEAR(-3.7, p2.z(), 1e-5);
}
    double ConvexHullProjectionConstraint::computeMargin(const Vector2& posIn2D)
    {
        bool isInside = true;

        // First check if the point is inside the convex hull or not
        iDynTree::VectorDynSize Ax(A.rows());

        toEigen(Ax) = toEigen(A)*toEigen(posIn2D);

        // If even one of the constraint is violated, then the point is outside the convex hull
        for (int i=0; i < Ax.size(); i++)
        {
            if (!(Ax(i) <= b(i)))
            {
                isInside = false;
                break;
            }
        }

        // Then, compute the distance between each segment of the convex hull and the point :
        // the minimum one is the distance of the point from the convex hull

        // We start from the last segment that do not follow the segment[i],segment[i+1] structure
        double distanceWithoutSign = distanceBetweenPointAndSegment(posIn2D,
                                                                    projectedConvexHull(projectedConvexHull.getNrOfVertices()-1),
                                                                    projectedConvexHull(0));
        // Find the minimum distance
        for (int i=0; i < projectedConvexHull.getNrOfVertices()-1; i++)
        {
            double candidateDistance = distanceBetweenPointAndSegment(posIn2D,
                                                                      projectedConvexHull(i),
                                                                      projectedConvexHull(i+1));

            if (candidateDistance < distanceWithoutSign)
            {
                distanceWithoutSign = candidateDistance;
            }
        }

        double margin;
        // If the point is inside the convex hull, we return the distance, otherwise the negated distance
        if (isInside)
        {
            margin = distanceWithoutSign;
        }
        else
        {
            margin = -distanceWithoutSign;
        }

        return margin;
    }
Matrix6x6 SpatialMotionVector::asCrossProductMatrixWrench() const
{
    Matrix6x6 res;

    Eigen::Map< Eigen::Matrix<double,6,6,Eigen::RowMajor> > retEigen(res.data());

    retEigen.block<3,3>(0,0) = skew(toEigen(this->angularVec3));
    retEigen.block<3,3>(0,3).setZero();
    retEigen.block<3,3>(3,0) = skew(toEigen(this->linearVec3));
    retEigen.block<3,3>(3,3) = skew(toEigen(this->angularVec3));

    return res;
}
TEST(rosToEigen, quaternion) {
	Eigen::Quaterniond q1 = toEigen(makeQuaternion(0, 1.5, 2, 3.6));
	Eigen::Quaterniond q2 = toEigen(makeQuaternion(-1.5, -2.6, -3.7, 4.9));

	ASSERT_NEAR(0.0, q1.x(), 1e-5);
	ASSERT_NEAR(1.5, q1.y(), 1e-5);
	ASSERT_NEAR(2.0, q1.z(), 1e-5);
	ASSERT_NEAR(3.6, q1.w(), 1e-5);
	ASSERT_NEAR(-1.5, q2.x(), 1e-5);
	ASSERT_NEAR(-2.6, q2.y(), 1e-5);
	ASSERT_NEAR(-3.7, q2.z(), 1e-5);
	ASSERT_NEAR(4.9, q2.w(), 1e-5);
}
    double distanceBetweenPointAndSegment(const Vector2& point,
                                          const Vector2& segmentFirstPoint,
                                          const Vector2& segmentLastPoint)
    {
        double segmentLengthSquared = (toEigen(segmentLastPoint)-toEigen(segmentFirstPoint)).squaredNorm();

        // First case: the segment is actually a point
        if (segmentLengthSquared == 0.0)
        {
            return distanceBetweentTwoPoints(point, segmentFirstPoint);
        }

        // The segment can be written as the set of segment points sp that can be written as:
        // sp = segmentFirstPoint + t*( segmentLastPoint - segmentFirstPoint )
        // for t \in [0, 1]
        // To find the segment point closest to the point, we can just find the t of the projection
        // of the point in the segment, and clamp it to [0, 1]
        double tProjection = ((toEigen(point)-toEigen(segmentFirstPoint)).dot(toEigen(segmentLastPoint)-toEigen(segmentFirstPoint)))/segmentLengthSquared;

        double tClosestPoint = std::max(0.0, std::min(1.0, tProjection));

        Vector2 closestPoint;
        toEigen(closestPoint) = toEigen(segmentFirstPoint) + tClosestPoint*(toEigen(segmentLastPoint)-toEigen(segmentFirstPoint));

        return distanceBetweentTwoPoints(point, closestPoint);
    }
Beispiel #10
0
    bool Direction::isPerpendicular(const Direction& otherDirection, double tolerance) const
    {
        assert(tolerance > 0);

        double fabsDotProduct = fabs(toEigen(*this).dot(toEigen(otherDirection)));

        if( fabsDotProduct > tolerance )
        {
            return false;
        }
        else
        {
            return true;
        }
    }
Beispiel #11
0
std::vector< Eigen::Matrix4d > PhysicsEngine::GetVehiclePoses(
    Vehicle_Entity* Vehicle ){
  std::vector<Eigen::Matrix4d> VehiclePoses;
  btTransform VehiclePose;
  VehiclePose.setIdentity();
  VehiclePose = Vehicle->m_pVehicle->getChassisWorldTransform();
  VehiclePoses.push_back(toEigen(VehiclePose));
  for( int i = 0; i<Vehicle->m_pVehicle->getNumWheels(); i++){
    Vehicle->m_pVehicle->updateWheelTransform(i,false);
    btTransform WheelPose;
    WheelPose.setIdentity();
    WheelPose = Vehicle->m_pVehicle->getWheelTransformWS(i);
    VehiclePoses.push_back(toEigen(WheelPose));
  }
  return VehiclePoses;
}
    void ConvexHullProjectionConstraint::buildConstraintMatrix()
    {
        // The rows of the A matrix and of the b vector depends on the number of vertices in the convex hull
        A.resize(projectedConvexHull.getNrOfVertices(),2);
        b.resize(projectedConvexHull.getNrOfVertices());

        // We assume that the vertices in projectedConvexHull are expressed in counter-clockwise order: this
        // is ensured by the structure of the Monotone Chain algorithm

        // Iterate on all line segments one by one
        for (size_t i=0; i < projectedConvexHull.getNrOfVertices(); i++)
        {
            Vector2 p0 = projectedConvexHull(i);
            Vector2 p1;

            if ( i != projectedConvexHull.getNrOfVertices()-1 )
            {
                p1 = projectedConvexHull(i+1);
            }
            else
            {
                // if we are using the last vertix, we build the line connecting it with the first vertex
                p1 = projectedConvexHull(0);
            }

            toEigen(A).block<1,2>(i,0) = Eigen::Vector2d(p1(1)-p0(1),p0(0)-p1(0));
            b(i) = p0(0)*p1(1) - p1(0)*p0(1);
        }

        return;
    }
Beispiel #13
0
/**
 * @function createDartNode
 */
dynamics::BodyNode* DartLoader::createDartNode(const urdf::Link* _lk, std::string _rootToSkelPath) {

  dynamics::BodyNode* node = new dynamics::BodyNode(_lk->name);
  
  // Mesh Loading
  //FIXME: Shouldn't mass and inertia default to 0?
  double mass = 0.1;
  Eigen::Matrix3d inertia = Eigen::MatrixXd::Identity(3,3);
  inertia *= 0.1;
  
  // Load Inertial information
  if(_lk->inertial) {
      node->setLocalCOM(toEigen(_lk->inertial->origin.position));
      node->setMass(_lk->inertial->mass);
      node->setInertia(_lk->inertial->ixx, _lk->inertial->iyy, _lk->inertial->izz,
                               _lk->inertial->ixy, _lk->inertial->ixz, _lk->inertial->iyz);
  }

  // Set visual information
  for(unsigned int i = 0; i < _lk->visual_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->visual_array[i].get(), _rootToSkelPath)) {
      node->addVisualizationShape(shape);
    }
  }

  // Set collision information
  for(unsigned int i = 0; i < _lk->collision_array.size(); i++) {
    if(dynamics::Shape* shape = createShape(_lk->collision_array[i].get(), _rootToSkelPath)) {
      node->addCollisionShape(shape);
    }
  }

  return node;
}
 Eigen::VectorXd toEigen(const KDL::Wrench & f, const KDL::JntArray & tau)
 {
     VectorXd ret(6+tau.rows());
     ret.segment(0,6) = toEigen(f);
     for(int i=0; i < (int)tau.rows(); i++ ) { ret(6+i) = tau(i); }
     return ret;
 }
 Eigen::VectorXd toEigen(const KDL::Twist & v, const KDL::JntArray & dq)
 {
     VectorXd ret(6+dq.rows());
     ret.segment(0,6) = toEigen(v);
     for(int i=0; i < (int)dq.rows(); i++ ) { ret(6+i) = dq(i); }
     return ret;
 }
Beispiel #16
0
/**
 * @function createDartJoint
 */
dynamics::Joint* DartLoader::createDartJoint(const urdf::Joint* _jt)
{ 
  dynamics::Joint* joint;
  switch(_jt->type) {
  case urdf::Joint::REVOLUTE:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      joint->setPositionLowerLimit(0, _jt->limits->lower);
      joint->setPositionUpperLimit(0, _jt->limits->upper);
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::CONTINUOUS:
      joint = new dynamics::RevoluteJoint(toEigen(_jt->axis));
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::PRISMATIC:
      joint = new dynamics::PrismaticJoint(toEigen(_jt->axis));
      joint->setPositionLowerLimit(0, _jt->limits->lower);
      joint->setPositionUpperLimit(0, _jt->limits->upper);
      joint->setDampingCoefficient(0, _jt->dynamics->damping);
      break;
  case urdf::Joint::FIXED:
      joint = new dynamics::WeldJoint();
      break;
  case urdf::Joint::FLOATING:
      joint = new dynamics::FreeJoint();
      break;
  case urdf::Joint::PLANAR:
      std::cout << "Planar joint not supported." << std::endl;
      assert(false);
      return NULL;
  default:
      std::cout << "Unsupported joint type." << std::endl;
      assert(false);
      return NULL;
  }
  joint->setName(_jt->name);
  joint->setTransformFromParentBodyNode(toEigen(_jt->parent_to_joint_origin_transform));
  joint->setTransformFromChildBodyNode(Eigen::Isometry3d::Identity());
  if(joint->getNumDofs() == 1 && _jt->limits) {
    joint->setVelocityLowerLimit(0, -_jt->limits->velocity);
    joint->setVelocityUpperLimit(0, _jt->limits->velocity);
    joint->setForceLowerLimit(0, -_jt->limits->effort);
    joint->setForceUpperLimit(0, _jt->limits->effort);
  }
  return joint;
}
    void ConvexHullProjectionConstraint::setProjectionAlongDirection(Vector3 direction)
    {
        Vector3 xProjection, yProjection;

        // define the projection for the x-component
        xProjection.setVal(0, 1.0);
        xProjection.setVal(1, 0.0);
        xProjection.setVal(2, -direction.getVal(0) / direction.getVal(2));

        // define the projection for the y-component
        yProjection.setVal(0, 0.0);
        yProjection.setVal(1, 1.0);
        yProjection.setVal(2, -direction.getVal(1) / direction.getVal(2));

        // fill the projection matrix
        toEigen(Pdirection).block<1, 3>(0,0) = toEigen(xProjection);
        toEigen(Pdirection).block<1, 3>(1,0) = toEigen(yProjection);

    }
Beispiel #18
0
    bool Direction::isParallel(const Direction& otherDirection, double tolerance) const
    {
        // The tolerance should be positive
        assert(tolerance > 0);

        // Compute the difference of the norm
        Eigen::Vector3d diff = toEigen(*this)-toEigen(otherDirection);
        double diffNorm = diff.norm();

        // There are two possibilities for two directions to be parallel
        // either they point in the same direction, or in opposite directions
        if( ( diffNorm < tolerance ) ||
            ( fabs(diffNorm-2) < tolerance ) )
        {
            return true;
        }
        else
        {
            return false;
        }
    }
Beispiel #19
0
simulation::WorldPtr DartLoader::parseWorldString(
    const std::string& _urdfString, const common::Uri& _baseUri,
    const common::ResourceRetrieverPtr& _resourceRetriever)
{
  const common::ResourceRetrieverPtr resourceRetriever
    = getResourceRetriever(_resourceRetriever);

  if(_urdfString.empty())
  {
    dtwarn << "[DartLoader::parseWorldString] A blank string cannot be "
           << "parsed into a World. Returning a nullptr\n";
    return nullptr;
  }

  std::shared_ptr<urdf_parsing::World> worldInterface =
      urdf_parsing::parseWorldURDF(_urdfString, _baseUri);

  if(!worldInterface)
  {
    dtwarn << "[DartLoader::parseWorldString] Failed loading URDF.\n";
    return nullptr;
  }

  simulation::WorldPtr world(new simulation::World);

  for(size_t i = 0; i < worldInterface->models.size(); ++i)
  {
    const urdf_parsing::Entity& entity = worldInterface->models[i];
    dynamics::SkeletonPtr skeleton = modelInterfaceToSkeleton(
      entity.model.get(), entity.uri, resourceRetriever);

    if(!skeleton)
    {
      dtwarn << "[DartLoader::parseWorldString] Robot " << worldInterface->models[i].model->getName()
             << " was not correctly parsed!\n";
      continue;
    }

    // Initialize position and RPY
    dynamics::Joint* rootJoint = skeleton->getRootBodyNode()->getParentJoint();
    Eigen::Isometry3d transform = toEigen(worldInterface->models[i].origin);

    if (dynamic_cast<dynamics::FreeJoint*>(rootJoint))
      rootJoint->setPositions(dynamics::FreeJoint::convertToPositions(transform));
    else
      rootJoint->setTransformFromParentBodyNode(transform);

    world->addSkeleton(skeleton);
  }

  return world;
}
Beispiel #20
0
void dynamicsRegressorLoop(const UndirectedTree & ,
                         const KDL::JntArray &q,
                         const Traversal & traversal,
                         const std::vector<Frame>& X_b,
                         const std::vector<Twist>& v,
                         const std::vector<Twist>& a,
                         Eigen::MatrixXd & dynamics_regressor)
{
        dynamics_regressor.setZero();

        Eigen::Matrix<double, 6, 10> netWrenchRegressor_i;

        // Store the base_world translational transform in world orientation
        KDL::Frame world_base_X_world_world = KDL::Frame(-(X_b[traversal.getBaseLink()->getLinkIndex()].p));

        for(int l =(int)traversal.getNrOfVisitedLinks()-1; l >= 0; l-- ) {
            LinkMap::const_iterator link = traversal.getOrderedLink(l);
            int i = link->getLinkIndex();

            //Each link affects the dynamics of the joints from itself to the base
            netWrenchRegressor_i = netWrenchRegressor(v[i],a[i]);

            //Base dynamics
            // The base dynamics is expressed with the orientation of the world but
            // with respect to the base origin
            dynamics_regressor.block(0,(int)(10*i),6,10) = WrenchTransformationMatrix(world_base_X_world_world*X_b[i])*netWrenchRegressor_i;

            //dynamics_regressor.block(0,(int)(10*i),6,10) = WrenchTransformationMatrix(X_b[i])*netWrenchRegressor_i;

            LinkMap::const_iterator child_link = link;
            LinkMap::const_iterator parent_link=traversal.getParentLink(link);
            while( child_link != traversal.getOrderedLink(0) ) {
                if( child_link->getAdjacentJoint(parent_link)->getNrOfDOFs() == 1 ) {
                    #ifndef NDEBUG
                    //std::cerr << "Calculating regressor columns for link " << link->getName() << " and joint " << child_link->getAdjacentJoint(parent_link)->getName() << std::endl;
                    #endif
                    int dof_index = child_link->getAdjacentJoint(parent_link)->getDOFIndex();
                    int child_index = child_link->getLinkIndex();
                    Frame X_j_i = X_b[child_index].Inverse()*X_b[i];
                    dynamics_regressor.block(6+dof_index,10*i,1,10) =
                            toEigen(parent_link->S(child_link,q(dof_index))).transpose()*WrenchTransformationMatrix(X_j_i)*netWrenchRegressor_i;
                }
                child_link = parent_link;
                #ifndef NDEBUG
                //std::cout << "Getting parent link of link of index " << child_link->getName() << " " << child_link->getLinkIndex() << std::endl;
                //std::cout << "Current base " << traversal.order[0]->getName() << " " << traversal.order[0]->getLinkIndex() << std::endl;
                #endif
                parent_link = traversal.getParentLink(child_link);
            }
        }
}
Beispiel #21
0
/**
 * @function createDartNode
 */
bool DartLoader::createDartNodeProperties(
  const urdf::Link* _lk,
  dynamics::BodyNode::Properties &node,
  const common::Uri& _baseUri,
  const common::ResourceRetrieverPtr& _resourceRetriever)
{
  node.mName = _lk->name;
  
  // Load Inertial information
  if(_lk->inertial) {
    urdf::Pose origin = _lk->inertial->origin;
    node.mInertia.setLocalCOM(toEigen(origin.position));
    node.mInertia.setMass(_lk->inertial->mass);

    Eigen::Matrix3d J;
    J << _lk->inertial->ixx, _lk->inertial->ixy, _lk->inertial->ixz,
         _lk->inertial->ixy, _lk->inertial->iyy, _lk->inertial->iyz,
         _lk->inertial->ixz, _lk->inertial->iyz, _lk->inertial->izz;
    Eigen::Matrix3d R(Eigen::Quaterniond(origin.rotation.w, origin.rotation.x,
                                         origin.rotation.y, origin.rotation.z));
    J = R * J * R.transpose();

    node.mInertia.setMoment(J(0,0), J(1,1), J(2,2),
                            J(0,1), J(0,2), J(1,2));
  }

  // Set visual information
  for(size_t i = 0; i < _lk->visual_array.size(); i++)
  {
    dynamics::ShapePtr shape = createShape(
      _lk->visual_array[i].get(), _baseUri, _resourceRetriever);

    if(shape)
      node.mVizShapes.push_back(shape);
    else
      return false;
  }

  // Set collision information
  for(size_t i = 0; i < _lk->collision_array.size(); i++) {
    dynamics::ShapePtr shape = createShape(
      _lk->collision_array[i].get(), _baseUri, _resourceRetriever);

    if (shape)
      node.mColShapes.push_back(shape);
    else
      return false;
  }

  return true;
}
Beispiel #22
0
bool FreeFloatingJacobianUsingLinkPos(const Model& model,
                                      const Traversal& traversal,
                                      const JointPosDoubleArray& jointPositions,
                                      const LinkPositions& world_H_links,
                                      const LinkIndex jacobianLinkIndex,
                                      const Transform& jacobFrame_X_world,
                                      const Transform& baseFrame_X_jacobBaseFrame,
                                            MatrixDynSize& jacobian)
{
    // We zero the jacobian
    jacobian.zero();

    // Compute base part
    const Transform & world_H_base = world_H_links(traversal.getBaseLink()->getIndex());
    toEigen(jacobian).block(0,0,6,6) = toEigen((jacobFrame_X_world*world_H_base*baseFrame_X_jacobBaseFrame).asAdjointTransform());

    // Compute joint part
    // We iterate from the link up in the traveral until we reach the base
    LinkIndex visitedLinkIdx = jacobianLinkIndex;

    while (visitedLinkIdx != traversal.getBaseLink()->getIndex())
    {
        LinkIndex parentLinkIdx = traversal.getParentLinkFromLinkIndex(visitedLinkIdx)->getIndex();
        IJointConstPtr joint = traversal.getParentJointFromLinkIndex(visitedLinkIdx);

        size_t dofOffset = joint->getDOFsOffset();
        for(int i=0; i < joint->getNrOfDOFs(); i++)
        {
            toEigen(jacobian).block(0,6+dofOffset+i,6,1) =
                toEigen(jacobFrame_X_world*(world_H_links(visitedLinkIdx)*joint->getMotionSubspaceVector(i,visitedLinkIdx,parentLinkIdx)));
        }

        visitedLinkIdx = parentLinkIdx;
    }

    return true;
}
Beispiel #23
0
/**
 * @function parseWorld
 */
simulation::World* DartLoader::parseWorld(std::string _urdfFileName) {

    std::string xmlString = readFileToString(_urdfFileName);

    // Change path to a Unix-style path if given a Windows one
    // Windows can handle Unix-style paths (apparently)
    std::replace(_urdfFileName.begin(), _urdfFileName.end(), '\\' , '/');
    std::string worldDirectory = _urdfFileName.substr(0, _urdfFileName.rfind("/") + 1);
    
    urdf::World* worldInterface = urdf::parseWorldURDF(xmlString, worldDirectory);
    if(!worldInterface)
        return NULL;

    // Store paths from world to entities
    parseWorldToEntityPaths(xmlString);

    simulation::World* world = new simulation::World();

    for(unsigned int i = 0; i < worldInterface->models.size(); ++i) {
      std::string skeletonDirectory = worldDirectory + mWorld_To_Entity_Paths.find(worldInterface->models[i].model->getName())->second;
      dynamics::Skeleton* skeleton = modelInterfaceToSkeleton(worldInterface->models[i].model.get(), skeletonDirectory);

      if(!skeleton) {
        std::cout << "[ERROR] Robot " << worldInterface->models[i].model->getName() << " was not correctly parsed. World is not loaded. Exiting!" << std::endl;
        return NULL; 
      }

      // Initialize position and RPY
      dynamics::Joint* rootJoint = skeleton->getRootBodyNode()->getParentJoint();
      Eigen::Isometry3d transform = toEigen(worldInterface->models[i].origin);

      if(dynamic_cast<dynamics::FreeJoint*>(rootJoint)) {
          Eigen::Vector6d coordinates;
          coordinates << math::logMap(transform.linear()), transform.translation();
          rootJoint->set_q(coordinates);
      }
      else {
          rootJoint->setTransformFromParentBodyNode(transform);
      }

      world->addSkeleton(skeleton);
    }
    return world;
}
ArticulatedBodyInertia TransformDerivative::transform(const Transform& transform,
                                                      ArticulatedBodyInertia& other)
{
    // Inefficient implementation for the time being, this should not be a bottleneck
    Matrix6x6 oldABI = other.asMatrix();
    Matrix6x6 a_X_b_wrench  = transform.asAdjointTransformWrench();
    Matrix6x6 a_dX_b_wrench = this->asAdjointTransformWrenchDerivative(transform);
    Eigen::Matrix<double,6,6,Eigen::RowMajor> b_X_a = toEigen(a_X_b_wrench).transpose();
    Eigen::Matrix<double,6,6,Eigen::RowMajor> b_dX_a = toEigen(a_dX_b_wrench).transpose();

    Matrix6x6 newABI;

    toEigen(newABI) =  toEigen(a_dX_b_wrench)*toEigen(oldABI)*(b_X_a)
                      +toEigen(a_X_b_wrench)*toEigen(oldABI)*(b_dX_a);

    return ArticulatedBodyInertia(newABI.data(),6,6);
}
Beispiel #25
0
dynamics::Shape* DartLoader::createShape(const VisualOrCollision* _vizOrCol, std::string _rootToSkelPath) {
  dynamics::Shape* shape;

  // Sphere
  if(urdf::Sphere* sphere = dynamic_cast<urdf::Sphere*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::EllipsoidShape(2.0 * sphere->radius * Eigen::Vector3d::Ones());
  }

  // Box
  else if(urdf::Box* box = dynamic_cast<urdf::Box*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::BoxShape(Eigen::Vector3d(box->dim.x, box->dim.y, box->dim.z));
  }

  // Cylinder
  else if(urdf::Cylinder* cylinder = dynamic_cast<urdf::Cylinder*>(_vizOrCol->geometry.get())) {
    shape = new dynamics::CylinderShape(cylinder->radius, cylinder->length);
  }

  // Mesh
  else if(urdf::Mesh* mesh = dynamic_cast<urdf::Mesh*>(_vizOrCol->geometry.get())) {
    std::string fullPath = _rootToSkelPath + mesh->filename;
    const aiScene* model = dynamics::MeshShape::loadMesh( fullPath );
    
    if(!model) {
      std::cout<< "[add_Shape] [ERROR] Not loading model " << fullPath << " (NULL) \n";
      shape = NULL;
    } 
    else {
      shape = new dynamics::MeshShape(Eigen::Vector3d(mesh->scale.x, mesh->scale.y, mesh->scale.z), model);
    }
  }

  // Unknown geometry type
  else {
    std::cout << "[add_Shape] No MESH, BOX, CYLINDER OR SPHERE! Not loading this shape." << std::endl;
    return NULL;
  }

  shape->setLocalTransform(toEigen(_vizOrCol->origin));
  setMaterial(shape, _vizOrCol);
  return shape;
}
SpatialForceVector TransformDerivative::transform(const Transform& transform,
                                                  SpatialForceVector& other)
{
    SpatialForceVector ret;

    Eigen::Map<const Eigen::Vector3d> p(transform.getPosition().data());
    Eigen::Map<const Eigen::Matrix<double,3,3,Eigen::RowMajor> > R(transform.getRotation().data());
    Eigen::Map<const Eigen::Vector3d> dp(this->posDerivative.data());
    Eigen::Map<const Eigen::Matrix<double,3,3,Eigen::RowMajor> > dR(this->rotDerivative.data());

    toEigen(ret.getLinearVec3()) = dR*toEigen(other.getLinearVec3());
    toEigen(ret.getAngularVec3())  =  dR*toEigen(other.getAngularVec3())
                                    + p.cross(toEigen(ret.getLinearVec3()))
                                    + dp.cross(R*toEigen(other.getLinearVec3()));

    return ret;
}
Beispiel #27
0
void dynamicsRegressorFixedBaseLoop(const UndirectedTree & ,
                         const KDL::JntArray &q,
                         const Traversal & traversal,
                         const std::vector<Frame>& X_b,
                         const std::vector<Twist>& v,
                         const std::vector<Twist>& a,
                         Eigen::MatrixXd & dynamics_regressor)
{
        dynamics_regressor.setZero();

        Eigen::Matrix<double, 6, 10> netWrenchRegressor_i;

        for(int l =(int)traversal.getNrOfVisitedLinks()-1; l >= 0; l-- ) {
            LinkMap::const_iterator link = traversal.getOrderedLink(l);
            int i = link->getLinkIndex();

            //Each link affects the dynamics of the joints from itself to the base
            netWrenchRegressor_i = netWrenchRegressor(v[i],a[i]);

             //dynamics_regressor.block(0,(int)(10*i),6,10) = WrenchTransformationMatrix(X_b[i])*netWrenchRegressor_i;

            LinkMap::const_iterator child_link = link;
            LinkMap::const_iterator parent_link=traversal.getParentLink(link);
            while( child_link != traversal.getOrderedLink(0) ) {
                if( child_link->getAdjacentJoint(parent_link)->getNrOfDOFs() == 1 ) {
                    int dof_index = child_link->getAdjacentJoint(parent_link)->getDOFIndex();
                    int child_index = child_link->getLinkIndex();
                    Frame X_j_i = X_b[child_index].Inverse()*X_b[i];
                    dynamics_regressor.block(dof_index,10*i,1,10) =
                            toEigen(parent_link->S(child_link,q(dof_index))).transpose()*WrenchTransformationMatrix(X_j_i)*netWrenchRegressor_i;
                }
                child_link = parent_link;
                parent_link = traversal.getParentLink(child_link);
            }
        }
}
    int TreeInertialParameters::dynamicsRegressor( const JntArray &q, 
                                                    const JntArray &q_dot,
                                                    const JntArray &q_dotdot,  
                                                    const Twist& base_velocity, 
                                                    const Twist& base_acceleration,
                                                    Eigen::MatrixXd & dynamics_regressor)
    {
        if(q.rows()!=nj || q_dot.rows()!=nj || q_dotdot.rows()!=nj || dynamics_regressor.cols()!=10*ns || dynamics_regressor.rows()!=(6+nj))
            return -1;
        
        unsigned int i;
        unsigned int j=0;
        
        //Kinematic propagation copied by RNE   
        for(unsigned int l = 0; l < recursion_order.size(); l++ ) {
            
            unsigned int curr_index = recursion_order[l];
        
			const Segment& seg = seg_vector[curr_index]->second.segment;
			const Joint& jnt = seg.getJoint();
			
            double q_,qdot_,qdotdot_;
            if(jnt.getType() !=Joint::None){
				int idx = link2joint[curr_index];
                q_=q(idx);
                qdot_=q_dot(idx);
                qdotdot_=q_dotdot(idx);
            }else
                q_=qdot_=qdotdot_=0.0;
                
            Frame& eX  = X[curr_index];
            Twist& eS  = S[curr_index];
            Twist& ev  = v[curr_index];
            Twist& ea  = a[curr_index];
            Wrench& ef = f[curr_index];
            Frame& eX_b = X_b[curr_index];

            assert(X.size() == ns);
            //Calculate segment properties: X,S,vj,cj
            X[curr_index] = seg.pose(q_);
            //eX=seg.pose(q_);
                            //Remark this is the inverse of the 
                            //frame for transformations from 
                            //the parent to the current coord frame
            //Transform velocity and unit velocity to segment frame
            Twist vj=eX.M.Inverse(seg.twist(q_,qdot_));
            eS=eX.M.Inverse(seg.twist(q_,1.0));
            //We can take cj=0, see remark section 3.5, page 55 since the unit velocity vector S of our joints is always time constant
            //calculate velocity and acceleration of the segment (in segment coordinates)
            
            int parent_index = lambda[curr_index];
            
            if( parent_index == -1 ) {
                eX_b = eX;
            } else {
                eX_b = X_b[parent_index]*eX;
            }
            
            
  
            Twist parent_a, parent_v;
            
            if( parent_index == -1 ) {
                parent_a = base_acceleration;
                parent_v = base_velocity;
            } else {
                parent_a = a[parent_index];
                parent_v = v[parent_index];
            }
            
            ev=eX.Inverse(parent_v)+vj;
            ea=eX.Inverse(parent_a)+eS*qdotdot_+ev*vj;
            
        }      
        //end kinematic phase
        
        dynamics_regressor.setZero();
        
        //just for design, then the loop can be put together
        Eigen::Matrix<double, 6, 10> netWrenchRegressor_i;

        for(i=0;i<ns;i++) {
                        
            netWrenchRegressor_i = netWrenchRegressor(v[i],a[i]);
            
            dynamics_regressor.block(0,(int)(10*i),6,10) = WrenchTransformationMatrix(X_b[i])*netWrenchRegressor_i;

            Frame X_j_i;
            for(j=0;j<ns;j++) {
                X_j_i = X_b[j].Inverse()*X_b[i];
                
                if( seg_vector[j]->second.segment.getJoint().getType() != Joint::None ) {
                    if( indicator_function[i][link2joint[j]] ) {
                        dynamics_regressor.block(6+link2joint[j],10*i,1,10) = 
                            toEigen(S[j]).transpose()*WrenchTransformationMatrix(X_j_i)*netWrenchRegressor_i;
                    }
                }
            }
        
            
        }

        return 0;
        
    }
Beispiel #29
0
int crba_momentum_jacobian_loop(const UndirectedTree & undirected_tree,
                                const Traversal & traversal,
                                const JntArray & q,
                                std::vector<RigidBodyInertia> & Ic,
                                MomentumJacobian & H,
                                RigidBodyInertia & InertiaCOM
                               )
{
#ifndef NDEBUG
    if( undirected_tree.getNrOfLinks() != traversal.getNrOfVisitedLinks() ||
            undirected_tree.getNrOfDOFs() != q.rows() ||
            Ic.size() != undirected_tree.getNrOfLinks() ||
            H.columns() != (undirected_tree.getNrOfDOFs() + 6) )
    {
        std::cerr << "crba_momentum_jacobian_loop: input data error" << std::endl;
        return -1;
    }
#endif

    double q_;
    Wrench F = Wrench::Zero();

    //Sweep from root to leaf
    for(int i=0; i<(int)traversal.getNrOfVisitedLinks(); i++)
    {
        LinkMap::const_iterator link_it = traversal.getOrderedLink(i);
        int link_index = link_it->getLinkIndex();

        //Collect RigidBodyInertia
        Ic[link_index]=link_it->getInertia();

    }

    for(int i=(int)traversal.getNrOfVisitedLinks()-1; i >= 1; i-- ) {
        int dof_id;
        LinkMap::const_iterator link_it = traversal.getOrderedLink(i);
        int link_index = link_it->getLinkIndex();

        LinkMap::const_iterator parent_it = traversal.getParentLink(link_index);
        int parent_index = parent_it->getLinkIndex();

        if( link_it->getAdjacentJoint(parent_it)->getNrOfDOFs() == 1 ) {
            dof_id = link_it->getAdjacentJoint(parent_it)->getDOFIndex();
            q_ = q(dof_id);
        } else {
            q_ = 0.0;
            dof_id = -1;
        }

        Ic[parent_index] = Ic[parent_index]+link_it->pose(parent_it,q_)*Ic[link_index];

        if( link_it->getAdjacentJoint(parent_it)->getNrOfDOFs() == 1 ) {
            KDL::Twist S_link_parent = parent_it->S(link_it,q_);
            F = Ic[link_index]*S_link_parent;

            if( traversal.getParentLink(link_it) != undirected_tree.getInvalidLinkIterator() ) {
                double q__;
                int dof_id_;
                LinkMap::const_iterator predecessor_it = traversal.getParentLink(link_it);
                LinkMap::const_iterator successor_it = link_it;

                while(true) {

                    if( predecessor_it->getAdjacentJoint(successor_it)->getNrOfDOFs() == 1 ) {
                        q__ = q( predecessor_it->getAdjacentJoint(successor_it)->getDOFIndex());
                    } else {
                        q__ = 0.0;
                    }

                    F = successor_it->pose(predecessor_it,q__)*F;

                    successor_it = predecessor_it;
                    predecessor_it = traversal.getParentLink(predecessor_it);

                    if( predecessor_it == undirected_tree.getInvalidLinkIterator() ) {
                        break;
                    }

                    if( predecessor_it->getAdjacentJoint(successor_it)->getNrOfDOFs() == 1 ) {
                        dof_id_ =  predecessor_it->getAdjacentJoint(successor_it)->getDOFIndex();
                        q__ = q(dof_id_);
                    } else {
                        q__ = 0.0;
                        dof_id_ = -1;
                    }


                }
                if( dof_id >= 0 ) {
                    H.data.block(0,6+dof_id,6,1) = toEigen(F);
                }

                //The first 6x6 submatrix of the Momentum Jacobian are simply the spatial inertia
                //of all the structure expressed in the base reference frame
                H.data.block(0,0,6,6) = toEigen(Ic[traversal.getBaseLink()->getLinkIndex()]);


            }

        }
    }

    //We have then to translate the reference point of the obtained jacobian to the com
    //The Ic[traversal.order[0]->getLink(index)] contain the spatial inertial of all the tree
    //expressed in link coordite frames
    Vector com = Ic[traversal.getBaseLink()->getLinkIndex()].getCOG();
    H.changeRefPoint(com);

    InertiaCOM = Frame(com)*Ic[traversal.getBaseLink()->getLinkIndex()];

    return 0;
}
Beispiel #30
0
int torqueRegressor::computeRegressor(const KDL::JntArray &q,
                                      const KDL::JntArray &/*q_dot*/,
                                      const KDL::JntArray &/*q_dotdot*/,
                                      const std::vector<KDL::Frame> & X_dynamic_base,
                                      const std::vector<KDL::Twist> & v,
                                      const std::vector<KDL::Twist> & a,
                                      const iDynTree::SensorsMeasurements & measured_wrenches,
                                      const KDL::JntArray & measured_torques,
                                      Eigen::MatrixXd & regressor_matrix_global_column_serialization,
                                      Eigen::VectorXd & known_terms)
{
#ifndef NDEBUG
    if( verbose ) std::cerr << "Called torqueRegressor::computeRegressor " << std::endl;
#endif
    //const KDL::CoDyCo::UndirectedTree &  = *p_undirected_tree;
    //const KDL::CoDyCo::FTSensorList & ft_list = *p_ft_list;


    if( regressor_local_parametrization.rows() != getNrOfOutputs() ) {
        return -1;
    }

         /**
         * \todo move this stuff in UndirectedTree
         *
         */
        JunctionMap::const_iterator torque_dof_it = p_undirected_tree->getJunction(torque_dof_index);
        LinkMap::const_iterator parent_root_it;
        if( torque_dof_it->getChildLink() == p_undirected_tree->getLink(subtree_root_link_id) ) {
            parent_root_it = torque_dof_it->getParentLink();
        } else {
            parent_root_it = torque_dof_it->getChildLink();
        }
        assert(torque_dof_it->getJunctionIndex() < (int)p_undirected_tree->getNrOfDOFs());
        KDL::Twist S = parent_root_it->S(p_undirected_tree->getLink(subtree_root_link_id),q(torque_dof_it->getJunctionIndex()));

    //all other columns, beside the one relative to the inertial parameters of the links of the subtree, are zero
    regressor_local_parametrization.setZero();

    for(int i =0; i < (int)subtree_links_indices.size(); i++ ) {
        int link_id = subtree_links_indices[i];

        #ifndef NDEBUG
        if( verbose ) std::cerr << "Adding to the torque regressor of joint " << torque_dof_it->getName() << " the regressor relative to link " << p_undirected_tree->getLink(link_id)->getName() << std::endl;
        #endif

        if( linkIndeces2regrCols[link_id] != -1 ) {
            Eigen::Matrix<double,6,10> netWrenchRegressor_i = netWrenchRegressor(v[link_id],a[link_id]);
            regressor_local_parametrization.block(0,(int)(10*linkIndeces2regrCols[link_id]),getNrOfOutputs(),10)
                = toEigen(S).transpose()*WrenchTransformationMatrix(X_dynamic_base[subtree_root_link_id].Inverse()*X_dynamic_base[link_id])*netWrenchRegressor_i;
        }
    }

#ifndef NDEBUG
    if( consider_ft_offset ) {
        if( verbose ) std::cerr << "considering ft offset" << std::endl;
    } else {
        if( verbose ) std::cerr << "not considering ft offset" << std::endl;
    }
#endif
    // if the ft offset is condidered, we have to set also the columns relative to the offset
    // For each subgraph, we consider the measured wrenches as the one excerted from the rest of the
    // tree to the considered subtree
    // So the sign of the offset should be consistent with the other place where it is defined.
    // In particular, the offset of a sensor is considered
    // as an addictive on the measured wrench, so f_s = f_sr + f_o, where the frame of expression
    // and the sign of f_s are defined in the SensorsTree structure
    for(int leaf_id = 0; leaf_id < (int) subtree_leaf_links_indeces.size(); leaf_id++ ) {
        if( consider_ft_offset ) {
            int leaf_link_id = subtree_leaf_links_indeces[leaf_id];

            // for now we are supporting just one six axis FT sensor for link
            //std::vector< FTSensor> fts_link = ft_list.getFTSensorsOnLink(leaf_link_id);
            //assert(fts_link.size()==1);
            //int ft_id = fts_link[0].getID();
            int ft_id = getFirstFTSensorOnLink(*p_sensors_tree,leaf_link_id);
            assert( ft_id >= 0 );

            iDynTree::SixAxisForceTorqueSensor * sens
                = (iDynTree::SixAxisForceTorqueSensor *) p_sensors_tree->getSensor(iDynTree::SIX_AXIS_FORCE_TORQUE,ft_id);

            assert( sens->isLinkAttachedToSensor(leaf_link_id) );

            #ifndef NDEBUG
            if( verbose ) std::cerr << "Adding to the torque regressor of joint " << torque_dof_it->getName()
                                    << " the columns relative to offset of ft sensor "
                                    << sens->getName() << std::endl;
            #endif

            /** \todo find a more robust way to get columns indeces relative to a given parameters */
            assert(ft_id >= 0 && ft_id < 100);
            assert(10*NrOfRealLinks_subtree+6*ft_id+5 < regressor_local_parametrization.cols());

            double sign;
            if( sens->getAppliedWrenchLink() == leaf_link_id ) {
                sign = 1.0;
            } else {
                sign = -1.0;
            }

            iDynTree::Transform leaf_link_H_sensor;

            bool ok = sens->getLinkSensorTransform(leaf_link_id,leaf_link_H_sensor);

            assert(ok);

            regressor_local_parametrization.block(0,(int)(10*NrOfRealLinks_subtree+6*ft_id),getNrOfOutputs(),6)
                = sign*toEigen(S).transpose()*regressor_local_parametrization*WrenchTransformationMatrix(X_dynamic_base[subtree_root_link_id].Inverse()*X_dynamic_base[leaf_link_id]*iDynTree::ToKDL(leaf_link_H_sensor));

        }
    }

    //The known terms are simply all the measured wrenches acting on the subtree
    // projected on the axis plus the measured torque
    known_terms(0) = measured_torques(torque_dof_index);

    #ifndef NDEBUG
    //std::cerr << "computing kt " << std::endl;
    //std::cerr << (ft_list).toString();
#endif
    for(int leaf_id = 0; leaf_id < (int) subtree_leaf_links_indeces.size(); leaf_id++ ) {
        int leaf_link_id = subtree_leaf_links_indeces[leaf_id];

        int ft_id = getFirstFTSensorOnLink(*p_sensors_tree,leaf_link_id);
        assert( ft_id >= 0 );

        iDynTree::SixAxisForceTorqueSensor * sens
            = (iDynTree::SixAxisForceTorqueSensor *) p_sensors_tree->getSensor(iDynTree::SIX_AXIS_FORCE_TORQUE,ft_id);

#ifndef NDEBUG
        //std::cerr << "For leaf " << leaf_link_id << " found ft sensor " << ft_id << " that connects " << fts_link[0].getParent() << " and " << fts_link[0].getChild() << std::endl;
#endif
        iDynTree::Wrench sensor_measured_wrench, link_measured_branch;

        bool ok = measured_wrenches.getMeasurement(iDynTree::SIX_AXIS_FORCE_TORQUE,ft_id,sensor_measured_wrench);

        ok = ok && sens->getWrenchAppliedOnLink(leaf_link_id,sensor_measured_wrench,link_measured_branch);

        assert(ok);

        known_terms(0) +=  dot(S,X_dynamic_base[subtree_root_link_id].Inverse()*X_dynamic_base[leaf_link_id]*iDynTree::ToKDL(link_measured_branch));
    }

#ifndef NDEBUG
/*
std::cout << "Returning from computeRegressor (subtree):" << std::endl;
std::cout << "Regressor " << std::endl;
std::cout << regressor_matrix << std::endl;
std::cout << "known terms" << std::endl;
std::cout << known_terms << std::endl;
*/
#endif

    convertLocalRegressorToGlobalRegressor(regressor_local_parametrization,regressor_matrix_global_column_serialization,this->localParametersIndexToOutputParametersIndex);


    return 0;
}