bool CustomizedJointPath::calcInverseKinematics(const Vector3& end_p, const Matrix33& end_R)
{
    bool solved;
	
    if(ikTypeId == 0 || isBestEffortIKMode){

        solved = JointPath::calcInverseKinematics(end_p, end_R);

    } else {

        std::vector<double> qorg(numJoints());
		
        for(int i=0; i < numJoints(); ++i){
            qorg[i] = joint(i)->q;
        }

        const Link* targetLink = endLink();
        const Link* baseLink_ = baseLink();

        Vector3 p_relative;
        Matrix33 R_relative;
        if(!isCustomizedIkPathReversed){
            p_relative.noalias() = baseLink_->R.transpose() * (end_p - baseLink_->p);
            R_relative.noalias() = baseLink_->R.transpose() * end_R;
        } else {
            p_relative.noalias() = end_R.transpose() * (baseLink_->p - end_p);
            R_relative.noalias() = end_R.transpose() * baseLink_->R;
        }
        solved = body->customizerInterface->
            calcAnalyticIk(body->customizerHandle, ikTypeId, p_relative, R_relative);

        if(solved){

            calcForwardKinematics();

            Vector3 dp(end_p - targetLink->p);
            Vector3 omega(omegaFromRot(targetLink->R.transpose() * end_R));
			
            double errsqr = dp.dot(dp) + omega.dot(omega);
			
            if(errsqr < maxIKErrorSqr){
                solved = true;
            } else {
                solved = false;
                for(int i=0; i < numJoints(); ++i){
                    joint(i)->q = qorg[i];
                }
                calcForwardKinematics();
            }
        }
    }

    return solved;
}
int main(int arg, char* argc[]) {

  DetermineCameraPositionParser parser(helpMsg);

  try{

    parser.parse(arg,argc);
  
    MarkerType markerType;
    vector<Point2d> markers;
    string dataFolder = parser.get<string>("dataFolder");
    int camID = parser.get<int>("camID");
    int camW = parser.get<int>("camWidth");
    int camH = parser.get<int>("camHeight");

    string markerName = dataFolder + "/markers/" + parser.get<string>("markerName") + ".txt";
    markerType =  MarkerType(markerName);
  
    string distanceFile = dataFolder + "/distances/" + parser.get<string>("distanceMatrix") + ".txt";
    MatrixDD distances = loadDistanceMatrix(distanceFile);
  
    Mat src;

    string cameraFileName = dataFolder + "/camera/" + parser.get<string>("cameraName") + ".txt";
    Camera cam = loadCameraFromFile( cameraFileName );

    VideoCapture cap(camID);
    cap.set(CV_CAP_PROP_FRAME_WIDTH,cam.getResWidth());
    cap.set(CV_CAP_PROP_FRAME_HEIGHT,cam.getResHeight());

    if (!cap.isOpened())
      return false;

    Matrix33 planeR = Matrix33::Identity();
    Vector3 planeT;
  
    while (1) {
      cap >> src;

      // Track markers
      trackMarker(src, markerType, markers);

      // sort markers in circular patern
      reorganizePoints(markers);

      // print markers in picture
      for (size_t i = 0; i < markers.size(); i++) {
	circle(src, markers[i], 1, Scalar(255, 0, 0), 2);
	stringstream ss;
	ss << i;
	putText(src, ss.str(), markers[i], FONT_HERSHEY_PLAIN, 1.5,
		Scalar(255, 0, 0));
      }

      if (markers.size() == distances.rows() ) {

	vector<Vector3> outPoints;
	double optiError;
	
	vector<Real> x(distances.rows(),2000);
	optiError = findPointPositions(distances, markers, cam, outPoints, x);

	findPlaneCoordinateFrame( cam, outPoints, planeR, planeT );

	cout << "Camera is: " << (planeR.transpose()*(cam.getT() - planeT))[2] << "mm above ground." << endl;
	cout << "Marker distances are: ";
	for(Real y : x){
	  cout << y << " ";
	}
	cout << endl << endl;

      }else{
	cout << "Detected " << markers.size() << " ground markers but there should be " << distances.rows() << " markers in the picture!" << endl;
      }

      imshow("determineCameraPosition", src);
     
      if (waitKey(1) >= 0)
	break;
    }
  }catch( std::exception const & exc ){
    cerr << exc.what() << endl;
    return 0;
  }

  return 0;
}
void BodyInfo_impl::setSegmentParameters(int linkInfoIndex, JointNodeSetPtr jointNodeSet)
{
    LinkInfo& linkInfo = links_[linkInfoIndex];

    vector<VrmlProtoInstancePtr>& segmentNodes = jointNodeSet->segmentNodes;
    int numSegment = segmentNodes.size();

    linkInfo.mass = 0.0;
    for( int i = 0 ; i < 3 ; ++i ) {
        linkInfo.centerOfMass[i] = 0.0;
        for( int j = 0 ; j < 3 ; ++j ) {
            linkInfo.inertia[i*3 + j] = 0.0;
        }
    }

    //  Mass = Σmass                 //
    //  C = (Σmass * T * c) / Mass   //
    //  I = Σ(R * I * Rt + G)       //
    //  R = Tの回転行列               //
    //  G = y*y+z*z, -x*y, -x*z, -y*x, z*z+x*x, -y*z, -z*x, -z*y, x*x+y*y    //
    //  (x, y, z ) = T * c - C        //
    std::vector<Vector4, Eigen::aligned_allocator<Vector4> > centerOfMassArray;
    std::vector<double> massArray;
    for(int i = 0 ; i < numSegment ; ++i){
        SegmentInfo& segmentInfo = linkInfo.segments[i];
        Matrix44 T = jointNodeSet->transforms.at(i);
        DblArray3& centerOfMass = segmentInfo.centerOfMass;
        CORBA::Double& mass =segmentInfo.mass;
        DblArray9& inertia = segmentInfo.inertia;
        TProtoFieldMap& fmap = segmentNodes[i]->fields;
        copyVrmlField( fmap, "centerOfMass",     centerOfMass );
        copyVrmlField( fmap, "mass",             mass );
        copyVrmlField( fmap, "momentsOfInertia", inertia );
        Vector4 c0(centerOfMass[0], centerOfMass[1], centerOfMass[2], 1.0);
        Vector4 c1(T * c0);
        centerOfMassArray.push_back(c1);
        massArray.push_back(mass);
        for(int j=0; j<3; j++){
            linkInfo.centerOfMass[j] = c1(j) * mass + linkInfo.centerOfMass[j] * linkInfo.mass;
        }
        linkInfo.mass += mass;
        if(linkInfo.mass > 0.0){
            for(int j=0; j<3; j++){
                linkInfo.centerOfMass[j] /= linkInfo.mass;
            }
        }
        Matrix33 I;
        I << inertia[0], inertia[1], inertia[2], inertia[3], inertia[4], inertia[5], inertia[6], inertia[7], inertia[8];
        Matrix33 R;
        R << T(0,0), T(0,1), T(0,2), T(1,0), T(1,1), T(1,2), T(2,0), T(2,1), T(2,2);
        Matrix33 I1(R * I * R.transpose());
        for(int j=0; j<3; j++){
            for(int k=0; k<3; k++)
                linkInfo.inertia[j*3+k] += I1(j,k);    
        }
        segmentInfo.name = CORBA::string_dup( segmentNodes[i]->defName.c_str() );
    }
    if(linkInfo.mass <=0.0 )
        std::cerr << "Warning: Mass is zero. <Model>" << this->name() << " <Link>" << linkInfo.name << std::endl;

    for(int i = 0 ; i < numSegment ; ++i){
        Vector4 c( centerOfMassArray.at(i) );
        double x = c(0) - linkInfo.centerOfMass[0];
        double y = c(1) - linkInfo.centerOfMass[1];
        double z = c(2) - linkInfo.centerOfMass[2];
        double m = massArray.at(i);

        linkInfo.inertia[0] += m * (y*y + z*z);
        linkInfo.inertia[1] += -m * x * y;
        linkInfo.inertia[2] += -m * x * z;
        linkInfo.inertia[3] += -m * y * x;
        linkInfo.inertia[4] += m * (z*z + x*x);
        linkInfo.inertia[5] += -m * y * z;
        linkInfo.inertia[6] += -m * z * x;
        linkInfo.inertia[7] += -m * z * y;
        linkInfo.inertia[8] += m * (x*x + y*y);
    }
}
    ProcessTopologyKdTree(NeighbourRanksListType& nbRanks,
                          AdjacentNeighbourRanksMapType& adjNbRanks,
                          RankIdType processRank,
                          RankIdType masterRank,
                          std::shared_ptr<TreeType> tree,
                          const LeafNeighbourMapType& neighbours,
                          const AABB3d& aabb,
                          bool aligned,
                          const Matrix33& A_IK = Matrix33::Identity())
        : m_rank(processRank)
        , m_axisAligned(aligned)
        , m_A_KI(A_IK.transpose())
        , m_kdTree(tree.get())
        , m_kdTreeRefCount(tree)
    {
        if (!m_kdTree)
        {
            GRSF_ERRORMSG("KdTree is nullptr")
        }

        // insert our neighbours
        auto it = neighbours.find(processRank);
        if (it == neighbours.end())
        {
            GRSF_ERRORMSG("neighbours does not contain an entry for rank: " << processRank);
        }
        nbRanks.insert(it->second.begin(), it->second.end());

        // get adj neighbours
        for (auto& rank : nbRanks)
        {
            std::cerr << "ProcessTopologyKdTree: NbRank: " << rank << std::endl;
            // Initialize adjacent neighbour ranks to m_nbRanks for this neighbours[*it]$
            auto itN = neighbours.find(rank);
            if (itN == neighbours.end())
            {
                GRSF_ERRORMSG("neighbours does not contain an entry for rank: " << rank);
            }
            // build the intersection of our ranks with neighbours of other rank
            adjNbRanks.emplace(rank, unorderedHelpers::makeIntersection(nbRanks, itN->second));
            for (auto& v : adjNbRanks[rank])
            {
                std::cerr << " adjNB: " << v << std::endl;
            }
        }

        // get our aabb

        m_leaf = m_kdTree->getLeaf(m_rank);
        if (!m_leaf)
        {
            GRSF_ERRORMSG("Trying to get leaf node for our rank: " << m_rank << " failed!")
        }
        std::cerr << " got leaf " << m_leaf->getIdx() << std::endl;

        // adjust kdTree
        // TODO (unlink childs which corresponds to subtrees we never need to check because the leafs subtree are not
        // neighbours)
        // not essential for correct algorithm
        // but we leave the leafs which are not part of our neighbours as is, such that error messages contain these idx
        // values
        // if a body overlaps into a neighbour which is not part of ours

        // the kdTree is already filling the whole space
        // no need to expand!

        // get lowest common ancestors of all boundary subtrees, including our own leaf node
        // the lca node is the node we start from for collision detection
        auto bndIt = m_leaf->getBoundaries().begin();
        auto root  = m_kdTree->getRootNode();
        GRSF_ASSERTMSG(root, "Root nullptr!")

        m_lcaBoundary = m_leaf;
        while (bndIt != m_leaf->getBoundaries().end() && m_lcaBoundary != root)
        {
            if (*bndIt != nullptr)
            {
                m_lcaBoundary = m_kdTree->getLowestCommonAncestor(m_lcaBoundary, *bndIt);
            }
            ++bndIt;
        }
        // if m_leaf = root node or , the lca becomes nullptr which is not good,
        // we set it to the root node, this means we only have one leaf = 1 process = root node
        if (m_lcaBoundary == nullptr)
        {
            m_lcaBoundary = root;
        }
        // collider should not add m_leaf in the results list over the overlap check
        m_colliderKdTree.setNonAddedLeaf(m_leaf);
        std::cerr << " finished " << std::endl;
    };
Exemple #5
0
bool hrp::isOrthogonalMatrix(Matrix33& m){
    Matrix33 w(m * m.transpose() - Matrix33::Identity());
    return (abs(w.array())<1.0e-12).all();
    //return all_elements( m * m.transpose() == Matrix33::Identity() );
}