void BlockLocalPositionEstimator::publishLocalPos()
{
	const Vector<float, n_x> &xLP = _xLowPass.getState();

	// publish local position
	if (PX4_ISFINITE(_x(X_x)) && PX4_ISFINITE(_x(X_y)) && PX4_ISFINITE(_x(X_z)) &&
	    PX4_ISFINITE(_x(X_vx)) && PX4_ISFINITE(_x(X_vy))
	    && PX4_ISFINITE(_x(X_vz))) {
		_pub_lpos.get().timestamp = _timeStamp;
		_pub_lpos.get().xy_valid = _validXY;
		_pub_lpos.get().z_valid = _validZ;
		_pub_lpos.get().v_xy_valid = _validXY;
		_pub_lpos.get().v_z_valid = _validZ;
		_pub_lpos.get().x = xLP(X_x); 	// north
		_pub_lpos.get().y = xLP(X_y);  	// east
		_pub_lpos.get().z = xLP(X_z); 	// down
		_pub_lpos.get().vx = xLP(X_vx); // north
		_pub_lpos.get().vy = xLP(X_vy); // east
		_pub_lpos.get().vz = xLP(X_vz); // down
		_pub_lpos.get().yaw = _sub_att.get().yaw;
		_pub_lpos.get().xy_global = _sub_home.get().timestamp != 0; // need home for reference
		_pub_lpos.get().z_global = _baroInitialized;
		_pub_lpos.get().ref_timestamp = _sub_home.get().timestamp;
		_pub_lpos.get().ref_lat = _map_ref.lat_rad * 180 / M_PI;
		_pub_lpos.get().ref_lon = _map_ref.lon_rad * 180 / M_PI;
		_pub_lpos.get().ref_alt = _sub_home.get().alt;
		_pub_lpos.get().dist_bottom = agl();
		_pub_lpos.get().dist_bottom_rate = - xLP(X_vz);
		_pub_lpos.get().surface_bottom_timestamp = _timeStamp;
		_pub_lpos.get().dist_bottom_valid = _validTZ && _validZ;
		_pub_lpos.get().eph = sqrtf(_P(X_x, X_x) + _P(X_y, X_y));
		_pub_lpos.get().epv = sqrtf(_P(X_z, X_z));
		_pub_lpos.update();
	}
}
void BlockLocalPositionEstimator::predict()
{
	// if can't update anything, don't propagate
	// state or covariance
	if (!_validXY && !_validZ) { return; }

	if (integrate) {
		matrix::Quaternion<float> q(&_sub_att.get().q[0]);
		_eul = matrix::Euler<float>(q);
		_R_att = matrix::Dcm<float>(q);
		Vector3f a(_sub_sensor.get().accelerometer_m_s2);
		// note, bias is removed in dynamics function
		_u = _R_att * a;
		_u(U_az) += 9.81f; // add g

	} else {
		_u = Vector3f(0, 0, 0);
	}

	// update state space based on new states
	updateSSStates();

	// continuous time kalman filter prediction
	// integrate runge kutta 4th order
	// TODO move rk4 algorithm to matrixlib
	// https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
	float h = getDt();
	Vector<float, n_x> k1, k2, k3, k4;
	k1 = dynamics(0, _x, _u);
	k2 = dynamics(h / 2, _x + k1 * h / 2, _u);
	k3 = dynamics(h / 2, _x + k2 * h / 2, _u);
	k4 = dynamics(h, _x + k3 * h, _u);
	Vector<float, n_x> dx = (k1 + k2 * 2 + k3 * 2 + k4) * (h / 6);

	// propagate
	correctionLogic(dx);
	_x += dx;
	Matrix<float, n_x, n_x> dP = (_A * _P + _P * _A.transpose() +
				      _B * _R * _B.transpose() + _Q) * getDt();
	covPropagationLogic(dP);
	_P += dP;

	_xLowPass.update(_x);
	_aglLowPass.update(agl());
}
Ejemplo n.º 3
0
int BlockLocalPositionEstimator::flowMeasure(Vector<float, n_y_flow> &y)
{
	// check for agl
	if (agl() < flow_min_agl) {
		return -1;
	}

	// check quality
	float qual = _sub_flow.get().quality;

	if (qual < _flow_min_q.get()) {
		return -1;
	}

	// calculate range to center of image for flow
	if (!_validTZ) {
		return -1;
	}

	float d = agl() * cosf(_sub_att.get().roll) * cosf(_sub_att.get().pitch);

	// check for global accuracy
	if (_gpsInitialized) {
		double  lat = _sub_gps.get().lat * 1.0e-7;
		double  lon = _sub_gps.get().lon * 1.0e-7;
		float px = 0;
		float py = 0;
		map_projection_project(&_map_ref, lat, lon, &px, &py);
		Vector2f delta(px - _flowX, py - _flowY);

		if (delta.norm() > 3) {
			mavlink_and_console_log_info(&mavlink_log_pub,
						     "[lpe] flow too far from GPS, resetting position");
			_flowX = px;
			_flowY = py;
			return -1;
		}
	}

	// optical flow in x, y axis
	float flow_x_rad = _sub_flow.get().pixel_flow_x_integral;
	float flow_y_rad = _sub_flow.get().pixel_flow_y_integral;

	// angular rotation in x, y axis
	float gyro_x_rad = _flow_gyro_x_high_pass.update(
				   _sub_flow.get().gyro_x_rate_integral);
	float gyro_y_rad = _flow_gyro_y_high_pass.update(
				   _sub_flow.get().gyro_y_rate_integral);

	//warnx("flow x: %10.4f y: %10.4f gyro_x: %10.4f gyro_y: %10.4f d: %10.4f",
	//double(flow_x_rad), double(flow_y_rad), double(gyro_x_rad), double(gyro_y_rad), double(d));

	// compute velocities in camera frame using ground distance
	// assume camera frame is body frame
	Vector3f delta_b(
		-(flow_x_rad - gyro_x_rad)*d,
		-(flow_y_rad - gyro_y_rad)*d,
		0);

	// rotation of flow from body to nav frame
	Matrix3f R_nb(_sub_att.get().R);
	Vector3f delta_n = R_nb * delta_b;

	// flow integration
	_flowX += delta_n(0);
	_flowY += delta_n(1);

	// measurement
	y(Y_flow_x) = _flowX;
	y(Y_flow_y) = _flowY;

	_flowQStats.update(Scalarf(_sub_flow.get().quality));

	// imporant to timestamp flow even if distance is bad
	_time_last_flow = _timeStamp;

	return OK;
}
Ejemplo n.º 4
0
void BlockLocalPositionEstimator::flowCorrect()
{
	// measure flow
	Vector<float, n_y_flow> y;

	if (flowMeasure(y) != OK) { return; }

	// flow measurement matrix and noise matrix
	Matrix<float, n_y_flow, n_x> C;
	C.setZero();
	C(Y_flow_x, X_x) = 1;
	C(Y_flow_y, X_y) = 1;

	SquareMatrix<float, n_y_flow> R;
	R.setZero();
	float d = agl() * cosf(_sub_att.get().roll) * cosf(_sub_att.get().pitch);
	float flow_xy_stddev = _flow_xy_stddev.get() + _flow_xy_d_stddev.get() * d ;
	R(Y_flow_x, Y_flow_x) = flow_xy_stddev * flow_xy_stddev;
	R(Y_flow_y, Y_flow_y) = R(Y_flow_x, Y_flow_x);

	// residual
	Vector<float, 2> r = y - C * _x;
	_pub_innov.get().flow_innov[0] = r(0);
	_pub_innov.get().flow_innov[1] = r(1);
	_pub_innov.get().flow_innov_var[0] = R(0, 0);
	_pub_innov.get().flow_innov_var[1] = R(1, 1);

	// residual covariance, (inverse)
	Matrix<float, n_y_flow, n_y_flow> S_I =
		inv<float, n_y_flow>(C * _P * C.transpose() + R);

	// fault detection
	float beta = (r.transpose() * (S_I * r))(0, 0);

	if (beta > BETA_TABLE[n_y_flow]) {
		if (_flowFault < FAULT_MINOR) {
			//mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] flow fault,  beta %5.2f", double(beta));
			_flowFault = FAULT_MINOR;
		}

	} else if (_flowFault) {
		_flowFault = FAULT_NONE;
		//mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] flow OK");
	}

	if (_flowFault < fault_lvl_disable) {
		Matrix<float, n_x, n_y_flow> K =
			_P * C.transpose() * S_I;
		Vector<float, n_x> dx = K * r;
		correctionLogic(dx);
		_x += dx;
		_P -= K * C * _P;

	} else {
		// reset flow integral to current estimate of position
		// if a fault occurred
		_flowX = _x(X_x);
		_flowY = _x(X_y);
	}

}
Ejemplo n.º 5
0
/*This function computes the agl in num_wave directions*/
void mexFunction(int nlhs, mxArray *plhs[], /* Output variables */
                 int nrhs, const mxArray *prhs[]) /* Input variables */
{
#define agl(ai,bi,j) agl[ai+dims[0]*(bi+dims[1]*j)]
#define R(ai,bi,j) R[ai+dims[0]*(bi+dims[1]*j)]
#define TTEng_1st(ai,bi,j) TTEng_1st[ai+dims[0]*(bi+dims[1]*j)]
#define TTEng_2nd(ai,bi,j) TTEng_2nd[ai+dims[0]*(bi+dims[1]*j)]
#define W_sec(ai,bi,j) W_sec[ai+dims[0]*(bi+dims[1]*j)]
#define ss_energy(ci,di,ai,bi) ss_energy[ci+Nss[0]*(di+Nss[1]*(ai+Nss[2]*bi))]
#define ss_avgdx(ci,di,ai,bi) ss_avgdx[ci+Nss[0]*(di+Nss[1]*(ai+Nss[2]*bi))]
#define ss_avgdy(ci,di,ai,bi) ss_avgdy[ci+Nss[0]*(di+Nss[1]*(ai+Nss[2]*bi))]
#define aglPos(ai,bi) aglPos[ai+bi*Nss[2]]
#define checktemp2(di,ai,bi) checktemp2[di+dims2[0]*(ai+dims2[1]*bi)]
    /* #define agl2(ai,bi,j) agl2[ai+dims[0]*(bi+dims[1]*j)]
     #define R2(ai,bi,j) R2[ai+dims[0]*(bi+dims[1]*j)] */
#define pi 3.141592653589793
    
    size_t ai, bi, ci, k, j;
    int di,cnt2,cnt;
    int num_wave, pos_temp;
    double *ss_energy, *ss_avgdx, *ss_avgdy, *agl, *R, *TTEng_1st, *TTEng_2nd, *W_sec, *aglPos, *checktemp2; /* R2, agl2 */
    double temp_avgdx, temp_avgdy, sumEng;
    ss_energy = mxGetPr(prhs[0]);
    const mwSize *Nss = mxGetDimensions(prhs[0]);
    ss_avgdx = mxGetPr(prhs[1]);
    ss_avgdy = mxGetPr(prhs[2]);
    num_wave = mxGetScalar(prhs[3]);
    aglPos = mxGetPr(prhs[4]);
    nrhs = 5;
    
    nlhs = 6;
    int ndim = 3, dims[3] = {Nss[2],Nss[3],num_wave}, numm = (int)Nss[1]/num_wave/8, numm_R = (int)floor(Nss[0]/4.0);
    int LL = (int)Nss[1]/num_wave/4;
    plhs[0] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[1] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[2] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[3] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[4] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    /* plhs[5] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL); */
    /* plhs[6] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL); */
    agl = mxGetPr(plhs[0]);
    R = mxGetPr(plhs[1]);
    TTEng_1st = mxGetPr(plhs[2]);
    TTEng_2nd = mxGetPr(plhs[3]);
    W_sec = mxGetPr(plhs[4]);
    /* agl2 = mxGetPr(plhs[5]); */
    /* R2 = mxGetPr(plhs[6]); */
    int dims2[3] = {Nss[1],Nss[2],Nss[3]};
    plhs[5] = mxCreateNumericArray(ndim,dims2,mxDOUBLE_CLASS,mxREAL);
    checktemp2 = mxGetPr(plhs[5]);
    
    int L = ceil(1.0*Nss[1]/num_wave), maxpos, st, ed, stR, edR, moveStep, pos, sgn, temp_di, markPos;
    double *temp, energy_sum, *temp_R, *temp2, *tempss, tpR;
    temp = (double *)mxMalloc(sizeof(double)*L);
    temp2 = (double *)mxMalloc(sizeof(double)*Nss[1]);
    tempss = (double *)mxMalloc(sizeof(double)*Nss[1]);
    temp_R = (double *)mxMalloc(sizeof(double)*Nss[0]);
    
    for (ai=0;ai<Nss[2];ai++) {
        for (bi=0;bi<Nss[3];bi++) {
            /*compute tempss*/
            for (di=0;di<Nss[1];di++){
                temp2[di] = 0;
            }
            for (cnt=0;cnt<num_wave;cnt++) {
                for (cnt2=-LL+1;cnt2<LL;cnt2++){
                    di = cnt2 + aglPos(ai,bi) + cnt*L;
                    if (di<0) {
                        di = di + Nss[1];
                    }else if (di>=Nss[1]) {
                        di = di - Nss[1];
                    }
                    /*mexPrintf("%d  %f  %d  %d  %d  %d\n",di,aglPos(ai,bi),LL,L,cnt,cnt2);*/
                    /*for (di=0;di<Nss[1];di++) {*/
                    for (ci=0;ci<Nss[0];ci++) {
                        if (ci==0)
                            temp2[di] = ss_energy(ci,di,ai,bi);
                        else
                            temp2[di] = temp2[di] + ss_energy(ci,di,ai,bi);
                    }
                }
            }
            for (di=0;di<Nss[1];di++)
                checktemp2(di,ai,bi) = temp2[di];
            /*mexPrintf("(%d,%f)  %f\n",LL,aglPos(ai,bi),aglPos[0]);*/
            moveStep = floor(L/4.0);
            /*maxpos = fmod(findmax(temp2,Nss[1]),L);*/
            maxpos = findmax(temp2,Nss[1]);
            markPos = floor(1.0*maxpos/L);
            maxpos = maxpos - markPos*L;
            moveStep = floor(maxpos-L/2.0);
            if (moveStep>=0) {
                sgn = 1;
                for (cnt=0;cnt<Nss[1]-moveStep;cnt++) {
                    tempss[cnt] = temp2[cnt+moveStep];
                }
                for (cnt=Nss[1]-moveStep;cnt<Nss[1];cnt++) {
                    tempss[cnt] = temp2[cnt -(Nss[1]-moveStep)];
                }            }
            if (moveStep<0) {
                moveStep = -moveStep;
                sgn = -1;
                for (cnt = 0; cnt < Nss[1]-moveStep; cnt++) {
                    tempss[cnt+moveStep] = temp2[cnt];
                }
                for (cnt = Nss[1]-moveStep; cnt < Nss[1]; cnt++) {
                    tempss[cnt-(Nss[1]-moveStep)] = temp2[cnt];
                }            }
            for (j=0;j<num_wave;j++) {
                for (cnt=0;cnt<L;cnt++) {
                    W_sec(ai,bi,j) = W_sec(ai,bi,j) + tempss[cnt+j*L];
                }
            }
            /*tempss[:] computed*/
            for (j=0;j<num_wave;j++) {
                maxpos = findmax2(tempss,j*L,L);
                ed = maxpos;
                cnt = 1;
                while (ed<Nss[1]-1 & cnt==1 & tempss[ed+1]>0 & ed-maxpos < numm) {
                    if (tempss[ed]>=tempss[ed+1])
                        ed++;
                    else
                        cnt = 0;
                }
                st = maxpos;
                cnt = 1;
                while (st>0 & cnt == 1 & tempss[st-1]>0 & maxpos-st < numm) {
                    if (tempss[st] >= tempss[st-1])
                        st--;
                    else
                        cnt = 0;
                }
                energy_sum = 0;
                for (cnt = st; cnt <= ed; cnt++)
                    energy_sum = energy_sum + tempss[cnt];
                /*compute TTEng_1st(ai,bi,j)*/
                TTEng_1st(ai,bi,j) = energy_sum;
                
                /* /\*compute agl(ai,bi,j)*\/ */
                for (cnt = st; cnt <= ed; cnt++) {
                    /*     agl(ai,bi,j) = agl(ai,bi,j) + tempss[cnt]*cnt/energy_sum; */
                    tempss[cnt] = 0;
                }
                /* agl(ai,bi,j) = agl(ai,bi,j) + sgn*moveStep; */
                /*compute R(ai,bi,j)*/
                /* change (st,ed) back to original coordinate */
                st = st + sgn*moveStep;
                if (st>=Nss[1]) {
                    st = st - Nss[1];
                }
                else {
                    if (st<0){
                        st = st + Nss[1];
                    }
                }
                ed = ed + sgn*moveStep;
                if (ed>=Nss[1]) {
                    ed = ed - Nss[1];
                }
                else {
                    if (ed<0){
                        ed = ed + Nss[1];
                    }
                }
                int st_agl = st;
                int ed_agl = ed;
                /*compute R*/
                /*compute temp_R*/
                if (1) {
                    if (st<=ed) {
                        for (di=st;di<=ed;di++) {
                            for (ci = 0;ci<Nss[0];ci++) {
                                if (di==st) {
                                    temp_R[ci] = ss_energy(ci,di,ai,bi);
                                }
                                else
                                    temp_R[ci] = temp_R[ci] + ss_energy(ci,di,ai,bi);
                            }
                        }
                        maxpos = findmax(temp_R,Nss[0]);
                        ed = maxpos;
                        cnt = 1;
                        while (ed<Nss[0]-1 & cnt==1 & temp_R[ed+1]>0 & ed-maxpos < numm_R) {
                            if (temp_R[ed]>=temp_R[ed+1]) {
                                ed++;
                            }
                            else
                                cnt = 0;
                        }
                        st = maxpos;
                        cnt = 1;
                        while (st>0 & cnt == 1 & temp_R[st-1]>0 & maxpos-st < numm_R) {
                            if (temp_R[st] >= temp_R[st-1]) {
                                st--;
                            }
                            else
                                cnt = 0;
                        }
                        
                        /*
                         energy_sum = 0;
                         for (cnt = st; cnt <= ed; cnt++) {
                         energy_sum = energy_sum + temp_R[cnt];
                         }
                         if (energy_sum>0) {
                         for (cnt = st; cnt <= ed; cnt++) {
                         R(ai,bi,j) = R(ai,bi,j) + temp_R[cnt]*(cnt)/energy_sum;
                         }
                         } */
                        sumEng = 0;
                        temp_avgdx = 0; temp_avgdy = 0;
                        for (di=st_agl;di<=ed_agl;di++) {
                            for (ci=st;ci<=ed;ci++) {
                                temp_avgdx += ss_avgdx(ci,di,ai,bi);
                                temp_avgdy += ss_avgdy(ci,di,ai,bi);
                                sumEng += ss_energy(ci,di,ai,bi);
                            }
                        }
                        if (sumEng==0) {
                            agl(ai,bi,j) = 0;
                            R(ai,bi,j) = 0;
                            /*mexPrintf("%f %f, ",sumEng,TTEng_1st(ai,bi,j));*/
                        }else {
                            
                            temp_avgdx /= sumEng;
                            temp_avgdy /= sumEng;
                            R(ai,bi,j) = sqrt(temp_avgdx*temp_avgdx + temp_avgdy*temp_avgdy);
                            if (temp_avgdx>=0) {
                                agl(ai,bi,j) = acos(temp_avgdy/R(ai,bi,j));
                            }
                            else
                                agl(ai,bi,j) = pi - acos(temp_avgdy/R(ai,bi,j));
                        }
                    }
                    else {
                        ed = ed + Nss[1];
                        for (di=st;di<=ed;di++) {
                            for (ci = 0;ci<Nss[0];ci++) {
                                if (di==st) {
                                    temp_R[ci] = ss_energy(ci,di,ai,bi);
                                }
                                else {
                                    if (di>=Nss[1]) {
                                        temp_R[ci] = temp_R[ci] + ss_energy(ci,di-Nss[1],ai,bi);
                                    }
                                    else
                                        temp_R[ci] = temp_R[ci] + ss_energy(ci,di,ai,bi);
                                }
                            }
                        }
                        maxpos = findmax(temp_R,Nss[0]);
                        ed = maxpos;
                        cnt = 1;
                        while (ed<Nss[0]-1 & cnt==1 & temp_R[ed+1]>0 & ed-maxpos < numm_R) {
                            if (temp_R[ed]>=temp_R[ed+1]) {
                                ed++;
                            }
                            else
                                cnt = 0;
                        }
                        st = maxpos;
                        cnt = 1;
                        while (st>0 & cnt == 1 & temp_R[st-1]>0 & maxpos-st < numm_R) {
                            if (temp_R[st] >= temp_R[st-1]) {
                                st--;
                            }
                            else
                                cnt = 0;
                        }
                        /*
                         energy_sum = 0;
                         for (cnt = st; cnt <= ed; cnt++) {
                         energy_sum = energy_sum + temp_R[cnt];
                         }
                         if (energy_sum>0) {
                         for (cnt = st; cnt <= ed; cnt++) {
                         R(ai,bi,j) = R(ai,bi,j) + temp_R[cnt]*(cnt)/energy_sum;
                         }
                         } */
                        ed_agl = ed_agl + Nss[1];
                        sumEng = 0;
                        temp_avgdx = 0; temp_avgdy = 0;
                        
                        for (di=st_agl;di<=ed_agl;di++) {
                            if (di>=Nss[1]) {
                                for (ci=st;ci<=ed;ci++) {
                                    temp_avgdx -= ss_avgdx(ci,di-Nss[1],ai,bi); /* "-" due to shifting to negative half plane */
                                    temp_avgdy -= ss_avgdy(ci,di-Nss[1],ai,bi);
                                    sumEng += ss_energy(ci,di-Nss[1],ai,bi);
                                }
                            }
                            else {
                                for (ci=st;ci<=ed;ci++) {
                                    temp_avgdx += ss_avgdx(ci,di,ai,bi);
                                    temp_avgdy += ss_avgdy(ci,di,ai,bi);
                                    sumEng += ss_energy(ci,di,ai,bi);
                                }
                            }
                        }
                        if (sumEng==0) {
                            agl(ai,bi,j) = 0;
                            R(ai,bi,j) = 0;
                            /*mexPrintf("%f %f, ",sumEng,TTEng_1st(ai,bi,j));*/
                        }else {
                            
                            temp_avgdx /= sumEng;
                            temp_avgdy /= sumEng;
                            R(ai,bi,j) = sqrt(temp_avgdx*temp_avgdx + temp_avgdy*temp_avgdy);
                            if (temp_avgdx>=0) {
                                agl(ai,bi,j) = acos(temp_avgdy/R(ai,bi,j));
                            }
                            else
                                agl(ai,bi,j) = pi - acos(temp_avgdy/R(ai,bi,j));
                        }
                    }
                }
                /*compute TTEng_2nd(ai,bi,j)*/
                maxpos = findmax2(tempss,j*L,L);
                if (tempss[maxpos]>0) {
                    ed = maxpos;
                    cnt = 1;
                    while (ed<Nss[1]-1 & cnt==1 & tempss[ed+1]>0 & ed-maxpos < numm) {
                        if (tempss[ed]>=tempss[ed+1])
                            ed++;
                        else
                            cnt = 0;
                    }
                    st = maxpos;
                    cnt = 1;
                    while (st>0 & cnt == 1 & tempss[st-1]>0 & maxpos-st < numm) {
                        if (tempss[st] >= tempss[st-1])
                            st--;
                        else
                            cnt = 0;
                    }
                    energy_sum = 0;
                    for (cnt = st; cnt <= ed; cnt++)
                        energy_sum = energy_sum + tempss[cnt];
                    if (energy_sum<=TTEng_1st(ai,bi,j))
                        TTEng_2nd(ai,bi,j) = energy_sum;
                    else {
                        agl(ai,bi,j) = 0;
                        /* agl2(ai,bi,j) = 0;
                         for (cnt = st; cnt <= ed; cnt++)
                         agl(ai,bi,j) = agl(ai,bi,j) + tempss[cnt]*cnt/energy_sum;
                         agl(ai,bi,j) = agl(ai,bi,j) + sgn*moveStep; */
                        /*compute total energy*/
                        TTEng_2nd(ai,bi,j) = TTEng_1st(ai,bi,j);
                        TTEng_1st(ai,bi,j) = energy_sum;
                        
                        R(ai,bi,j) = 0;
                        /* R2(ai,bi,j) = 0; */
                        /*compute R(ai,bi,j)*/
                        st = st + sgn*moveStep;
                        if (st>=Nss[1]) {
                            st = st - Nss[1];
                        }
                        else {
                            if (st<0){
                                st = st + Nss[1];
                            }
                        }
                        ed = ed + sgn*moveStep;
                        if (ed>=Nss[1]) {
                            ed = ed - Nss[1];
                        }
                        else {
                            if (ed<0){
                                ed = ed + Nss[1];
                            }
                        }
                        int st_agl = st;
                        int ed_agl = ed;
                        /*compute R*/
                        /*compute temp_R*/
                        if (1) {
                            if (st<=ed) {
                                for (di=st;di<=ed;di++) {
                                    for (ci = 0;ci<Nss[0];ci++) {
                                        if (di==st) {
                                            temp_R[ci] = ss_energy(ci,di,ai,bi);
                                        }
                                        else
                                            temp_R[ci] = temp_R[ci] + ss_energy(ci,di,ai,bi);
                                    }
                                }
                                maxpos = findmax(temp_R,Nss[0]);
                                ed = maxpos;
                                cnt = 1;
                                while (ed<Nss[0]-1 & cnt==1 & temp_R[ed+1]>0 & ed-maxpos < numm_R) {
                                    if (temp_R[ed]>=temp_R[ed+1]) {
                                        ed++;
                                    }
                                    else
                                        cnt = 0;
                                }
                                st = maxpos;
                                cnt = 1;
                                while (st>0 & cnt == 1 & temp_R[st-1]>0 & maxpos-st < numm_R) {
                                    if (temp_R[st] >= temp_R[st-1]) {
                                        st--;
                                    }
                                    else
                                        cnt = 0;
                                }
                                /*
                                 energy_sum = 0;
                                 for (cnt = st; cnt <= ed; cnt++) {
                                 energy_sum = energy_sum + temp_R[cnt];
                                 }
                                 if (energy_sum>0) {
                                 for (cnt = st; cnt <= ed; cnt++) {
                                 R(ai,bi,j) = R(ai,bi,j) + temp_R[cnt]*(cnt)/energy_sum;
                                 }
                                 } */
                                sumEng = 0;
                                temp_avgdx = 0; temp_avgdy = 0;
                                
                                for (di=st_agl;di<=ed_agl;di++) {
                                    for (ci=st;ci<=ed;ci++) {
                                        temp_avgdx += ss_avgdx(ci,di,ai,bi);
                                        temp_avgdy += ss_avgdy(ci,di,ai,bi);
                                        sumEng += ss_energy(ci,di,ai,bi);
                                    }
                                }
                                temp_avgdx /= sumEng;
                                temp_avgdy /= sumEng;
                                
                                R(ai,bi,j) = sqrt(temp_avgdx*temp_avgdx + temp_avgdy*temp_avgdy);
                                if (temp_avgdx>=0) {
                                    agl(ai,bi,j) = acos(temp_avgdy/R(ai,bi,j));
                                }
                                else
                                    agl(ai,bi,j) = pi - acos(temp_avgdy/R(ai,bi,j));
                            }
                            else {
                                ed = ed + Nss[1];
                                for (di=st;di<=ed;di++) {
                                    for (ci = 0;ci<Nss[0];ci++) {
                                        if (di==st) {
                                            temp_R[ci] = ss_energy(ci,di,ai,bi);
                                        }
                                        else {
                                            if (di>=Nss[1]) {
                                                temp_R[ci] = temp_R[ci] + ss_energy(ci,di-Nss[1],ai,bi);
                                            }
                                            else
                                                temp_R[ci] = temp_R[ci] + ss_energy(ci,di,ai,bi);
                                        }
                                    }
                                }
                                maxpos = findmax(temp_R,Nss[0]);
                                ed = maxpos;
                                cnt = 1;
                                while (ed<Nss[0]-1 & cnt==1 & temp_R[ed+1]>0 & ed-maxpos < numm_R) {
                                    if (temp_R[ed]>=temp_R[ed+1]) {
                                        ed++;
                                    }
                                    else
                                        cnt = 0;
                                }
                                st = maxpos;
                                cnt = 1;
                                while (st>0 & cnt == 1 & temp_R[st-1]>0 & maxpos-st < numm_R) {
                                    if (temp_R[st] >= temp_R[st-1]) {
                                        st--;
                                    }
                                    else
                                        cnt = 0;
                                }
                                /*
                                 energy_sum = 0;
                                 for (cnt = st; cnt <= ed; cnt++) {
                                 energy_sum = energy_sum + temp_R[cnt];
                                 }
                                 if (energy_sum>0) {
                                 for (cnt = st; cnt <= ed; cnt++) {
                                 R(ai,bi,j) = R(ai,bi,j) + temp_R[cnt]*(cnt)/energy_sum;
                                 }
                                 } */
                                ed_agl = ed_agl + Nss[1];
                                sumEng = 0;
                                temp_avgdx = 0; temp_avgdy = 0;
                                
                                for (di=st_agl;di<=ed_agl;di++) {
                                    if (di>=Nss[1]) {
                                        for (ci=st;ci<=ed;ci++) {
                                            temp_avgdx -= ss_avgdx(ci,di-Nss[1],ai,bi);
                                            
                                            temp_avgdy -= ss_avgdy(ci,di-Nss[1],ai,bi);
                                            sumEng += ss_energy(ci,di-Nss[1],ai,bi);
                                        }
                                    }
                                    else {
                                        for (ci=st;ci<=ed;ci++) {
                                            temp_avgdx += ss_avgdx(ci,di,ai,bi);
                                            temp_avgdy += ss_avgdy(ci,di,ai,bi);
                                            sumEng += ss_energy(ci,di,ai,bi);
                                        }
                                    }
                                }
                                temp_avgdx /= sumEng;
                                temp_avgdy /= sumEng;
                                
                                R(ai,bi,j) = sqrt(temp_avgdx*temp_avgdx + temp_avgdy*temp_avgdy);
                                if (temp_avgdx>=0) {
                                    agl(ai,bi,j) = acos(temp_avgdy/R(ai,bi,j));
                                }
                                else
                                    agl(ai,bi,j) = pi - acos(temp_avgdy/R(ai,bi,j));
                                
                                
                                
                                
                            }
                        }
                        
                        
                    }
                }
                else
                    TTEng_2nd(ai,bi,j) = 0;
                
            }
            for (j=0;j<num_wave;j++) {
                W_sec(ai,bi,j) = TTEng_1st(ai,bi,j)/W_sec(ai,bi,j);
                if (R(ai,bi,j)==0) {
                    R(ai,bi,j) = R(ai,bi,markPos);
                    agl(ai,bi,j) = agl(ai,bi,markPos) + (j-markPos)*pi/num_wave;
                }
            }
        }
    }
    
    mxFree(temp);
    mxFree(temp2);
    mxFree(tempss);
    mxFree(temp_R);
    return;
}
Ejemplo n.º 6
0
/*NP*/
char *init_phase(float *plevel, short *phase)
/*************************************************************/
/*  INIT_PHASE                                               */
/*************************************************************/
{
	short       i, ok, avail;
	short       pIndex, zIndex, tIndex, tdIndex, oIndex;
	float       rh, p1, pbegin, pos, neg, p, w1;
	float       p_pres, p_phase, ptop, pbot;
	static char st[80];
	char        pt[80];

	*plevel = 0;
	*phase = -1;

	pIndex  = getParmIndex("PRES");
	zIndex  = getParmIndex("HGHT");
	tIndex  = getParmIndex("TEMP");
	tdIndex = getParmIndex("DWPT");
	oIndex  = getParmIndex("OMEG");

	if (!sndg || pIndex == -1 || zIndex == -1 || tIndex == -1 || 
	    tdIndex == -1) {
	  strcpy(st, "N/A");
	  return st;
	}

	/* First, determine whether VVELS are available.  If they are,   */
	/* use them to determine level where precipitation will develop. */
	avail=0;
	if (oIndex != -1) {
          for( i = 0; i < numlvl; i++) {
	    if (qc(sndg[i][oIndex]) && (sndg[i][oIndex] < 1)) avail++;
	  }
	}

	if (avail< 5) {
	   /* No VVELS...must look for saturated level */

	   /* ----- Find the highest near-saturated 50mb 
	      layer blo 5km agl ---- */
	   for(i=numlvl-1;i>0;i--) {
	      ok = 0;
	      pbegin = -999;
	      if (agl(sndg[i][zIndex]) < 5000.0) {
		  rh = mixratio(sndg[i][pIndex], sndg[i][tdIndex]) / 
	               mixratio(sndg[i][pIndex], sndg[i][tIndex]);
		  if (rh > 0.8) {
		    p1 = sndg[i][pIndex]+50;
		     if ((mixratio(p1, i_dwpt(p1, I_PRES)) / 
	                 mixratio(p1, i_temp(p1, I_PRES))) > 0.8) {
				ok = 1;
				pbegin = p1-25.0;
				break;
		     }
		}
	      }
	   }
	}
	else {
		/* ----- Find the highest near-saturated layer with UVV in 
	           the lowest 5km ----- */
	        for(i=numlvl-1;i>0;i--) {
			ok=0;
			pbegin=-999;
			if ((agl(sndg[i][zIndex])<5000) && 
	                    (sndg[i][oIndex] <= 0)) {
		  		rh = mixratio(sndg[i][pIndex], 
	                                      sndg[i][tdIndex]) / 
	                             mixratio(sndg[i][pIndex], sndg[i][tIndex]);
		  		if (rh > 0.8) {
					p1 = sndg[i][pIndex]+50;
				if ((mixratio(p1, i_dwpt(p1, I_PRES)) / 
	                             mixratio(p1, i_temp(p1, I_PRES))) > 0.8) {
						ok = 1;
						pbegin = p1-25;
						break;
				}
				}
				}
			}
	      }	

	if (!ok) {
	   *plevel =  0;
	   *phase  = -1;
	   strcpy(st, "N/A");
	   return st;
	}

	p1 = i_temp(pbegin, I_PRES);
	if(p1>0) {p_phase=0; strcpy(pt, "Rain"); }
	if((p1<=0) && (p1 > -5)) {p_phase=1; strcpy(pt, "Freezing Rain"); }
	if((p1<=-5) && (p1 > -9)) {p_phase=1; strcpy(pt, "ZR/S Mix" ); }
	if(p1 <= -9) {p_phase=3; strcpy(pt, "Snow"); }
	*plevel = pbegin;
	*phase = p_phase;
	return pt;
}
Ejemplo n.º 7
0
/*NP*/
char *best_guess(struct _ptype p)
/***********************************************************************/
/* BEST_GUESS                                                          */
/***********************************************************************/
{
	float       x1, y1, x2, y2;
	static char st[80];

	/* Case:  no precip */
	if (p.init_phase<0) {
		strcpy(st, "None.");
		return st;
	}

	/* Case:  always too warm - Rain */
	if ((p.init_phase==0) && (p.tneg>=0) && (p.tsfc>0)) {
		strcpy(st, "Rain.");
		return st;
	}

	/* Case:  always too cold - Snow */
	if ((p.init_phase==3) && (p.tpos<=0) && (p.tsfc<=0)) {
		strcpy(st, "Snow.");
		return st;
	}

	/* Case:  ZR too warm at sfc - Rain */
	if ((p.init_phase==1) && (p.tpos<=0) && (p.tsfc>0)) {
		strcpy(st, "Rain.");
		return st;
	}

	/* Case:  non-snow init...always too cold - Initphase&sleet  */
	if ((p.init_phase==1) && (p.tpos<=0) && (p.tsfc<=0)) {
		if (agl(i_hght(p.init_lvl, I_PRES))>=3000) {
			if (p.init_temp <= -4) {
				strcpy(st, "Sleet and Snow." );
				return st;
			}
			else {
				strcpy(st, "Sleet." );
				return st;
			}
		}
		else {
			strcpy(st, "Freezing Rain/Drizzle.");
			return st;
		}
	}

	/* Case:  Snow...but warm at sfc */
	if ((p.init_phase==3) && (p.tpos<=0) && (p.tsfc>0)) {
		if (p.tsfc>4) 
	          strcpy(st, "Rain.");
	        else
	          strcpy(st, "Snow.");
		return st;
	}


	/* Case:  Warm layer. */
	if (p.tpos>0) {
		x1 = p.tpos;
		y1 = -p.tneg;
		y2 = (.62 * x1) + 60;
		if (y1 > y2) 
			{ strcpy(st, "Sleet." ); }
		else
			{
			if (p.tsfc<=0) 
	                  strcpy(st, "Freezing Rain." );
	                else
	                  strcpy( st, "Rain." );
			}

		return st;
	}

	strcpy(st, "Unknown.");
	return st;
}
Ejemplo n.º 8
0
void BlockLocalPositionEstimator::flowCorrect()
{
	// measure flow
	Vector<float, n_y_flow> y;

	if (flowMeasure(y) != OK) { return; }

	// flow measurement matrix and noise matrix
	Matrix<float, n_y_flow, n_x> C;
	C.setZero();
	C(Y_flow_vx, X_vx) = 1;
	C(Y_flow_vy, X_vy) = 1;

	SquareMatrix<float, n_y_flow> R;
	R.setZero();

	// polynomial noise model, found using least squares fit
	// h, h**2, v, v*h, v*h**2
	const float p[5] = {0.04005232f, -0.00656446f, -0.26265873f,  0.13686658f, -0.00397357f};

	// prevent extrapolation past end of polynomial fit by bounding independent variables
	float h = agl();
	float v = y.norm();
	const float h_min = 2.0f;
	const float h_max = 8.0f;
	const float v_min = 0.5f;
	const float v_max = 1.0f;

	if (h > h_max) {
		h = h_max;
	}

	if (h < h_min) {
		h = h_min;
	}

	if (v > v_max) {
		v = v_max;
	}

	if (v < v_min) {
		v = v_min;
	}

	// compute polynomial value
	float flow_vxy_stddev = p[0] * h + p[1] * h * h + p[2] * v + p[3] * v * h + p[4] * v * h * h;

	float rotrate_sq = _sub_att.get().rollspeed * _sub_att.get().rollspeed
			   + _sub_att.get().pitchspeed * _sub_att.get().pitchspeed
			   + _sub_att.get().yawspeed * _sub_att.get().yawspeed;

	matrix::Eulerf euler(matrix::Quatf(_sub_att.get().q));
	float rot_sq = euler.phi() * euler.phi() + euler.theta() * euler.theta();

	R(Y_flow_vx, Y_flow_vx) = flow_vxy_stddev * flow_vxy_stddev +
				  _flow_r.get() * _flow_r.get() * rot_sq +
				  _flow_rr.get() * _flow_rr.get() * rotrate_sq;
	R(Y_flow_vy, Y_flow_vy) = R(Y_flow_vx, Y_flow_vx);

	// residual
	Vector<float, 2> r = y - C * _x;

	// residual covariance
	Matrix<float, n_y_flow, n_y_flow> S = C * _P * C.transpose() + R;

	// publish innovations
	_pub_innov.get().flow_innov[0] = r(0);
	_pub_innov.get().flow_innov[1] = r(1);
	_pub_innov.get().flow_innov_var[0] = S(0, 0);
	_pub_innov.get().flow_innov_var[1] = S(1, 1);

	// residual covariance, (inverse)
	Matrix<float, n_y_flow, n_y_flow> S_I = inv<float, n_y_flow>(S);

	// fault detection
	float beta = (r.transpose() * (S_I * r))(0, 0);

	if (beta > BETA_TABLE[n_y_flow]) {
		if (!(_sensorFault & SENSOR_FLOW)) {
			mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] flow fault,  beta %5.2f", double(beta));
			_sensorFault |= SENSOR_FLOW;
		}

	} else if (_sensorFault & SENSOR_FLOW) {
		_sensorFault &= ~SENSOR_FLOW;
		mavlink_and_console_log_info(&mavlink_log_pub, "[lpe] flow OK");
	}

	if (!(_sensorFault & SENSOR_FLOW)) {
		Matrix<float, n_x, n_y_flow> K =
			_P * C.transpose() * S_I;
		Vector<float, n_x> dx = K * r;
		_x += dx;
		_P -= K * C * _P;
	}
}
Ejemplo n.º 9
0
        /*NP*/
void plot_windspeedprofile(void)
        /*************************************************************/
        /*  PLOT_WINDSPEEDPROFILE                                    */
        /*  John Hart  SPC Norman                                    */
        /*                                                           */
        /*  Plots vertical profile of Wind Speeds                    */
        /*************************************************************/
{
	float lasthght;
        float bothgt, tophgt, h, wsp;
        short x1, y1, x2, y2, i, tlx, tly, wid, hgt;
        short pIndex, zIndex, wsIndex, wdIndex;
        char st[10];

        pIndex = getParmIndex("PRES");
        zIndex = getParmIndex("HGHT");
        wsIndex = getParmIndex("SPED");

        if (!sndg || pIndex == -1 || zIndex == -1 || wsIndex == -1) return;

        tlx = skv.brx;
        tly = skv.tly;
	wid = 93;
	hgt = skv.bry - skv.tly;

        setcliprgn(tlx, tly, tlx+wid, tly+hgt+15);
        setcolor(0);
        setlinestyle( 1, 1 );
        rectangle(1,tlx, tly, tlx+wid, tly+hgt);
        setcolor(1);
        rectangle(0, tlx, tly, tlx+wid, tly+hgt);

	/* Plot scale */
        setlinestyle(2, 1);
	set_font(5);
	for (i=20;i<=120;i+=20) {
        	setcolor(8);
		x1 = tlx + (i/1.5);
		x2 = x1;
		y1 = tly + 1;
		y2 = tly + hgt;
              	moveto(x1, y1);
              	lineto(x2, y2);
        	setcolor(1);
		sprintf( st, "%d", i);	
		outgtext(st, x1-3, y2+2);
		}

        /* ----- Plot Label ----- */
        setcolor(1);
	set_font(5);
        outgtext("Wind Speed (kt)", tlx+5, tly+3);
        outgtext("vs Height",  tlx+5, tly+15);


	/* color code to match hodograph layers */
	lasthght = 0;
	setlinestyle(1, 1);
        for (i=0; i<numlvl; i++) 
	{
      		if ((lasthght >= 0) && (lasthght < 3000))
        		{
           		if (qc(sndg[i][wsIndex])) {
                		wsp = sndg[i][wsIndex];
                		x1 = tlx;
                		x2 = tlx + (short)(wsp / 1.5);
                		y2 = pres_to_pix(sndg[i][pIndex]);
                		y1 = y2;
                		setcolor(2);
                		moveto(x1, y1);
                		lineto(x2, y2);
				lasthght = agl(sndg[i][zIndex]);
           			}
		  	}

        	if ((lasthght >= 3000) && (lasthght < 6000))                                              
                	{
                	if (qc(sndg[i][wsIndex])) {
                        	wsp = sndg[i][wsIndex];
                        	x1 = tlx;
                        	x2 = tlx + (short)(wsp / 1.5);
                        	y2 = pres_to_pix(sndg[i][pIndex]);
                        	y1 = y2;
                        	setcolor(3);
                        	moveto(x1, y1);
                        	lineto(x2, y2);
                        	lasthght = agl(sndg[i][zIndex]);
				}
		  	}
        	if ((lasthght >= 6000) && (lasthght < 9000))
                	{
                	if (qc(sndg[i][wsIndex])) {
                        	wsp = sndg[i][wsIndex];
                        	x1 = tlx;
                        	x2 = tlx + (short)(wsp / 1.5);
                        	y2 = pres_to_pix(sndg[i][pIndex]);
                        	y1 = y2;
                        	setcolor(5);
                        	moveto(x1, y1);
                        	lineto(x2, y2);
                        	lasthght = agl(sndg[i][zIndex]);
				}
		  	}
        	if ((lasthght >= 9000) && (lasthght < 12000))
                	{
                	if (qc(sndg[i][wsIndex])) {
                        	wsp = sndg[i][wsIndex];
                        	x1 = tlx;
                        	x2 = tlx + (short)(wsp / 1.5);
                        	y2 = pres_to_pix(sndg[i][pIndex]);
                        	y1 = y2;
                        	setcolor(6);
                        	moveto(x1, y1);
                        	lineto(x2, y2);
                        	lasthght = agl(sndg[i][zIndex]);
				}
		  	}
        	if (lasthght >= 12000)
                	{
                	if (qc(sndg[i][wsIndex])) {
                        	wsp = sndg[i][wsIndex];
                        	x1 = tlx;
                        	x2 = tlx + (short)(wsp / 1.5);
                        	y2 = pres_to_pix(sndg[i][pIndex]);
                        	y1 = y2;
                        	setcolor(29);
                        	moveto(x1, y1);
                        	lineto(x2, y2);
                        	lasthght = agl(sndg[i][zIndex]);
				}
                  	}

	}
        setcliprgn(1, 1, xwdth, xhght);
        copytodisplay();
}
Ejemplo n.º 10
0
	/*NP*/
void plot_thetae(void)
	/*************************************************************/
	/*  PLOT_THETAE                                              */
	/*  John Hart  NSSFC KCMO                                    */
	/*                                                           */
	/*  Plots vertical profile of Theta-E (sfc-500mb)            */
	/*************************************************************/
{
	float bothgt, tophgt, h, cthe, ix1;
	short x1, y1, x2, y2, i, tlx, tly;
	short pIndex, zIndex, tIndex, tdIndex;
	char st[10];

	pIndex = getParmIndex("PRES");
	zIndex = getParmIndex("HGHT");
	tIndex = getParmIndex("TEMP");
	tdIndex = getParmIndex("DWPT");

	if (!sndg || pIndex == -1 || tIndex == -1 || tdIndex == -1 ||
	    zIndex == -1)
	  return;

	/* tlx = hov.brx - 150;
	tly = hov.tly; */

	tlx = hov.tlx + 120;
	tly = hov.bry;

	setcliprgn(tlx, tly, tlx+134, tly+120);
	setcolor(0);
	setlinestyle( 1, 1 );
	rectangle(1,tlx, tly, tlx+134, tly+120); 
	setcolor(1);
	rectangle(0, tlx, tly, tlx+134, tly+120);

	/* ----- Set Layer (AGL) ----- */
	bothgt = 0;
	tophgt = agl(i_hght(500, I_PRES));

	/* ----- Plot Label ----- */
	setcolor(1);
	set_font(4);
	outgtext("Theta-E vs", tlx+55, tly+3);
	outgtext("Pressure",  tlx+55, tly+15);

	/* ----- Plot horizontal legend ----- */
        if (800 < pIndex < 850){
                cthe = (thetae(800, i_temp(800, I_PRES), i_dwpt(800, I_PRES)) +
                        thetae(650, i_temp(650, I_PRES), i_dwpt(650, I_PRES)) +
                        thetae(sndg[sfc()][pIndex], sndg[sfc()][tIndex],
                        sndg[sfc()][tdIndex])) / 3.0;
                        }
        if (750 < pIndex < 800){
                cthe = (thetae(750, i_temp(750, I_PRES), i_dwpt(750, I_PRES)) +
                        thetae(600, i_temp(600, I_PRES), i_dwpt(600, I_PRES)) +
                        thetae(sndg[sfc()][pIndex], sndg[sfc()][tIndex],
                        sndg[sfc()][tdIndex])) / 3.0;
                        }
        if (700 < pIndex < 750){
                cthe = (thetae(700, i_temp(700, I_PRES), i_dwpt(700, I_PRES)) +
                        thetae(500, i_temp(500, I_PRES), i_dwpt(500, I_PRES)) +
                        thetae(sndg[sfc()][pIndex], sndg[sfc()][tIndex],
                        sndg[sfc()][tdIndex])) / 3.0;
                        }
        if (pIndex >= 850){
                cthe = (thetae(850, i_temp(850, I_PRES), i_dwpt(850, I_PRES)) +
                        thetae(700, i_temp(700, I_PRES), i_dwpt(700, I_PRES)) +
                        thetae(sndg[sfc()][pIndex], sndg[sfc()][tIndex],
                        sndg[sfc()][tdIndex])) / 3.0;
                        }
	setcolor(19);
	set_font(5);
	for(h=cthe - 30.0; h<=cthe + 30.0; h += 10) {
	   x1 = (short)(tlx + 60 + ((h-cthe)*2.5));
	   y1 = tly+120;
	   moveto( x1, y1);
	   lineto( x1, y1-5);
	   sprintf(st, "%.0f", h + 273.15);
	   outgtext(st, x1-6, y1-14);
	   }

	/* ----- Plot vertical theta-e profile ----- */
	setlinestyle(1, 2);
	setcolor(2);
	x2 = 999;
        if (sndg[numlvl-1][pIndex] < 500) {
	   for (i=0; sndg[i][pIndex] >= 500; i++) {
	      /*printf ("i = %d,    PRES = %.1f\n", i, sndg[i][pIndex]);*/
	      if (qc(sndg[i][tdIndex])) {
	         x1 = (short)(tlx + 60 + ((thetae(sndg[i][pIndex], 
	              sndg[i][tIndex], sndg[i][tdIndex])-cthe)*2.5));
   	         y1 = vert_coords(agl(sndg[i][zIndex]), tophgt, tly);
	         if(x2 == 999) { x2=x1; y2=y1; }

	         moveto(x1, y1);
	         lineto(x2, y2);

	         x2=x1;
	         y2=y1;
	      }
	   }
	}


	/* ----- Plot Vertical Legend ----- */
	setlinestyle(1, 1);
	setcolor(1);
	set_font(5);
	x2 = 999;
	for(i=1000; i >= 600; i -= 100) {
	   x1 = tlx;
	   y1 = vert_coords(agl(i_hght(i, I_PRES)), tophgt, tly);
	   moveto( x1, y1);
	   lineto( x1+5, y1);
	   sprintf(st, "%d", i);
	   if (i<1000) outgtext(st, x1+6, y1-5);
	}

	setcliprgn(1, 1, xwdth, xhght);
	copytodisplay();

	/* plot theta-e index */
	setcolor(19);
	set_font(4);
	sprintf( st, "TEI = %s", qc2( ThetaE_diff(&ix1), "", 0));
        outgtext( st, tlx + 80, tly + 50);
}
Ejemplo n.º 11
0
	/*NP*/
float visual1(float lower, float upper, float pres, float temp, float dwpt, int ulx, int uly, int vwid)
	/*************************************************************/
	/*  VISUAL1                                                  */
	/*  John Hart  NSSFC KCMO                                    */
	/*                                                           */
	/*  Lifts specified parcel, given an initial 5 m/s push.     */
	/*  parcel trajectory is then calculated, using strict       */
	/*  parcel theory.  Updraft size is assumed 1km dia.         */
	/*                                                           */
	/*  All calculations use the virtual temperature correction. */
	/*                                                           */
	/*  lower       =  Bottom level of layer (mb)  [ -1=SFC]     */
	/*  upper       =  Top level of layer (mb)     [ -1=TOP]     */
	/*  pres        =  LPL pressure (mb)                         */
	/*  temp        =  LPL temperature (c)                       */
	/*  dwpt        =  LPL dew point (c)                         */
	/*************************************************************/
{
	short i, lptr, uptr, pIndex, zIndex, tIndex, tdIndex;
	float te1, pe1, te2, pe2, h1, h2, lyre, tdef1, tdef2, totp, totn;
	float te3, pe3, h3, tp1, tp2, tp3, tdef3, lyrf, lyrlast, pelast;
	float tote, dh, restim, uvv, ix1, ix2, tottim;
	float u, v, du, dv, tsu, tsv, tdist, tangle, disp, angl;
	short colrx;

	lyre = -1;
	totp = 25;
	totn = 0;

	pIndex = getParmIndex("PRES");
	zIndex = getParmIndex("HGHT");
	tIndex = getParmIndex("TEMP");
	tdIndex = getParmIndex("DWPT");
	if (!sndg || pIndex == -1 || zIndex == -1 || tIndex == -1 || tdIndex == -1) return RMISSD;

	/* ----- See if default layer is specified ----- */
	if (lower == -1) { lower = sndg[sfc()][pIndex]; }
	if (upper == -1) { upper = sndg[numlvl-1][pIndex]; }

	/* ----- Make sure this is a valid layer ----- */
	if( lower > pres ) { lower = pres; }
	if( !qc( i_vtmp( upper , I_PRES))) { return RMISSD; }
	if( !qc( i_vtmp( lower , I_PRES))) { return RMISSD; }

	/* ----- Begin with Mixing Layer (LPL-LCL) ----- */
	te1 = i_vtmp(pres , I_PRES);
	pe1 = lower;
	h1 =  i_hght(pe1 , I_PRES);
	tp1 = virtemp(pres, temp, dwpt);

	drylift(pres, temp, dwpt, &pe2, &tp2);
	h2 =  i_hght(pe2 , I_PRES);
	te2 = i_vtmp(pe2 , I_PRES);

	if( lower > pe2 ) { lower = pe2; }

	/* ----- Find lowest observation in layer ----- */
	i = 0;
	while( sndg[i][pIndex] > lower)  { i++; }
	while ( !qc(sndg[i][tdIndex]) ) { i++; }
	lptr = i;
	if( sndg[i][pIndex] == lower ) { lptr++; }

	/* ----- Find highest observation in layer ----- */
	i=numlvl-1;
	while(sndg[i][pIndex] < upper) { i--; }
	uptr = i;
	if( sndg[i][pIndex] == upper ) { uptr--; }

	/* ----- Start with interpolated bottom layer ----- */
	pe1 = lower;
	h1 =  i_hght( pe1 , I_PRES);
	te1 = i_vtmp( pe1 , I_PRES);
	tp1 = wetlift(pe2, tp2, pe1);

	totp = 25;
	totn = 0;
	tsu = 0;
	tsv = 0;
	restim = 0;
	tottim = 0;
	for (i = lptr; i < numlvl; i++) {
	   if (qc(sndg[i][tIndex])) {
	      /* ----- Calculate every level that reports a temp ----- */
	      pe2 = sndg[i][pIndex];
	      h2 =  sndg[i][zIndex];
	      te2 = i_vtmp( pe2 , I_PRES);
	      tp2 = wetlift(pe1, tp1, pe2);
	      tdef1 = (virtemp(pe1, tp1, tp1) - te1) / (te1 + 273.15);
	      tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15);
	      lyrlast = lyre;
	      lyre = 9.8F * (tdef1 + tdef2) / 2.0F * (h2 - h1);

	      if( lyre > 0 ) { totp += lyre; }
	      else { if(pe2 > 500) { totn += lyre; } }
	      tote += lyre;

	      uvv = (float)sqrt( totp * 2 );
	      dh = h2 - h1;
	      restim = dh / uvv;
	      tottim += restim;

	      sr_wind( pe1, pe2, st_dir, st_spd, &u, &v, &ix1, &ix2);
	      du = kt_to_mps(u) * restim;
	      dv = kt_to_mps(v) * restim;
	      tsu -= du;
	      tsv += dv;
	      tdist = (float)sqrt((tsu*tsu) + (tsv*tsv));
	      tangle = angle(tsu, tsv);

	      pelast = pe1;
	      pe1 = pe2;
	      h1 = h2;
	      te1 = te2;
	      tp1 = tp2;

	      /* ----- Is this the top of given layer ----- */
	      if(i >= uptr) {
		 pe3 = pe1;
		 h3 = h1;
		 te3 = te1;
		 tp3 = tp1;
		 lyrf = lyre;

		 if( lyrf > 0 )
		    { totp -= lyrf; }
		 else
		    { if(pe2 > 500) { totn -= lyrf; } }

		 pe2 = upper;
		 h2 = i_hght( pe2 , I_PRES);
		 te2 = i_vtmp( pe2 , I_PRES);
		 tp2 = wetlift(pe3, tp3, pe2);
		 tdef3 = (virtemp(pe3, tp3, tp3) - te3) / (te3 + 273.15);
		 tdef2 = (virtemp(pe2, tp2, tp2) - te2) / (te2 + 273.15);
		 lyrf = 9.8F * (tdef3 + tdef2) / 2.0F * (h2 - h3);
		 if( lyrf > 0 )
		    { totp += lyrf; }
		 else
		    { if(pe2 > 500) { totn -= lyrf; } }

		 if( totp == 0 ) { totn = 0; }

		 uvv = (float)sqrt( totp * 2 );
		 dh = h2 - h1;
		 restim = dh / uvv;
		 tottim += restim;

		 sr_wind( pe1, pe2, st_dir, st_spd, &u, &v, &ix1, &ix2);
		 du = kt_to_mps(u) * restim;
		 dv = kt_to_mps(v) * restim;
		 tsu -= du;
		 tsv += dv;
		 tdist = (float)sqrt((tsu*tsu) + (tsv*tsv));
		 tangle = angle(tsu, tsv);

		 colrx = 7;
		 vis_xy( -tsu, -tsv, colrx, ulx, uly, vwid);

		 angl = 90 - angle( tdist, agl(h2));

		 write_vis_data( tottim, angl, ulx, uly, vwid );
		 return 1;
	      }

	      colrx = 13;
	      if (h2>msl(3000)) colrx=3;
	      if (h2>msl(6000)) colrx=27;
	      if (h2>msl(9000)) colrx=20;
	      if (h2>msl(12000)) colrx=6;
	      vis_xy(-tsu, -tsv, colrx, ulx, uly, vwid);

	      if (sndg[i][pIndex] == 500) {
		 disp = tdist;
		 angl = 90 - angle( tdist, agl(sndg[i][zIndex]));
	      }
	   }
	}

	return 1.0;  /* ? mkay. there was no value before. bad thing */
}
Ejemplo n.º 12
0
        /*NP*/
float bndry_ci(float lift, float distance)
        /*************************************************************/
        /*  BOUNDARY CONVECTIVE INITIATION                           */
        /*  Rich Thompson and John Hart  SPC OUN                     */
        /*                                                           */
        /*  Lifts ML parcel to find LFC, then calculates parcel      */
        /*  trajectory relative to a boundary.  If parcel stays      */
        /*  within dist_to_bndry long enough to reach the LFC,       */
        /*  then convective initiation is likely                     */
        /*                                                           */
        /*  lift       =  ascent rate in m/min along boundary        */
        /*  dist_to_bndry       =  width of ascent zone (m)          */
        /*************************************************************/

{
	float ix1, ix2, u, v, pe1, pe2, lfc, height, pres;
	short oldlplchoice, i, min_lift;
	Parcel pcl;

	oldlplchoice = lplvals.flag;

	/* ----- Begin with ML parcel LFC height (m AGL) */
	define_parcel(4,100);
	ix1 = parcel( -1, -1, lplvals.pres, lplvals.temp, lplvals.dwpt, &pcl);
	lfc = agl(i_hght(pcl.lfcpres, I_PRES));

	/* ----- Calculate minutes of lift needed to reach LFC */

	min_lift = (short)(lfc / lift);

	printf("\nminutes of lift to LFC = %d\n", min_lift);

	/* if parcel remains within distance (to bndry), continue ascent */
	for (i = 0; i < min_lift; i++){
		
                 height = i * lift;
/*		 pe1 = i_pres(msl(height));
		 pe2 = i_pres(msl(height));

                 restim = dh / uvv;
                 tottim += restim;

                 sr_wind( pe1, pe2, st_dir, st_spd, &u, &v, &ix1, &ix2);
                 du = kt_to_mps(u) * restim;
                 dv = kt_to_mps(v) * restim;
                 tsu -= du;
                 tsv += dv;
                 distance = (float)sqrt((tsu*tsu) + (tsv*tsv));
                 tangle = angle(tsu, tsv);
*/		

	}

        if (oldlplchoice == 3)
          pres = mu_layer;
        else if (oldlplchoice == 4)
          pres = mml_layer;
        else if (oldlplchoice == 5)
          pres = user_level;
        else
          pres = mml_layer;
        define_parcel(oldlplchoice, pres);


	return min_lift;
}
Ejemplo n.º 13
0
        /* NP */
short ww_type(short *wwtype, short *dcp)
        /********************************************************************/
        /*      Watch type guidance                                         */
        /*      A decision tree to help with ww issuance                    */
        /*                                                                  */
        /*      Rich Thompson SPC OUN                                       */
        /********************************************************************/
        {
        float ix1, ix2, ix3, ix4, lr75, shr6, t500, fzlh, mumixr, lowrh, midrh, low_mid_rh;
        float mucn, mlcn, mlcp, sbcp, mucp, lr1, lr3, shr6_dir, sr46_dir, sr46_spd, shr6_sr46_diff, mmp;
        float sig_tor, sig_tor_winter, sighail, wind_dmg, rm_scp, cbsig, dncp, srh1, sblcl, mllcl;
        float oldlplpres, pres, pbot, ptop, shr8, bot, top, esrh, lm_scp;
        short oldlplchoice, ww_choice;
        short pIndex, tIndex, zIndex, tdIndex;
        short x1, y1, x2, y2, tlx, tly, wid;
        struct _parcel pcl;
        char st[40];

        tlx = hov.tlx + 409;
        tly = hov.bry;
        wid = 119;

        setcliprgn( tlx+2, tly+2, tlx+wid+24, tly+wid+1);
        setcolor(0);
        setlinestyle( 1, 1 );
        rectangle( 1,tlx, tly, tlx+wid+27, tly+wid+1);
        setcolor(1);
        rectangle( 0, tlx, tly, tlx+wid+27, tly+wid+1);
        setlinestyle( 1, 1 );
        moveto( tlx + 2, tly + 18);
	lineto(tlx + wid + 27, tly + 18);


        /* ----- Plot Label ----- */
        set_font(6);
        setcolor(1);
        outgtext( "Psbl Watch Type", tlx + 20, tly + 3 );

	*wwtype = 0;
	*dcp = 0;

        oldlplchoice = lplvals.flag;

        tIndex = getParmIndex("TEMP");
        pIndex = getParmIndex("PRES");
        zIndex = getParmIndex("HGHT");
        tdIndex = getParmIndex("DWPT");

/* 24 Mar 2008 */
/*        effective_inflow_layer(100, -250, &pbot, &ptop);*/

	/* sb parcel */
        define_parcel(1,0);
        ix1 = parcel(-1, -1, lplvals.pres, lplvals.temp, lplvals.dwpt, &pcl);
        sbcp = pcl.bplus;
        sblcl = agl(i_hght(pcl.lclpres, I_PRES));
        sig_tor_winter = sigtorn_fixed(st_dir, st_spd);

	/* ml parcel */
        define_parcel(4,100);
        ix1 = parcel(-1, -1, lplvals.pres, lplvals.temp, lplvals.dwpt, &pcl);
        mlcn = pcl.bminus;
        mlcp = pcl.bplus;
        mllcl = agl(i_hght(pcl.lclpres, I_PRES));
        sig_tor = sigtorn_cin(st_dir, st_spd);

	/* mu parcel */
        define_parcel(3,400);
        mucp = parcel(-1, -1, lplvals.pres, lplvals.temp, lplvals.dwpt, &pcl);
        mucn = pcl.bminus;

	dncp = dcape(&ix1, &ix2);

	/* sighail ingredients */
        lr75 = lapse_rate(&ix1, 700, 500);
        wind_shear(sndg[sfc()][pIndex], i_pres(msl(6000)), &ix1, &ix2, &ix3, &ix4);
        shr6 = ix4;
        shr6_dir = ix3;
        wind_shear(sndg[sfc()][pIndex], i_pres(msl(8000)), &ix1, &ix2, &ix3, &ix4);
	shr8 = ix4;
        mumixr = mixratio(lplvals.pres, lplvals.dwpt);
        t500 =  i_temp(500, I_PRES);
        fzlh = mtof(agl(i_hght(temp_lvl(0, &ix1), I_PRES)));
        sighail = sig_hail(pcl.bplus, mumixr, lr75, t500, kt_to_mps(shr6), fzlh, pcl.bminus, 0, 0, 25, mlcp);

        rm_scp = scp(st_dir, st_spd);
        wind_dmg = damaging_wind();

        sr_wind( i_pres(msl(4000)), i_pres(msl(6000)), st_dir, st_spd, &ix1, &ix2, &ix3, &ix4);
        sr46_dir = ix3;
        sr46_spd = ix4;
        shr6_sr46_diff = (shr6_dir - sr46_dir);
	srh1 = helicity(0, 1000, st_dir, st_spd, &ix1, &ix2);
	bot = agl(i_hght(p_bot, I_PRES));
	top = agl(i_hght(p_top, I_PRES));	
	esrh = helicity(bot, top, st_dir, st_spd, &ix1, &ix2);

        lapse_rate(&ix2, sndg[sfc()][pIndex], i_pres(sndg[sfc()][zIndex]+1000));
        lr1 = ix2;
        lapse_rate(&ix2, sndg[sfc()][pIndex], i_pres(sndg[sfc()][zIndex]+3000));
        lr3 = ix2;

        mean_relhum(&ix1, sndg[sfc()][pIndex]-150, sndg[sfc()][pIndex]-350);
        midrh = ix1;
        mean_relhum(&ix1, sndg[sfc()][pIndex], sndg[sfc()][pIndex]-150);
        lowrh = ix1;
        low_mid_rh = ((lowrh + midrh)/2);
        mmp = coniglio1();
        cbsig = (mlcp * kt_to_mps(shr6));

/* 24 Mar 2008 */
/* all "p_bot" below were changed from "pbot" */

/* Decision tree below is identical to the operational "ww_type" flow chart documentation 9/23/09 RLT */
        if ((sig_tor >= 3.0) && (sig_tor_winter >= 3.0) && (srh1 >= 150) && (esrh >= 150) && (sr46_spd >= 15.0) && (shr8 >= 40.0) && (sblcl < 1000) && (mllcl < 1100) && (lr1 >= 5.0) && (bot == 0.0)) {
		*dcp = 1;
		*wwtype = 5;
                ww_choice = 5;
        	/*printf("\n dcp (in PDS) = %d", *dcp);*/
        	set_font(6);
        	setcolor(7);
        	outgtext( "PDS TOR", tlx + 45, tly + 60 );
                }

/*        else
        if ((sig_tor_winter >= 4.0) && (sr46_spd >= 15.0) && (shr8 >= 40.0) && (sblcl < 1000) && (lr1 >= 5.0) && (bot == 0.0)) {
                *dcp = 2;
                *wwtype = 5;
                ww_choice = 5;
                set_font(6);
                setcolor(7);
                outgtext( "PDS TOR", tlx + 45, tly + 60 );
                }
*/	
        else
        if (((sig_tor >= 3.0) || (sig_tor_winter >= 4.0)) && (bot == 0.0)) {
                *dcp = 3;
                *wwtype = 4;
                ww_choice = 4;
                /*printf("\n dcp (in TOR) = %d", *dcp);*/
                set_font(6);
                setcolor(2);
                outgtext( "TOR", tlx + 45, tly + 60 );
                }
	
        else
        if (((sig_tor >= 1.0) || (sig_tor_winter >= 1.0)) && ((sr46_spd >= 15.0) || (shr8 >= 40.0)) && (bot == 0.0)) {
                *dcp = 4;
                *wwtype = 4;
                ww_choice = 4;
                /*printf("\n dcp (in TOR) = %d", *dcp);*/
                set_font(6);
                setcolor(2);
                outgtext( "TOR", tlx + 45, tly + 60 );
                }

        else
        if (((sig_tor >= 1.0) || (sig_tor_winter >= 1.0)) && (low_mid_rh >= 60) && (lr1 >= 5.0) && (bot == 0.0)) {
                *dcp = 5;
                *wwtype = 4;
                ww_choice = 4;
                /*printf("\n dcp (in TOR) = %d", *dcp);*/
                set_font(6);
                setcolor(2);
                outgtext( "TOR", tlx + 45, tly + 60 );
                }

        else
        if ((( sig_tor >= 1.0) || (sig_tor_winter >= 1.0)) && (bot == 0.0)) {
                *dcp = 6;
                *wwtype = 3;	
                ww_choice = 3; 
                /*printf("\n dcp (in mrgl TOR) = %d", *dcp);*/
	        set_font(6);
                setcolor(2);
                outgtext( "mrgl TOR", tlx + 40, tly + 60 );
                }

        else
        if (((( sig_tor >= 0.5) && (esrh >= 150)) || ((sig_tor_winter >= 0.5) && (srh1 >= 150))) && (bot == 0.0)) {
                *dcp = 7;
                *wwtype = 3;	
                ww_choice = 3;
                /*printf("\n dcp (in mrgl TOR) = %d", *dcp);*/
                set_font(6);
                setcolor(2);
                outgtext( "mrgl TOR", tlx + 40, tly + 60 );
                }

        else
        if ((( sig_tor_winter >= 1.0) || (rm_scp >= 4.0) || (sig_tor >= 1.0)) && (mucn >= -50.0)) {
                *dcp = 8;
                *wwtype = 2;
                ww_choice = 2;
                /*printf("\n dcp (in SVR) = %d", *dcp);*/
	        set_font(6);
                setcolor(6);
                outgtext( "SVR",  tlx + 60, tly + 60 );
                }

        else
        if ((rm_scp >= 2.0) && ((sighail >= 1.0) || (dncp >= 750)) && (mucn >= -50.0)) {
                *dcp = 9;
                *wwtype = 2;
                ww_choice = 2;
                /*printf("\n dcp (in SVR) = %d", *dcp);*/
                set_font(6);
                setcolor(6);
                outgtext( "SVR",  tlx + 60, tly + 60 );
                }

        else
        if ((cbsig >= 30000) && (mmp >= 0.6) && (mucn >= -50.0)) {
                *dcp = 10;
                *wwtype = 2;
                ww_choice = 2;
                /*printf("\n dcp (in SVR) = %d", *dcp);*/
                set_font(6);
                setcolor(6);
                outgtext( "SVR",  tlx + 60, tly + 60 );
                }
        
	else
        if ((mucn >= -75.0) && ((wind_dmg >= 0.5) || (sighail >= 0.5) || (rm_scp >= 0.5)))  {
                *dcp = 11;
                *wwtype = 1;
                ww_choice = 1;
                /*printf("\n dcp (in mrgl SVR) = %d", *dcp);*/
	        set_font(6);
                setcolor(26);
                outgtext( "MRGL SVR",  tlx + 40, tly + 60 );
                }
        else    {
                *dcp = 0;
                /*printf("\n dcp (after logic checks) = %d", *dcp);*/
                *wwtype = 0;
                ww_choice = 0;
		}

        if (*wwtype == 0) {
                set_font(6);
                setcolor(19);
                outgtext( "NONE",  tlx + 50, tly + 60 );
                }
    	//printf("sig_tor=%f sig_tor_winter=%f srh1=%f esrh=%f sr46_spd=%f shr8=%f sblcl=%f\n mllcl=%f lr1=%f bot=%f low_mid_rh=%f rm_scp=%f\n mucn=%f dncp=%f sighail=%f cbsig=%f wind_dmg=%f",
    	//		sig_tor,sig_tor_winter,srh1,esrh,sr46_spd,shr8, sblcl, mllcl, lr1, bot, low_mid_rh, rm_scp,mucn, dncp, sighail, cbsig, wind_dmg);

/*      define_parcel(oldlplchoice, oldlplpres); */
        
        /* set parcel back to user selection */
        if (oldlplchoice == 1)
          pres = 0;
        else if (oldlplchoice == 2)
          pres = 0;
        else if (oldlplchoice == 3)
          pres = mu_layer;
        else if (oldlplchoice == 4)
          pres = mml_layer;
        else if (oldlplchoice == 5)
          pres = user_level;
        else if (oldlplchoice == 6)
          pres = mu_layer;
        define_parcel(oldlplchoice, pres);

        return ww_choice;

        }
Ejemplo n.º 14
0
int BlockLocalPositionEstimator::flowMeasure(Vector<float, n_y_flow> &y)
{
	matrix::Eulerf euler(matrix::Quatf(_sub_att.get().q));

	// check for sane pitch/roll
	if (euler.phi() > 0.5f || euler.theta() > 0.5f) {
		return -1;
	}

	// check for agl
	if (agl() < flow_min_agl) {
		return -1;
	}

	// check quality
	float qual = _sub_flow.get().quality;

	if (qual < _flow_min_q.get()) {
		return -1;
	}

	// calculate range to center of image for flow
	if (!(_estimatorInitialized & EST_TZ)) {
		return -1;
	}

	float d = agl() * cosf(euler.phi()) * cosf(euler.theta());

	// optical flow in x, y axis
	// TODO consider making flow scale a states of the kalman filter
	float flow_x_rad = _sub_flow.get().pixel_flow_x_integral * _flow_scale.get();
	float flow_y_rad = _sub_flow.get().pixel_flow_y_integral * _flow_scale.get();
	float dt_flow = _sub_flow.get().integration_timespan / 1.0e6f;

	if (dt_flow > 0.5f || dt_flow < 1.0e-6f) {
		return -1;
	}

	// angular rotation in x, y axis
	float gyro_x_rad = 0;
	float gyro_y_rad = 0;

	if (_fusion.get() & FUSE_FLOW_GYRO_COMP) {
		gyro_x_rad = _flow_gyro_x_high_pass.update(
				     _sub_flow.get().gyro_x_rate_integral);
		gyro_y_rad = _flow_gyro_y_high_pass.update(
				     _sub_flow.get().gyro_y_rate_integral);
	}

	//warnx("flow x: %10.4f y: %10.4f gyro_x: %10.4f gyro_y: %10.4f d: %10.4f",
	//double(flow_x_rad), double(flow_y_rad), double(gyro_x_rad), double(gyro_y_rad), double(d));

	// compute velocities in body frame using ground distance
	// note that the integral rates in the optical_flow uORB topic are RH rotations about body axes
	Vector3f delta_b(
		+(flow_y_rad - gyro_y_rad) * d,
		-(flow_x_rad - gyro_x_rad) * d,
		0);

	// rotation of flow from body to nav frame
	Vector3f delta_n = _R_att * delta_b;

	// imporant to timestamp flow even if distance is bad
	_time_last_flow = _timeStamp;

	// measurement
	y(Y_flow_vx) = delta_n(0) / dt_flow;
	y(Y_flow_vy) = delta_n(1) / dt_flow;

	_flowQStats.update(Scalarf(_sub_flow.get().quality));

	return OK;
}
void BlockLocalPositionEstimator::predict()
{
	// get acceleration
	matrix::Quatf q(&_sub_att.get().q[0]);
	_eul = matrix::Euler<float>(q);
	_R_att = matrix::Dcm<float>(q);
	Vector3f a(_sub_sensor.get().accelerometer_m_s2);
	// note, bias is removed in dynamics function
	_u = _R_att * a;
	_u(U_az) += 9.81f;	// add g

	// update state space based on new states
	updateSSStates();

	// continuous time kalman filter prediction
	// integrate runge kutta 4th order
	// TODO move rk4 algorithm to matrixlib
	// https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods
	float h = getDt();
	Vector<float, n_x> k1, k2, k3, k4;
	k1 = dynamics(0, _x, _u);
	k2 = dynamics(h / 2, _x + k1 * h / 2, _u);
	k3 = dynamics(h / 2, _x + k2 * h / 2, _u);
	k4 = dynamics(h, _x + k3 * h, _u);
	Vector<float, n_x> dx = (k1 + k2 * 2 + k3 * 2 + k4) * (h / 6);

	// don't integrate position if no valid xy data
	if (!(_estimatorInitialized & EST_XY))  {
		dx(X_x) = 0;
		dx(X_vx) = 0;
		dx(X_y) = 0;
		dx(X_vy) = 0;
	}

	// don't integrate z if no valid z data
	if (!(_estimatorInitialized & EST_Z))  {
		dx(X_z) = 0;
	}

	// don't integrate tz if no valid tz data
	if (!(_estimatorInitialized & EST_TZ))  {
		dx(X_tz) = 0;
	}

	// saturate bias
	float bx = dx(X_bx) + _x(X_bx);
	float by = dx(X_by) + _x(X_by);
	float bz = dx(X_bz) + _x(X_bz);

	if (std::abs(bx) > BIAS_MAX) {
		bx = BIAS_MAX * bx / std::abs(bx);
		dx(X_bx) = bx - _x(X_bx);
	}

	if (std::abs(by) > BIAS_MAX) {
		by = BIAS_MAX * by / std::abs(by);
		dx(X_by) = by - _x(X_by);
	}

	if (std::abs(bz) > BIAS_MAX) {
		bz = BIAS_MAX * bz / std::abs(bz);
		dx(X_bz) = bz - _x(X_bz);
	}

	// propagate
	_x += dx;
	Matrix<float, n_x, n_x> dP = (_A * _P + _P * _A.transpose() +
				      _B * _R * _B.transpose() + _Q) * getDt();

	// covariance propagation logic
	for (int i = 0; i < n_x; i++) {
		if (_P(i, i) > P_MAX) {
			// if diagonal element greater than max, stop propagating
			dP(i, i) = 0;

			for (int j = 0; j < n_x; j++) {
				dP(i, j) = 0;
				dP(j, i) = 0;
			}
		}
	}

	_P += dP;
	_xLowPass.update(_x);
	_aglLowPass.update(agl());
}
Ejemplo n.º 16
0
/*NP*/
void write_file2( char *filename )
/*************************************************************/
/*  WRITE_FILE                                               */
/*  John Hart  NSSFC KCMO                                    */
/*                                                           */
/*  Writes contents of sndg array into SHARP95 file.         */
/*************************************************************/
{
    short i, j;
    short idx[7];
    float sfctemp, sfcdwpt, sfcpres, j1, j2, ix1;
    struct _parcel pcl;
    char st[80];
    FILE *fout;

    idx[1]  = getParmIndex("PRES");
    idx[2]  = getParmIndex("HGHT");
    idx[3]  = getParmIndex("TEMP");
    idx[4]  = getParmIndex("DWPT");
    idx[5]  = getParmIndex("DRCT");
    idx[6]  = getParmIndex("SPED");

    fout = fopen( filename, "wt" );
    if (fout==NULL)
    {
        printf("Unable to write output file!\n" );
        return;
    }
    fputs( "%TITLE%\n", fout );
    fputs( raobtitle, fout );
    fputs( "\n\n", fout );
    fprintf( fout, "   LEVEL       HGHT       TEMP       DWPT       WDIR       WSPD\n");
    fprintf( fout, "-------------------------------------------------------------------\n");
    fputs( "%RAW%\n", fout );
    for(i=0; i<numlvl; i++)
    {
        for(j=1; j<=5; j++) fprintf( fout, "%8.2f,  ", sndg[i][idx[j]]);
        fprintf( fout, "%8.2f\n", sndg[i][idx[6]]);
    }
    fputs( "%END%\n\n", fout );

    if ((numlvl<4) || (!qc(i_dwpt(700, I_PRES)))) return;

    fprintf( fout, "----- Parcel Information-----\n");

    /* ----- Calculate Parcel Data ----- */
    sfctemp = lplvals.temp;
    sfcdwpt = lplvals.dwpt;
    sfcpres = lplvals.pres;

    strcpy( st, "*** " );
    strcat( st, lplvals.desc );
    strcat( st, " ***" );
    fprintf( fout, "%s\n", st);
    ix1 = parcel( -1, -1, sfcpres, sfctemp, sfcdwpt, &pcl);

    fprintf( fout, "LPL:  P=%.0f  T=%.0fF  Td=%.0fF\n", sfcpres, ctof(sfctemp), ctof(sfcdwpt));
    fprintf( fout, "CAPE:            %6.0f J/kg\n", pcl.bplus);
    fprintf( fout, "CINH:            %6.0f J/kg\n", pcl.bminus);

    fprintf( fout, "LI:              %6.0f C\n", pcl.li5);
    fprintf( fout, "LI(300mb):       %6.0f C\n", pcl.li3);

    fprintf( fout, "3km Cape:        %6.0f J/kg\n", pcl.cape3km);
    j1 = pcl.bplus;
    j2 = i_hght(pcl.elpres, I_PRES) - i_hght(pcl.lfcpres, I_PRES);
    fprintf( fout, "NCAPE:           %6.2f m/s2\n\n", j1/j2);

    fprintf( fout, "LCL:    %6.0fmb     %6.0fm\n", pcl.lclpres, agl(i_hght(pcl.lclpres, I_PRES)));
    fprintf( fout, "LFC:    %6.0fmb     %6.0fm\n", pcl.lfcpres, agl(i_hght(pcl.lfcpres, I_PRES)));
    fprintf( fout, "EL:     %6.0fmb     %6.0fm\n", pcl.elpres, agl(i_hght(pcl.elpres, I_PRES)));
    fprintf( fout, "MPL:    %6.0fmb     %6.0fm\n", pcl.mplpres, agl(i_hght(pcl.mplpres, I_PRES)));
    fprintf( fout, "All heights AGL\n\n" );

    fprintf( fout, "----- Moisture -----\n" );
    strcpy( st, qc2( precip_water( &ix1, -1, -1), " in", 2 ));
    fprintf( fout, "Precip Water:    %s\n", st);
    strcpy( st, qc2( mean_mixratio( &ix1, -1, -1 ), " g/Kg", 1 ));
    fprintf( fout, "Mean W:          %s\n\n", st);

    fprintf( fout, "----- Lapse Rates -----\n" );
    j1 = delta_t(&ix1);
    j2 = lapse_rate( &ix1, 700, 500);
    fprintf( fout, "700-500mb   %.0f C      %.1f C/km\n", j1, j2);

    j1 = vert_tot(&ix1);
    j2 = lapse_rate( &ix1, 850, 500);
    fprintf( fout, "850-500mb   %.0f C      %.1f C/km\n", j1, j2);

    fclose( fout );
}
Ejemplo n.º 17
0
/*This function uses the symmetric property and computes the agl in one direction*/
void mexFunction(int nlhs, mxArray *plhs[], /* Output variables */
int nrhs, const mxArray *prhs[]) /* Input variables */
{
    #define agl(ai,bi) agl[ai+dims[0]*bi]
    #define TTEng_1st(ai,bi) TTEng_1st[ai+dims[0]*bi]
    #define TTEng_2nd(ai,bi) TTEng_2nd[ai+dims[0]*bi]
    #define ss_energy(ci,di,ai,bi) ss_energy[ci+Nss[0]*(di+Nss[1]*(ai+Nss[2]*bi))]
    
    size_t ai, bi, ci, di, k, j, cnt;
    int num_wave;
    double *ss_energy, *agl, *TTEng_1st, *TTEng_2nd;
    ss_energy = mxGetPr(prhs[0]);
    const mwSize *Nss = mxGetDimensions(prhs[0]);
    num_wave = mxGetScalar(prhs[1]);
    nrhs = 2;
    
    nlhs = 3;
    int ndim = 2, dims[2] = {Nss[2],Nss[3]}, numm = (int)(Nss[1]/num_wave/4);
    plhs[0] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[1] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    plhs[2] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS,mxREAL);
    agl = mxGetPr(plhs[0]);
    TTEng_1st = mxGetPr(plhs[1]);
    TTEng_2nd = mxGetPr(plhs[2]);
    
    int L = Nss[1]/num_wave, maxpos, st, ed;
    double *temp, energy_sum, *tempss;
    temp = (double *)mxMalloc(sizeof(double)*L);
    tempss = (double *)mxMalloc(sizeof(double)*(2*numm+1));
    for (ai=0;ai<Nss[2];ai++) {
        for (bi=0;bi<Nss[3];bi++) {
            for (k=0;k<L;k++) {
                for (j=0;j<num_wave;j++) {
                    di = j*L + k;
                    for (ci=0;ci<Nss[0];ci++) {
                        if (ci==0 & j==0)
                            temp[k] = ss_energy(ci,di,ai,bi);
                        else
                            temp[k] = temp[k] + ss_energy(ci,di,ai,bi);
                    }
                }
            }
            /*temp[:] computed*/
            maxpos = findmax(temp,L);
            for (cnt=0;cnt<2*numm+1;cnt++) {
                tempss[cnt] = temp[(int)fmod(cnt+maxpos-numm,L)];
            }
            ed = numm;
            cnt = 1;
            while (ed<2*numm & cnt==1 & tempss[ed+1]>0) {
                if (tempss[ed]>=tempss[ed+1])
                    ed++;
                else
                    cnt = 0;
            }
            st = numm;
            cnt = 1;
            while (st>0 & cnt == 1 & tempss[st-1]>0) {
                if (tempss[st] >= tempss[st-1])
                    st--;
                else
                    cnt = 0;
            }
            /*compute agl(ai,bi)*/
            energy_sum = 0;
            for (cnt = st; cnt <= ed; cnt++)
                energy_sum = energy_sum + tempss[cnt];
            for (cnt = st; cnt <= ed; cnt++) {
                agl(ai,bi) = agl(ai,bi) + tempss[cnt]*(cnt+0.5)/energy_sum;
                temp[(int)fmod(cnt+maxpos-numm,L)] = 0;
            }
            agl(ai,bi) = fmod(agl(ai,bi)+maxpos-numm,L);/*any problem here??????*/
            
            /*compute TTEng_1st(ai,bi)*/
            TTEng_1st(ai,bi) = energy_sum;
            /*compute TTEng_2nd(ai,bi)*/
            maxpos = findmax(temp,L);
            if (temp[maxpos]>0) {
                for (cnt=0;cnt<2*numm+1;cnt++) {
                    tempss[cnt] = temp[(int)fmod(cnt+maxpos-numm,L)];
                }
                ed = numm;
                cnt = 1;
                while (ed<2*numm & cnt==1 & tempss[ed+1]>0) {
                    if (tempss[ed]>=tempss[ed+1])
                        ed++;
                    else
                        cnt = 0;
                }
                st = numm;
                cnt = 1;
                while (st>0 & cnt == 1 & tempss[st-1]>0) {
                    if (tempss[st] >= tempss[st-1])
                        st--;
                    else
                        cnt = 0;
                }
                /*compute agl(ai,bi)*/
                energy_sum = 0;
                for (cnt = st; cnt <= ed; cnt++)
                    energy_sum = energy_sum + tempss[cnt];
                if (energy_sum<=TTEng_1st(ai,bi))
                    TTEng_2nd(ai,bi) = energy_sum;
                else {
                    agl(ai,bi) = 0;
                    for (cnt = st; cnt <= ed; cnt++) {
                        agl(ai,bi) = agl(ai,bi) + tempss[cnt]*(cnt+0.5)/energy_sum;
                    }
                    agl(ai,bi) = fmod(agl(ai,bi)+maxpos-numm,L);
                    TTEng_2nd(ai,bi) = TTEng_1st(ai,bi);
                    TTEng_1st(ai,bi) = energy_sum;
                }
            }
            else
                TTEng_2nd(ai,bi) = 0;

        }
    }
    
    mxFree(temp);
    mxFree(tempss);
return;
}