/** * 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; }
@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); } }