Beispiel #1
0
void default_cam_mgr_follow_disable(default_cam_mgr_t * state)
{
    if (state->follow_lastpos != NULL) {
        matd_destroy(state->follow_lastpos);
        matd_destroy(state->follow_lastquat);
    }

    state->follow_lastpos = NULL;
    state->follow_lastquat = NULL;

}
Beispiel #2
0
line_t linear_regression(Blob<Gradient> &blob) {
	line_t line;
	//Perform linear regression
	//Ax = B
	//A = [1 X_0],[1 X_1]
	//B = [Y_0]  ,[Y_1]
	//x = [ b, m]
	matd_t *A = matd_create(blob.size(),2);
	matd_t *B = matd_create(blob.size(),1);
	int leftmost, rightmost;
	leftmost = rightmost = blob.getPos(0).x;
	//Convert to Matd
	for(size_t i = 0; i < blob.size(); ++i) {
		pos_t tmp = blob.getPos(i);
		if(tmp.x < leftmost) {
			leftmost = tmp.x;
		}
		if(tmp.x > rightmost) {
			rightmost = tmp.x;
		}

		MATD_EL(A, i, 0) = 1;
		MATD_EL(A, i, 1) = tmp.x;
		MATD_EL(B, i, 0) = tmp.y;
	}
	matd_t *x = matd_op("(M' * M)^-1 * M' * M",
			A,A,A,B);
	line.b = MATD_EL(x,0,0);
	line.m = MATD_EL(x,1,0);

	line.ll.x = leftmost;
	line.ll.y = line.m*leftmost + line.b;

	line.ru.x = rightmost;
	line.ru.y = line.m*rightmost + line.b;

	line.num_pts = blob.size();
	//Compute difference of hypothetical vs. real
	matd_t *diff = matd_op("(M*M) - M",
			A,x,B);
	//Sum of squares
	matd_t *var  = matd_op("M' * M",diff,diff);
	line.variance = MATD_EL(var,0,0);

	//Clean up
	matd_destroy(A);
	matd_destroy(B);
	matd_destroy(x);
	matd_destroy(diff);
	matd_destroy(var);
	return line;
}
Beispiel #3
0
vx_camera_pos_t * default_cam_mgr_get_cam_pos(default_cam_mgr_t * state, int * viewport, uint64_t mtime)
{
    vx_camera_pos_t * p = calloc(1, sizeof(vx_camera_pos_t));
    memcpy(p->viewport, viewport, 4*sizeof(int));

    p->perspective_fovy_degrees = state->perspective_fovy_degrees;
    p->zclip_near = state->zclip_near;
    p->zclip_far = state->zclip_far;

    // process a fit command if necessary:
    if (state->fit != NULL) {
        fit_t * f = state->fit;

        // consume the fit command
        state->fit = NULL; // XXX minor race condition, could lose a fit cmd

        // XXX We can probably do better than this using the viewport...
        state->lookat1[0] = (f->xy0[0] + f->xy1[0]) / 2;
        state->lookat1[1] = (f->xy0[1] + f->xy1[1]) / 2;
        state->lookat1[2] = 0;

        // dimensions of fit
        double Fw = f->xy1[0] - f->xy0[0];
        double Fh = f->xy1[1] - f->xy0[1];

        // aspect ratios
        double Far = Fw / Fh;
        double Var = p->viewport[2] * 1.0 / p->viewport[3];

        double tAngle = tan(p->perspective_fovy_degrees/2*M_PI/180.0);
        double height = fabs(0.5 * (Var > Far ? Fh : Fw / Var) / tAngle);

        state->eye1[0] = state->lookat1[0];
        state->eye1[1] = state->lookat1[1];
        state->eye1[2] = height;

        state->up1[0] = 0;
        state->up1[1] = 1;
        state->up1[2] = 0;

        state->mtime1 = f->mtime;

        free(f);
    }

    if (mtime > state->mtime1) {
        memcpy(p->eye, state->eye1, 3*sizeof(double));
        memcpy(p->up, state->up1, 3*sizeof(double));
        memcpy(p->lookat, state->lookat1, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness1;
    } else  if (mtime <= state->mtime0) {
        memcpy(p->eye, state->eye0, 3*sizeof(double));
        memcpy(p->up, state->up0, 3*sizeof(double));
        memcpy(p->lookat, state->lookat0, 3*sizeof(double));
        p->perspectiveness = state->perspectiveness0;
    } else {
        double alpha1 = ((double) mtime - state->mtime0) / (state->mtime1 - state->mtime0);
        double alpha0 = 1.0 - alpha1;

        scaled_combination(state->eye0,    alpha0, state->eye1,    alpha1, p->eye,    3);
        scaled_combination(state->up0,     alpha0, state->up1,     alpha1, p->up,     3);
        scaled_combination(state->lookat0, alpha0, state->lookat1, alpha1, p->lookat, 3);
        p->perspectiveness = state->perspectiveness0*alpha0 + state->perspectiveness1*alpha1;

        // Tweak so eye-to-lookat is the right distance
        {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            matd_t * eye0 = matd_create_data(3,1, state->eye0); zarray_add(fp, &eye0);
            matd_t * lookat0 = matd_create_data(3,1, state->lookat0); zarray_add(fp, &lookat0);
            matd_t * up0 = matd_create_data(3,1, state->up0); zarray_add(fp, &up0);

            matd_t * eye1 = matd_create_data(3,1, state->eye1); zarray_add(fp, &eye1);
            matd_t * lookat1 = matd_create_data(3,1, state->lookat1); zarray_add(fp, &lookat1);
            matd_t * up1 = matd_create_data(3,1, state->up1); zarray_add(fp, &up1);


            double dist0 = matd_vec_dist(eye0, lookat0);
            double dist1 = matd_vec_dist(eye1, lookat1);

            matd_t * dist = matd_create_scalar(dist0*alpha0 + dist1*alpha1); zarray_add(fp, &dist);

            matd_t * eye2p = matd_subtract(eye,lookat); zarray_add(fp, &eye2p);
            eye2p = matd_vec_normalize(eye2p); zarray_add(fp, &eye2p);

            eye = matd_op("M + (M*M)", lookat, eye2p, dist);

            // Only modified eye
            memcpy(p->eye, eye->data, 3*sizeof(double));

            zarray_vmap(fp, matd_destroy);

            zarray_destroy(fp);
        }
    }

    // Need to do more fixup depending on interface mode!
    {
        if (state->interface_mode <= 2.0) {
            // stack eye on lookat:
            p->eye[0] = p->lookat[0];
            p->eye[1] = p->lookat[1];
            p->lookat[2] = 0;

            // skip fabs() for ENU/NED compat
            //p->eye[2] = fabs(p->eye[2]);


            {
                matd_t * up = matd_create_data(3,1, p->up);
                up->data[2] = 0; // up should never point in Z
                matd_t * up_norm = matd_vec_normalize(up);

                memcpy(p->up, up_norm->data, sizeof(double)*3);
                matd_destroy(up);
                matd_destroy(up_norm);
            }

        } else if (state->interface_mode == 2.5) {
            zarray_t * fp = zarray_create(sizeof(matd_t*));

            matd_t * eye = matd_create_data(3,1, p->eye); zarray_add(fp, &eye);
            matd_t * lookat = matd_create_data(3,1, p->lookat); zarray_add(fp, &lookat);
            matd_t * up = matd_create_data(3,1, p->up); zarray_add(fp, &up);

            lookat->data[2] = 0.0;

            // Level horizon
            matd_t * dir = matd_subtract(lookat, eye); zarray_add(fp, &dir);
            matd_t * dir_norm = matd_vec_normalize(dir); zarray_add(fp, &dir_norm);
            matd_t * left = matd_crossproduct(up, dir_norm); zarray_add(fp, &left);
            left->data[2] = 0.0;

            left = matd_vec_normalize(left); zarray_add(fp, &left);


            // Don't allow upside down
            //up->data[2] = fmax(0.0, up->data[2]); // XXX NED?

            // Find an 'up' direction perpendicular to left
            matd_t * dot_scalar = matd_create_scalar(matd_vec_dot_product(up, left)); zarray_add(fp, &dot_scalar);
            up = matd_op("M - (M*M)", up,  left, dot_scalar); zarray_add(fp, &up);
            up = matd_vec_normalize(up); zarray_add(fp, &up);

            // Now find eye position by computing new lookat dir
            matd_t * eye_dir = matd_crossproduct(up, left); zarray_add(fp, &eye_dir);

            matd_t *eye_dist_scalar = matd_create_scalar(matd_vec_dist(eye, lookat)); zarray_add(fp, &eye_dist_scalar);

            eye = matd_op("M + (M*M)", lookat, eye_dir, eye_dist_scalar); zarray_add(fp, &eye);

            // export results back to p:
            memcpy(p->eye, eye->data, sizeof(double)*3);
            memcpy(p->lookat, lookat->data, sizeof(double)*3);
            memcpy(p->up, up->data, sizeof(double)*3);

            zarray_vmap(fp, matd_destroy);
            zarray_destroy(fp);
        }
    }

    // Fix up for bad zoom
    if (1) {
        matd_t * eye = matd_create_data(3,1, p->eye);
        matd_t * lookat = matd_create_data(3,1, p->lookat);
        matd_t * up = matd_create_data(3,1, p->up);

        matd_t * lookeye = matd_subtract(lookat, eye);
        matd_t * lookdir = matd_vec_normalize(lookeye);
        double dist =  matd_vec_dist(eye, lookat);
        dist  = fmin(state->zclip_far / 3.0, dist);
        dist  = fmax(state->zclip_near * 3.0, dist);

        matd_scale_inplace(lookdir, dist);

        matd_t * eye_fixed = matd_subtract(lookat, lookdir);

        memcpy(p->eye, eye_fixed->data, sizeof(double)*3);

        matd_destroy(eye);
        matd_destroy(lookat);
        matd_destroy(up);
        matd_destroy(lookeye);
        matd_destroy(lookdir);
        matd_destroy(eye_fixed);
    }

    // copy the result back into 'state'
    {
        memcpy(state->eye0, p->eye, 3*sizeof(double));
        memcpy(state->up0, p->up, 3*sizeof(double));
        memcpy(state->lookat0, p->lookat, 3*sizeof(double));
        state->perspectiveness0 = p->perspectiveness;
        state->mtime0 = mtime;
    }

    return p;
}
Beispiel #4
0
void default_cam_mgr_follow(default_cam_mgr_t * state, double * _pos3, double * _quat4, int followYaw, uint32_t animate_ms)
{
    matd_t * pos3 = matd_create_data(3, 1, _pos3);
    matd_t * quat4 = matd_create_data(4, 1, _quat4);

    if (state->follow_lastpos != NULL) {

        matd_t * eye1    = matd_create_data(3,1,state->eye1);
        matd_t * lookat1    = matd_create_data(3,1, state->lookat1);
        matd_t * up1    = matd_create_data(3,1, state->up1);

        if (followYaw) {

            matd_t * v2eye = matd_subtract(state->follow_lastpos, eye1);
            matd_t * v2look = matd_subtract(state->follow_lastpos, lookat1);

            matd_t * new_rpy = matd_create(3,1);
            //matd_quat_to_rpy(quat4);
            vx_util_quat_to_rpy(quat4->data, new_rpy->data);

            matd_t * last_rpy = matd_create(3,1);
            //matd_quat_to_rpy(state->follow_lastquat);
            vx_util_quat_to_rpy(state->follow_lastquat->data, last_rpy->data);

            double dtheta = new_rpy->data[2] - last_rpy->data[2];

            matd_t * zaxis = matd_create(3,1);
            zaxis->data[2] = 1;
            matd_t * zq = matd_create(4,1);
            //zq = matd_angle_axis_to_quat(dtheta, zaxis);
            vx_util_angle_axis_to_quat(dtheta, zaxis->data, zq->data);

            matd_t * v2look_rot = matd_create(3,1);
            //matd_quat_rotate(zq, v2look);
            vx_util_quat_rotate(zq->data, v2look->data, v2look_rot->data);
            matd_t * new_lookat = matd_subtract(pos3, v2look_rot);

            matd_t * v2eye_rot = matd_create(3,1);
            //matd_quat_rotate(zq, v2eye);
            vx_util_quat_rotate(zq->data, v2eye->data, v2eye_rot->data);

            matd_t * new_eye = matd_subtract(pos3, v2eye_rot);

            matd_t * new_up = matd_create(3,1);
            //matd_quat_rotate(zq, up1);
            vx_util_quat_rotate(zq->data, up1->data, new_up->data);

            internal_lookat(state, new_eye->data, new_lookat->data, new_up->data, animate_ms);

            // cleanup
            matd_destroy(v2eye);
            matd_destroy(v2look);

            matd_destroy(new_rpy);
            matd_destroy(last_rpy);

            matd_destroy(zaxis);
            matd_destroy(zq);

            matd_destroy(v2look_rot);
            matd_destroy(new_lookat);

            matd_destroy(v2eye_rot);
            matd_destroy(new_eye);

            matd_destroy(new_up);

        } else {

            matd_t * dpos   = matd_subtract(pos3, state->follow_lastpos);

            matd_t * newEye = matd_add(eye1, dpos);
            matd_t * newLookAt = matd_add(lookat1, dpos);


            internal_lookat(state, newEye->data, newLookAt->data, up1->data, animate_ms);


            matd_destroy(dpos);
            matd_destroy(newEye);
            matd_destroy(newLookAt);
        }


        matd_destroy(eye1);
        matd_destroy(lookat1);
        matd_destroy(up1);


        // Cleanup
        matd_destroy(state->follow_lastpos);
        matd_destroy(state->follow_lastquat);
    }


    state->follow_lastpos = pos3;
    state->follow_lastquat = quat4;

}
Beispiel #5
0
// correspondences is a list of float[4]s, consisting of the points x
// and y concatenated. We will compute a homography such that y = Hx
matd_t *homography_compute(zarray_t *correspondences, int flags)
{
    // compute centroids of both sets of points (yields a better
    // conditioned information matrix)
    double x_cx = 0, x_cy = 0;
    double y_cx = 0, y_cy = 0;

    for (int i = 0; i < zarray_size(correspondences); i++) {
        float *c;
        zarray_get_volatile(correspondences, i, &c);

        x_cx += c[0];
        x_cy += c[1];
        y_cx += c[2];
        y_cy += c[3];
    }

    int sz = zarray_size(correspondences);
    x_cx /= sz;
    x_cy /= sz;
    y_cx /= sz;
    y_cy /= sz;

    // NB We don't normalize scale; it seems implausible that it could
    // possibly make any difference given the dynamic range of IEEE
    // doubles.

    matd_t *A = matd_create(9,9);
    for (int i = 0; i < zarray_size(correspondences); i++) {
        float *c;
        zarray_get_volatile(correspondences, i, &c);

        // (below world is "x", and image is "y")
        double worldx = c[0] - x_cx;
        double worldy = c[1] - x_cy;
        double imagex = c[2] - y_cx;
        double imagey = c[3] - y_cy;

        double a03 = -worldx;
        double a04 = -worldy;
        double a05 = -1;
        double a06 = worldx*imagey;
        double a07 = worldy*imagey;
        double a08 = imagey;

        MATD_EL(A, 3, 3) += a03*a03;
        MATD_EL(A, 3, 4) += a03*a04;
        MATD_EL(A, 3, 5) += a03*a05;
        MATD_EL(A, 3, 6) += a03*a06;
        MATD_EL(A, 3, 7) += a03*a07;
        MATD_EL(A, 3, 8) += a03*a08;
        MATD_EL(A, 4, 4) += a04*a04;
        MATD_EL(A, 4, 5) += a04*a05;
        MATD_EL(A, 4, 6) += a04*a06;
        MATD_EL(A, 4, 7) += a04*a07;
        MATD_EL(A, 4, 8) += a04*a08;
        MATD_EL(A, 5, 5) += a05*a05;
        MATD_EL(A, 5, 6) += a05*a06;
        MATD_EL(A, 5, 7) += a05*a07;
        MATD_EL(A, 5, 8) += a05*a08;
        MATD_EL(A, 6, 6) += a06*a06;
        MATD_EL(A, 6, 7) += a06*a07;
        MATD_EL(A, 6, 8) += a06*a08;
        MATD_EL(A, 7, 7) += a07*a07;
        MATD_EL(A, 7, 8) += a07*a08;
        MATD_EL(A, 8, 8) += a08*a08;

        double a10 = worldx;
        double a11 = worldy;
        double a12 = 1;
        double a16 = -worldx*imagex;
        double a17 = -worldy*imagex;
        double a18 = -imagex;

        MATD_EL(A, 0, 0) += a10*a10;
        MATD_EL(A, 0, 1) += a10*a11;
        MATD_EL(A, 0, 2) += a10*a12;
        MATD_EL(A, 0, 6) += a10*a16;
        MATD_EL(A, 0, 7) += a10*a17;
        MATD_EL(A, 0, 8) += a10*a18;
        MATD_EL(A, 1, 1) += a11*a11;
        MATD_EL(A, 1, 2) += a11*a12;
        MATD_EL(A, 1, 6) += a11*a16;
        MATD_EL(A, 1, 7) += a11*a17;
        MATD_EL(A, 1, 8) += a11*a18;
        MATD_EL(A, 2, 2) += a12*a12;
        MATD_EL(A, 2, 6) += a12*a16;
        MATD_EL(A, 2, 7) += a12*a17;
        MATD_EL(A, 2, 8) += a12*a18;
        MATD_EL(A, 6, 6) += a16*a16;
        MATD_EL(A, 6, 7) += a16*a17;
        MATD_EL(A, 6, 8) += a16*a18;
        MATD_EL(A, 7, 7) += a17*a17;
        MATD_EL(A, 7, 8) += a17*a18;
        MATD_EL(A, 8, 8) += a18*a18;

        double a20 = -worldx*imagey;
        double a21 = -worldy*imagey;
        double a22 = -imagey;
        double a23 = worldx*imagex;
        double a24 = worldy*imagex;
        double a25 = imagex;

        MATD_EL(A, 0, 0) += a20*a20;
        MATD_EL(A, 0, 1) += a20*a21;
        MATD_EL(A, 0, 2) += a20*a22;
        MATD_EL(A, 0, 3) += a20*a23;
        MATD_EL(A, 0, 4) += a20*a24;
        MATD_EL(A, 0, 5) += a20*a25;
        MATD_EL(A, 1, 1) += a21*a21;
        MATD_EL(A, 1, 2) += a21*a22;
        MATD_EL(A, 1, 3) += a21*a23;
        MATD_EL(A, 1, 4) += a21*a24;
        MATD_EL(A, 1, 5) += a21*a25;
        MATD_EL(A, 2, 2) += a22*a22;
        MATD_EL(A, 2, 3) += a22*a23;
        MATD_EL(A, 2, 4) += a22*a24;
        MATD_EL(A, 2, 5) += a22*a25;
        MATD_EL(A, 3, 3) += a23*a23;
        MATD_EL(A, 3, 4) += a23*a24;
        MATD_EL(A, 3, 5) += a23*a25;
        MATD_EL(A, 4, 4) += a24*a24;
        MATD_EL(A, 4, 5) += a24*a25;
        MATD_EL(A, 5, 5) += a25*a25;
    }

    // make symmetric
    for (int i = 0; i < 9; i++)
        for (int j = i+1; j < 9; j++)
            MATD_EL(A, j, i) = MATD_EL(A, i, j);

    matd_t *H = matd_create(3,3);

    if (flags & HOMOGRAPHY_COMPUTE_FLAG_INVERSE) {
        // compute singular vector by (carefully) inverting the rank-deficient matrix.

        if (1) {
            matd_t *Ainv = matd_inverse(A);
            double scale = 0;

            for (int i = 0; i < 9; i++)
                scale += sq(MATD_EL(Ainv, i, 0));
            scale = sqrt(scale);

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0) / scale;

            matd_destroy(Ainv);
        } else {

            matd_t *b = matd_create_data(9, 1, (double[]) { 1, 0, 0, 0, 0, 0, 0, 0, 0 });
            matd_t *Ainv = NULL;

            if (0) {
                matd_lu_t *lu = matd_lu(A);
                Ainv = matd_lu_solve(lu, b);
                matd_lu_destroy(lu);
            } else {
                matd_chol_t *chol = matd_chol(A);
                Ainv = matd_chol_solve(chol, b);
                matd_chol_destroy(chol);
            }

            double scale = 0;

            for (int i = 0; i < 9; i++)
                scale += sq(MATD_EL(Ainv, i, 0));
            scale = sqrt(scale);

            for (int i = 0; i < 3; i++)
                for (int j = 0; j < 3; j++)
                    MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0) / scale;

            matd_destroy(b);
            matd_destroy(Ainv);
        }

    } else {
Beispiel #6
0
// correspondences is a list of float[4]s, consisting of the points x
// and y concatenated. We will compute a homography such that y = Hx
matd_t *homography_compute(zarray_t *correspondences)
{
    // compute centroids of both sets of points (yields a better
    // conditioned information matrix)
    double x_cx = 0, x_cy = 0;
    double y_cx = 0, y_cy = 0;

    for (int i = 0; i < zarray_size(correspondences); i++) {
        float *c;
        zarray_get_volatile(correspondences, i, &c);

        x_cx += c[0];
        x_cy += c[1];
        y_cx += c[2];
        y_cy += c[3];
    }

    int sz = zarray_size(correspondences);
    x_cx /= sz;
    x_cy /= sz;
    y_cx /= sz;
    y_cy /= sz;

    // NB We don't normalize scale; it seems implausible that it could
    // possibly make any difference given the dynamic range of IEEE
    // doubles.

    matd_t *A = matd_create(9,9);
    for (int i = 0; i < zarray_size(correspondences); i++) {
        float *c;
        zarray_get_volatile(correspondences, i, &c);

        // (below world is "x", and image is "y")
        double worldx = c[0] - x_cx;
        double worldy = c[1] - x_cy;
        double imagex = c[2] - y_cx;
        double imagey = c[3] - y_cy;

        double a03 = -worldx;
        double a04 = -worldy;
        double a05 = -1;
        double a06 = worldx*imagey;
        double a07 = worldy*imagey;
        double a08 = imagey;

        MATD_EL(A, 3, 3) += a03*a03;
        MATD_EL(A, 3, 4) += a03*a04;
        MATD_EL(A, 3, 5) += a03*a05;
        MATD_EL(A, 3, 6) += a03*a06;
        MATD_EL(A, 3, 7) += a03*a07;
        MATD_EL(A, 3, 8) += a03*a08;
        MATD_EL(A, 4, 4) += a04*a04;
        MATD_EL(A, 4, 5) += a04*a05;
        MATD_EL(A, 4, 6) += a04*a06;
        MATD_EL(A, 4, 7) += a04*a07;
        MATD_EL(A, 4, 8) += a04*a08;
        MATD_EL(A, 5, 5) += a05*a05;
        MATD_EL(A, 5, 6) += a05*a06;
        MATD_EL(A, 5, 7) += a05*a07;
        MATD_EL(A, 5, 8) += a05*a08;
        MATD_EL(A, 6, 6) += a06*a06;
        MATD_EL(A, 6, 7) += a06*a07;
        MATD_EL(A, 6, 8) += a06*a08;
        MATD_EL(A, 7, 7) += a07*a07;
        MATD_EL(A, 7, 8) += a07*a08;
        MATD_EL(A, 8, 8) += a08*a08;

        double a10 = worldx;
        double a11 = worldy;
        double a12 = 1;
        double a16 = -worldx*imagex;
        double a17 = -worldy*imagex;
        double a18 = -imagex;

        MATD_EL(A, 0, 0) += a10*a10;
        MATD_EL(A, 0, 1) += a10*a11;
        MATD_EL(A, 0, 2) += a10*a12;
        MATD_EL(A, 0, 6) += a10*a16;
        MATD_EL(A, 0, 7) += a10*a17;
        MATD_EL(A, 0, 8) += a10*a18;
        MATD_EL(A, 1, 1) += a11*a11;
        MATD_EL(A, 1, 2) += a11*a12;
        MATD_EL(A, 1, 6) += a11*a16;
        MATD_EL(A, 1, 7) += a11*a17;
        MATD_EL(A, 1, 8) += a11*a18;
        MATD_EL(A, 2, 2) += a12*a12;
        MATD_EL(A, 2, 6) += a12*a16;
        MATD_EL(A, 2, 7) += a12*a17;
        MATD_EL(A, 2, 8) += a12*a18;
        MATD_EL(A, 6, 6) += a16*a16;
        MATD_EL(A, 6, 7) += a16*a17;
        MATD_EL(A, 6, 8) += a16*a18;
        MATD_EL(A, 7, 7) += a17*a17;
        MATD_EL(A, 7, 8) += a17*a18;
        MATD_EL(A, 8, 8) += a18*a18;

        double a20 = -worldx*imagey;
        double a21 = -worldy*imagey;
        double a22 = -imagey;
        double a23 = worldx*imagex;
        double a24 = worldy*imagex;
        double a25 = imagex;

        MATD_EL(A, 0, 0) += a20*a20;
        MATD_EL(A, 0, 1) += a20*a21;
        MATD_EL(A, 0, 2) += a20*a22;
        MATD_EL(A, 0, 3) += a20*a23;
        MATD_EL(A, 0, 4) += a20*a24;
        MATD_EL(A, 0, 5) += a20*a25;
        MATD_EL(A, 1, 1) += a21*a21;
        MATD_EL(A, 1, 2) += a21*a22;
        MATD_EL(A, 1, 3) += a21*a23;
        MATD_EL(A, 1, 4) += a21*a24;
        MATD_EL(A, 1, 5) += a21*a25;
        MATD_EL(A, 2, 2) += a22*a22;
        MATD_EL(A, 2, 3) += a22*a23;
        MATD_EL(A, 2, 4) += a22*a24;
        MATD_EL(A, 2, 5) += a22*a25;
        MATD_EL(A, 3, 3) += a23*a23;
        MATD_EL(A, 3, 4) += a23*a24;
        MATD_EL(A, 3, 5) += a23*a25;
        MATD_EL(A, 4, 4) += a24*a24;
        MATD_EL(A, 4, 5) += a24*a25;
        MATD_EL(A, 5, 5) += a25*a25;
    }

    // make symmetric
    for (int i = 0; i < 9; i++)
        for (int j = i+1; j < 9; j++)
            MATD_EL(A, j, i) = MATD_EL(A, i, j);

    matd_svd_t svd = matd_svd(A);
    
    matd_t *Ainv = matd_inverse(A);

    double scale = 0;
    for (int i = 0; i < 9; i++)
        scale += sq(MATD_EL(Ainv, i, 0));
    scale = sqrt(scale);

    if (1) {
        // compute singular vector using SVD. A bit slower, but more accurate.
        matd_svd_t svd = matd_svd(A);

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                // MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0)/ scale;
                MATD_EL(H, i, j) = MATD_EL(svd.U, 3*i+j, 8);

        matd_destroy(svd.U);
        matd_destroy(svd.S);
        matd_destroy(svd.V);

    } else {
        // compute singular vector by (carefully) inverting the rank-deficient matrix.
        matd_t *Ainv = matd_inverse(A);
        double scale = 0;
        for (int i = 0; i < 9; i++)
            scale += sq(MATD_EL(Ainv, i, 0));
        scale = sqrt(scale);

        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                MATD_EL(H, i, j) = MATD_EL(Ainv, 3*i+j, 0)/ scale;

        matd_destroy(Ainv);
    }

    
    matd_t *Tx = matd_identity(3);
    MATD_EL(Tx,0,2) = -x_cx;
    MATD_EL(Tx,1,2) = -x_cy;

    matd_t *Ty = matd_identity(3);
    MATD_EL(Ty,0,2) = y_cx;
    MATD_EL(Ty,1,2) = y_cy;

    matd_t *H2 = matd_op("M*M*M", Ty, H, Tx);

    matd_destroy(A);
    matd_destroy(Tx);
    matd_destroy(Ty);
    matd_destroy(H);

    matd_destroy(svd.U);
    matd_destroy(svd.S);
    matd_destroy(svd.V);

    return H2;
}
BoundingBox::~BoundingBox() {
	matd_destroy(this->pos);
	matd_destroy(this->ux);
	matd_destroy(this->uy);
	matd_destroy(this->uz);
}
bool BoundingBox::intersect(BoundingBox *b) {
	double checkL, sum;
	BoundingBox *a = this;
	matd_t *cross;
	matd_t *T = matd_subtract(b->pos, a->pos);

	// Case 1
	checkL = fabs(matd_vec_dot_product(T, a->ux));
	sum = a->hW;
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->uz));

	if (checkL > sum) {
	    //printf("Axis found, case 1\n");
		return false;
	}
	//printf("1 - checkL %f, sum %f\n", checkL, sum);

	// Case 2
	checkL = fabs(matd_vec_dot_product(T, a->uy));
	sum = a->hH;
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->uz));

	if (checkL > sum) {
	    //printf("Axis found, case 2\n");
		return false;
	}
	//printf("2 - checkL %f, sum %f\n", checkL, sum);

	// Case 3
	checkL = fabs(matd_vec_dot_product(T, a->uz));
	sum = a->hD;
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->uz));

	if (checkL > sum) {
    	//printf("Axis found, case 3\n");
		return false;
	}
	//printf("3 - checkL %f, sum %f\n", checkL, sum);

	// Case 4
	checkL = fabs(matd_vec_dot_product(T, b->ux));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->ux));
	sum += b->hW;

	if (checkL > sum) {
	    //printf("Axis found, case 4\n");
		return false;
	}
	//printf("4 - checkL %f, sum %f\n", checkL, sum);

	// Case 5
	checkL = fabs(matd_vec_dot_product(T, b->uy));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->uy));
	sum += b->hH;

	if (checkL > sum) {
	    //printf("Axis found, case 5\n");
		return false;
	}
	//printf("5 - checkL %f, sum %f\n", checkL, sum);

	// Case 6
	checkL = fabs(matd_vec_dot_product(T, b->uz));
	sum = fabs(a->hW*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(a->hH*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->uz, b->uz));
	sum += b->hD;
	
	if (checkL > sum) {
	    //printf("Axis found, case 6\n");
		return false;
	}
	//printf("6 - checkL %f, sum %f\n", checkL, sum);

	// Case 7
	cross = matd_crossproduct(a->ux, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 7\n");
		return false;
	}
	//printf("7 - checkL %f, sum %f\n", checkL, sum);

	// Case 8
	cross = matd_crossproduct(a->ux, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->ux, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 8\n");
		return false;
	}
	//printf("8 - checkL %f, sum %f\n", checkL, sum);

	// Case 9
	cross = matd_crossproduct(a->ux, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hH*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->ux, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 9\n");
		return false;
	}
	//printf("9 - checkL %f, sum %f\n", checkL, sum);

	// Case 10
	cross = matd_crossproduct(a->uy, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->ux));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 10\n");
		return false;
	}
	//printf("10 - checkL %f, sum %f\n", checkL, sum);

	// Case 11
	cross = matd_crossproduct(a->uy, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uy, b->ux));
	matd_destroy(cross);
	
	if (checkL > sum) {
	    //printf("Axis found, case 11\n");
		return false;
	}
	//printf("11 - checkL %f, sum %f\n", checkL, sum);

	// Case 12
	cross = matd_crossproduct(a->uy, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(a->hD*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->uy, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 12\n");
		return false;
	}
	//printf("12 - checkL %f, sum %f\n", checkL, sum);

	// Case 13
	cross = matd_crossproduct(a->uz, b->ux);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->ux));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->ux));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->uy));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 13\n");
		return false;
	}
	//printf("13 - checkL %f, sum %f\n", checkL, sum);

	// Case 14
	cross = matd_crossproduct(a->uz, b->uy);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->uy));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->uy));
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->uz));
	sum += fabs(b->hD*matd_vec_dot_product(a->uz, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 14\n");
		return false;
	}
	//printf("14 - checkL %f, sum %f\n", checkL, sum);

	// Case 15
	cross = matd_crossproduct(a->uz, b->uz);
	checkL = fabs(matd_vec_dot_product(T, cross));
	sum = fabs(a->hW*matd_vec_dot_product(a->uy, b->uz));
	sum += fabs(a->hH*matd_vec_dot_product(a->ux, b->uz));
	sum += fabs(b->hW*matd_vec_dot_product(a->uz, b->uy));
	sum += fabs(b->hH*matd_vec_dot_product(a->uz, b->ux));
	matd_destroy(cross);

	if (checkL > sum) {
	    //printf("Axis found, case 15\n");
		return false;
	}
	//printf("15 - checkL %f, sum %f\n", checkL, sum);

	matd_destroy(T);
	return true;
}
Beispiel #9
0
void * camera_loop(void * data)
{
    state_t * state = data;

    sleep(2); // wait for 2 seconds before starting the animation

    matd_t * zaxis = matd_create(3,1);
    zaxis->data[2] = 1;

    vx_buffer_add_back(vx_world_get_buffer(state->world, "cam-circle"), vxo_chain(vxo_mat_scale(CAM_RADIUS),
                       vxo_circle(vxo_lines_style(vx_green, 3))));
    vx_buffer_swap(vx_world_get_buffer(state->world, "cam-circle"));


    int64_t start_mtime =  vx_util_mtime();
    // tell each layer to follow
    pthread_mutex_lock(&state->mutex);
    {
        zhash_iterator_t itr;
        zhash_iterator_init(state->layers, &itr);
        vx_display_t * key;
        vx_layer_t * vl;

        while(zhash_iterator_next(&itr, &key, &vl)) {
            if (1) {
                float eye3[] = {CAM_RADIUS,-CAM_RADIUS,45.0f};
                float lookat3[] = {CAM_RADIUS,0,0.0f};
                float up3[] = {0,1,0};
                vx_layer_camera_lookat(vl, eye3, lookat3, up3, 0);
            }
        }
    }
    pthread_mutex_unlock(&state->mutex);

    while (state->running) {
        // 5 seconds revolutions
        double rad = ( (vx_util_mtime() - start_mtime) % 5000) * 2* M_PI / 5e3;

        // compute the current position and orientation of the "robot"
        matd_t * orientation = matd_angle_axis_to_quat(rad, zaxis);
        matd_t * pos =  matd_create(3,1);
        pos->data[0] = cos(rad) * CAM_RADIUS;
        pos->data[1] = sin(rad) * CAM_RADIUS;

        // tell each layer to follow
        pthread_mutex_lock(&state->mutex);
        {
            zhash_iterator_t itr;
            zhash_iterator_init(state->layers, &itr);
            vx_display_t * key;
            vx_layer_t * vl;

            while(zhash_iterator_next(&itr, &key, &vl)) {
                vx_layer_camera_follow(vl, pos->data, orientation->data, 1);
            }
        }
        pthread_mutex_unlock(&state->mutex);


        vx_buffer_add_back(vx_world_get_buffer(state->world, "robot-proxy"),
                           vxo_chain(vxo_mat_quat_pos(orientation->data, pos->data),
                                     vxo_box(vxo_lines_style(vx_purple, 3))));
        vx_buffer_swap(vx_world_get_buffer(state->world, "robot-proxy"));


        matd_destroy(orientation);
        matd_destroy(pos);

        usleep(100000);
    }

    matd_destroy(zaxis);

    return NULL;
}
void body_getServoAngles(Body *body, double servoAngles[], bool right_side) {
	matd_t* floor_shoulder;
	matd_t* shoulder_elbow;
	matd_t* shoulder_elbow0;
	matd_t* shoulder_elbow1;
	matd_t* elbow_wrist;
	joint_t shoulder, elbow, wrist;

	if(right_side){
		//use right side of body
		shoulder = body->getJoint(RSHOULDER);
		elbow = body->getJoint(RELBOW);
		wrist = body->getJoint(RWRIST);
	}else{
		//use left side of body
		shoulder = body->getJoint(LSHOULDER);
		elbow = body->getJoint(LELBOW);
		wrist = body->getJoint(LWRIST);
	}

	double floor_shoulder_data[3] = {
		0, shoulder.y, 0};

	double shoulder_elbow_data[3] = {
		elbow.x - shoulder.x,
		elbow.y - shoulder.y,
		elbow.z - shoulder.z};

	//Shoulder rotation in the yz plane (forward/backward)
	double shoulder_elbow_data0[3] = {
		0,
		elbow.y - shoulder.y,
		elbow.z - shoulder.z}; 

	//Shoulder rotation in the xy plane (left/right)
	double shoulder_elbow_data1[3] = {
		elbow.x - shoulder.x,
		elbow.y - shoulder.y,
		0};

	double elbow_wrist_data[3] = {
		wrist.x - elbow.x,
		wrist.y - elbow.y,
		wrist.z - elbow.z};

	floor_shoulder = matd_create_data(3, 1, floor_shoulder_data);
	shoulder_elbow = matd_create_data(3, 1, shoulder_elbow_data);
	//shoulder_elbow0 = matd_create_data(3, 1, shoulder_elbow_data0);
	shoulder_elbow1 = matd_create_data(3, 1, shoulder_elbow_data1);
	elbow_wrist = matd_create_data(3, 1, elbow_wrist_data);

	double magfs = matd_vec_mag(floor_shoulder);
	double magse = matd_vec_mag(shoulder_elbow);
	//double magse0 = matd_vec_mag(shoulder_elbow0);
	double magse1 = matd_vec_mag(shoulder_elbow1);
	double magew = matd_vec_mag(elbow_wrist);
	
	//double shoulderValue0 = matd_vec_dot_product(floor_shoulder, shoulder_elbow0) / (magfs * magse0);
	double shoulderValue1 = matd_vec_dot_product(floor_shoulder, shoulder_elbow1) / (magfs * magse1);
	double elbowValue = matd_vec_dot_product(shoulder_elbow, elbow_wrist) / (magse * magew);

	//printf("Elbow: %g\n", elbowValue);

	//double shoulderAngle0 = (acos(shoulderValue0));
	double shoulderAngle1 = sgn(elbow.y - shoulder.y)*(acos(shoulderValue1) - M_PI/2);
	double elbowAngle = acos(elbowValue);

	/*if (elbow.z - shoulder.z < 0) {
		shoulderAngle0 = M_PI - shoulderAngle0;
	} else {
		shoulderAngle0 = shoulderAngle0 - M_PI;
	}*/

	if (elbow.y < shoulder.y) {
		shoulderAngle1 = -shoulderAngle1;
	}

	double unitZ_data[3] = {0, 0, 1};
	matd_t *unitZ = matd_create_data(3, 1, unitZ_data);
	matd_t *elbowCheck = matd_crossproduct(elbow_wrist, shoulder_elbow);
	double elbowSign = sgn(matd_vec_dot_product(elbowCheck, unitZ));

	matd_destroy(unitZ);
	matd_destroy(elbowCheck);

	servoAngles[1] = shoulderAngle1;
	servoAngles[2] = elbowSign*elbowAngle;

	//printf("shoulder - %f, elbow - %f\n", servoAngles[1], servoAngles[2]);

	matd_destroy(floor_shoulder);
	matd_destroy(shoulder_elbow);
	//matd_destroy(shoulder_elbow0);
	matd_destroy(shoulder_elbow1);
	matd_destroy(elbow_wrist);
}