Android Open Source - sonarlog Sonar Reader






From Project

Back to project page sonarlog.

License

The source code is released under:

GNU General Public License

If you think the Android project sonarlog listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package org.sonarlog.ioio;
/*from   ww w.  j  a  va  2s .  co m*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.CopyOnWriteArrayList;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.Uart;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOService;

import org.sonarlog.R;
import org.sonarlog.Project;
import org.sonarlog.SonarLoggerActivity;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;

public class SonarReader extends IOIOService {
  private static final String TAG = "SonarReader";

  public static String projectName = "default";
  public Project prj;
  private NotificationManager mNM;
  private NMEAParser parser;
  public static CopyOnWriteArrayList<GpsReading> positions;
  public static Queue<SonarReading> depths;

  private LocationManager lm;
  private MyLocationListener locationListener;

  private static boolean showingDebugToast = false;
  private int lastStatus = 0;
  
  public static double MIN_ACCURACY_METERS = 5;
  int MIN_TIME_MILLIS = 100;
  int MIN_DISTANCE_METERS = 0;
  double MAX_INTERPOLATION_DIST = 20;
  
  @Override
  protected IOIOLooper createIOIOLooper() {
    return new BaseIOIOLooper() {
      
      //output signals
      private DigitalOutput led_;
      private Uart uart_;
      private final int BAUD_RATE = 4800;
      private int nloops = 0;
      //pins
      private final int TX_PIN = 3;
      private final int RX_PIN = 6;
      
      private final int deltat=100;
      @Override
      protected void setup() throws ConnectionLostException,
      InterruptedException {
        Log.i(TAG,"IOIO setup");
        led_ = ioio_.openDigitalOutput(IOIO.LED_PIN);
        uart_ = ioio_.openUart(RX_PIN, TX_PIN, BAUD_RATE, Uart.Parity.NONE, Uart.StopBits.ONE);
        parser = new NMEAParser(uart_.getInputStream());
        led_.write(true);          
      }
      
      @Override
      public void loop() throws ConnectionLostException,
      InterruptedException {
        this.nloops += 1;
        
        Log.d(TAG, String.format("Loop no %d", this.nloops) );
        try {
          parser.handleCharacters();

        } catch (IOException e) {
          Log.e(TAG, e.getMessage());
        }
        synchronized(depths) {
          Log.d(TAG,  String.format("No depths: %d, No positions: %d", depths.size(), positions.size()));
        }
        while (interpolate_pos()) {
          led_.write(true);
        }
        Thread.sleep(this.deltat);
        led_.write(false);      
      }
        
    };
  }
  

  public void onCreate() {
    this.prj = new Project(projectName);
    this.prj.initLogs();
    MIN_ACCURACY_METERS = this.prj.getParameterAsDouble("gps.accuracy");
    mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    depths = new LinkedList<SonarReading>();
    positions = new CopyOnWriteArrayList<GpsReading>();
    showNotification();
    startGpsListener();
    super.onCreate();    
  }
  @Override
  public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    
  }
  
  private void startGpsListener() {

    // ---use the LocationManager class to obtain GPS locations---
    lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    locationListener = new MyLocationListener();
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,
          MIN_TIME_MILLIS,
          MIN_DISTANCE_METERS, locationListener);
    
    Log.d(TAG, "Started location manager");
  }

  private void shutdownGpsListener() {
    lm.removeUpdates(locationListener);
  }
  
  private void sendUpdateUIBroadcast(){
    Intent intent = new Intent("UPDATE_STATS");
      LocalBroadcastManager.getInstance(this).sendBroadcastSync(intent);
  }

  private void showNotification() {
    // In this sample, we'll use the same text for the ticker and the
        // expanded notification
    CharSequence text = "Logging sonar!";
        
    // prepare intent which is triggered if the
    // notification is selected

    Intent intent = new Intent(this, SonarLoggerActivity.class);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
        
    // build notification
    // the addAction re-use the same intent to keep the example short
    Notification n  = new NotificationCompat.Builder(this)
        .setContentTitle(text)
        .setContentText("Sonar Logger is running!")
        .setSmallIcon(R.drawable.ic_launcher)
        .setContentIntent(pIntent)
        .addAction(R.drawable.ic_launcher,"Go to activity", pIntent).build();
    
    mNM.notify(0, n);  
  }
  public  void disconnected() {
    Log.d(TAG, "IOIO disconnected!");
  }
  
  @Override
  public void onDestroy() {
    super.onDestroy();
    this.prj.close();
    shutdownGpsListener();
    // Tell the user we stopped.
    Toast.makeText(this, "Sonar Logger stopped!", Toast.LENGTH_SHORT).show();
    mNM.cancel(0);

  }
  
  
  public boolean interpolate_pos() {
    this.sendUpdateUIBroadcast();
    int posInd = 1;
    SonarReading reading;
    synchronized(depths) {
      reading = depths.peek();
      while (reading != null && positions.size() > 0 && reading.timestamp < positions.get(0).timestamp) {
        depths.remove();
        reading = depths.peek();
      }
    }

    // depth queue empty
    if (reading == null)
      return false;
    
    //no positions recorded
    if (positions.size() < 2) {
      return false;
    }
    
    while( posInd < positions.size() - 1 &&
        reading.timestamp > positions.get(posInd).timestamp) {    
      posInd += 1; 
    }

    if (posInd < 1 | posInd >= positions.size())
      return false;
    
    GpsReading p1 = positions.get(posInd - 1);
    GpsReading p2 = positions.get(posInd);
  

    if (reading.timestamp > p2.timestamp | reading.timestamp < p1.timestamp)
      return false;

    if (distance(p1, p2) > MAX_INTERPOLATION_DIST) {
      Log.d(TAG, "Too large distance between positions");
      synchronized(depths) {
        depths.remove();
      }
      this.remove_old_positions(posInd -1);
      return true;
    }
    
    if (reading.timestamp == p1.timestamp)
      reading.set_pos(p1.longitude, p1.latitude, p1.accuracy);
    else if (reading.timestamp == p2.timestamp)
      reading.set_pos(p2.longitude, p2.latitude, p2.accuracy);
    else {
      double weight = ((reading.timestamp - p1.timestamp) /
          (p2.timestamp-p1.timestamp));
      reading.set_pos(
          p1.longitude + weight * (p2.longitude - p1.longitude),
          p1.latitude + weight * (p2.latitude - p1.latitude),
          Math.max(p1.accuracy, p2.accuracy)
      );
    }

    this.remove_old_positions(posInd -1);
    this.prj.log_depth(reading);
    synchronized(depths) {
      depths.remove();
    }
    SonarLoggerActivity.logged_depths += 1;

    return true;
  }
  
  public double distance(GpsReading p1, GpsReading p2) {
    double R = 6371; // km
    double phi_1 = Math.toRadians(p1.latitude);
    double phi_2 = Math.toRadians(p2.latitude);
    double delta_phi = Math.toRadians(p2.latitude - p1.latitude);
    double delta_lambda = Math.toRadians(p2.longitude - p1.longitude);

    double a = Math.sin(delta_phi/2) * Math.sin(delta_phi/2) +
            Math.cos(phi_1) * Math.cos(phi_2) *
            Math.sin(delta_lambda/2) * Math.sin(delta_lambda/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = R * c;
    SonarLoggerActivity.distance = dist;
    return dist;
  }
  
   public void remove_old_positions(int lastOldIndex) {
     positions = new CopyOnWriteArrayList<GpsReading>(positions.subList(lastOldIndex, positions.size()));
   }
  
  private class MyLocationListener implements LocationListener {
    
    public void onLocationChanged(Location loc) {
      if (loc != null) {
        try { 
          SonarLoggerActivity.tot_pos += 1;

          if (loc.hasAccuracy() && (loc.getAccuracy() <= MIN_ACCURACY_METERS)) {
            GpsReading reading = new GpsReading(
                loc.getLongitude(),
                loc.getLatitude(),
                System.currentTimeMillis(),
                (double) loc.getAccuracy());
            positions.add(reading);
            SonarLoggerActivity.valid_pos += 1;
            SonarLoggerActivity.accuracy = loc.getAccuracy();
            
          }
        } catch (Exception e) {
          Log.e(TAG, e.toString());
        }
      }
    }
            
    public void onProviderDisabled(String provider) {
      if (showingDebugToast)
        Toast.makeText(getBaseContext(),
            "onProviderDisabled: " + provider, Toast.LENGTH_SHORT)
            .show();

    }

    public void onProviderEnabled(String provider) {
      if (showingDebugToast)
        Toast.makeText(getBaseContext(),
            "onProviderEnabled: " + provider, Toast.LENGTH_SHORT)
            .show();

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
      String showStatus = null;
      if (status == LocationProvider.AVAILABLE)
        showStatus = "Available";
      if (status == LocationProvider.TEMPORARILY_UNAVAILABLE)
        showStatus = "Temporarily Unavailable";
      if (status == LocationProvider.OUT_OF_SERVICE)
        showStatus = "Out of Service";
      if (status != lastStatus && showingDebugToast) {
        Toast.makeText(SonarReader.this, "new status: " + showStatus,
            Toast.LENGTH_SHORT).show();
      }
      lastStatus = status;
    }

  }

  
  @Override
  public IBinder onBind(Intent arg0) {
    return ioioBinder;
  }

  // This is the object that receives interactions from clients. See
  // RemoteService for a more complete example.
  private final IBinder ioioBinder = new LocalBinder();

  /*
   * Class for clients to access. Because we know this service always runs in
   * the same process as its clients, we don't need to deal with IPC.
   */
  public class LocalBinder extends Binder {
    public SonarReader getService() {
      return SonarReader.this;
    }
  }
  
}




Java Source Code List

org.sonarlog.Project.java
org.sonarlog.SonarLoggerActivity.java
org.sonarlog.ioio.GpsReading.java
org.sonarlog.ioio.NMEAParser.java
org.sonarlog.ioio.SonarReader.java
org.sonarlog.ioio.SonarReading.java