T O P I C R E V I E W |
wygonski |
Posted - 17 Sep 2016 : 13:13:21 I am having trouble solving a problem with a RT scrolling graph that is a single SimpleLinePlot. I'm using your QCRTGraph library for Android Studio. Apologies if I'm posting in the wrong forum, but there doesn't seem to be an Android-specific forum.
Here's the issue:
The scrolling plot needs to display one of three signals under user control. My data rate is 200 points/sec, and I am updating the display every 200ms. I have set setScrollScaleModeY to RT_AUTOSCALE_Y_MINMAX, and this works well for two of the three signals whose value is constrained to a range of amplitude values (e.g. periodic sine wave). However, for a signal that is "noisy", the scroll graph lags significantly to the point of being unusable. (What I mean by "noisy" is that the data is roughly constrained to a range of 50, but the center point of the range can vary. I hope that adequately describes the problematic data).
My hypothesis is that the autoscaling of the y-axis is slowing down the updates. Is this hypothesis correct? If so, is there any other mode that I can set to handle this?
In trying to solve my problem, I found this post on your forum that seems to address the same issue. https://www.quinn-curtis.com/qxy/topic.asp?TOPIC_ID=388&SearchTerms=RT_AUTOSCALE_Y_MINMAX
But the solution proposed by one of the members seems to reference a class that's not in the library that I have (ChartObjScale.ScaleStopY)? Do you have any suggestions along the lines of that solution?
|
15 L A T E S T R E P L I E S (Newest First) |
wygonski |
Posted - 28 Sep 2016 : 10:18:03 Ok, thanks for the suggestion to decimate the data for display, and thanks for the great tech support. |
quinncurtis |
Posted - 28 Sep 2016 : 08:47:41 Yes, that is the case. We do not see anyway to plot all of the points in the exact scale that you want, with a thick line width, as the limiting factor is the Android graphics engine. If the thick line width is the critical factor, then you will probably have to reduce your effective sample rate to half, or one third, using a two or three point average. I expect that the line drawing will speed back up once the thick points of the scroll line no longer overlap, which they do in your original scenario.
|
wygonski |
Posted - 28 Sep 2016 : 01:56:34 When I read your findings, it made sense because that matched every symptom I had described to you. Thanks much for taking the time to work with my app to determine the cause of the issue.
I had a change to implement your suggested change on both my simulated and "live" app. I tested it on a Samsung Galaxy S4 and on a &" tablet. In either case, the UI and scrolling graph performance is only acceptable with a line width of 1. However, the visibility of the plot deteriorates significantly with that setting. I tried a line width of 2 but the UI was still sluggish. Perhaps some other combination of background color and line color with line width of 1 would be more visible--I'll experiment.
So if I understand your response, the underlying line drawing routine is the limiting factor, and that is out of your control since you're using the Android API, is that correct? Is there a way to override that method with something faster? I'm looking for a way to have a fast plot update and have it visible, too.
|
quinncurtis |
Posted - 27 Sep 2016 : 08:31:47 We determined that the issue is clearly in the Android graphics polyline drawing routine. It is slowing down to a crawl for certain types of waveforms. It is probably related to some combination of long polyline runs, thick line widths, close adjacent points, and anti-aliasing.
But, the simple solution is to NOT use a thick line width for the drawing object of the real-time plot. In your program that means changing the line width of the SimpleLinePlot to 1.
ChartAttribute attrib1 = new ChartAttribute (ChartColor.YELLOW, 1,ChartConstants.LS_SOLID); . . . SimpleLinePlot lineplot1 = new SimpleLinePlot(pTransform1, null, attrib1); lineplot1.setFastClipMode( ChartConstants.FASTCLIP_X); rtPlot1 = new RTSimpleSingleValuePlot(pTransform1,lineplot1, inputChannel1); chartVu.addChartObject(rtPlot1);
We also tried a line width of 2, and that seemed to work, but not a line width of 3. Try and a width of 1 and 2 in your program to see if 2 is fast enough, otherwise revert to 1.
Let us know the results. |
wygonski |
Posted - 23 Sep 2016 : 17:10:22 Firstly, I really appreciate the support and response on this issue. I've been running on a Google Nexus 7, and a Samsung Galaxy S4.
It will take some time for me to decouple my code from the bluetooth connection management and the data input stream so that my app can run standalone. The part of my app's UI that becomes unresponsive is a toggle button that sends a command over bluetooth to my hardware, and then waits for a response and displays that text message. I will write a software driver that simulates this part and data generation.
I can probably get it to you by tomorrow, knowing that you may not get to it until the start of the week.
Thanks again. |
quinncurtis |
Posted - 23 Sep 2016 : 15:16:36 We wrote a simple program (two traces, 200 Hz data update, 5 Hz display update, x-axis displays 3 seconds, y-autoaxis enabled, scroll frame reset margin at 0.05) to test your basic setup and cannot make the software act the way you describe. We were using an old Nexus 7 2012 as the test hardware. I assume you are using test hardware at least as fast as that?
If you are able to make yours work using simulated data (i.e. no dependencies we wouldn't have), send us a complete Android Studio project we can run and debug, where some sort of flag will toggle between your fast and slow mode. Send the zipped project as an attachment to support@quinn-curtis.com
|
wygonski |
Posted - 23 Sep 2016 : 12:09:35 No, the data is random but the actual range of the data is (315.0,335.0). No clipping is visible.
And not to distract the discussion, but when the data is the periodic square wave, i.e., data values alternating periodically between -1000.0 and 1000.0, and the visible data fills the plot area, the plot is in the "working" scenario. |
quinncurtis |
Posted - 23 Sep 2016 : 12:04:00 OK, in both of your scenarios, what is the actual dynamic range of the data.
Is this a clipping issue, i.e. when the data is clipped the chart slows? |
wygonski |
Posted - 23 Sep 2016 : 11:41:14 I can switch between scenarios with the following code:
scrollFrame.setScrollScaleModeY( ChartConstants.RT_NO_AUTOSCALE_Y);
/*
maxH = 3600.0;
minH = 0.0;
*/
maxH = 340.0;
minH = 310.0;
/**/
scrollFrame.getChartObjScale().setScaleStartY( minH );
scrollFrame.getChartObjScale().setScaleStopY( maxH );
// what does this do? html doc is blank on this method:
scrollFrame.setScrollRescaleMargin( 0.05 );
// Allow 10 samples to accumlate before autoscaling y-axis. This prevents rapid
// changes of the y-scale for the first few samples
scrollFrame.setMinSamplesForAutoScale ( 10 );
chartVu.addChartObject(scrollFrame); The display is updated every 200ms, and the scrolling graph is set to display 3s of data at 200 points/sec.
"working" scenario: (minH,maxH) = (0.0,3600.0) graph lagging and UI buttons unresponsive: (minH,maxH) = (310.0,340.0)
|
quinncurtis |
Posted - 23 Sep 2016 : 09:20:22 No, you can't update the display from a non-ui thread. You can acquire the data for the display from a non-ui thread. That's standard Android programming.
I want to go back to your original assertion that the slow-down only occurs when the data varies large amounts from point to point, compared to a simple smooth signal of the same number of data points. With your further experimentation, do you still think this is true? This points to some problem with the Android polyline routine where it breaks down for large point counts of highly varying data. Our software does not treat the two signal types differently. |
wygonski |
Posted - 22 Sep 2016 : 21:43:21 So if I can tolerate some lag in displaying the scrolling graph, is it feasible to update the display in another thread (not the UI thread) so that the UI remains responsive? I have some buttons in another fragment that turn the data stream on and off, change the data that is streamed, etc. |
wygonski |
Posted - 22 Sep 2016 : 18:33:02 No. If I update the graph every 200ms, it seems that whether I autoscale "manually" or with RT_AUTOSCALE_Y_MINMAX, I still have issues. Slowing down the update to 600ms fixes the problem. Reducing the interval of displayed data from 3s to 1s fixes the problem. Also, if the Y axis range for the "random" number plot is scaled large with respect to the data (e.g. range of 0-500 for data varying between 320-350, the problem is fixed.
Does it also seem to you that the problem is related to writing to the screen? |
quinncurtis |
Posted - 22 Sep 2016 : 11:05:36 If you turn off the RTScrollFrame y-axis auto-scaling, and use the external auto-scaling already discussed, does everything work under all of your scenarios?
|
wygonski |
Posted - 21 Sep 2016 : 16:01:17 I forgot to add that if I disable the timer that causes the display to update, user CPU time is under 7%. In this case, data streaming from Bluetooth and updating RTProcessVar is still occurring. |
wygonski |
Posted - 21 Sep 2016 : 15:52:03 I'm reporting some additional observations of the problem with the lagging graph. For these results, the only axis range scaling that is done is when switching from one dataset to another. I totally removed the feature of saving data to a file, with no impact on the problem -- graph is still lagging and the UI is slow to respond to button presses, etc. When actively plotting, user (non-kernal) CPU time goes from near 0% to 50% no matter what dataset being plotted.
For data that is a square wave toggling between -1000 and 1000, and for data that is steadily increasing, there are no problems with UI performance. For data that is "random" but limited to the range 325 to 345, the plot lags and the UI is slow to respond, when the Y axis scale is set to 320 to 350 (fixed). Interestingly, if the Y axis scale is set to -1000 to 1000 (fixed) such that the data now appears as a horizontal line, the problem goes away--scrolling plot is smooth, no lag, and UI is responsive.
If I drop the time interval that I'm plotting from 3s to 1s (rate is 200 points/sec) the problem goes away, plot does not lag and UI is responsive.
Any thoughts?
|
|
|