예제 #1
0
    Spectrum PerspectiveSensor::sampleRay(Ray3f& ray, const Point2f& samplePosition, const Point2f& apertureSample) const
    {
        Point3f nearPoint = m_sampleToCamera * Point3f(
            samplePosition.x() * m_invImageSize.x(),
            samplePosition.y() * m_invImageSize.y(), 0.f);

        Vector3f dir = nearPoint.normalized();
        float invZ = 1.f / dir.z();

        ray.o = m_cameraToWorld * Point3f(0.f, 0.f, 0.f);
        ray.d = m_cameraToWorld * dir;
        ray.minT = m_nearClip * invZ;
        ray.maxT = m_farClip * invZ;
        ray.update();

        return Spectrum(1.f);
    }
예제 #2
0
void Arm::solve(Point3f goal_point, int life_count) {
    // prev and curr are for use of halving
    // last is making sure the iteration gets a better solution than the last iteration,
    // otherwise revert changes
    float prev_err, curr_err, last_err = 9999;
    Point3f current_point;
    int max_iterations = 200;
    int count = 0;
    float err_margin = 0.01;

    goal_point -= base;
    if (goal_point.norm() > get_max_length()) {
        goal_point = goal_point.normalized() * get_max_length();
    }

    current_point = calculate_end_effector();

    // save the first err
    prev_err = (goal_point - current_point).norm();
    curr_err = prev_err;
    last_err = curr_err;

    // while the current point is close enough, stop iterating
    while (curr_err > err_margin) {
        // calculate the difference between the goal_point and current_point
        Vector3f dP = goal_point - current_point;

        // create the jacovian
        int segment_size = segments.size();

        // build the transpose matrix (easier for eigen matrix construction)
        MatrixXf jac_t(3*segment_size, 3);
        for(int i=0; i<3*segment_size; i+=3) {
            Matrix<float, 1, 3> row_theta = compute_jacovian_segment(i/3, goal_point, segments[i/3]->get_right());
            Matrix<float, 1, 3> row_phi = compute_jacovian_segment(i/3, goal_point, segments[i/3]->get_up());
            Matrix<float, 1, 3> row_z = compute_jacovian_segment(i/3, goal_point, segments[i/3]->get_z());

            jac_t(i, 0) = row_theta(0, 0);
            jac_t(i, 1) = row_theta(0, 1);
            jac_t(i, 2) = row_theta(0, 2);

            jac_t(i+1, 0) = row_phi(0, 0);
            jac_t(i+1, 1) = row_phi(0, 1);
            jac_t(i+1, 2) = row_phi(0, 2);

            jac_t(i+2, 0) = row_z(0, 0);
            jac_t(i+2, 1) = row_z(0, 1);
            jac_t(i+2, 2) = row_z(0, 2);
        }
        // compute the final jacovian
        MatrixXf jac(3, 3*segment_size);
        jac = jac_t.transpose();

        Matrix<float, Dynamic, Dynamic> pseudo_ijac;
        MatrixXf pinv_jac(3*segment_size, 3);
        pinv_jac = pseudoInverse(jac);

        Matrix<float, Dynamic, 1> changes = pinv_jac * dP;

        cout << "changes: " << changes << endl;

        for(int i=0; i<3*segment_size; i+=3) {
            // save the current transformation on the segments
            segments[i/3]->save_transformation();

            // apply the change to the theta angle
            segments[i/3]->apply_angle_change(changes[i], segments[i/3]->get_right());
            // apply the change to the phi angle
            segments[i/3]->apply_angle_change(changes[i+1], segments[i/3]->get_up());
            // apply the change to the z angle
            segments[i/3]->apply_angle_change(changes[i+2], segments[i/3]->get_z());
        }

        // compute current_point after making changes
        current_point = calculate_end_effector();

        //cout << "current_point: " << vectorString(current_point) << endl;
        //cout << "goal_point: " << vectorString(goal_point) << endl;

        prev_err = curr_err;
        curr_err = (goal_point - current_point).norm();

        int halving_count = 0;

        cout << "curr err: " << curr_err << " || prev err: " << prev_err << " || last err: " << last_err << endl;
        // make sure we aren't iterating past the solution
        while (curr_err > last_err) {
            // undo changes
            for(int i=0; i<segment_size; i++) {
                // unapply the change to the saved angle
                segments[i]->load_transformation();
            }
            current_point = calculate_end_effector();
            changes *= 0.5;
            // reapply halved changes
            for(int i=0; i<3*segment_size; i+=3) {
                // save the current transformation on the segments
                segments[i/3]->save_transformation();

                // apply the change to the theta angle
                segments[i/3]->apply_angle_change(changes[i], segments[i/3]->get_right());
                // apply the change to the phi angle
                segments[i/3]->apply_angle_change(changes[i+1], segments[i/3]->get_up());
                // apply the change to the z angle
                segments[i/3]->apply_angle_change(changes[i+2], segments[i/3]->get_z());
            }

            // compute the end_effector and measure error
            current_point = calculate_end_effector();
            prev_err = curr_err;
            curr_err = (goal_point - current_point).norm();

            cout << "|half| curr err: " << curr_err << " || prev err: " << prev_err << endl;
            halving_count++;
            if (halving_count > 100)
                break;
        }

        if (curr_err > last_err) {
            // undo changes
            for(int i=0; i<segment_size; i++) {
                // unapply the change to the saved angle
                segments[i]->load_last_transformation();
            }
            current_point = calculate_end_effector();
            curr_err = (goal_point - current_point).norm();
            cout << "curr iteration not better than last, reverting" << endl;
            cout << "curr err: " << curr_err << " || last err: " << last_err << endl;
            break;
        }
        for(int i=0; i<segment_size; i++) {
            // unapply the change to the saved angle
            segments[i]->save_last_transformation();
        }
        cout << "curr err: " << curr_err << " || last err: " << last_err << endl;
        last_err = curr_err;
        cout << "last_err is now : " << last_err << endl;


        // make sure we don't infinite loop
        count++;
        if (count > max_iterations) {
            break;
        }
    }

    /*
    // if we haven't gotten to a nice solution
    if (curr_err > err_margin) {
        // kill off infinitely recursive solutions
        if (life_count <= 0) {
            return;
        }

        // try to solve it again
        solve(goal_point, life_count-1);
    } else {
    */
    cout << "final error: " << curr_err << endl;
}