2013-04-01 111 views
1

我有GPS數據每秒進入我的PC上的串行端口。我已成功處理GPS數據,並將經度和緯度作爲浮點數存儲在單獨的數組中。根據平均值預測數據

double[] dlat = new double[100000]; //contains the latitude data 
double[] dlon = new double[100000]; //contains the longitude data 

大多數時候經緯度數字與GPS位置保持相同,每5米只改變一次。當數組中的緯度或經度值發生變化時,我希望我的程序根據平均值來預測變化之間存儲的數據點的緯度或經度。例如:

比方說,這是latitude數組的內容:

2,2,2,2,2,17 

我希望我的程序來改變什麼數組中:

2,5,8,11,14,17 

我試着解決問題,但我的方法不起作用: - /我是C#的新手;必須有更好的方式來做到這一點。這裏是我的代碼,試圖做預測的片段(---GPS coordinate prediction---後位是不工作的位):

string RxString;// where the raw serial data is stored 
string mag; 
double[] dmag = new double[100000];//magnetic data stored here 
string lat; 
double[] dlat = new double[100000];//latitude data stored here 
string lon; 
double[] dlon = new double[100000];//longitude data stored here 
double average;//average step between change in latiude 
int i; //pointer double array data; 
int count;//counter for prediction code 

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)//activates when port is open and data in buffer 
{ 
    RxString = serialPort1.ReadTo("\r\n");//read raw data from serial port into string 
    this.Invoke(new EventHandler(DisplayText));//invoke allows it to call function diplay text*/ 

    if(RxString.StartsWith("G")) 
    { 
     lat = RxString.Split(',')[0].Substring(4);// extract latitude 
     this.Invoke(new EventHandler(DisplayText1));//invoke allows it to call function diplay text 
     dlat[i] = Convert.ToDouble(lat);//convert and store in double array 
     this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function 

     lon = RxString.Split(',')[2];// extract longitude 
     this.Invoke(new EventHandler(DisplayText2));//invoke allows it to call function diplay text 
     dlon[i] = Convert.ToDouble(lon);//covert and store in double array 
     this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function 

     mag = RxString.Split(',')[3].Substring(6).Trim();// extract magnetic data 
     this.Invoke(new EventHandler(DisplayText3));//invoke allows it to call function diplay text 
     dmag[i] = Convert.ToDouble(mag);//convert and store in double array 
     this.Invoke(new EventHandler(Form1_Load));//invoke allows it to call function 
     i++; 
     RxString = null; 

     /* -------------------------GPS coordinate prediction--------------------------------------------- */ 

     if (i > 0) 
     { 
      if (dlat[i] == dlat[i - 1]) 
      { 
       count++; 
      } 
      if (dlat[i] != dlat[i - 1]) 
      { 
       double average = (dlat[i] - dlat[i - 1])/(count);//average data step beween changed values 
       int firstAv = i - (count - 1);//position of first average 
       int lastAv = i - 1;//position of last average 

       for (int j = firstAv; j <= lastAv; i++) 
       { 
        dlat[j] = dlat[j - 1] + average; 
       } 

       count = 0; 
      } 
     } 
     if (i==0) count = 1; 
    } 

回答

1

以下工作:

using System; 
    using System.Text; 

    namespace Practice 
    { 
     public class Hello 
     { 
      static double[] ldat = {2.0,2.0,2.00,2.0,2.0,17.0}; 
      static double[] ldat2 = {2.0,3.0,4.00,4.0,7.0,19.0}; 
      static double[] ldat3 = {0.0, 0.0, -5.0, -5.0, -11.0, -11.0, -20}; 

      public static void Main(string[] args) 
      { 
       test(ldat); 
       test(ldat2); 
       test(ldat3); 
      } 

      public static void test(double[] array){ 
       //Use Code from here..... 
       int firstEqualIndex = -1; 
       for(int i = 1; i < array.Length ; i ++) 
       { 
        if (i > 0) 
        { 
         if(array[i] == array[i - 1]) 
         { 
          if(firstEqualIndex == -1) 
          { 
           firstEqualIndex = i - 1; 
          } 
         } 
         else //They are not equal 
         { 
          //Figure out the average. 
          if(firstEqualIndex >= 0) 
          { 
           double average = (array[i] - array[firstEqualIndex])/(Double)((i - firstEqualIndex)); 
           int k = 0; 
           for(int j = firstEqualIndex; j < i; j++) 
           { 
            array[j] += average * k; 
            k++; 
           } 
           firstEqualIndex = -1; 
          } 
         } 
        } 
       } 
       //..... to here. 
       StringBuilder builder = new StringBuilder(); 
       foreach (double entry in array) 
       { 
        // Append each int to the StringBuilder overload. 
        builder.Append(entry).Append(", "); 
       } 
       string result = builder.ToString(); 
       Console.WriteLine(result); 
      } 
     } 
    }  

該測試輸出

2, 5, 8, 11, 14, 17, 
2, 3, 4, 5.5, 7, 19, 
0, -2.5, -5, -8, -11, -15.5, -20, 

對不起,我試圖確保該方法適用於其他測試用例的所有編輯。

編輯:增加了一個負面情況的測試。

+0

感謝這工作得很好:-)但是有一個問題。因爲我的數組設置是這樣的:'double [] dmag = new double [100000];'在我的緯度或經度數據後面有空值,這會使平均值變差。有沒有一種方法可以將數組設置爲在添加新數據時變得更大,以便在數組的空位中不存在空值? –

+0

我解決了使用ArrayList解決了問題:-) –

+0

太棒了!對不起,我沒有看到你的評論早些時候我會建議。 – nattyddubbs

1

我會根據信號處理制定這個問題。所以,如果你有一個信號f(t)(這可能是你的離散latitude陣列爲例),您要創建由

g(t) = E[f(z) | t-0.5*w <= z <= t+0.5*w] 

定義一個新的信號g(t)其中E時表示預期值(或平均),而w是你的過濾器的寬度。

以這種方式對問題進行建模的好處之一是,您有一種指定運動模型的非常具體的方法。也就是說,你將如何轉換數據[0,0,0,0,1,1,1,1]?

它應該是[0,0,0,1/3,2/3,1,1,1]嗎?

還是應該是[0,1/7,2/7,3/7,4/7,5/7,6/7,1]?

鑑於您知道您的樣本之間有多少時間間隔,您可以選擇w持續時間來指定所需的模型。

另一個好處是,如果你想要一個非線性運動模型,你也可以很容易地擴展到這一點。在上面給出的例子中,我使用了盒子過濾器來進行平滑,但是您可以使用其他方法來考慮無論您正在跟蹤的物體的加速/減速的物理限制。更像高斯曲線的濾波器可以實現這一點。