【问题标题】:Predicting data based on averages基于平均值预测数据
【发布时间】:2013-04-01 16:27:00
【问题描述】:

我每秒都有 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# 新手;必须有更好的方法来做到这一点。这是我尝试进行预测的代码的 sn-p(---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;
   }

【问题讨论】:

    标签: c# serial-port data-processing


    【解决方案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,  
    

    抱歉,我正在尝试确保该方法适用于其他测试用例的所有编辑。

    编辑:添加了否定案例的测试。

    【讨论】:

    • 谢谢这工作真的很好:-) 但是有一个问题。因为我的数组设置是这样的:`double[] dmag = new double[100000];` 在我的纬度或经度数据之后有空值,这会弄乱平均值。有没有办法将数组设置为随着新数据的添加而变得更大,以便数组的空位中没有空值?
    • 我用 ArrayList 解决了这个问题 :-)
    • 太棒了!抱歉,我之前没有看到您的评论,我会建议这样做的。
    【解决方案2】:

    我会从信号处理的角度来阐述这个问题。因此,如果您有一个信号 f(t)(例如,它可能是您的离散化 latitude 数组),您想创建一个由

    定义的新信号 g(t)
    g(t) = E[f(z) | t-0.5*w <= z <= t+0.5*w]
    

    其中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 持续时间来指定您想要的模型。

    另一个好处是,如果您想要一个非线性运动模型,您也可以轻松地扩展到该模型。在我上面给出的示例中,我使用了一个盒子过滤器来进行平滑处理,但是您可以使用其他东西来考虑您正在跟踪的任何东西的加速/减速的物理限制。形状更像高斯曲线的滤波器可以做到这一点。

    【讨论】:

      猜你喜欢
      • 2023-02-16
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-18
      • 2022-08-16
      • 1970-01-01
      相关资源
      最近更新 更多