/**
  * Use the magnetic field to compute true (geographic) north from the specified heading relative
  * to magnetic north.
  *
  * @param heading the heading (in degrees) relative to magnetic north
  * @return the heading (in degrees) relative to true north
  */
 private float computeTrueNorth(float heading) {
   if (mGeomagneticField != null) {
     return heading + mGeomagneticField.getDeclination();
   } else {
     return heading;
   }
 }
  private Object eventToHashMap(SensorEvent event, long timestamp) {
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];

    KrollDict heading = new KrollDict();
    heading.put(TiC.EVENT_PROPERTY_TYPE, TiC.EVENT_HEADING);
    heading.put(TiC.PROPERTY_TIMESTAMP, timestamp);
    heading.put(TiC.PROPERTY_X, x);
    heading.put(TiC.PROPERTY_Y, y);
    heading.put(TiC.PROPERTY_Z, z);
    heading.put(TiC.PROPERTY_MAGNETIC_HEADING, x);
    heading.put(TiC.PROPERTY_ACCURACY, event.accuracy);

    if (Log.isDebugModeEnabled()) {
      switch (event.accuracy) {
        case SensorManager.SENSOR_STATUS_UNRELIABLE:
          Log.i(TAG, "Compass accuracy unreliable");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
          Log.i(TAG, "Compass accuracy low");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
          Log.i(TAG, "Compass accuracy medium");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
          Log.i(TAG, "Compass accuracy high");
          break;
        default:
          Log.w(TAG, "Unknown compass accuracy value: " + event.accuracy);
      }
    }

    updateDeclination();
    if (geomagneticField != null) {
      float trueHeading = (x + geomagneticField.getDeclination() + 360) % 360;

      heading.put(TiC.PROPERTY_TRUE_HEADING, trueHeading);
    }

    KrollDict data = new KrollDict();
    data.putCodeAndMessage(TiC.ERROR_CODE_NO_ERROR, null);
    data.put(TiC.PROPERTY_HEADING, heading);
    return data;
  }
  protected TiDict eventToTiDict(SensorEvent event, long ts) {
    float x = event.values[0];
    float y = event.values[1];
    float z = event.values[2];

    TiDict heading = new TiDict();
    heading.put("type", EVENT_HEADING);
    heading.put("timestamp", ts);
    heading.put("x", x);
    heading.put("y", y);
    heading.put("z", z);
    heading.put("magneticHeading", x);
    heading.put("accuracy", event.accuracy);
    if (DBG) {
      switch (event.accuracy) {
        case SensorManager.SENSOR_STATUS_UNRELIABLE:
          Log.i(LCAT, "Compass accuracy unreliable");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_LOW:
          Log.i(LCAT, "Compass accuracy low");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM:
          Log.i(LCAT, "Compass accuracy medium");
          break;
        case SensorManager.SENSOR_STATUS_ACCURACY_HIGH:
          Log.i(LCAT, "Compass accuracy high");
          break;
        default:
          Log.w(LCAT, "Unknown compass accuracy value: " + event.accuracy);
      }
    }
    if (geomagneticField != null) {
      float trueHeading = x - geomagneticField.getDeclination();
      if (trueHeading < 0) {
        trueHeading = 360 - trueHeading;
      }

      heading.put("trueHeading", trueHeading);
    }
    TiDict data = new TiDict();
    data.put("heading", heading);

    return data;
  }
Exemple #4
0
  @Override
  public void onSensorChanged(SensorEvent event) {
    // if (!computing.compareAndSet(false, true)) return;
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
      /*smoothed = LowPassFilter.filter(event.values, grav);
      grav[0] = smoothed[0];
      grav[1] = smoothed[1];
      grav[2] = smoothed[2];*/
      grav[0] = event.values[0];
      grav[1] = event.values[1];
      grav[2] = event.values[2];
    } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
      /*            smoothed = LowPassFilter.filter(event.values, mag);
                  mag[0] = smoothed[0];
                  mag[1] = smoothed[1];
                  mag[2] = smoothed[2];
      */
      mag[0] = event.values[0];
      mag[1] = event.values[1];
      mag[2] = event.values[2];
    }

    // Get rotation matrix given the gravity and geomagnetic matrices
    SensorManager.getRotationMatrix(rotation, null, grav, mag);
    SensorManager.getOrientation(rotation, orientation);
    floatBearing = orientation[0];

    // Convert from radians to degrees
    floatBearing = Math.toDegrees(floatBearing); // degrees east of true north (180 to -180)

    // Compensate for the difference between true north and magnetic north
    if (gmf != null) floatBearing += gmf.getDeclination();

    // adjust to 0-360
    if (floatBearing < 0) floatBearing += 360;

    computing.set(false);

    builder.setLength(0);
    builder.append("X " + rotation[0] + "\nY " + rotation[1] + "\nZ " + rotation[2] + "\n");
    builder.append("X " + rotation[3] + "\nY " + rotation[4] + "\nZ " + rotation[5] + "\n");
    builder.append("X " + rotation[6] + "\nY " + rotation[7] + "\nZ " + rotation[8] + "\n");
    textView.setText(builder.toString());
  }
  /** This function registers sensor listeners for the accelerometer, magnetometer and gyroscope. */
  private void initListeners() {
    sensorMgr = (SensorManager) mContext.getSystemService(Activity.SENSOR_SERVICE);
    fuseTimer = new Timer();

    sensors = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
    if (sensors.size() > 0) {
      sensorGravRunning = false;
      sensorGrav = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
      sensorMgr.registerListener(this, sensorGrav, sensorRate);
    }
    sensors = sensorMgr.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
    if (sensors.size() > 0) {
      sensorMagRunning = false;
      sensorMag = sensorMgr.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
      sensorMgr.registerListener(this, sensorMag, sensorRate);
    }
    sensors = sensorMgr.getSensorList(Sensor.TYPE_GYROSCOPE);
    if (sensors.size() > 0) {
      sensorGyroRunning = false;
      sensorGyro = sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
      sensorMgr.registerListener(this, sensorGyro, sensorRate);
      fuseTimer.scheduleAtFixedRate(
          new calculateFusedOrientationTask(), 1000, TIME_CONSTANT); // use the gyro
      NLog.d(TAG, "initListeners() - " + "Gyro found");
    } else {
      fuseTimer.scheduleAtFixedRate(
          new calculateUnfusedOrientationTask(), 1000, TIME_CONSTANT); // don't use the gyro
      NLog.d(TAG, "initListeners() - " + "No gyro found");
    }

    locationMgr = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
    locationMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, this);

    try {
      Location gps = locationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
      Location network = locationMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
      if (gps != null) onLocationChanged(gps);
      else if (network != null) onLocationChanged(network);
      else onLocationChanged(NCompassARData.hardFix);
    } catch (Exception ex2) {
      onLocationChanged(NCompassARData.hardFix);
    }

    float angleY = -90 * toRadians;

    gmf =
        new GeomagneticField(
            (float) NCompassARData.getCurrentLocation().getLatitude(),
            (float) NCompassARData.getCurrentLocation().getLongitude(),
            (float) NCompassARData.getCurrentLocation().getAltitude(),
            System.currentTimeMillis());
    angleY = -gmf.getDeclination() * toRadians;

    synchronized (mageticNorthCompensation) {
      mageticNorthCompensation.toIdentity();

      // Counter-clockwise rotation at negative declination around the y-axis
      // note2: declination is the difference between true north and magnetic north
      mageticNorthCompensation.set(
          FloatMath.cos(angleY),
          0f,
          FloatMath.sin(angleY),
          0f,
          1f,
          0f,
          -FloatMath.sin(angleY),
          0f,
          FloatMath.cos(angleY));

      // Rotate the matrix to match the orientation
      mageticNorthCompensation.prod(xAxisRotation);
    }
  }