Orbiter-Forum  

Go Back   Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK
Register Blogs Orbinauts List Social Groups FAQ Projects Mark Forums Read

Orbiter SDK Orbiter software developers post your questions and answers about the SDK, the API interface, LUA, meshing, etc.

Reply
 
Thread Tools
Old 08-07-2018, 12:08 PM   #16
martins
Orbiter Founder
Default

No problems ...
Quote:
My problem (so far) is how to store without being overwritten by following frame........
This is easy - you want to overwrite the stored value, just not before you have done your calculation. So the structure looks like this:
Code:
VECTOR3 p;
oapiGetRelativePos(...,&p);
VECTOR3 dp = p-last_p;
last_p = p;
// now use dp for whatever calcuation you need ...
where last_p is the stored position from the last frame (presumably a member of your class)
The only thing to take care of then is not to use last_p before it is initialised.
martins is offline   Reply With Quote
Thanked by:
Old 08-07-2018, 08:29 PM   #17
JMW
Aspiring Addon Developer
 
JMW's Avatar
Default

I've tried to implement but am getting seemingly random results with the colours.
Some right, ie: red when increasing distance, others wrong.
In first row, bases 5,7,11,14 & 16 are wrong.
As seen from debug "dp" registers zero ?
"Too many bases" is just there as a test.

code now: (don't forget to paste it into a compiler if it helps and have a good laugh )

Thanks in anticipation.

Code:
if(HUD2 == 1 && oapiGetHUDMode() == HUD_DOCKING &&oapiCockpitMode() == COCKPIT_VIRTUAL)  // ---------- Display Bases and Distances --------------
{
	
	if(zoom < 100) { zoom -= 0.25;}
			oapiCameraSetAperture (zoom*RAD);
			if(zoom < 16) zoom = 16;

		double  line = 70;
		double linespacing =0;//= 0;
	oapi::Font *font = oapiCreateFont (15, false, "MyFont", FONT_NORMAL);
	skp->SetFont(font);
		char buf[256];
		int len = 84;
		int len2 = 4;
		int ib;
		double dis4;
		double dis3;
		int distance ;
		double lat4, lng4; 
		char basename[84];
		VECTOR3 last_p = {0,0,0};
		OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
		int nBase=oapiGetBaseCount(hPlanet);



for (ib=0; ib <nBase; ib++) {
				
		linespacing = linespacing + 11;
		
	   OBJHANDLE Base = oapiGetBaseByIndex(hPlanet, ib);
						oapiGetObjectName(Base, basename, len);
						oapiGetBaseEquPos (Base, &lng, &lat);
						GetEquPos (longitude, latitude, radius);
						dis = sin((latitude)*RAD) * sin(lat*RAD) + cos((latitude)*RAD) * cos((lat)*RAD) * cos((longitude-lng)*RAD);
						dis = acos(dis);
						dis = (dis)*DEG;
						distance = dis * 6371;
						if(units == 0) distance = distance *0.539957;
	
		OBJHANDLE hBase = oapiGetBaseByIndex(hPlanet, ib); 
		OBJHANDLE hRef = oapiGetVesselByName("J-F-35B"); 
		VECTOR3 p;
		oapiGetRelativePos(hBase,hRef,&p);
		VECTOR3 dp = p-last_p;
		last_p = p;
		// now use dp for whatever calcuation you need ...
			
if (ib < 48)
	{

		if (ib <16)
		{                                           
			skp->SetTextColor( 0xffffff);
			line = 313;
			len = sprintf_s(buf,"                    %s",  basename);
			skp->SetTextAlign (oapi::Sketchpad::LEFT, oapi::Sketchpad::TOP);
			skp->Text(-140,((line) +linespacing), buf,  len);

			if(units == 0) 
					{
					skp->Text(190, 70, "Nautical Miles", 14);
					}
				else
					{
					skp->Text(200, 70, "Kilometers", 10);
					}

	if (dp.z > 0 &&hspd >10)
			{
				skp->SetTextColor( 0x0000ff);} //red}
				else skp->SetTextColor( 0xffffff);
				{
				len2 = sprintf_s(buf,"     %i", distance);
				skp->Text(85,((line)+linespacing), buf,  len2);
				}
				
		}	
		
		else if(ib <32)
		{
				skp->SetTextColor( 0xffffff);
				line = 311;
				len = sprintf_s(buf,"                    %s",  basename);
				skp->SetTextAlign (oapi::Sketchpad::LEFT, oapi::Sketchpad::TOP);
				skp->Text(30,((line-175) +linespacing), buf,  len);
				skp->SetTextAlign (oapi::Sketchpad::RIGHT, oapi::Sketchpad::TOP);

	if (dp.z > 0 &&hspd >10)
			{
			skp->SetTextColor( 0x0000ff); //red
			} 
				
			else
			{
			skp->SetTextColor( 0xffffff); //white
			}
			len2 = sprintf_s(buf,"     %i", distance);
			skp->Text(340,((line-175)+linespacing), buf,  len2);
			
		}
			
	 
		else
		{
				skp->SetTextColor( 0xffffff); //white
				line = 334;
				len = sprintf_s(buf,"                    %s",  basename);
				skp->SetTextAlign (oapi::Sketchpad::LEFT, oapi::Sketchpad::TOP);
				skp->Text(220,((line-375) +linespacing), buf,  len);
				skp->SetTextAlign (oapi::Sketchpad::RIGHT, oapi::Sketchpad::TOP);

	if (dp.z > 0 &&hspd >10)
			{
			skp->SetTextColor( 0x0000ff); //red}
			} 
				
			else
			{
			skp->SetTextColor( 0xffffff); //white
			}
			len2 = sprintf_s(buf,"     %i", distance);
			skp->Text(510,((line-375)+linespacing), buf,  len2);
			
		}
	
		sprintf(oapiDebugString(),"lng %1.8f :lat %1.8f :dp.z %1.8f :timer4 %1.8f", longitude, latitude, dp.z, timer4);
	}
	
else 
			if (timer4 > 18)
			{
			skp->SetTextColor( 0x0000ff); //red
			skp->Text(340, 165, "T O O  M A N Y   B A S E S !",28);
			}
	}
	oapiReleaseFont (font);
	timer4 = timer4 += 1;
		if(timer4>35) 
		{
		timer4 = 0;
		}
}
Attached Thumbnails
Bases.png  

Last edited by JMW; 08-07-2018 at 08:32 PM. Reason: Added screenshot
JMW is offline   Reply With Quote
Old 08-08-2018, 12:17 AM   #18
martins
Orbiter Founder
Default

The way you have written it, dp is not the position difference from a given base between current and last time step, but the difference between the previous and current base in the list, which is meaningless in this context.
  • You have to store last_p outside the function body, so it persists between frames. You are defining it as an automatic variable inside the function, which means it is re-initialised at each frame, losing its stored value. Don't use a static variable; that's just asking for trouble.
  • You need a separate last_p for every base in the list.
The second point is a bit tricky, because you can't just store all last_p values in an array. The order in which Orbiter returns the bases is not guaranteed to be the same each time (even if in practice it may be), so you need to store the basis name or handle with the value, and search for it in your loop to pick the correct saved value.

That makes this algorithm a bit inelegant and inefficient. My preferred choice here would be not to calculate the closing speed from the position difference, but directly from the relative velocity.

In general: what happens if the base we are interested in is not among the first 48 returned by Orbiter? What if the user has installed a thousand bases? Will you provide a method to page through the entire list? I would suggest sorting the list in ascending order of distance from the current vessel position, since the closest ones are likely to be more relevant.

A few remarks on the code:
  • The code between "for (ib = 0; ib <nBase; ib++) {" and "if (ib < 48)" is evaluated for every base, but only used for the ones displayed, so it should be moved inside the if clause.
  • The "kilometer" and "nautical miles" indicator is overwritten 16 times for no reason. It should be moved out of the loop.
  • After that, the difference between the three columns is just in the output position, so the 3 code blocks could be merged by just computing the row and column from the linear index:
    Code:
    const int numRows = 16;
    int row = ib % numRows;
    int col = ib / numRows;
    int x = colOffset + col * colSpacing;
    int y = rowOffset + row * rowSpacing;
martins is offline   Reply With Quote
Thanked by:
Old 08-08-2018, 09:01 AM   #19
jedidia
shoemaker without legs
 
jedidia's Avatar
Default

Quote:
The second point is a bit tricky, because you can't just store all last_p values in an array.
You could store them in a map, with the OBJHANDLE as key.
jedidia is offline   Reply With Quote
Thanked by:
Old 08-08-2018, 10:20 AM   #20
martins
Orbiter Founder
Default

And another thing:

Before getting into the business of fixing the entire list, you might want to make sure that the algorithm itself is sound, by testing it on just one base. So for debugging purposes, set nBase = 1 and check if it works as expected.

I suspect it won't (even after fixing the problem with the non-persistent last_p), because as far as I can tell you are using dp.z > 0 as the selection criterion. But dp is just the relative speed (in units of m/frame) in the global frame. You have to project it onto the base's relative position vector (p) and check if the projection points towards or away from the base. So instead of dp.z, use dotp(p, dp) as the criterion. See e.g. here for details.
martins is offline   Reply With Quote
Thanked by:
Reply

  Orbiter-Forum > Orbiter Space Flight Simulator > Orbiter SDK


Thread Tools

Posting Rules
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
Forum Jump


All times are GMT. The time now is 05:10 AM.

Quick Links Need Help?


About Us | Rules & Guidelines | TOS Policy | Privacy Policy

Orbiter-Forum is hosted at Orbithangar.com
Powered by vBulletin® Version 3.8.6
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Copyright 2007 - 2017, Orbiter-Forum.com. All rights reserved.