1

我有时域数据样本,这些样本不断更新一个名为“rollHistory”的 LinkedList,然后将其显示在图中,如下所示:

if (rollHistory.size() > HISTORY_SIZE) {
                        rollHistory.removeFirst(); //remove first value
                    }
                        rollHistory.addLast(sensorReading); //insert latest value


                        rollHistorySeries.setModel(rollHistory , SimpleXYSeries.ArrayFormat.Y_VALS_ONLY); //added 06/24/2013
                        aprHistoryPlot.redraw(); 

                    } 

“HISTORY_SIZE”是要绘制的数据的最大长度。这段代码工作正常。但是,我真正想展示的是时域数据的 FFT,而不是数据本身。为此,我下载了 JTransform 库。realForwardFull() 函数似乎需要一个双精度数组,所以我尝试将 LinkedList(上面称为 rollHistory)转换为一个数组,然后将其传递给 realForwardFull() 函数。但是 rollHistorySeries.setModel 命令似乎需要一个 LinkedList。所以我然后尝试将 realForwardFull() 的输出转换回链表。该代码在eclipse中没有显示错误,但是当我尝试在手机上运行它时它会关闭。

DoubleFFT_1D fftDo = new DoubleFFT_1D(512); 
if (rollHistory.size() > HISTORY_SIZE) {
                        rollHistory.removeFirst();
                    }
                        rollHistory.addLast(sensorReading);

                        Double[] rollHistoryAr = rollHistory.toArray(new Double[0]); // convert rollHistory to array

                        double[] fft = new double[256 * 2];
                        System.arraycopy(rollHistoryAr, 0, fft, 0, 256);            //copy rollHistoryAr to fft array
                        fftDo.realForwardFull(fft);                                 //find fft of rollHistory and save to fft
                        LinkedList rollHistoryFreq = new LinkedList(Arrays.asList(fft)); //convert back to LinkedList
                        rollHistorySeries.setModel(rollHistoryFreq , SimpleXYSeries.ArrayFormat.Y_VALS_ONLY); //added 06/24/2013
                        aprHistoryPlot.redraw(); 
                        //mGraph.addDataPoint(sensorReading);
                } 

我尝试用 try/catch 包装上述代码的子集,如下所示:

try {
                        //jTransform Attempt
                        Double[] rollHistoryAr = rollHistory.toArray(new Double[rollHistory.size()]);
                        double[] fft = new double[256];
                        System.arraycopy(rollHistoryAr, 0, fft, 0, 256);     
                        dfft.realForward(fft); 
                        LinkedList rollHistoryFreq = new LinkedList(Arrays.asList(fft)); 
                        rollHistorySeries.setModel(rollHistoryFreq, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY); 
                        } catch (Exception e)
                        { e.printStackTrace(); }

在这种情况下,应用程序运行时不会出现“不幸...已停止”错误,但图表为空,并且 LogCat 显示以下消息:

07-13 16:18:18.509: W/System.err(11288): java.lang.ArrayStoreException: java.lang.Integer 不能存储在 java.lang.Double[] 类型的数组中
07-13 16:18 :18.509: W/System.err(11288): at java.util.LinkedList.toArray(LinkedList.java:958)
07-13 16:18:18.509: W/System.err(11288): at com.example。 MyActivity$ArduinoReceiver.onReceive(MyActivity.java:166)
07-13 16:18:18.509: W/System.err(11288): 在 android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:758)
07 -13 16:18:18.509: W/System.err(11288): 在 android.os.Handler.handleCallback(Handler.java:725)
07-13 16:18:18.509: W/System.err(11288):在 android.os.Handler.dispatchMessage(Handler.java:92)
07-13 16:18:18.509: W/System.err(11288): 在 android.os.Looper.loop(Looper.java:137) 07-13 16:18:18.509: W/System.err(11288) : 在 android.app.ActivityThread.main(ActivityThread.java:5293)
07-13 16:18:18.509: W/System.err(11288): 在 java.lang.reflect.Method.invokeNative(Native Method) 07- 13 16:18:18.509: W/System.err(11288): 在 java.lang.reflect.Method.invoke(Method.java:511) 07-13 16:18:18.509: W/System.err(11288) : 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102) 07-13 16:18:18.509: W/System.err(11288): 在 com.android.internal.os.ZygoteInit .main(ZygoteInit.java:869)
07-13 16:18:18.509:W/System.err(11288):在 dalvik.system.NativeStart.main(本机方法)

有人对我做错了什么有任何想法吗?如有必要,我可以发布更多代码。谢谢!

4

1 回答 1

2

当你说代码关闭时,你是什么意思?它是无限期地冻结并且不产生堆栈跟踪,还是应用程序实际上崩溃并产生堆栈跟踪?如果是前者,您可以在调试模式下运行该应用程序并检查它是否在 Androidplot 库中的某个位置冻结?如果是后者,你能提供堆栈跟踪吗?

关于上面代码的一些想法:首先,据我所知,FFT 可能是 - 非常 - cpu 密集型操作。也许不如他们的 DFT 对手那么糟糕,但从 CPU/主线程的角度来看,仍然非常繁重。我无法确定,但似乎您正在主线程上进行所有 FFT 处理,这很糟糕。我强烈建议在后台线程上进行这些计算。这很有可能解决您的主要问题。

我还注意到您可能会考虑一个完全可选的优化:您正在使用 SimpleXYSeries 作为您的系列实现,并且您在上面提到它的 setModel(...) 方法需要一个 LinkedList,这并不完全正确。它能够接受 LinkedList,但也可以接受任何列表。对于需要任意增长和收缩的动态实现,LinkedList 是一个很好的通用选择。但是,使特定 Series 实现高效的原因在于它是否与应用程序的数据模型相匹配,并避免了昂贵的复制/新操作的需要。鉴于您使用了采用 double[] 的 FFT 库,我认为更有效的设计是围绕 double[] 编写您自己的 XYSeries 实现,以便绘图和 fft 代码可以共享数据。环形缓冲区。SimpleXYSeries 只是一个方便的实现,可以帮助您入门,但它几乎从来都不是最优的,因为它试图迎合最低的公分母。同样,这是一个完全可选的性能优化,取决于您绘制的点数和频率,这可能完全是浪费时间。

于 2013-06-27T14:17:54.667 回答