SDK Question Determining Pad Availability

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Got this code from a post by Mogeley in early 2010.
Code:
double tgtlng, tgtlat, tgtrad;

// Callback function for target input dialog
bool clbkTargetDialog(void *id, char *str, void *usrdata)
{
	AutoPilotMFD* cMFD = (AutoPilotMFD*)usrdata;
	//OBJHANDLE objTarget;
	ELEMENTS e;
	ORBITPARAM op;
	
	OBJHANDLE hVessel = oapiGetVesselByName(str);
	OBJHANDLE hObj = NULL, hRef = NULL, hBase = NULL, hPlanet = NULL;
	hObj = oapiGetGbodyByName(str);
	hRef = cMFD->mV->GetSurfaceRef();
	hBase = oapiGetBaseByName(hRef, str);
	DWORD navtype;
	char* desc;
	bool result;

	// Determine if the string is a ship, planet, base, or orbit parameters
	if (hVessel != NULL)
	{
		cMFD->tgtV = oapiGetVesselInterface(hVessel);
		//cMFD->tgtname = cMFD->tgtV->GetName();
		strncpy(cMFD->tgtname,cMFD->tgtV->GetClassName(),31);
	} else if (hBase != NULL) {
		hTGT = hBase;
	} else if (hObj != NULL) {
		hBase = oapiGetBaseByName(hObj, str);
		hTGT = hBase;
	}

	if (hBase != NULL) {
		DWORD padcount = oapiGetBasePadCount(hBase); // 0 to < padcount
		NAVHANDLE hNav = NULL;
		for (int i = 0; i < padcount; i++) {
			// Finds first available landing pad. If ILS runways are found these override landing pads. This assumes that if a base has a runway it should be used.
			hNav = oapiGetBasePadNav(hBase, i);
			if (hNav != NULL) {
				navtype = oapiGetNavType(hNav);
				if (navtype == TRANSMITTER_ILS) {
					result = oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
				} else if (navtype == TRANSMITTER_VTOL) {
					
				}
				
			}
		}
	}

	return(true);
}

I'm trying to use it for a land autopilot coded in the .dll, but my craft lands on top of any on the pad!
How does it determine if the pad is "available" as stated after padcount?
Do we not need to use "oapiGetBasePadStatus" for example?
If so, how? (Can't find ANYTHING significant on oapiGetBasePadStatus either Googling or searching orbiter-forum - need examples with my coding skills:lol:)
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
The information provided by OrbiterSDK documentation or OrbiterAPI.h header should be sufficient:

bool oapiGetBasePadStatus (OBJHANDLE hBase, DWORD pad, int *status);

hBase - surface base handle
pad - pad index
status - pointer to variable to receive pad status

Function returns false if pad is out of range (pad: 0 <= pad < oapiGetBasePadCount(hBase)). The hBase must be a valid base handle.
Returned status: 0 = pad is free, 1 = pad is occupied, 2 = pad is cleared for an incoming vessel.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
OK, thanks. I'll give it a go.

I'm just curious why can't find any references to oapiGetBasePadStatus.

And why doesn't it appear in Mogeley's code if he thinks he's finding an "available pad"?
Is availability determined by any other call in his code?
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
And why doesn't it appear in Mogeley's code if he thinks he's finding an "available pad"?
Available pads in base, not "free" or "occupied", but "available".
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Thank you for your compiler logic orb:blush::blink::salute:
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Well, I've been struggling with this for days now - can anyone spot my mistake(s)?
Trying to determine if a pad is "free" for landing, but its not doing that.
Code:
bool InputTarget(void *id, char *str, void *user_data)
{

OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");//GetSurfaceRef();//
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
if (hBase != NULL) 
	{
		int status , i = NULL; 
			DWORD padcount = oapiGetBasePadCount(hBase); // 0 to < padcount
	NAVHANDLE hNav = NULL;
		
	oapiGetBasePadStatus(hBase, i, &status);
	if (&status > 0 && i < padcount) i++;
						
		else
		
		//if(&status == 0) 
			Nav = 1;
		{
				hNav = oapiGetBasePadNav(hBase, i);
			
			if (hNav != NULL) 
			{
				navtype = oapiGetNavType(hNav);
				if (navtype == TRANSMITTER_VTOL)
					
					{
					oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
					Nav = 1;
					}
				else 

				if (navtype == TRANSMITTER_ILS)
					{
					oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
					sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
					}
			}
		}
}
return true;
}

Any help appreciated.
 

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
9,290
Reaction score
3,258
Points
203
Location
Toulouse
Another method could maybe to get a handle from the selected pad, and then check if there is any vessel in a radius equal to the size of the pad...
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Well, I've been struggling with this for days now - can anyone spot my mistake(s)?
Trying to determine if a pad is "free" for landing, but its not doing that.
Code:
bool InputTarget(void *id, char *str, void *user_data)
{

OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");//GetSurfaceRef();//
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
if (hBase != NULL) 
	{
		int status , i = NULL; 
			DWORD padcount = oapiGetBasePadCount(hBase); // 0 to < padcount
	NAVHANDLE hNav = NULL;
		
	oapiGetBasePadStatus(hBase, i, &status);
	if (&status > 0 && i < padcount) i++;
						
		else
		
		//if(&status == 0) 
			Nav = 1;
		{
				hNav = oapiGetBasePadNav(hBase, i);
			
			if (hNav != NULL) 
			{
				navtype = oapiGetNavType(hNav);
				if (navtype == TRANSMITTER_VTOL)
					
					{
					oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
					Nav = 1;
					}
				else 

				if (navtype == TRANSMITTER_ILS)
					{
					oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
					sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
					}
			}
		}
}
return true;
}

Any help appreciated.

You are not looping over the pads. You check pad 0 and increment i but never loop to check any other pads.

You should also initialize ints to 0, btw, not NULL, for clarity.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Well, now I've got this - and it doesn't work.
Code:
bool InputTarget(void *id, char *str, void *user_data)
{

OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);

if (hBase != NULL) 
{
		int* status = 0;
		DWORD padcount = oapiGetBasePadCount(hBase); 
		NAVHANDLE hNav = NULL;
		for (DWORD i = 0; i < padcount, status != 0; i++) {
			
			oapiGetBasePadStatus(hBase, i, status);
			
			

						
				Nav = 1;
		
			hNav = oapiGetBasePadNav(hBase, i);
			
			if (hNav != NULL) 
			{
				navtype = oapiGetNavType(hNav);
				if (navtype == TRANSMITTER_VTOL)
					
				{
								
			oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
				
			Nav = 1; 
				}
				else 
					if (navtype == TRANSMITTER_ILS)
					{
					
			oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
			sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
	
					}
				
			}
		}
		
}

 return true;
 
}
If I change to
Code:
{
		[B]int status [/B]= 0;
		DWORD padcount = oapiGetBasePadCount(hBase); 
		NAVHANDLE hNav = NULL;
		for (DWORD i = 0; i < padcount, [B]&status[/B] != 0; i++) {
			
			oapiGetBasePadStatus(hBase, i, [B]&status[/B]);
it just "hangs".

If I remove
Code:
, &status != 0
it runs up to "padcount" and navigates to that last pad, disregarding all the others.

Can someone tell me what I'm doing wrong? It should be so simple shouldn't it?!
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Well, now I've got this - and it doesn't work.
Code:
bool InputTarget(void *id, char *str, void *user_data)
{
 
OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
 
if (hBase != NULL) 
{
        int* status = 0;
        DWORD padcount = oapiGetBasePadCount(hBase); 
        NAVHANDLE hNav = NULL;
        for (DWORD i = 0; i < padcount, status != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);
 
 
 
 
                Nav = 1;
 
            hNav = oapiGetBasePadNav(hBase, i);
 
            if (hNav != NULL) 
            {
                navtype = oapiGetNavType(hNav);
                if (navtype == TRANSMITTER_VTOL)
 
                {
 
            oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
 
            Nav = 1; 
                }
                else 
                    if (navtype == TRANSMITTER_ILS)
                    {
 
            oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
            sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
 
                    }
 
            }
        }
 
}
 
 return true;
 
}
If I change to
Code:
{
        [B]int status [/B]= 0;
        DWORD padcount = oapiGetBasePadCount(hBase); 
        NAVHANDLE hNav = NULL;
        for (DWORD i = 0; i < padcount, [B]&status[/B] != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, [B]&status[/B]);
it just "hangs".

If I remove
Code:
, &status != 0
it runs up to "padcount" and navigates to that last pad, disregarding all the others.

Can someone tell me what I'm doing wrong? It should be so simple shouldn't it?!

You need an && operator between "i < padcount" and "status != 0" instead of a comma. The comma doesn't do you any good there--think about why the boolean and is the correct operator.

Also, the design is very inefficient--consider checking the value of status first, and if it's unavailable use "continue;" to skip to the next iteration of the loop.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
OK - so basically I'm still not getting anywhere with this -
tried using the && operator, but still doesn't work.

Code:
bool InputTarget(void *id, char *str, void *user_data)
{
 
OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
 
if (hBase != NULL) 
{
        int* status = 0;
        DWORD padcount = oapiGetBasePadCount(hBase); 
        NAVHANDLE hNav = NULL;
        for (DWORD i = 0; i < padcount [B]&& &status [/B]!= 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);
 
 
 
 
                Nav = 1;
 
            hNav = oapiGetBasePadNav(hBase, i);
 
            if (hNav != NULL) 
            {
                navtype = oapiGetNavType(hNav);
                if (navtype == TRANSMITTER_VTOL)
 
                {
 
            oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
 
            Nav = 1; 
                }
                else 
                    if (navtype == TRANSMITTER_ILS)
                    {
 
            oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
            sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
 
                    }
 
            }
        }
 
}
 
 return true;
 
}

I don't get it, why am I not getting a loop around "&status !=0" ??

Can someone show me what I should be doing please.
If I can't get this part of the autopilot to work it's really going to reduce the practical realism of the thing - like landing on top of other craft !!:facepalm:
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
OK - so basically I'm still not getting anywhere with this -
tried using the && operator, but still doesn't work.

Code:
bool InputTarget(void *id, char *str, void *user_data)
{
 
OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
 
if (hBase != NULL) 
{
        int* status = 0;
        DWORD padcount = oapiGetBasePadCount(hBase); 
        NAVHANDLE hNav = NULL;
        for (DWORD i = 0; i < padcount [B]&& &status [/B]!= 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);
 
 
 
 
                Nav = 1;
 
            hNav = oapiGetBasePadNav(hBase, i);
 
            if (hNav != NULL) 
            {
                navtype = oapiGetNavType(hNav);
                if (navtype == TRANSMITTER_VTOL)
 
                {
 
            oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
 
            Nav = 1; 
                }
                else 
                    if (navtype == TRANSMITTER_ILS)
                    {
 
            oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
            sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
 
                    }
 
            }
        }
 
}
 
 return true;
 
}

I don't get it, why am I not getting a loop around "&status !=0" ??

Can someone show me what I should be doing please.
If I can't get this part of the autopilot to work it's really going to reduce the practical realism of the thing - like landing on top of other craft !!:facepalm:

"&status" is "the address of the variable 'status'." That is not what you want, because it will never be 0. You want the value of status, so remove that &.

I am currently doing this on my phone which makes it difficult, but tomorrow i'll be able to fix he code for you if you still can't get it.
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Thanks Hielor, but still not working - doesn't now seem to be getting past
Code:
for (DWORD i = 0; i < padcount && status != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);

Unfortunately, can't get my little de-bugger to work either on this machine: getting message as below:-
PHP:
Unhandled exception at 0x0ea488b7 in orbiter.exe: 0xC0000005: Access violation writing location 0xf96f671c.

Any ideas? (just to add to the confusion!)

I'm gonna transfer the code down on another machine and see if I can de-bug it, but that is at another location, and doesn't have internet access.....:facepalm::rofl::beathead:
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
There:
JMW said:
Code:
int* status = 0;

// ...

for (DWORD i = 0; i < padcount && status != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);
  1. Address for the status pointer is set to NULL = 0 (status is declared as a pointer to int variable, not an int variable).
  2. The 'status' pointer is always NULL (== 0) because it isn't set to point to actual int variable anywhere.
  3. You are giving a NULL pointer for status parameter to retrieve the status from oapiGetBasePadStatus function.
Suggested modifications:
Code:
        int status = -1;

// ...

        for (DWORD i = 0; i < padcount && status != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, &status);
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
So, with this
Code:
bool InputTarget(void *id, char *str, void *user_data)
{
 
OBJHANDLE hPlanet = oapiGetGbodyByName("Earth");
OBJHANDLE hBase = oapiGetBaseByName(hPlanet, str);
 
if (hBase != NULL) 
{
        int* status = 0;
        DWORD padcount = oapiGetBasePadCount(hBase); 
        NAVHANDLE hNav = NULL;
		for (DWORD i = 0; i < padcount && status != 0; i++) {
 
            oapiGetBasePadStatus(hBase, i, status);
 
                 Nav = 1;
 
            hNav = oapiGetBasePadNav(hBase, i);
 
            if (hNav != NULL) 
            {
                navtype = oapiGetNavType(hNav);
                if (navtype == TRANSMITTER_VTOL)
 
                {
 
            oapiGetBasePadEquPos(hBase, i, &tgtlng, &tgtlat, &tgtrad);
 
            Nav = 1; 
                }
                else 
                    if (navtype == TRANSMITTER_ILS)
                    {
 
            oapiGetBasePadEquPos (hBase, i,  &tgtlng,  &tgtlat, &tgtrad);
            sprintf(oapiDebugString(),"Target ILS long %02.10f : lat_ils %02.10f : rad_ils %02.07f", tgtlng, tgtlat, tgtrad);
 
                    }
 
			}
        }
 
}
 
 return true;
 
}
de-bugger shows first screen below. (excuse my "jottings" in between code).


Going back to code as shown (screen2,3&4) gives results that step through, but that don't recognize pad being occupied ( pads 1 & 2 are occupied) by not choosing hNav for those pads.
Also, doesn't seem to respect "i < padcount", as steps through 'forever' past total number of pads. :huh:
 
Last edited:

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Did you see my post above?
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
i was away at "other location"........Thanks Orb -I'll try that now...........

---------- Post added at 07:21 PM ---------- Previous post was at 07:17 PM ----------

Gives mesage
Code:
1>e:\j-f-35\copy of j-f-35b_stepping_pad_8.1.cpp(3021) : error C2664: 'oapiGetBasePadStatus' : cannot convert parameter 3 from 'int' to 'int *'
1>        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

SORRY, COMPILES - I FORGOT &STATUS !!

---------- Post added at 07:27 PM ---------- Previous post was at 07:21 PM ----------

cOMPILES - BUT STILL NOT "SENSING" PAD OCCUPIED.... ?
 
Last edited:

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
Did you change the "status != 0" to "status == 0" condition in the for loop?



Wrong assumption above. Status == 0 then it's free so you need to change the initial:
Code:
int status = 0;
to
Code:
int status = 1;
or
Code:
int status = -1;
 

JMW

Aspiring Addon Developer
Joined
Aug 5, 2008
Messages
611
Reaction score
52
Points
43
Location
Happy Wherever
Code:
int status = 1;

has done the trick Orb -

Thank you Orb and Hielor for your help. :cheers: :cheers:

---------- Post added 02-01-12 at 09:21 AM ---------- Previous post was 01-01-12 at 11:15 PM ----------

Still got problems with my de-bug setup -
Unfortunately, can't get my little de-bugger to work either on this machine: getting message as below:-
PHP:
Unhandled exception at 0x0ea488b7 in orbiter.exe: 0xC0000005: Access violation writing location 0xf96f671c.

Any ideas? (just to add to the confusion!)

Any help, much appreciated.

JMW

EDit: Moving this to a new thread - before Orb is on my tail >>>>>>>>>>>>>>>>
 
Last edited:
Top