PDA

View Full Version : Compass+GPS - Part Deux



Al Grant
08-08-2006, 04:07 AM
Hi Folks,

Those that read my earlier post will know I am trying to do linear interpolation on compass headings that are received from a GPS 1/second.

The drawing is done at maybe 60 frames per second. Based on advise from zeoverlord and others I have tried to impliment this but it doesnt look quite right when it draws.

Could someone please take a look at my code - especially the way the loop works around interpolating the course heading.

Thanks

-Al





WinMain()...
...<snip>....

while(!done) // Loop That Runs While done=FALSE
{
if (PeekMessage(&amp;msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message==WM_QUIT) // Have We Received A Quit Message?
{
done=TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&amp;msg); // Translate The Message
DispatchMessage(&amp;msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done=TRUE; // ESC Signalled A Quit
}
else // Not Time To Quit, Update Screen
{ tickCount = GetTickCount();
deltaTime = ((float)(tickCount - lastTickCount))/1000;
lastTickCount = tickCount;

timecounter=timecounter+deltaTime;

if (timecounter>1.0)
{
lastcourse=course;
GetGPSData();
deltacourse=(course-lastcourse);
courseincrement=(deltacourse/(1/deltaTime));
timecounter=0;
}
//course has been updated and gldraw shows this rather than incremented ver
lastcourse=lastcourse+courseincrement;
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)

}
}




GetGPSData()
void GetGPSData()
{int Code;
char *pend;

// lock data buffer
mgcLockData(1);
// get timestamp
Code = mgcGetData(GPRMC_COURSE,(LPSTR)DataBuffer);
if(Code<0) ShowMGC32Error(Code);
// if(Code>0) course=(LPSTR)DataBuffer;
course=strtod(DataBuffer, &amp;pend);
mgcLockData(0); // Lock Data Buffer
Sleep(200);

} /* end GetGPSData */

k_szczech
08-08-2006, 01:49 PM
This is wrong:

courseincrement=(deltacourse/(1/deltaTime));Should be:

courseincrement=(deltacourse/timecounter);Since course changed by 'deltacourse' during 'timecounter' then this is proper way of calculating how fast course is changing during one second.

And another error:

lastcourse=lastcourse+courseincrement;Should be:

lastcourse=lastcourse+courseincrement*deltaTime;I think this one is obvious.

nickn
08-08-2006, 06:02 PM
Aren't you calling GetGPSData only once per second (timecounter > 1.0)? I thought you said earlier the GPS provided updates at 200 ms. You ought to get every one to have a smoother display.

Also, you call Sleep(200) in that routine. Are you trying to suspend yourself for 200 ms? This shouldn't be done here (maybe shouldn't be done at all).

Is this a real GPS you're handling? I work in the aviation industry and we don't average heading or attitude at all from digital sources. You shouldn't get a 50 to 65 degree jump in one n to n+1 sample period. (Unless your aircraft has just been hit by a missile.)

Al Grant
08-08-2006, 10:20 PM
Originally posted by k_szczech:
This is wrong:

courseincrement=(deltacourse/(1/deltaTime));Should be:

courseincrement=(deltacourse/timecounter);Since course changed by 'deltacourse' during 'timecounter' then this is proper way of calculating how fast course is changing during one second.
I dont get it? If delta course is lets say 40 degrees. And deltatime is 0.1s to draw a frame, then I know I can draw 10 frames per second.

Therefore I want to increment the course 4 degrees at a time to get to the next heading over a 1 second interval????

Using the same figures with your formula yields 40/0.1 = 400 for the course increment?????

Could you please explain more?

Ta

-Al

Al Grant
08-08-2006, 10:24 PM
Originally posted by k_szczech:
And another error:

lastcourse=lastcourse+courseincrement;Should be:

lastcourse=lastcourse+courseincrement*deltaTime;I think this one is obvious. Again, I dont get it. Over one second you want to get from say 50 dgrees to 90 degrees. This is a delta heading of 40 degrees. If you are drawing 10 frames a second (deltatime = 0.1) then you want last course (50) to be equal to lastcourse + 4 for each frame drawn???

Or am I missing something?

-Al

Al Grant
08-08-2006, 10:29 PM
I have been watching it draw the compass and it seems to draw one increment past the newheading before flicking to the new heading.....

I might try writing some values to a log file to see whats going on.

-Al

Al Grant
08-08-2006, 10:31 PM
k_szczech

Maybe it wasnt clear but time counter is not a integer counter like from 1-10. It sums a float until it gets to 1 and then repolls the gps.

k_szczech
08-09-2006, 01:38 PM
Seems like you have read my post with one eye closed. :)
Or maybe I wasn't clear enough - to get it work properly don't put 'degrees per frame' to courseincrement - put 'degrees per second' there.


Using the same figures with your formula yields 40/0.1 = 400 for the course increment?????You have put wrong data into my formula. Don't divide deltacourse by deltatime - divide it by timecounter.



Again, I dont get it. Over one second you want to get from say 50 dgrees to 90 degrees. This is a delta heading of 40 degrees. If you are drawing 10 frames a second (deltatime = 0.1) then you want last course (50) to be equal to lastcourse + 4 for each frame drawn???If time between measuring 40 degrees and 90 degrees was 1 second, then according to my first formula you will get courseincrement = 40. If you render 10 frames with deltatime = 0.1 then you will add 4 degrees each frame and will end up at 90 degrees. This is exactly what you want, isn't it?

k_szczech
08-09-2006, 01:53 PM
And by the way - what nickn wrote is true - you could just display what you get from GPS. Smoothing will cause the display to be a bit delayed.
And watch out for the situation when course will change from 359 to 0 - in current implementation your application will show that vehicle (aircraft?) turned left by 359 degrees.

Al Grant
08-09-2006, 10:56 PM
I still dont get it k_szczech. Each time A frame is drawn timecounter gets slightly higher, until it reaches 1, then the program knows to poll the GPS again. Typically the program is around 60fps.

If I divide deltacourse by timecounter, I will always be diving deltacourse by a number slightly above 1 (since this occurs inside the if >1 loop). Therefore I could end up with something like 40/1.1=36.6

so you are saying courseincrement is now 36.6? So each time I draw a frame you want me to add 36.6 degrees to the course.

I may just be really thick, but I dont follow?

If you could explain for this dummie/n00b I would relly appreciate it.

Maybe even show me how you would set the logic out?

-Al

Komat
08-10-2006, 02:33 AM
If I divide deltacourse by timecounter, I will always be diving deltacourse by a number slightly above 1 (since this occurs inside the if >1 loop). Therefore I could end up with something like 40/1.1=36.6
You have two samples that are deltacourse degress (40) apart and you know that the angle changed from the first to the second in timecounter seconds (1.1) so if you divide them you will get speed (36.6) necessary to cause that change during that time.



so you are saying courseincrement is now 36.6? So each time I draw a frame you want me to add 36.6 degrees to the course.
You know the speed of the change of the angle in degress per second (36.6) from previous sampling and you know that since last frame the deltaTime seconds has pass (say 0.1). So you need to add value corresponding to how much the course can be changed during deltaTime interval if you have that speed which is speed * deltaTime (36.6 * 0.1). This is what he was saying.

Al Grant
08-10-2006, 03:08 AM
Komat,

That may of been his point but I cant see where he said that?

You can get the same answer, the way I did it.

Lets say you can move 40 degress in one second. Lets say deltatime (time to draw 1 frame) is 0.1 seconds.

then 40/(1/0.1)=40/10=4.

this is the same as 40*0.1=4

Agreed?

-Al

Al Grant
08-10-2006, 03:21 AM
Just to clear this whole mess up:

I want to workout how many frames are being drawn per second so that I can work out how much I should add to lastcourse each frame so that after a period of 1 second lastcourse==course.

deltatime = time to draw one frame
timecounter = counter. starts at 0 and has delta time added to it for each frame until its greater than 1.
deltacourse = change in course
courseincrement = how much to add to lastcourse each time it is drawn

Thus:

deltacourse/(1/deltatime) = courseincrement

eachtime a frame is drawn
timecounter=timecounter+deltatime so it will be something like
0
0.1
0.2
0.3
0.4
0.5
....
0.9
1.0
1.1 <- at this point it will reset to 0 and repoll the GPS.

So lastcourse=lastcourse+courseincrement will be
lastcourse=50+4=54
lastcourse=54=54+4=58
lastcourse=58=58+4=62
etc....

I think me and k_szczech were talking at cross purposes.

When he said:

lastcourse=lastcourse+courseincrement*deltaTime;

I think he thought the values would be
lastcourse=50+40*0.1
but this is wrong because courseincerement is 4 and he would get:
lastcourse=50+4*0.1=50.4

-Al

Komat
08-10-2006, 09:40 AM
I want to workout how many frames are being drawn per second so that I can work out how much I should add to lastcourse each frame so that after a period of 1 second lastcourse==course.
You can use that approach however you have to ensure that you will have constant frame rate. This was certainly not true if Sleep(200); was present inside the GetGPSData() function.



I think he thought the values would be
lastcourse=50+40*0.1
but this is wrong because courseincerement is 4 In his initial post he told you about two changes. The first one (with (courseincrement=(deltacourse/timecounter) ) was to change the courseincerement to be independent on frame rate so it represents speed and not change per frame. The second change (with the courseincrement * deltatime) was dependent on making the first change.

Al Grant
08-10-2006, 12:50 PM
I think he thought the values would be
lastcourse=50+40*0.1
but this is wrong because courseincerement is 4 In his initial post he told you about two changes. The first one (with (courseincrement=(deltacourse/timecounter) ) was to change the courseincerement to be independent on frame rate so it represents speed and not change per frame. The second change (with the courseincrement * deltatime) was dependent on making the first change. [/QB][/QUOTE]

Ahhhh I see, that explains everything! Will go back and have another look at understanding it.

Thanks Komat.