Jump to content

pqsController.GetSurfaceHeight


Recommended Posts

I'm trying to make a mod to find the highest peak on every celestial body and log it to a text file in both lat/lon and DMS formats but pqsController.GetSurfaceHeight keeps throwing an index out of range exception even tho I'm converting degrees to radians.

obviously my input of 0 to 360 degrees is wrong, so what's the correct input?

Link to comment
Share on other sites

5 hours ago, Aelfhe1m said:

Looks like it's: 0 <= lon < 360; 0 <= lat < 180

Cribbed from SCANsat/scanutil.cs  line#404 and lines#474-481

thank you for your reply, using the above snippet of code from ScanSat that you provided, my code looks like this but still throws the index error.
not sure if it's because I run the method via multi-threading?

 

private void ScanBody(CelestialBody body) // Ran via Threadpool
    {
      try
      {
        double        LAT  = 0, LON = 0, ALT = 0; // highest
        var           JOBS = 0;


        DebugLog(m: $"Scanning {body.name}...");

        const double step = 0.01d;
        for (var lon = 0d; lon < 360d; lon += step)
        {
          for (var lat = 0d; lat < 180d; lat += step)
          {
            var alt = getElevation(
                body: body,
                lon: lon,
                lat: lat
              );

            if (alt <= ALT) continue;

            LAT = lat;
            LON = lon;
            ALT = alt;
          }
        }

 

Maybe @DMagic could provide some instruction?

 

Edited by Xyphos
Link to comment
Share on other sites

@Xyphos - Here you go :wink:

Quote

 public double GetAltitudeAtPos(double latitude, double longitude)
{

           Vector3d bodyUpVector = new Vector3d(1, 0, 0);
            bodyUpVector = QuaternionD.AngleAxis(latitude, Vector3d.forward) * bodyUpVector;
            bodyUpVector = QuaternionD.AngleAxis(longitude, Vector3d.down) * bodyUpVector;

            return bodyPQS.GetSurfaceHeight(bodyUpVector);
}

 

put it in your class and then use it like this ... Should give you what you are looki8ng for

Quote

public void SomeMethodInSomeClass()
{
           <.... some code ..... > ........

            _surfaceAltitude = GetAltitudeAtPos(latitude, longitude);

           <.... more code ..... > ........
}


 

 

 

Link to comment
Share on other sites

44 minutes ago, Xyphos said:

@DoctorDavinci thanks, but it also crashes with index out of range. 

would being run from an async thread be the culprit?

I have no idea ... all I do know is that the code I posted works no issue since pre KSP v1.2 so I don't know what to tell you

Did you reference the PQS controller? ... as in like this  'PQS bodyPQS = FlightGlobals.currentMainBody.pqsController;'

Or have you changed the coordinates over to geo coords from world coords?

Try this method like it is below and it should work no issue ... if it doesn't then, like I said, I don't know what to tell you without looking at exactly what you are trying to do with your code
 

Quote

public double GetAltitudeAtPos(double latitude, double longitude)
{
            Vector3 gpsPos = WorldPositionToGeoCoords(FlightGlobals.currentMainBody.GetWorldSurfacePosition((double)latitude, (double)longitude, 0), FlightGlobals.currentMainBody);

           PQS bodyPQS = FlightGlobals.currentMainBody.pqsController;

           Vector3d bodyUpVector = new Vector3d(1, 0, 0);
            bodyUpVector = QuaternionD.AngleAxis(gpsPos.x, Vector3d.forward) * bodyUpVector;
            bodyUpVector = QuaternionD.AngleAxis(gpsPos.y, Vector3d.down) * bodyUpVector;

            return bodyPQS.GetSurfaceHeight(bodyUpVector);
}

 

EDIT: I didn't even consider the possibility that you are trying to do this while not in the flight scene so there is that ...

The above code works as tested in the flight scene and is based off of the code that is in vessel movers move vessel function that keeps the vessel at the same height from the terrain when moving it around, preventing vessels crashing through the terrain surface

Edited by DoctorDavinci
Link to comment
Share on other sites

I don't understand the difference between world position and regular lon/lat?

the mod is supposed to run only from the tracking station, not in flight on a vessel.

the PQS is referenced in the celestial body that is passed to the method via parameter, it's not null.

Edited by Xyphos
Link to comment
Share on other sites

Just now, Xyphos said:

I don't understand the difference between world position and regular lon/lat?

The World Pos deal converts a double precision Vector3d to a Vector3 that Unity can use ... Unity can only use Vector3's unless you write your own coordinate system on top of Unity and convert back to Vector3's when you need to use a Vector function inside the game engine

In order to use the double precision longitude and latitude numbers you will get out of KSP (doubles :wink:) they need to be converted to single precision values (floats), however in the case of vector math the vector must be converted, not just the numbers ... TL DR; you need to create a new Vector3 out of the Vector3d that the KSP coordinate system uses

Basically look at the gpsPos.x and gpsPos.y ... They are floats that were created by converting a vector3d into a vector3

And then we use those floats (gpsPos.x and gpsPos.y) in the creation of a new vector3d called bodyUpVector that utilizes the PQS system to get the altitude and return a double precision number

Yes, Unity can be odd :)

The code I posted above does this while in the flight scene, perfectly might I add :wink:  ... No idea how to get it to work in the tracking station though

Edited by DoctorDavinci
Link to comment
Share on other sites

4 hours ago, DoctorDavinci said:

The code I posted above does this while in the flight scene, perfectly might I add :wink:  ... No idea how to get it to work in the tracking station though

well then, I guess my 'simple' logger mod just got more complex; I'll try to get it to work in the tracking station but if I can't, I'll just re-write it for flight and hyperedit some probes in orbit just to scan from there.

thanks for your input, I'll keep you posted on what becomes of it.

Link to comment
Share on other sites

Update: the altitude method works fine, but it really doesn't like to be multithreaded. the index errors cease when it's run normally, but the scanner freezes the game until the scan is completed. I'm going to have to find another way.

Link to comment
Share on other sites

2 minutes ago, Xyphos said:

Update: the altitude method works fine, but it really doesn't like to be multithreaded. the index errors cease when it's run normally, but the scanner freezes the game until the scan is completed. I'm going to have to find another way.

Unity is not thread safe.  Try using CoRoutines

Link to comment
Share on other sites

1 hour ago, Xyphos said:

Update: the altitude method works fine, but it really doesn't like to be multithreaded. the index errors cease when it's run normally, but the scanner freezes the game until the scan is completed. I'm going to have to find another way.

So unless you are getting into DOTS and able to rewrite some of the core of KSP to designate which thread is the main then you will have pauses as unity switches between threads

Yes, Unity can utilize multithreading... no, it's not easy to get it to work ... and, like I mentioned above, unless you have access to the KSP code and able to rewrite portions of it you will continue to have the issue of KSP locking up since KSP has not been set up to be multithreaded (even though Squad has made this claim)

The Unity project itself must be configured to utilize multithreading as well as having your code designated as usable in a separate thread

EDIT: This might help ... https://docs.unity3d.com/Manual/JobSystemMultithreading.html

Edited by DoctorDavinci
Link to comment
Share on other sites

The only way to do this practically is using coroutines to run the calculation over time. SCANsat basically does this by generating the maps over time.

DOTS or any of the Unity Job system isn't a possibility. All of the DOTS systems are still in experimental form in Unity 2019.1, and none of the packages are included with KSP. It wouldn't matter anyway, since the PQS height calculations all use regular Unity game objects and so wouldn't be accessible from a different thread.

DOTS has very strict limitations on how the code must be designed to work with multithreading. KSP (and KSP 2 in all likelihood) was designed long before that was a thing for Unity, so it will never be available in any significant way.

 

Link to comment
Share on other sites

Well, thank you all for teaching me about Coroutines.

here's what I have so far, in a dev branch but it's behaving a bit wonky and I can't figure out why. The attached screenshot is after the scan completes, but it seems to complete too early around 27% (and aborts?)
unless my progress indicator math is wrong?
https://github.com/Xyphos/KSP_PeakScan/blob/dev/PeakScan.cs

tSPI1QY.png

Link to comment
Share on other sites

1 hour ago, Xyphos said:

Well, thank you all for teaching me about Coroutines.

here's what I have so far, in a dev branch but it's behaving a bit wonky and I can't figure out why. The attached screenshot is after the scan completes, but it seems to complete too early around 27% (and aborts?)
unless my progress indicator math is wrong?
https://github.com/Xyphos/KSP_PeakScan/blob/dev/PeakScan.cs

tSPI1QY.png

I suggest changing the yield return new waitforseconds(0.01f) in the DoScan coroutine to yield return new waitforfixedupdate();

This will allow for the scan to happen every physics tick instead of multiple times per physics tick ... it will also help with slower computers as the timing between each physics calc will change depending on if your using a potato vs a decent computer ... fixed update is tied to physics updates which are tied to the processing speed of the computer running the pickle (.dll ... dill ... dill pickle :wink:)

Hope this helps ......

 

Link to comment
Share on other sites

1 minute ago, Xyphos said:

:D

 

thanks!

No problem ... Any other question you have feel free to ask as what you are doing with your mod is along the lines of what I've been doing in OrX Kontinuum, albeit your mods purpose, ie getting the highest altitude of a given point to be displayed to the user, is not part of it

I'm doing the same sort of deal in W[ind/s] to simulate updrafts for hang gliding as well as ocean currents for Scuba Kerb ... scuba diving is a thing in KSP now :wink:

Link to comment
Share on other sites

10 minutes ago, DoctorDavinci said:

No problem ... Any other question you have feel free to ask as what you are doing with your mod is along the lines of what I've been doing in OrX Kontinuum, albeit your mods purpose, ie getting the highest altitude of a given point to be displayed to the user, is not part of it

I'm doing the same sort of deal in W[ind/s] to simulate updrafts for hang gliding as well as ocean currents for Scuba Kerb ... scuba diving is a thing in KSP now :wink:

The mod's original purpose was to locate the highest peak on every celestial body from the tracking station and log it to a text file.

but plans change; now I'm thinking of making it a part module (currently for command modules during testing, will transition to the Stock M700 Survey Scanner later) that only scans the current orbiting body.

when I get it working properly, I intend on having it set a Stock Waypoint at the highest peak, and maybe even send some science data back.

landing vessels at these peaks would save dV for landing and takeoff  but would require some precision piloting to achieve.

I got this idea from a youtube video I saw, someone completed the Jool 5 Challenge in a < 7tonne SSTO SpacePlane but he landed on their highest peaks to do it, so I wanna give it a shot too, and maybe even beat the lowest mass record

Edited by Xyphos
Link to comment
Share on other sites

That is actually a pretty good idea

I assume you're using 1 offset GPS point per cardinal direction to calculate the highest of the 9 during scan and if this is the case you could easily add in a landing difficulty indicator based on the difference in altitude of each of the GPS points

If you were to happen to do this then your mod would be the first mod that can utilize the challenge creator I made in OrX Kontinuum ... there already is short track racing and dakar racing built in with the BD Armory challenge builder going to be released in the next week or so 

Adding in a challenge type based on your mod idea would be fairly easy ... let me know if you're interested in discussing this further :wink:

EDIT: I don't mean integrating your mod into OrX K, just a challenge deal that your mod can interface with

Link to comment
Share on other sites

3 minutes ago, DoctorDavinci said:

I assume you're using 1 offset GPS point per cardinal direction to calculate the highest of the 9 during scan and if this is the case you could easily add in a landing difficulty indicator based on the difference in altitude of each of the GPS points

I have no clue what any of that means :D

and I'll seriously consider interfacing, I've done interfaces with MechJeb before so it's possible.

Link to comment
Share on other sites

7 minutes ago, Xyphos said:

I have no clue what any of that means :D

and I'll seriously consider interfacing, I've done interfaces with MechJeb before so it's possible.

It's easier than you may think ... I just include an extension method you can hook into and OrX K will not need to be a dependancy for your mod

Would probably need to put one into your mod as well so OrX K can talk to your mod but that is trivial, I can write one of those for you in a matter of minutes

Link to comment
Share on other sites

14 minutes ago, Xyphos said:

I meant, that 1 GPS point.... 9 directions, etc. I didn't understand.

So how I am figuring out wind and updraft direction is by taking the current gps point of the active vessel (the glider) and then checking 8 gps points (N, NW, W, SW, S, SE, E, NE) around that gps point to get the terrain altitude at each of them (I plan to increase the amount of scan points to 68 or more)

I then take those altitudes, calculate the highest and lowest points and through some math calculate a vector for the wind direction and any updrafts for the glider to rise on

You could use the same idea for calculating how rough of a landing it would be based off of a bunch of terrain altitude calcs in the general area of the scanned gps coordinates your mod just ran in the DoScan coroutine

Theoretically you could tell a player how rough the terrain is in that area

Most of the code you would need to do this you already have

:cool:

Edited by DoctorDavinci
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...