float MPU6050::dmpGetFirstYPRData() { long long time = timeCheck(); if(dmpReady && time > 0) { // get current FIFO count dmpFifoCount = getFIFOCount(); if (dmpFifoCount == 1024) { // reset so we can continue cleanly resetFIFO(); timeReset(); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (dmpFifoCount >= 42) { timeCount(time); // read a packet from FIFO getFIFOBytes(dmpFifoBuffer, dmpPacketSize); // display quaternion values in easy matrix form: w x y z dmpGetQuaternion(&dmpQuat, dmpFifoBuffer); // if(dmpDebug) printf("quat %7.2f %7.2f %7.2f %7.2f ", dmpQuat.w,dmpQuat.x,dmpQuat.y,dmpQuat.z); #ifdef OUTPUT_READABLE_EULER // display Euler angles in degrees dmpGetEuler(dmpEuler, &dmpQuat); dmpEuler[0] = dmpEuler[0] * 180/M_PI; dmpEuler[1] = dmpEuler[1] * 180/M_PI; dmpEuler[2] = dmpEuler[2] * 180/M_PI; // if(dmpDebug) printf("euler %7.2f %7.2f %7.2f ", dmpEuler[0], dmpEuler[1], dmpEuler[2]); #endif #ifdef OUTPUT_READABLE_YAWPITCHROLL // display Euler angles in degrees dmpGetGravity(&dmpGravity, &dmpQuat); dmpGetYawPitchRoll(dmpYawPitchRoll, &dmpQuat, &dmpGravity); dmpYawPitchRoll[0] = dmpYawPitchRoll[0] * 180/M_PI; dmpYawPitchRoll[1] = dmpYawPitchRoll[1] * 180/M_PI; dmpYawPitchRoll[2] = dmpYawPitchRoll[2] * 180/M_PI; // if(dmpDebug) printf("ypr %7.2f %7.2f %7.2f ", dmpYawPitchRoll[0], dmpYawPitchRoll[1], dmpYawPitchRoll[2]); if(dmpDebug) return dmpYawPitchRoll[0]; #endif #ifdef OUTPUT_READABLE_REALACCEL // display real acceleration, adjusted to remove gravity dmpGetAccel(&dmpAccel, dmpFifoBuffer); dmpGetGravity(&dmpGravity, &dmpQuat); dmpGetLinearAccel(&dmpAccelReal, &dmpAccel, &dmpGravity); // if(dmpDebug) printf("areal %6d %6d %6d ", dmpAccelReal.x, dmpAccelReal.y, dmpAccelReal.z); #endif #ifdef OUTPUT_READABLE_WORLDACCEL // display initial world-frame acceleration, adjusted to remove gravity // and rotated based on known orientation from quaternion dmpGetAccel(&dmpAccel, dmpFifoBuffer); dmpGetGravity(&dmpGravity, &dmpQuat); dmpGetLinearAccelInWorld(&dmpAccelWorld, &dmpAccelReal, &dmpQuat); // if(dmpDebug) printf("aworld %6d %6d %6d ", dmpAccelWorld.x, dmpAccelWorld.y, dmpAccelWorld.z); #endif #ifdef OUTPUT_TEAPOT // display quaternion values in InvenSense Teapot demo format: dmpTeapotPacket[2] = dmpFifoBuffer[0]; dmpTeapotPacket[3] = dmpFifoBuffer[1]; dmpTeapotPacket[4] = dmpFifoBuffer[4]; dmpTeapotPacket[5] = dmpFifoBuffer[5]; dmpTeapotPacket[6] = dmpFifoBuffer[8]; dmpTeapotPacket[7] = dmpFifoBuffer[9]; dmpTeapotPacket[8] = dmpFifoBuffer[12]; dmpTeapotPacket[9] = dmpFifoBuffer[13]; //Serial.write(dmpTeapotPacket, 14); dmpTeapotPacket[11]++; // packetCount, loops at 0xFF on purpose #endif return -255; } } return -255; }
bool BkgdObsSplineLoader::loadBkgdObs(QList<real> &bgIn) { // Turn Debug on if there are problems with the vertical spline interpolation, // Eventually this should be replaced with the internal spline code // SplineD::Debug(1); // Geographic functions // GeographicLib::TransverseMercatorExact tm = GeographicLib::TransverseMercatorExact::UTM(); real referenceLon = configHash->value("ref_lon").toFloat(); int time; real lat, lon, alt, u, v, w, t, qv, rhoa, qr; real Pi = acos(-1); bool debugDomain = isTrue("debug_domain"); // bgZ = -32768.; TODO. What was that about? // background is in km, ROI is gridpoints iROI = configHash->value("i_background_roi").toFloat() / iincr; jROI = configHash->value("j_background_roi").toFloat() / jincr; maxGridDist = 3.0; QString interp_mode = configHash->value("bg_interpolation"); if (interp_mode == "Cressman") maxGridDist = 1.0; if (frameVector.size() == 0) { std::cout << "Frame Vector is not initialized." << std::endl; return false; } std::cout << "Loading background onto Gaussian mish with " << iROI << " grid length radius of influence in i direction" << std::endl; std::cout << "and " << jROI << " grid length radius of influence in j direction" << std::endl; QDateTime startTime = frameVector.front().getTime(); QDateTime endTime = frameVector.back().getTime(); std::cout << "Start time: " << startTime.toTime_t() << " " << startTime.toString("yyyy-MM-dd-HH:mm:ss").toLatin1().data() << std::endl; std::cout << "End time: " << endTime.toTime_t() << " " << endTime.toString("yyyy-MM-dd-HH:mm:ss").toLatin1().data() << std::endl; int timeProblem = 0; int domainProblem = 0; int radiusProblem = 0; int levelProblem = 0; int splineProblem = 0; std::cout << "iROI: " << iROI << ", jROI: " << jROI << ", maxGridDist: " << maxGridDist << std::endl; std::cout << "imin: " << imin << ", iincr: " << iincr << std::endl; std::cout << "jmin: " << jmin << ", jincr: " << jincr << std::endl; std::cout << "kmin: " << kmin << ", kincr: " << kincr << std::endl; while( bkgdAdapter->next(time, lat, lon, alt, u, v, w, t, qv, rhoa, qr) ) { int tci; if (! timeCheck(time, startTime, endTime, tci)) { timeProblem++; continue; } real Um = frameVector[tci].getUmean(); real Vm = frameVector[tci].getVmean(); // Get the X, Y & Z real tcX, tcY, metX, metY; projection.Forward(referenceLon, frameVector[tci].getLat() , frameVector[tci].getLon(), tcX, tcY); projection.Forward(referenceLon, lat, lon , metX, metY); bgX = (metX - tcX) / 1000.; bgY = (metY - tcY) / 1000.; real heightm = (alt > 10.0) ? alt : 10; // don't want to take log of zero below... bgZ = heightm / 1000.; bgRadius = sqrt(bgX * bgX + bgY * bgY); bgTheta = 180.0 * atan2(bgY, bgX) / Pi; if (configHash->value("allow_negative_angles") != "true") if (bgTheta < 0) bgTheta += 360.0; // Make sure the ob is in the Interpolation domain if (runMode == RUN_MODE_XYZ) { if ((bgX < (imin - iincr - (iROI * iincr * maxGridDist))) or (bgX > (imax + iincr + (iROI * iincr * maxGridDist))) or (bgY < (jmin - jincr - (jROI * jincr * maxGridDist))) or (bgY > (jmax + jincr + (jROI * jincr * maxGridDist))) or (bgZ < kmin)) { //Allow for higher values for interpolation purposes domainProblem++; if (debugDomain) std::cout << "bgX: " << bgX << " bgY: " << bgY << " bgZ: " << bgZ << std::endl; continue; } } else if (runMode == RUN_MODE_RTZ) { if ((bgRadius < (imin - iincr - (iROI * iincr * maxGridDist))) or (bgRadius > (imax + iincr + (iROI * iincr * maxGridDist))) or (bgTheta < jmin - jincr - (jROI * jincr * maxGridDist)) or (bgTheta > jmax + jincr + (jROI * jincr * maxGridDist)) or (bgZ < kmin)) { //Exceeding the Theta domain only makes sense for sectors domainProblem++; continue; } real cylUm = (Um * bgX + Vm * bgY) / bgRadius; real cylVm = (-Um * bgY + Vm * bgX) / bgRadius; Um = cylUm; Vm = cylVm; } // Reference states real rhoBar = refstate->getReferenceVariable(ReferenceVariable::rhoaref, heightm); real qBar = refstate->getReferenceVariable(ReferenceVariable::qvbhypref, heightm); real tBar = refstate->getReferenceVariable(ReferenceVariable::tempref, heightm); real rho = rhoa + rhoa * qv / 1000.; real rhou = rho * (u - Um); real rhov = rho * (v - Vm); real rhow = rho * w; real tprime = t - tBar; qv = refstate->bhypTransform(qv); real qvprime = qv - qBar; real rhoprime = (rhoa - rhoBar) * 100; real logZ = log(bgZ); if (configHash->value("qr_variable") == "qr") qr = refstate->bhypTransform(qr); // We assume here that the background precipitation field is always zero // real qr = 0.; if (runMode == RUN_MODE_XYZ) { bgIn << bgX << bgY << logZ << time << rhou << rhov << rhow << tprime << qvprime << rhoprime << qr ; } else if (runMode == RUN_MODE_RTZ) bgIn << bgRadius << bgTheta << logZ << time << rhou << rhov << rhow << tprime << qvprime << rhoprime << qr ; // Push values for an entire column, then solve for the spline if ( (logheights.size() != 0) && (logZ <= logheights.back()) ) { // Not first level, not same column, Solve for the spline if (logheights.size() == 1) { std::cerr << "Error at " << lat << ", " << lon << ", " << bgZ << std::endl << "Only one level found in background spline setup. " << std::endl << "Please check Background.in to ensure sorting by descending Z coordinate and re-run." << std::endl; levelProblem++; return false; } splineSolver(0); // This will also clear logheights, uBG, vBG, ... } logheights.push_back(logZ); uBG.push_back(rhou); vBG.push_back(rhov); wBG.push_back(rhow); tBG.push_back(tprime); qBG.push_back(qvprime); rBG.push_back(rhoprime); zBG.push_back(qr); } // each obs std::cout << "timeProblem: " << timeProblem << ", domainProblem: " << domainProblem << ", radiusProblem: " << radiusProblem << ", levelProblem: " << levelProblem << ", splineProblem: " << splineProblem << std::endl; if (!logheights.size()) { // Error reading in the background field std::cout << "No background estimates read in. " << "Please check the time and location of your background field.\n"; #if 0 std::cout << "Observation window: " << tcstart.toStdString() << " to " << tcend.toStdString() << "\n"; std::cout << "Background time: " << bgTimestring.toStdString() << "\n"; #endif return false; } // std::cout << "------------------------2\n"; // Solve for the last spline if (logheights.size() == 1) { std::cerr << "Only one level found in background spline setup. " << "Please check Background.in to ensure sorting by Z coordinate and re-run." << std::endl; return false; } // Exponential interpolation in horizontal, b-Spline interpolation on log height in vertical splineSolver(2); // This will also clear logheights, uBG, vBG, ... int numbgObs = bgIn.size() / 11; // 11 entries per ob if (isTrue("debug_bgIn")) dumpBgIn(0, numbgObs, bgIn); QVector<int> emptybg; // TODO Do we need to check interpolation and fill hole for KD too? // bgWeight is a byproduct of calling the spline solver, so that's not available. // what about fill holes? It depends on emptyBg which is also a byproduct of the spline solver. // Check interpolation if (numbgObs > 0) { START_TIMER(timeci); for (int ki = -1; ki < (kdim); ki++) { for (int kmu = -1; kmu <= 1; kmu += 2) { real kPos = kmin + kincr * (ki + (0.5 * sqrt(1. / 3.) * kmu + 0.5)); for (int ii = -1; ii < (idim); ii++) { for (int imu = -1; imu <= 1; imu += 2) { real iPos = imin + iincr * (ii + (0.5 * sqrt(1. / 3.) * imu + 0.5)); for (int ji = -1; ji < (jdim); ji++) { for (int jmu = -1; jmu <= 1; jmu += 2) { real jPos = jmin + jincr * (ji + (0.5 * sqrt(1. / 3.) * jmu + 0.5)); int bgI = (ii + 1) * 2 + (imu + 1) / 2; int bgJ = (ji + 1) * 2 + (jmu + 1) / 2; int bgK = (ki + 1) * 2 + (kmu + 1) / 2; int bIndex = numVars * (idim + 1) * 2 * (jdim + 1) * 2 * bgK + numVars * (idim + 1) * 2 * bgJ + numVars * bgI; for (unsigned int var = 0; var < numVars; var++) { if (bgWeights[bIndex] != 0) { bgU[bIndex + var] /= bgWeights[bIndex]; } else { emptybg.push_back(bIndex); if (emptybg.size() < 15) { std::cout << "Empty background mish for variable " << var << " at " << iPos << ", " << jPos << ", " << kPos << std::endl; } else if (emptybg.size() == 15) { std::cout << "Too many empty mish points, will no longer report.\n"; } } } if (configHash->value("qr_variable") == "dbz") { if (bgU[bIndex + 6] > 0) { real dbzavg = 10 * log10(bgU[bIndex + 6]); bgU[bIndex + 6] = (dbzavg + 35.) * 0.1; } else { bgU[bIndex + 6] = 0.0; } } } } } } } } fillHoles(emptybg); PRINT_TIMER("Interpolation check", timeci); } else { std::cout << "No background observations loaded" << std::endl; return false; } std::cout << numbgObs << " background observations loaded" << std::endl; if (isTrue("debug_bgU")) { dumpBgU(0, uStateSize, bgU); } if (configHash->contains("debug_bgU_nc")) bgu2nc(configHash->value("debug_bgU_nc").toLatin1().data(), bgU); return true; }
bool BkgdObsKDLoader::loadBkgdObs(QList<real> &bgIn) { int time; real lat, lon, alt, u, v, w, t, qv, rhoa, qr; real Pi = acos(-1); KD_tree *kdTree; QDateTime startTime = frameVector.front().getTime(); QDateTime endTime = frameVector.back().getTime(); std::cout << "Start time: " << startTime.toTime_t() << " " << startTime.toString("yyyy-MM-dd-HH:mm:ss").toLatin1().data() << std::endl; std::cout << "End time: " << endTime.toTime_t() << " " << endTime.toString("yyyy-MM-dd-HH:mm:ss").toLatin1().data() << std::endl; // background is in km, ROI is gridpoints // TODO that comment doesn't seem correct. These are set to 45.0 in the config file... iROI = configHash->value("i_background_roi").toFloat() / iincr; jROI = configHash->value("j_background_roi").toFloat() / jincr; maxGridDist = 3.0; int timeProblem = 0; int domainProblem = 0; int debugKd = 0; if (configHash->contains("debug_kd") ) { debugKd = configHash->value("debug_kd").toInt(); std::cout << "*** dbugKD: " << debugKd << std::endl; } int debugKdStep = 0; if (configHash->contains("debug_kd_step") ) { debugKdStep = configHash->value("debug_kd_step").toInt(); std::cout << "*** Debug KD Step: " << debugKdStep << std::endl; } while( bkgdAdapter->next(time, lat, lon, alt, u, v, w, t, qv, rhoa, qr) ) { // Process the bkgdObs into Observations int tci; if (! timeCheck(time, startTime, endTime, tci)) { timeProblem++; continue; } real Um = frameVector[tci].getUmean(); real Vm = frameVector[tci].getVmean(); // Get the X, Y & Z real tcX, tcY, metX, metY; real referenceLon = configHash->value("ref_lon").toFloat(); projection.Forward(referenceLon, frameVector[tci].getLat() , frameVector[tci].getLon(), tcX, tcY); projection.Forward(referenceLon, lat, lon , metX, metY); bgX = (metX - tcX) / 1000.; bgY = (metY - tcY) / 1000.; real heightm = (alt > 10.0) ? alt : 10; // don't want to take log of zero below... bgZ = heightm / 1000.; bgRadius = sqrt(bgX * bgX + bgY * bgY); bgTheta = 180.0 * atan2(bgY, bgX) / Pi; if (configHash->value("allow_negative_angles") != "true") if (bgTheta < 0) bgTheta += 360.0; // Make sure the ob is in the Interpolation domain if (runMode == RUN_MODE_XYZ) { if ((bgX < (imin - iincr - (iROI * iincr * maxGridDist))) or (bgX > (imax + iincr + (iROI * iincr * maxGridDist))) or (bgY < (jmin - jincr - (jROI * jincr * maxGridDist))) or (bgY > (jmax + jincr + (jROI * jincr * maxGridDist))) or (bgZ < kmin)) { //Allow for higher values for interpolation purposes domainProblem++; continue; } } else if (runMode == RUN_MODE_RTZ) { if ((bgRadius < (imin - iincr - (iROI * iincr * maxGridDist))) or (bgRadius > (imax + iincr + (iROI * iincr * maxGridDist))) or (bgTheta < jmin - jincr - (jROI * jincr * maxGridDist)) or (bgTheta > jmax + jincr + (jROI * jincr * maxGridDist)) or (bgZ < kmin)) { //Exceeding the Theta domain only makes sense for sectors domainProblem++; continue; } real cylUm = (Um * bgX + Vm * bgY) / bgRadius; real cylVm = (-Um * bgY + Vm * bgX) / bgRadius; Um = cylUm; Vm = cylVm; } // Reference states real rhoBar = refstate->getReferenceVariable(ReferenceVariable::rhoaref, heightm); real qBar = refstate->getReferenceVariable(ReferenceVariable::qvbhypref, heightm); real tBar = refstate->getReferenceVariable(ReferenceVariable::tempref, heightm); real rho = rhoa + rhoa * qv / 1000.; real rhou = rho * (u - Um); real rhov = rho * (v - Vm); real rhow = rho * w; real tprime = t - tBar; qv = refstate->bhypTransform(qv); real qvprime = qv - qBar; real rhoprime = (rhoa - rhoBar) * 100; real logZ = log(bgZ); if (configHash->value("qr_variable") == "qr") qr = refstate->bhypTransform(qr); // We assume here that the background precipitation field is always zero // real qr = 0.; if (runMode == RUN_MODE_XYZ) { bgIn << bgX << bgY << logZ << time << rhou << rhov << rhow << tprime << qvprime << rhoprime << qr ; } else if (runMode == RUN_MODE_RTZ) bgIn << bgRadius << bgTheta << logZ << time << rhou << rhov << rhow << tprime << qvprime << rhoprime << qr; } // each obs std::cout << "timeProblem: " << timeProblem << ", domainProblem: " << domainProblem << std::endl; int numbgObs = bgIn.size() / 11; // 11 entries per ob if (numbgObs <= 0) { std::cout << "No background observations loaded" << std::endl; return false; } std::cout << numbgObs << " background observations loaded" << std::endl; if (isTrue("debug_bgIn")) dumpBgIn(0, numbgObs, bgIn); // All the obs are now loaded in bgIn. Build a KD tree kdTree = buildKDTree(bgIn); QVector<int> emptybg; KD_real *centerLoc = new KD_real[3]; // 3 dim int nbrMax = configHash->value("bkgd_kd_num_neighbors").toInt(); if (nbrMax <= 0) { std::cerr << "Number of neighbors must be greater than 0." << std::endl; return false; } float maxDist = configHash->value("bkgd_kd_max_distance").toFloat(); // KD tree returns the square of the distance... maxDist *= maxDist; // For each point on the mish std::cout << "*** idim: " << idim << ", jdim: " << jdim << ", kdim: " << kdim << std::endl; if (debugKd) std::cout << "--- start of debug kd" << std::endl; for (int ii = -1; ii < (idim); ii++) { for (int imu = -1; imu <= 1; imu += 2) { real iPos = imin + iincr * (ii + (0.5 * sqrt(1. / 3.) * imu + 0.5)); for (int ji = -1; ji < (jdim); ji++) { for (int jmu = -1; jmu <= 1; jmu += 2) { real jPos = jmin + jincr * (ji + (0.5 * sqrt(1. / 3.) * jmu + 0.5)); for (int ki = -1; ki < (kdim); ki++) { for (int kmu = -1; kmu <= 1; kmu += 2) { real kPos = kmin + kincr * (ki + (0.5 * sqrt(1. / 3.) * kmu + 0.5)); int bgI = (ii + 1) * 2 + (imu + 1) / 2; int bgJ = (ji + 1) * 2 + (jmu + 1) / 2; int bgK = (ki + 1) * 2 + (kmu + 1) / 2; // std::cout << "iPos: " << iPos << ", jPos: " << jPos << ", kPos: " << kPos << std::endl; // std::cout << "bgI: " << bgI << ", bgJ: " << bgJ << ", bgK " << bgK << std::endl; // continue; // index into bgU (flat array) int bIndex = numVars * (idim + 1) * 2 * (jdim + 1) * 2 * bgK + numVars * (idim + 1) * 2 * bgJ + numVars * bgI; // Do the KD tree here. // give me the n nearest neighbors and average. centerLoc[0] = iPos; centerLoc[1] = jPos; centerLoc[2] = kPos; fillBguEntry(centerLoc, nbrMax, maxDist, bgIn, kdTree, bgU, bIndex, emptybg, debugKd); if (debugKd > 0) debugKd -= debugKdStep; } } } } } } if (emptybg.size() > 0) std::cout << "** KD left " << emptybg.size() << " holes in bgU" << std::endl; if (debugKd) std::cout << "--- end of debug kd" << std::endl; if (configHash->contains("debug_bgU_overwrite")) overwriteBgu(configHash->value("debug_bgU_overwrite").toLatin1().data()); if (isTrue("debug_bgU")) { dumpBgU(0, uStateSize, bgU); } if (configHash->contains("debug_bgU_nc")) bgu2nc(configHash->value("debug_bgU_nc").toLatin1().data(), bgU); return true; }
bool Foam::conformalVoronoiMesh::distributeBackground(const Triangulation& mesh) { if (!Pstream::parRun()) { return false; } Info<< nl << "Redistributing points" << endl; timeCheck("Before distribute"); label iteration = 0; scalar previousLoadUnbalance = 0; while (true) { scalar maxLoadUnbalance = mesh.calculateLoadUnbalance(); if ( maxLoadUnbalance <= foamyHexMeshControls().maxLoadUnbalance() || maxLoadUnbalance <= previousLoadUnbalance ) { // If this is the first iteration, return false, if it was a // subsequent one, return true; return iteration != 0; } previousLoadUnbalance = maxLoadUnbalance; Info<< " Total number of vertices before redistribution " << returnReduce(label(mesh.number_of_vertices()), sumOp<label>()) << endl; const fvMesh& bMesh = decomposition_().mesh(); volScalarField cellWeights ( IOobject ( "cellWeights", bMesh.time().timeName(), bMesh, IOobject::NO_READ, IOobject::NO_WRITE ), bMesh, dimensionedScalar("weight", dimless, 1e-2), zeroGradientFvPatchScalarField::typeName ); meshSearch cellSearch(bMesh, polyMesh::FACE_PLANES); labelList cellVertices(bMesh.nCells(), label(0)); for ( typename Triangulation::Finite_vertices_iterator vit = mesh.finite_vertices_begin(); vit != mesh.finite_vertices_end(); ++vit ) { // Only store real vertices that are not feature vertices if (vit->real() && !vit->featurePoint()) { pointFromPoint v = topoint(vit->point()); label cellI = cellSearch.findCell(v); if (cellI == -1) { // Pout<< "findCell conformalVoronoiMesh::distribute " // << "findCell " // << vit->type() << " " // << vit->index() << " " // << v << " " // << cellI // << " find nearest cellI "; cellI = cellSearch.findNearestCell(v); } cellVertices[cellI]++; } } forAll(cellVertices, cI) { // Give a small but finite weight for empty cells. Some // decomposition methods have difficulty with integer overflows in // the sum of the normalised weight field. cellWeights.internalField()[cI] = max ( cellVertices[cI], 1e-2 ); } autoPtr<mapDistributePolyMesh> mapDist = decomposition_().distribute ( cellWeights ); cellShapeControl_.shapeControlMesh().distribute(decomposition_); distribute(); timeCheck("After distribute"); iteration++; }