2013-04-01 79 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持续时间来指定所需的模型。

另一个好处是,如果你想要一个非线性运动模型,你也可以很容易地扩展到这一点。在上面给出的例子中,我使用了盒子过滤器来进行平滑,但是您可以使用其他方法来考虑无论您正在跟踪的物体的加速/减速的物理限制。更像高斯曲线的滤波器可以实现这一点。