coreplote realtime plot can't execute normally in 20ms refresh time interval - real-time

I want to reach the goal that the XYplot can refresh every 20ms, and every refresh time add 5 new points, and show 5000 points in a graphview(xRanage = 5000, yRange = 2048).
In first 1000 points, the refresh speed look like normally, but after 1000 points, the refresh speed getting slower by every refresh event.
Although I use inertDataAtIndex:numberOfRecords to update the data can decrease procedure to run the numberForPlot:field:recordIndex function, but I feel it still refresh all the graphview, not drawing point by point.
So,it still refresh slowly when after 1000 points, and getting lower by every input data.
Is it that mean coreplot doesn't suitable to do fast realtime event?
This is my code:
- (IBAction)Refresh:(UIButton *)sender {
timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self
selector:#selector(show) userInfo:nil repeats:YES];
}
- (void)show {
for (int i=0; i<5; i++) {
[dataArray addObject:[NSNumber numberWithInt:arc4random()%801+1000]];
[dataArray2 addObject:[NSNumber numberWithInt:arc4random()%601+300]];
}
//[graph reloadData];
[plotLine insertDataAtIndex:[dataArray count]-5 numberOfRecords:5];
[plotLine2 insertDataAtIndex:[dataArray2 count]-5 numberOfRecords:5];
}
- (NSUInteger) numberOfRecordsForPlot:(CPTPlot *)plot {
return [dataArray count];
}
- (NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx {
NSNumber *num;
if (fieldEnum == CPTScatterPlotFieldY) {
if ([(NSString *)plot.identifier isEqualToString:#"line1"])
num = [dataArray objectAtIndex:idx];
else if ([(NSString *)plot.identifier isEqualToString:#"line2"])
num = [dataArray2 objectAtIndex:idx];
}else{
num = [NSNumber numberWithInt:idx];
}
return num;
}

What device are you using to display this graph? Mac or iOS? Even a Retina MacBook Pro has less than 3,000 pixels across the screen so the first thing you can do is to reduce the number of points being plotted. You also have two separate plots which makes everything take twice as long.
The display formatting of the plot (line style, area fill, plot symbols, etc.) also makes a big difference. Simplify and eliminate elements that you don't need (set the corresponding properties to nil). Experiment with different settings and measure the results.
Set alignsPointsToPixels to NO to save some time spent aligning each plot point with the pixel grid. For a live display of rapidly changing data, nobody will notice.

Related

FPS Lag scheduler?

I've been getting FPS lag. I've looked around and people say to use
[self schedule:#selector(gameLoop:) interval: 1/60.0f];
When I use this I get choppy lag. but when I use
[self schedule:#selector(gameLoop:)];
It's a lot smoother. Here is a snippet of my movement code.
- (void)gameLoop :(ccTime)dt
{
[self manageCannon:dt];
[self manageBullets:dt];
[self manageEnemies:dt];
[self manageAllies:dt];
}
- (void) manageEnemies :(ccTime)dt
{
enemyClass *tempEnemy;
for(int i = 0; i < [enemies count]; i++)
{
tempEnemy = [enemyClass new];
tempEnemy = [enemies objectAtIndex:i];
tempEnemy.position = ccp(tempEnemy.position.x-tempEnemy.speed*dt,tempEnemy.position.y);
if((tempEnemy.position.x - tempEnemy.range) < [wall getwally])
{
tempEnemy.speed = 0;
}
if(tempEnemy.health < 1)
{
tempEnemy.alive = false;
}
if(tempEnemy.alive == false)
{
[enemies removeObjectAtIndex:i];
[tempEnemy removeFromParentAndCleanup:true];
}
}
}
I always try to write my own code from scratch, so if you can help me out with other things that i'm doing that is incorrect that would be very helpful towards me.
It's hard to say what is slowing down your app from the information given. As LearnCocos2D suggested, you can use Instruments to figure out where the slow stuff is. Or if you want to get very granular analysis, you can always use the following macros in your code:
#define TIC start = [NSDate date]
#define TOC -[start timeIntervalSinceNow]
#define TOCP NSLog(#"TIME: %f", TOC)
Before using, be sure to declare NSDate *start in scope of use. Then just put a series of TIC/TOC or TIC/TOCP pairs in your code to print out times your code is taking in different places. You can very quickly find the bottlenecks this way.

CADisplay link seems to be speeding up each time method is called

I'm working on an iPhone app and in my app there's an object that moves from the top to the bottom of the screen. To do this I use a CADisplay link. Once the object leaves the screen it is supposed to restart its route. The problem that I'm encountering is that each time the object restarts its route, it speeds up. This continues until the object is going so fast that you can barely see it. Any ideas why this is happening and how to stop it? Any help is appreciated, thanks in advance!
-(void)spawnButton{
int x = (arc4random() % (240) + 40;
int y = -100;
button1.center = CGPointMake(x,y);
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(moveObject)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
-(void) moveObject {
int z = 1;
button1.center = CGPointMake(button1.center.x , button1.center.y +z);
if (button1.center.y >= 480) {
[self spawnButton];
}
}
You are creating a new display link on each call to spawnButton. If you're not doing anything to remove the old display link from the run loop, then the old display link will continue sending moveObject: messages. So after two calls to spawnButton you will get two moveObject: messages per video frame, and after three calls you will get three moveObject: messages per video frame, and so on.
I seem to have solved the problem by invalidating the display link each time I restart the objects route.
if (button1.center.y >= 480) {
[self spawnButton];
[displaylink invalidate];
}
}

Issue in finding the speed when using CLLocationManager

I am developing a speedometer application in iPhone. I have used CLLocationManager(GPS based) to measure the speed of a vehicle. But i don't get accurate speed. I have tried all the filtering methods given in various stackoverflow discussions. But i don't get any improvement. At times, the speed reaches to a greater value(>400kmph).
I dont know what goes wrong. Please suggest me any code to get the accurate speed.
Thanks in advance,
I have followed the below mentioned stack over flow discussions
Measuring velocity via iPhone SDK
Optimizing CLLocationManager/CoreLocation to retrieve data points faster on the iPhone
CLLocation speed
Why is my CLLocation speed so inaccurate?
I have currently implemented the following code:
//locationManager declaration in ViewDidLoad
locManager=[[CLLocationManager alloc]init];
locManager.delegate =self;
[locManager startUpdatingLocation];
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
NSTimeInterval locationAge = abs([newLocation.timestamp timeIntervalSinceNow]);
if (locationAge > 5.0) return;
if (newLocation.speed < 0 || newLocation.horizontalAccuracy < 0) return;
if ((newLocation.horizontalAccuracy < (oldLocation.horizontalAccuracy - 10.0)) || (newLocation.horizontalAccuracy < 50.0)|| (newLocation.horizontalAccuracy <= 150.0))
{
if(oldLocation != nil)
{
CLLocationDistance distanceChange = [newLocation distanceFromLocation:oldLocation];
NSTimeInterval sinceLastUpdate = [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp];
double calculatedSpeed;
calculatedSpeed = (distanceChange / sinceLastUpdate)*3.6; // to convert the speed into kmph.
}
}
}
Even if you don't like the built-in velocity stuff, it's simple to roll your own.
Speed is distance over time, right?
If you've got two CLLocations, you can do:
CLLocationDistance distance = [aLocation distanceFromLocation:bLocation];
distance is now a float of the distance between those two points, in meters. And those two CLLocations have timestamp properties too, right? Containing NSDate objects. Well...
NSTimeInterval timediff = [aDate timeIntervalSinceDate:bDate];
timediff is the difference in seconds.
So your average speed between those points in meters per second is distance over timediff. You can now calculate instantaneous speed as accurately as the frequency with which you're getting location updates.
I imagine this is all that's happening to get the speed property of the CLLocation object you're getting handed. But hey, you want to be closer to the math, go right ahead.
From there, you can convert to whatever units you like. There are 1609.344 meters in a mile. There are 3600 seconds in an hour.
NOW: This is as flawed as any pure GPS-based speed calculation, in that you're not going to get perfectly spaced tick-marks of location updates, and sometimes they're going to be way wrong. If you lose GPS signal and the device falls back to cell tower triangulation, it might put you WAY off the road somewhere, and it's going to look like you strapped on a rocket pack to get way over there that fast.

Output from OouraFFT correct sometimes but completely false other times. Why?

I am using Ooura FFT to compute the FFT of the accelerometer data in windows of 1024 samples. The code works fine, but then for some reason it produces very strange outputs, i.e. continuous spectrum with amplitudes of the order of 10^200.
Here is the code:
OouraFFT *myFFT=[[OouraFFT alloc] initForSignalsOfLength:1024 NumWindows:10]; // had to allocate it
UIAcceleration *tempAccel = nil;
double *input=(double *)malloc(1024 * sizeof(double));
double *frequency=(double *)malloc(1024*sizeof(double));
if (input)
{
//NSLog(#"%d",[array count]);
for (int u=0; u<[array count]; u++)
{
tempAccel = (UIAcceleration *)[array objectAtIndex:u];
input[u]=tempAccel.z;
//NSLog(#"%g",input[u]);
}
}
myFFT.inputData=input; // specifies input data to myFFT
[myFFT calculateWelchPeriodogramWithNewSignalSegment]; // calculates FFT
for (int i=0;i<myFFT.dataLength;i++) // loop to copy output of myFFT, length of spectrumData is half of input data, so copy twice
{
if (i<myFFT.numFrequencies)
{
frequency[i]=myFFT.spectrumData[i]; //
}
else
{
frequency[i]=myFFT.spectrumData[myFFT.dataLength-i]; // copy twice
}
}
for (int i=0;i<[array count];i++)
{
TransformedAcceleration *NewAcceleration=[[TransformedAcceleration alloc]init];
tempAccel=(UIAcceleration*)[array objectAtIndex:i];
NewAcceleration.timestamp=tempAccel.timestamp;
NewAcceleration.x=tempAccel.x;
NewAcceleration.y=tempAccel.z;
NewAcceleration.z=frequency[i];
[newcurrentarray addObject:NewAcceleration]; // this does not work
//[self replaceAcceleration:NewAcceleration];
//[NewAcceleration release];
[NewAcceleration release];
}
TransformedAcceleration *a=nil;//[[TransformedAcceleration alloc]init]; // object containing fft of x,y,z accelerations
for(int i=0; i<[newcurrentarray count]; i++)
{
a=(TransformedAcceleration *)[newcurrentarray objectAtIndex:i];
//NSLog(#"%d,%#",i,[a printAcceleration]);
fprintf(fp,[[a printAcceleration] UTF8String]); //this is going wrong somewhow
}
fclose(fp);
[array release];
[myFFT release];
//[array removeAllObjects];
[newcurrentarray release];
free(input);
free(frequency);
You need to calloc the input and output arrays. It's a bug in my code that will NOT be fixed, as this library is made obsolete by Apple's new Accelerate framework.
Hey there, have you tried plotting the accelerometer values? If there are any abrupt changes, the FFT will go out of range.
Have you tried plotting the FFT? Can you post images of what that looks like? If it looks normal for most of the time, than goes out of range occasionally, I'm betting you should smooth your accelerometer data beforehand.
Also, why are you copying spectrumData twice? That array is already set up to provide you with plottable data.
Last, are you overlapping the segments of data you provide to OouraFFT? It's designed to be fed segments of data with around 50% overlap. You might get weird edge effects otherwise.

iPhone Gps logging inaccurate

I'm logging gps points during a walk. Below it shows the function that the coordinates are saved each 5 seconds.
i Did several tests but i cannot get the right accuracy i want. (When testing the sky is clear also tests in google maps shows me that the gps signal is good).
here is the code:
-(void)viewDidAppear:(BOOL)animated{
if (self.locationManager == nil){
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
// only notify under 100 m accuracy
locationManager.distanceFilter = 100.0f;
locationManager.desiredAccuracy= kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
}
- start logging
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(getData) userInfo:nil repeats:YES];
</code>
<code>
-(void)getData{
int distance;
// re-use location.
if ([ [NSString stringWithFormat:#"%1.2f",previousLat] isEqualToString:#"0.00"]){
// if previous location is not available, do nothing
distance = 0;
}else{
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:previousLat longitude:previousLong];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:latGlobal longitude:longGlobal];
distance = [loc1 getDistanceFrom: loc2];
}
// overwrite latGlobal with new variable
previousLat = latGlobal;
previousLong = longGlobal;
// store location and save data to database
// this part goes ok
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// track the time to get a new gps result (for gps indicator orb)
lastPointTimestamp = [newLocation.timestamp copy];
// test that the horizontal accuracy does not indicate an invalid measurement
if (newLocation.horizontalAccuracy < 0) return;
// test the age of the location measurement to determine if the measurement is cached
// don't rely on cached measurements
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
latGlobal = fabs(newLocation.coordinate.latitude);
longGlobal= fabs(newLocation.coordinate.longitude);
}
I have taken a screenshot of the plot results (the walk takes 30 minutes) and an example of what i'am trying to acomplish:
http://www.flickr.com/photos/21258341#N07/4623969014/
i really hope someone can put me in the right direction.
Looking at your plots - This is exactly what I see too in an app I am working on.
Looking at your code. Whenever location is updated, locationManager calls didUpdateToLocationFromLocation - polling at 5s intervals will give you a lot of points at the same location. (but not relevant to the question)
Also I think you are leaking a lastPointTimestamp (not relevant to the question)
Right - the jumping around - you can look at the accuracy of the points : you do this in locationManager anyway but only check for <0. Is there a pattern of what the horizontal accuracy is on the jumping points ? The accuracy figure may be much worse then for other points, or one specific value (caused by a switch to cell tower triangulation).
Finally, you may need to implement filtering. Kalman filters are the over-the-top way to go, but I am looking at using low-pass filters combined with some basic physics (max acceleration & speed for walking, cycling, running, driving etc) to improve results.
Happy to collaborate on this.