View Full Version : Compass +GPS

Al Grant
08-04-2006, 01:43 PM
Hi Folks,

I am writing a little program to display a graphical compass using opengl. The source data about headings etc comes from a library I am using which allows you to connect to a GPS.

I have two problems tho:

1. The GPS I have can update the heading 5 times per second, yet the openGL can update at about 60 times a second. Whats a good way to avoid calling the GPS routine unnessecarily?

2. In theory, the GPS could give a heading of say 050, then the next reading might be 065. To simulate a real world compass, and to look good, opengl wants to rotate smootly (albiet very fast) so I guess I need a if loop with roatate1 being the start value until hit reaches rotate2 and then rotate1 needs to take on the next compass reading and loop from rotate2 until it hits rotate1 value again?

Could someone please try to formalise this logic for me please?

Thanks heaps in advance,


08-04-2006, 02:03 PM
1. take a float variable(0.0f), and for each frame add the delta time to this variable(in seconds), then if the variable is above 0.2 then read the gps and subtract the variable with 0.2

2. in this case you have to delay any reaction with 0.2 seconds.
To do this, whenever you read a GPS heading then start moving the previous heading towards the new one at a rate that corresponds to 0.2 seconds.

It's relativly easy to implement, but a bit hard to explain.

Al Grant
08-04-2006, 02:35 PM
zeoverlord - you're always helpful, and give great answers!!

How do I get delta time?


08-04-2006, 05:54 PM
It depends on your platform, in most APIs there are some kind of timing functions, most give the time in milliseconds after the program was started.

In my own game engine i use this before every frame to get the delta time, it is based on the windows API.

tickCount = GetTickCount();
deltaTime = ((float)(tickCount - lastTickCount))/1000;
lastTickCount = tickCount;

This version is based on the SDL API (used in the new NeHe lessons).

m_currentTime = SDL_GetTicks();
delta = static_cast<float>(m_currentTime - m_lastTime) / 1000.0f;
m_lastTime = m_currentTime;

Unfortunatly i can't tell you exactly how it should look like because i don't know what API you are using, but i think you can figure it out.

08-05-2006, 02:40 AM
About #1 - if you subtract 0.2 second every time you read gps you will get average delay of 0.2 seconds.
If you want to make sure that delay will be no less than 0.2s then instead of subtracting 0.2 just reset value to 0.0.

Al Grant
08-06-2006, 04:46 PM

I have tried to impliment the solution, but somethnig is not quite right.

Please let me know if you spot something. The important parts are as below:

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

// lock data buffer
// 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


} /* end GetGPSData */

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;


if (timecounter>1.0)

DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)

if (keys[VK_F1]) // Is F1 Being Pressed?
keys[VK_F1]=FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("NeHe's OpenGL Framework",640,480,16,fullscreen))
return 0; // Quit If Window Was Not Created

for (deg=0;deg<360;deg+=10)
d = deg*pi/180;