Code


Below is all of the code I have written so far. It *should* be fully functioning. I haven't had time to completely test all of the edge cases yet, and there isn't much of error catching in the code. If you have any questions or suggestions please feel free to comment (using the link at the bottom of the page).

//This is the class that does all of the calculations

import java.util.Calendar;
import java.util.TimeZone;

public class Calc {
private static Double longitude;
private static Double latitude;
private static Double utc;
private static Double lst;
private static Double ra;
private static Double dec;
private static Double yaw;
private static Double pitch;


public Calc(){
longitude = 0.00;
latitude = 0.00;
utc = 0.00;
lst = 0.00;
ra = 0.00;
dec= 0.00;
yaw= 0.00;
pitch=0.00;
}

public static EqCoordinates calcEqua(Double longt,Double lat, Double p, Double y){
longitude = longt;
latitude = lat;
pitch = p;
yaw = y;
setLST();

convertCoordinates();
return (new EqCoordinates(ra,dec));
}


public static void convertCoordinates(){
//convert latitude yaw and pitch to radians

pitch = Math.toRadians(pitch);
yaw = Math.toRadians(yaw);
latitude = Math.toRadians(latitude);

//these constants make it to where these values only have to be calculated once per run
final Double twopi = 2.00 * Math.PI;
final Double sinPch = Math.sin(pitch);
final Double sinLat = Math.sin(latitude);
final Double cosPch = Math.cos(pitch);
final Double cosLat = Math.cos(latitude);
final Double cosYaw = Math.cos(yaw);

//calc dec, store sinDec for use to calc ra, convert dec to degrees
Double sinDec = (sinPch*sinLat)+(cosPch*cosLat*cosYaw);
dec = Math.asin(sinDec);
dec = Math.toDegrees(dec);

//calc ra
Double h = (sinPch-sinLat*sinDec)/(cosLat*Math.cos(dec));
h = Math.acos(h);
if(Math.sin(yaw)>0)
h = twopi - h;

//TODO Convert directly from radians to hours instead of from radians to degrees to hours
//convert to degrees than to hours
h = Math.toDegrees(h)/15;

//subtract hour angle (h) from local sidereel time (lst)
ra = lst - h;
//normalize ra so it falls within 0 to 24 hours
if(ra > 0)
ra = ra - (24*Math.floor(ra/24));
else if (ra < 0)
ra = ra - (24*Math.floor(ra/24));
}


public static double getLST(){
return lst;
}

public static float getJulianDate(){
   //calc julain date at 00:00:00 GMT on input date
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
   int month = cal.get(Calendar.MONTH) +1;
   System.out.println("Month = " +month);
   int year = cal.get(Calendar.YEAR);
   int day = cal.get(Calendar.DAY_OF_MONTH);
 
   int tempA = (year/100);
   int tempB = 2-tempA+(tempA/4);
   int tempC = (int) (365.25*year);
   int tempE = (int) (30.6001*(month+1));
 
   return (float) (tempB + tempC+ tempE + day + 1720994.5);
}

public static double getGST(){
   float jdate = getJulianDate();
   System.out.println("Jdate = " + jdate);
   Double temp = (jdate - 2451545.0)/36525.0;
   setUTC();
   double temp0 = 6.697374558+ (2400.051336*temp)+(0.000025862*(Math.pow(temp, 2)))+((utc*1.0027379093));
   while(temp0>24 || temp0<0){
  if(temp0>24)
  temp0 = temp0 - 24;
  else if(temp0<0)
  temp0 = temp0 + 24;
   }
   return temp0;
}

public static void setLST(){
   double gst = getGST();
   lst = gst + (longitude/15);
 
   if(lst<0){
  while(lst<0)
  lst= lst+24;
   }
   else{
  while(lst>24)
  lst = lst-24;
   }
   System.out.println("LST: " + lst);
}


public static void setUTC(){
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
double temp = cal.get(Calendar.HOUR_OF_DAY) + cal.get(Calendar.MINUTE)/60.0 + cal.get(Calendar.SECOND)/3600.0;
utc = temp;
}
}

//This class may change a lot. It started as a sample read serial port class, but I modified it quite a bit to suite my needs

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class ReadSerialPort {

public ReadSerialPort() {
super();
}
    void connect (String portName) throws Exception {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if ( portIdentifier.isCurrentlyOwned() ){
            System.out.println("Error: Port is currently in use");
        } else {
            CommPort commPort = portIdentifier.open(this.getClass().getName(),2000);
            
            if ( commPort instanceof SerialPort ) {
                SerialPort serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.FLOWCONTROL_NONE);
                
                InputStream in = serialPort.getInputStream();
                (new Thread(new SerialReader(in))).start();

            } else {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }

    
    /** */
    public static class SerialReader implements Runnable {
        InputStream in;
        BufferedReader reader;
        
        public SerialReader ( InputStream in ) {
            this.in = in;
            this.reader = new BufferedReader(new InputStreamReader(in));
        }
        
        public EqCoordinates getPieces(String line) {
        Double longitude = 0.0;
        Double latitude = 0.0;
        Double yaw = 0.0;
        Double pitch = 0.0;
        String delim = "[,]+";
        String[] sp = line.split(delim);
        ArrayList<Pair> p = new ArrayList<Pair>();
        String type = null;
        Double value = 0.00;
        Boolean errorflag = false;
        for(String s: sp){
        errorflag=false;
        String[] temp = s.split("[:]+");
        type = temp[0];
        try{
        value = Double.parseDouble(temp[1]);
        } catch(NumberFormatException e){
        errorflag = true;
        }
        if(!errorflag){
        p.add(new Pair(type,value));
        }
        if(type.equalsIgnoreCase("LAT"))
        latitude = value/10000000;
        else if (type.equalsIgnoreCase("LON"))
        longitude = value/10000000;
        else if (type.equalsIgnoreCase("YAW"))
        yaw = value;
        else if (type.equalsIgnoreCase("PCH"))
        pitch = value;
        }
       
        printList(p);
        return Calc.calcEqua(longitude, latitude, pitch, yaw);
        }
        
    public void printList(ArrayList<Pair> ap){
    for(Pair pa: ap){
    System.out.print(pa.getType()+ " : " +pa.getValue() + " , ");
    }
    System.out.println();
    }
        
        public void run () {
            String line = null;
            try{
               while ((line = reader.readLine()) != null) {
              if(line.length()>75){
              EqCoordinates coords = getPieces(line);
              System.out.println("RA = " + coords.getRA() + " , DEC = " + coords.getDec());

              System.out.println("Read line with " + line.length() + " characters: \"" + line + "\"");
              }
               }
            }
            catch ( IOException e ) {
                e.printStackTrace();
            }            
        }
    }

public static void main(String[] args) {
        try {
        //Thread.sleep(30000);
            (new ReadSerialPort()).connect("/dev/ttyUSB");
        } catch ( Exception e ) {
            e.printStackTrace();
        }
}
}

//This class isn't completely necesary, but it is helpful. It came with the class above as a sample. It lets you figure out which serial port the ArduIMU is on without having to leave eclipse

import gnu.io.*;

public class ListCommPorts {

    @SuppressWarnings("unchecked")
    static void listPorts()
    {
        java.util.Enumeration<CommPortIdentifier> portEnum = CommPortIdentifier.getPortIdentifiers();
        while ( portEnum.hasMoreElements() ) 
        {
            CommPortIdentifier portIdentifier = portEnum.nextElement();
            System.out.println(portIdentifier.getName()  +  " - " +  getPortTypeName(portIdentifier.getPortType()) );
        }        
    }
    
    static String getPortTypeName ( int portType )
    {
        switch ( portType )
        {
            case CommPortIdentifier.PORT_I2C:
                return "I2C";
            case CommPortIdentifier.PORT_PARALLEL:
                return "Parallel";
            case CommPortIdentifier.PORT_RAW:
                return "Raw";
            case CommPortIdentifier.PORT_RS485:
                return "RS485";
            case CommPortIdentifier.PORT_SERIAL:
                return "Serial";
            default:
                return "unknown type";
        }
    }

public static void main(String[] args) {
listPorts();
}
}

//This class stores a pair of values, the first is a string and the second is a Double. This is primarily used when I read in the sensor data

public class Pair {
private String type;
private Double value;
public Pair() {
type = null;
value = -1.00;
}
public Pair(String t, Double v){
type = t;
value = v;
}
public void setType(String t){
type =t;
}
public String getType(){
return type;
}
public void setValue(Double v){
value = v;
}
public Double getValue(){
return value;
}


}



//This class stores the equatorial coordinates in an easy to use way, I haven't used it yet but I plan to

public class EqCoordinates {
private Double ra;
private Double dec;
public EqCoordinates (){
ra = 0.0;
dec = 0.0;
}
public EqCoordinates(Double r, Double d){
ra = r;
dec = d;
}
public void setRA(Double r){
ra = r;
}
public Double getRA(){
return ra;
}
public void setDec(Double d){
dec = d;
}
public Double getDec(){
return dec;
}
}

No comments:

Post a Comment