diff --git a/interfaces/native/include/geomagnetic_field.h b/interfaces/native/include/geomagnetic_field.h old mode 100755 new mode 100644 index 2031e505e45dbb0a4ac1dc0301105f275bc19f13..28a20a7252283d97141ce4c0924a801b170fdec1 --- a/interfaces/native/include/geomagnetic_field.h +++ b/interfaces/native/include/geomagnetic_field.h @@ -28,62 +28,24 @@ class GeomagneticField { public: - GeomagneticField(float latitude, float longitude, float altitude, int64_t timeMillis); - ~GeomagneticField() = default; - float ObtainX(); - float ObtainY(); - float ObtainZ(); - float ObtainGeomagneticDip(); - float ObtainDeflectionAngle(); - float ObtainLevelIntensity(); - float ObtainTotalIntensity(); private: - float northComponent; - float eastComponent; - float downComponent; - static float geocentricLatitude; - static float geocentricLongitude; - static float geocentricRadius; - const static float EARTH_MAJOR_AXIS_RADIUS; - const static float EARTH_MINOR_AXIS_RADIUS; - const static float EARTH_REFERENCE_RADIUS; - const static float PRECISION; - const static float LATITUDE_MAX; - const static float LATITUDE_MIN; - const static float CONVERSION_FACTOR; - const static float DERIVATIVE_FACTOR; - const static int64_t WMM_BASE_TIME; - - const static float GAUSS_COEFFICIENT_G[13][13]; - const static float GAUSS_COEFFICIENT_H[13][13]; - const static float DELTA_GAUSS_COEFFICIENT_G[13][13]; - const static float DELTA_GAUSS_COEFFICIENT_H[13][13]; - const static int32_t GAUSSIAN_COEFFICIENT_DIMENSION; - static std::vector> schmidtQuasiNormalFactors; - - static std::vector> polynomials; - static std::vector> polynomialsDerivative; - static std::vector relativeRadiusPower; - static std::vector sinMLongitude; - static std::vector cosMLongitude; - - static std::vector> GetSchmidtQuasiNormalFactors(int32_t expansionDegree); + std::vector> GetSchmidtQuasiNormalFactors(int32_t expansionDegree); void CalculateGeomagneticComponent(double latDiffRad, int64_t timeMillis); - static void GetLongitudeTrigonometric(); - static void GetRelativeRadiusPower(); - static void CalibrateGeocentricCoordinates(float latitude, float longitude, float altitude); + void GetLongitudeTrigonometric(); + void GetRelativeRadiusPower(); + void CalibrateGeocentricCoordinates(float latitude, float longitude, float altitude); void InitLegendreTable(int32_t expansionDegree, float thetaRad); double ToDegrees(double angrad); - static double ToRadians(double angdeg); + double ToRadians(double angdeg); }; #endif // GEOMAGNETIC_FIELD_H \ No newline at end of file diff --git a/interfaces/native/src/geomagnetic_field.cpp b/interfaces/native/src/geomagnetic_field.cpp index 1b7c0f2d61c259036ff671e5ae89b6fd8bbdf6e5..7b2de3b15e9ab30e6bc61b4bd1d626706633c765 100644 --- a/interfaces/native/src/geomagnetic_field.cpp +++ b/interfaces/native/src/geomagnetic_field.cpp @@ -18,23 +18,20 @@ using namespace OHOS::HiviewDFX; using namespace std; -static const HiLogLabel LABEL = {LOG_CORE, OHOS::SensorsLogDomain::SENSORS_INTERFACE, "GeomagneticField"}; - -const float GeomagneticField::EARTH_MAJOR_AXIS_RADIUS = 6378.137f; -const float GeomagneticField::EARTH_MINOR_AXIS_RADIUS = 6356.7523142f; -const float GeomagneticField::EARTH_REFERENCE_RADIUS = 6371.2f; -const float GeomagneticField::PRECISION = 1e-5f; -const float GeomagneticField::LATITUDE_MAX = 90.0f; -const float GeomagneticField::LATITUDE_MIN = -90.0f; -const float GeomagneticField::CONVERSION_FACTOR = 1000.0f; -const float GeomagneticField::DERIVATIVE_FACTOR = 1.0f; +namespace { +constexpr HiLogLabel LABEL = {LOG_CORE, OHOS::SensorsLogDomain::SENSORS_INTERFACE, "GeomagneticField"}; +constexpr float EARTH_MAJOR_AXIS_RADIUS = 6378.137f; +constexpr float EARTH_MINOR_AXIS_RADIUS = 6356.7523142f; +constexpr float EARTH_REFERENCE_RADIUS = 6371.2f; +constexpr float PRECISION = 1e-5f; +constexpr float LATITUDE_MAX = 90.0f; +constexpr float LATITUDE_MIN = -90.0f; +constexpr float CONVERSION_FACTOR = 1000.0f; +constexpr float DERIVATIVE_FACTOR = 1.0f; // the time from 1970-01-01 to 2020-01-01 as UTC milliseconds from the epoch -const int64_t GeomagneticField::WMM_BASE_TIME = 1580486400000; - -/** -* The following Gaussian coefficients are derived from the US/ United Kingdom World Magnetic Model 2020-2025. -*/ -const float GeomagneticField::GAUSS_COEFFICIENT_G[13][13] = { +constexpr int64_t WMM_BASE_TIME = 1580486400000; +// The following Gaussian coefficients are derived from the US/ United Kingdom World Magnetic Model 2020-2025. +constexpr float GAUSS_COEFFICIENT_G[13][13] = { {0.0f}, {-29404.5f, -1450.7f}, {-2500.0f, 2982.0f, 1676.8f}, @@ -49,8 +46,7 @@ const float GeomagneticField::GAUSS_COEFFICIENT_G[13][13] = { {3.0f, -1.4f, -2.5f, 2.4f, -0.9f, 0.3f, -0.7f, -0.1f, 1.4f, -0.6f, 0.2f, 3.1f}, {-2.0f, -0.1f, 0.5f, 1.3f, -1.2f, 0.7f, 0.3f, 0.5f, -0.2f, -0.5f, 0.1f, -1.1f, -0.3f} }; - -const float GeomagneticField::GAUSS_COEFFICIENT_H[13][13] = { +constexpr float GAUSS_COEFFICIENT_H[13][13] = { {0.0f}, {0.0f, 4652.9f}, {0.0f, -2991.6f, -734.8f}, @@ -65,8 +61,7 @@ const float GeomagneticField::GAUSS_COEFFICIENT_H[13][13] = { {0.0f, 0.0f, 2.6f, -0.5f, -0.4f, 0.6f, -0.2f, -1.7f, -1.6f, -3.0f, -2.0f, -2.6f}, {0.0f, -1.2f, 0.5f, 1.3f, -1.8f, 0.1f, 0.7f, -0.1f, 0.6f, 0.2f, -0.9f, 0.0f, 0.5f} }; - -const float GeomagneticField::DELTA_GAUSS_COEFFICIENT_G[13][13] = { +constexpr float DELTA_GAUSS_COEFFICIENT_G[13][13] = { {0.0f}, {6.7f, 7.7f}, {-11.5f, -7.1f, -2.2f}, @@ -81,8 +76,7 @@ const float GeomagneticField::DELTA_GAUSS_COEFFICIENT_G[13][13] = { {0.0f, -0.1f, 0.0f, 0.0f, 0.0f, -0.1f, 0.0f, 0.0f, -0.1f, -0.1f, -0.1f, -0.1f}, {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -0.1f} }; - -const float GeomagneticField::DELTA_GAUSS_COEFFICIENT_H[13][13] = { +constexpr float DELTA_GAUSS_COEFFICIENT_H[13][13] = { {0.0f}, {0.0f, -25.1f}, {0.0f, -30.2f, -23.9f}, @@ -97,21 +91,27 @@ const float GeomagneticField::DELTA_GAUSS_COEFFICIENT_H[13][13] = { {0.0f, 0.0f, 0.1f, 0.0f, 0.2f, 0.0f, 0.0f, 0.1f, 0.0f, -0.1f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, -0.1f, 0.1f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 0.0f, 0.0f, -0.1f} }; +constexpr int32_t GAUSSIAN_COEFFICIENT_DIMENSION = 13; +std::mutex mutex_; + +float northComponent; +float eastComponent; +float downComponent; +float geocentricLatitude; +float geocentricLongitude; +float geocentricRadius; -const int32_t GeomagneticField::GAUSSIAN_COEFFICIENT_DIMENSION = - sizeof(GAUSS_COEFFICIENT_G) / sizeof(GAUSS_COEFFICIENT_G[0]); -std::vector> GeomagneticField::schmidtQuasiNormalFactors; -std::vector GeomagneticField::relativeRadiusPower(GAUSSIAN_COEFFICIENT_DIMENSION + 2); -std::vector GeomagneticField::sinMLongitude(GAUSSIAN_COEFFICIENT_DIMENSION); -std::vector GeomagneticField::cosMLongitude(GAUSSIAN_COEFFICIENT_DIMENSION); -std::vector> GeomagneticField::polynomials(GAUSSIAN_COEFFICIENT_DIMENSION); -std::vector> GeomagneticField::polynomialsDerivative(GAUSSIAN_COEFFICIENT_DIMENSION); -float GeomagneticField::geocentricLatitude; -float GeomagneticField::geocentricLongitude; -float GeomagneticField::geocentricRadius; +std::vector> schmidtQuasiNormalFactors; +std::vector> polynomials(GAUSSIAN_COEFFICIENT_DIMENSION); +std::vector> polynomialsDerivative(GAUSSIAN_COEFFICIENT_DIMENSION); +std::vector relativeRadiusPower(GAUSSIAN_COEFFICIENT_DIMENSION + 2); +std::vector sinMLongitude(GAUSSIAN_COEFFICIENT_DIMENSION); +std::vector cosMLongitude(GAUSSIAN_COEFFICIENT_DIMENSION); +} GeomagneticField::GeomagneticField(float latitude, float longitude, float altitude, int64_t timeMillis) { + std::lock_guard geomagneticLock(mutex_); schmidtQuasiNormalFactors = GetSchmidtQuasiNormalFactors(GAUSSIAN_COEFFICIENT_DIMENSION); float gcLatitude = fmax(LATITUDE_MIN + PRECISION, fmin(LATITUDE_MAX - PRECISION, latitude)); CalibrateGeocentricCoordinates(gcLatitude, longitude, altitude); @@ -258,45 +258,54 @@ void GeomagneticField::InitLegendreTable(int32_t expansionDegree, float thetaRad float GeomagneticField::ObtainX() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); return northComponent; } float GeomagneticField::ObtainY() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); return eastComponent; } float GeomagneticField::ObtainZ() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); return downComponent; } float GeomagneticField::ObtainGeomagneticDip() { - return static_cast(ToDegrees(atan2(downComponent, ObtainLevelIntensity()))); + std::lock_guard geomagneticLock(mutex_); + float horizontalIntensity = hypot(northComponent, eastComponent); + return static_cast(ToDegrees(atan2(downComponent, horizontalIntensity))); } double GeomagneticField::ToDegrees(double angrad) { + std::lock_guard geomagneticLock(mutex_); return angrad * 180.0 / M_PI; } double GeomagneticField::ToRadians(double angdeg) { + std::lock_guard geomagneticLock(mutex_); return angdeg / 180.0 * M_PI; } float GeomagneticField::ObtainDeflectionAngle() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); return static_cast(ToDegrees(atan2(eastComponent, northComponent))); } float GeomagneticField::ObtainLevelIntensity() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); float horizontalIntensity = hypot(northComponent, eastComponent); return horizontalIntensity; } @@ -304,6 +313,7 @@ float GeomagneticField::ObtainLevelIntensity() float GeomagneticField::ObtainTotalIntensity() { HiLog::Info(LABEL, "%{public}s begin", __func__); + std::lock_guard geomagneticLock(mutex_); float sumOfSquares = northComponent * northComponent + eastComponent * eastComponent + downComponent * downComponent; float totalIntensity = static_cast(sqrt(sumOfSquares));