Jump to content

[1.8.x to 1.12.x] kRPC: Control the game using C#, C++, Java, Lua, Python, Ruby, Haskell, C (Arduino)... (v0.5.2, 18th March 2023)


djungelorm

Recommended Posts

The Navball seems like it ought to be relatively simple in Unity, since you're really just rotating a 3D model in front of a camera?

As to a map view... if you're doing it the hard way...  I've got this -   It's ancient C# code from when I was playing with Telemachus years ago and it's terribly documented - and was just a test - all the orbital parameters are hard coded in.  It's only giving a 2D display, thus only really works for two vessels when their planes are matched, and I'm SURE there are a BUNCH of cases under which it doesn't work right at all, but it might get you STARTED on thinking through the steps to draw an orbit.   I make NO guarantee that it's RIGHT at all... and don't claim to really remember how it worked if it did!

It draws the planet, the atmosphere line, the ellipse of the 'active vessel's orbit and a dashed line to show it's current position along that ellipse, then the target vessel's orbital ellipse and current position line.

 

            float planetr = 600;  //radius
            float planetatmo = 70;  //atmosphere thickness in km
            float biggest = 0;  //determines what the biggest ellipse that needs drawn is
            float scalefactor = 1f;  // multiplier, used later
            float windowsize = 390;
           

            //myship variables
            
            float shipsma=751;
            float shipsmi = 713;
            float shipapa = 151;
            float shippea = 75;
            float shipmea = 3.1415f;
            float shiplan = 15;
            float shiparg = 15;  //arg of periapsis
            PointF shipcenter;
            float shipscaledx;
            float shipscaledy;


            //targetship variables
            float targetsma = 751;
            float targetsmi = 713;
            float targetapa = 151;
            float targetpea = 75;
            float targetmea = 3.010101f;
            float targetlan = 180;
            float targetarg = 15;
            PointF targetcenter;
            float targetscaledx;
            float targetscaledy;


            //myship next orbit variables
            float nxtsma = 751;
            float nxtsmi = 713;
            float nxtapa = 151;
            float nxtpea = 75;
            float nxtmea = 3.010101f;
            float nxtlan = 45;
            float nxtarg = 15;
            PointF nxtcenter;
            float nxtscaledx;
            float nxtscaledy;

            //graphics crap - including pen colors
            Graphics g = panel1.CreateGraphics();
            System.Drawing.Pen planetBrush = new System.Drawing.Pen(Color.Goldenrod, 3);
            System.Drawing.Pen atmoBrush = new System.Drawing.Pen(Color.Goldenrod, 2);
            
            atmoBrush.DashStyle = DashStyle.Dash;
            atmoBrush.DashPattern = new float[] { 10f, 10f, 5f, 10f };
            System.Drawing.Pen myBrush = new System.Drawing.Pen(Color.Cyan, 1);
            System.Drawing.Pen targetBrush = new System.Drawing.Pen(Color.Green, 1);
            System.Drawing.Pen nxtBrush = new System.Drawing.Pen(Color.Blue, 1);


            //Figure out what the biggest thing we have to draw is and scale that to the window's resolution.
            biggest = Math.Max(planetr, shipsma);
            biggest = Math.Max(biggest, targetsma);
            biggest = Math.Max(biggest, nxtsma);
            scalefactor = windowsize / biggest;
            scalefactor = (scalefactor * .4f);

            //rescale everything 
            planetr = planetr * scalefactor;
            planetatmo = planetatmo * scalefactor;
            shipsma = shipsma * scalefactor;
            shipsmi = shipsmi * scalefactor;
            shipapa = shipapa * scalefactor;
            shippea = shippea * scalefactor;
            targetsma = targetsma * scalefactor;
            targetsmi = targetsmi * scalefactor;
            targetapa = targetapa * scalefactor;
            targetpea = targetpea * scalefactor;
          

           //draw planet
            Point planetcenter = new Point((int)windowsize / 2, (int)windowsize / 2);  
            Point planetcorner = new Point((int)(planetcenter.X - planetr), (int)(planetcenter.Y - planetr));
            g.DrawEllipse(planetBrush, new Rectangle(planetcorner.X, planetcorner.Y, (int)(2*planetr), (int)(2*planetr)));
            g.DrawEllipse(atmoBrush, new Rectangle(planetcorner.X-(int)planetatmo, planetcorner.Y-(int)planetatmo, (int)(2 * (planetr+planetatmo)), (int)(2 * (planetr+planetatmo))));
           

            //draw ship
            float angle = shiplan + shiparg;  // rotation of orbit's SMA relative to Origin of Longitude 
            float centeradjust = 0.5f*(shippea - shipapa);
            shipcenter =new PointF((float)planetcenter.X-centeradjust,(float)planetcenter.Y);
            Point shipcorner = new Point((int)(shipcenter.X - (int)shipsma), (int)(shipcenter.Y - (int)shipsmi));
            using (Matrix rotate = new Matrix()){
                GraphicsContainer container = g.BeginContainer();
                rotate.RotateAt(angle, planetcenter);
                g.Transform = rotate;      
                g.DrawEllipse(myBrush, new Rectangle(shipcorner.X,shipcorner.Y,(int)(2*shipsma),(int)(2*shipsmi)));
                g.EndContainer(container);
            }
            float progressangle = (shipmea * 360) / 6.28319f;
            progressangle = progressangle + shiplan + shiparg;
            Point shippoint = new Point();
            shippoint.X = (int)((windowsize) * Math.Cos((Math.PI / 180) * progressangle) + planetcenter.X);
            shippoint.Y = (int)((windowsize) * Math.Sin((Math.PI / 180) * progressangle) + planetcenter.Y);
            //textBox1.Text = shippoint.X.ToString();
            //textBox2.Text = shippoint.Y.ToString();
            //textBox3.Text = progressangle.ToString();
            g.DrawLine(myBrush,planetcenter, shippoint);


            
           //draw target
            angle = targetlan + targetarg;
           centeradjust = 0.5f * (targetpea - targetapa);
            targetcenter = new PointF((float)planetcenter.X - centeradjust, (float)planetcenter.Y);
            Point targetcorner = new Point((int)(targetcenter.X - (int)targetsma), (int)(targetcenter.Y - (int)targetsmi));
            using (Matrix rotate = new Matrix())
            {
                GraphicsContainer container = g.BeginContainer();
                rotate.RotateAt(angle, planetcenter);
                g.Transform = rotate;
                g.DrawEllipse(targetBrush, new Rectangle(targetcorner.X, targetcorner.Y, (int)(2 * targetsma), (int)(2 * targetsmi)));
                g.EndContainer(container);
            }
            progressangle = (targetmea * 360) / 6.28319f;
            progressangle = progressangle + targetlan + targetarg;
            Point targetpoint = new Point();
            targetpoint.X = (int)((windowsize) * Math.Cos((Math.PI / 180) * progressangle) + planetcenter.X);
            targetpoint.Y = (int)((windowsize) * Math.Sin((Math.PI / 180) * progressangle) + planetcenter.Y);
            //textBox1.Text = shippoint.X.ToString();
            //textBox2.Text = shippoint.Y.ToString();
            //textBox3.Text = progressangle.ToString();
            g.DrawLine(targetBrush, planetcenter, targetpoint);




            g.Dispose();
            myBrush.Dispose();

 

Link to comment
Share on other sites

2 minutes ago, artwhaley said:

The Navball seems like it ought to be relatively simple in Unity, since you're really just rotating a 3D model in front of a camera?

As to a map view... if you're doing it the hard way...  I've got this -   It's ancient C# code from when I was playing with Telemachus years ago and it's terribly documented - and was just a test - all the orbital parameters are hard coded in.  It's only giving a 2D display, thus only really works for two vessels when their planes are matched, and I'm SURE there are a BUNCH of cases under which it doesn't work right at all, but it might get you STARTED on thinking through the steps to draw an orbit.   I make NO guarantee that it's RIGHT at all... and don't claim to really remember how it worked if it did!

It draws the planet, the atmosphere line, the ellipse of the 'active vessel's orbit and a dashed line to show it's current position along that ellipse, then the target vessel's orbital ellipse and current position line.

 


            float planetr = 600;  //radius
            float planetatmo = 70;  //atmosphere thickness in km
            float biggest = 0;  //determines what the biggest ellipse that needs drawn is
            float scalefactor = 1f;  // multiplier, used later
            float windowsize = 390;
           

            //myship variables
            
            float shipsma=751;
            float shipsmi = 713;
            float shipapa = 151;
            float shippea = 75;
            float shipmea = 3.1415f;
            float shiplan = 15;
            float shiparg = 15;  //arg of periapsis
            PointF shipcenter;
            float shipscaledx;
            float shipscaledy;


            //targetship variables
            float targetsma = 751;
            float targetsmi = 713;
            float targetapa = 151;
            float targetpea = 75;
            float targetmea = 3.010101f;
            float targetlan = 180;
            float targetarg = 15;
            PointF targetcenter;
            float targetscaledx;
            float targetscaledy;


            //myship next orbit variables
            float nxtsma = 751;
            float nxtsmi = 713;
            float nxtapa = 151;
            float nxtpea = 75;
            float nxtmea = 3.010101f;
            float nxtlan = 45;
            float nxtarg = 15;
            PointF nxtcenter;
            float nxtscaledx;
            float nxtscaledy;

            //graphics crap - including pen colors
            Graphics g = panel1.CreateGraphics();
            System.Drawing.Pen planetBrush = new System.Drawing.Pen(Color.Goldenrod, 3);
            System.Drawing.Pen atmoBrush = new System.Drawing.Pen(Color.Goldenrod, 2);
            
            atmoBrush.DashStyle = DashStyle.Dash;
            atmoBrush.DashPattern = new float[] { 10f, 10f, 5f, 10f };
            System.Drawing.Pen myBrush = new System.Drawing.Pen(Color.Cyan, 1);
            System.Drawing.Pen targetBrush = new System.Drawing.Pen(Color.Green, 1);
            System.Drawing.Pen nxtBrush = new System.Drawing.Pen(Color.Blue, 1);


            //Figure out what the biggest thing we have to draw is and scale that to the window's resolution.
            biggest = Math.Max(planetr, shipsma);
            biggest = Math.Max(biggest, targetsma);
            biggest = Math.Max(biggest, nxtsma);
            scalefactor = windowsize / biggest;
            scalefactor = (scalefactor * .4f);

            //rescale everything 
            planetr = planetr * scalefactor;
            planetatmo = planetatmo * scalefactor;
            shipsma = shipsma * scalefactor;
            shipsmi = shipsmi * scalefactor;
            shipapa = shipapa * scalefactor;
            shippea = shippea * scalefactor;
            targetsma = targetsma * scalefactor;
            targetsmi = targetsmi * scalefactor;
            targetapa = targetapa * scalefactor;
            targetpea = targetpea * scalefactor;
          

           //draw planet
            Point planetcenter = new Point((int)windowsize / 2, (int)windowsize / 2);  
            Point planetcorner = new Point((int)(planetcenter.X - planetr), (int)(planetcenter.Y - planetr));
            g.DrawEllipse(planetBrush, new Rectangle(planetcorner.X, planetcorner.Y, (int)(2*planetr), (int)(2*planetr)));
            g.DrawEllipse(atmoBrush, new Rectangle(planetcorner.X-(int)planetatmo, planetcorner.Y-(int)planetatmo, (int)(2 * (planetr+planetatmo)), (int)(2 * (planetr+planetatmo))));
           

            //draw ship
            float angle = shiplan + shiparg;  // rotation of orbit's SMA relative to Origin of Longitude 
            float centeradjust = 0.5f*(shippea - shipapa);
            shipcenter =new PointF((float)planetcenter.X-centeradjust,(float)planetcenter.Y);
            Point shipcorner = new Point((int)(shipcenter.X - (int)shipsma), (int)(shipcenter.Y - (int)shipsmi));
            using (Matrix rotate = new Matrix()){
                GraphicsContainer container = g.BeginContainer();
                rotate.RotateAt(angle, planetcenter);
                g.Transform = rotate;      
                g.DrawEllipse(myBrush, new Rectangle(shipcorner.X,shipcorner.Y,(int)(2*shipsma),(int)(2*shipsmi)));
                g.EndContainer(container);
            }
            float progressangle = (shipmea * 360) / 6.28319f;
            progressangle = progressangle + shiplan + shiparg;
            Point shippoint = new Point();
            shippoint.X = (int)((windowsize) * Math.Cos((Math.PI / 180) * progressangle) + planetcenter.X);
            shippoint.Y = (int)((windowsize) * Math.Sin((Math.PI / 180) * progressangle) + planetcenter.Y);
            //textBox1.Text = shippoint.X.ToString();
            //textBox2.Text = shippoint.Y.ToString();
            //textBox3.Text = progressangle.ToString();
            g.DrawLine(myBrush,planetcenter, shippoint);


            
           //draw target
            angle = targetlan + targetarg;
           centeradjust = 0.5f * (targetpea - targetapa);
            targetcenter = new PointF((float)planetcenter.X - centeradjust, (float)planetcenter.Y);
            Point targetcorner = new Point((int)(targetcenter.X - (int)targetsma), (int)(targetcenter.Y - (int)targetsmi));
            using (Matrix rotate = new Matrix())
            {
                GraphicsContainer container = g.BeginContainer();
                rotate.RotateAt(angle, planetcenter);
                g.Transform = rotate;
                g.DrawEllipse(targetBrush, new Rectangle(targetcorner.X, targetcorner.Y, (int)(2 * targetsma), (int)(2 * targetsmi)));
                g.EndContainer(container);
            }
            progressangle = (targetmea * 360) / 6.28319f;
            progressangle = progressangle + targetlan + targetarg;
            Point targetpoint = new Point();
            targetpoint.X = (int)((windowsize) * Math.Cos((Math.PI / 180) * progressangle) + planetcenter.X);
            targetpoint.Y = (int)((windowsize) * Math.Sin((Math.PI / 180) * progressangle) + planetcenter.Y);
            //textBox1.Text = shippoint.X.ToString();
            //textBox2.Text = shippoint.Y.ToString();
            //textBox3.Text = progressangle.ToString();
            g.DrawLine(targetBrush, planetcenter, targetpoint);




            g.Dispose();
            myBrush.Dispose();

 

Wow! Thank you so much artwhaley! I'm sure this will give me a better picture of how I'd make the map view. However, I doubt it'll be an easy feat for me, especially as I don't even really know how to get started on the navball display :P
Oh well... guess I should start reading up on the maths of spheres and rotation...   .--.

Link to comment
Share on other sites

Having two well knowing guys on this thread (djungelorm & artwhaley), I was wondering if you'd have to input as to how to properly rotate my navball (Unity).

I've set up a sphere and got the kRPC connection going, but I'm lost as to what exactly to change given the direction information from kRPC.

kRPC gives a vessel direction as a Tuple with three doubles seemingly ranging from -1 to 1. (https://krpc.github.io/krpc/csharp/api/space-center/flight.html#property-KRPC.Client.Services.SpaceCenter.Flight.Direction)

Simply multiplying the output from the direction Tuple and feeding it as euler angles (multiplied by 360) in to the quaternion transform of my sphere doesn't seem to do the trick (as it clearly doesn't match KSP's navball).

What am I getting wrong here?

Link to comment
Share on other sites

4 minutes ago, Fillipuster said:

Having two well knowing guys on this thread (djungelorm & artwhaley), I was wondering if you'd have to input as to how to properly rotate my navball (Unity).(...)

What am I getting wrong here?

For now you'll have to do with me. The direction is a (normalized, I think) vector, not representing angles. Also be aware that everything is measured in relation to your frame of reference—if you don't specify what frame of reference you pick, results may very wildly from what you're expecting.

Link to comment
Share on other sites

Just now, Kerbart said:

For now you'll have to do with me. The direction is a (normalized, I think) vector, not representing angles. Also be aware that everything is measured in relation to your frame of reference—if you don't specify what frame of reference you pick, results may very wildly from what you're expecting.

I see, thanks for the reply :D

There doesn't seem to be a way to specify the reference frame when getting the Direction Tuple :/ I assumed the direction would just use the reference frame that the navball in game uses (matching the navball).

I suppose I could use the pitch, roll and heading maybe?

Link to comment
Share on other sites

You should pass the reference frame as you request the direction.  There may be a default that gets assumed if you don't specify, but the documentation doesn't tell us what it is.   Something like : 

var vesselDirection = vessel.Direction (vessel.SurfaceReferenceFrame);

The example here shows some ways to work with that.  https://krpc.github.io/krpc/tutorials/pitch-heading-roll.html  Without TOTALLY thinking through the 3D space implications.... it sure SEEMS to me that the roll, pitch and heading values ((again, from a flight(vessel.SurfaceReferenceFrame) object)) COULD be used to rotate your ball?   I hate 3D rotation math... so hopefully someone smarter than me volunteers how to actually relate one to the other!    

 

Link to comment
Share on other sites

So I made it (not really) work with Heading, Pitch & Roll. But I cannot for the life of me figure out why I get these strange "flips" when I reach the top and bottom of the hemispheres...

Here's a short video showing it off. https://my.mixtape.moe/ynaabg.mp4

My guess is that it has something to do with my usage of euler angles and the raw heading, pitch and yaw data. I should probably be using Flight.Direction and Quaternions but that's beyond my understanding at the moment.

Any input?

Link to comment
Share on other sites

Hey!  That's looking like GREAT progress!   

If I had to wager a guess without seeing the code or testing anything here...  I'd actually guess it's a matter of scales that can be fixed with a simple bit of arithmetic.  Pitch and roll return values between -180 and 180 and heading returns values between 0 and 360.   If your unity model can have it's pitch, yaw, and roll set as 0 to 360 values, or you can convert pitch, yaw and roll to the format you need, make sure you've done something like - 

if(pitch<0) pitch += 360;

if(roll<0) roll += 360;

I may be missing something, but that's my first guess!  

Link to comment
Share on other sites

6 minutes ago, artwhaley said:

Hey!  That's looking like GREAT progress!   

If I had to wager a guess without seeing the code or testing anything here...  I'd actually guess it's a matter of scales that can be fixed with a simple bit of arithmetic.  Pitch and roll return values between -180 and 180 and heading returns values between 0 and 360.   If your unity model can have it's pitch, yaw, and roll set as 0 to 360 values, or you can convert pitch, yaw and roll to the format you need, make sure you've done something like - 


if(pitch<0) pitch += 360;

if(roll<0) roll += 360;

I may be missing something, but that's my first guess!  

I never even considered that pitch and roll don't range between -360 and 360, but with your addition, I get the exact same behavior.

This is my code:

    void UpdateNavball()
    {
        Flight flight = vessel.Flight(vessel.SurfaceReferenceFrame);

        float roll = flight.Roll;
        float pitch = flight.Pitch;
        if (roll < 0)
        {
            roll += 360;
        }
        if(pitch < 0)
        {
            pitch += 360;
        }
        Quaternion newRotation = Quaternion.Euler(-roll, flight.Heading, -pitch);
        transform.rotation = newRotation;
    }

 

Link to comment
Share on other sites

I know nothing about quaternions and euler angles. What I do know is that when converting vectors to angles one commonly uses the atan function, and there's a specific atan2 function in most languages that mitigates these flips. Maybe something similar is going on here?

Link to comment
Share on other sites

5 hours ago, Fillipuster said:

So I made it (not really) work with Heading, Pitch & Roll. But I cannot for the life of me figure out why I get these strange "flips" when I reach the top and bottom of the hemispheres...

Here's a short video showing it off. https://my.mixtape.moe/ynaabg.mp4

My guess is that it has something to do with my usage of euler angles and the raw heading, pitch and yaw data. I should probably be using Flight.Direction and Quaternions but that's beyond my understanding at the moment.

Any input?

Based on the Docs. I think the Flight Direction is the unit tangent vector. 

I can't see your video (404) so I can only guess the strange flips behavior  when you get to the top and bottom of the hemispheres: are because of your vessel's heading

Quote
Single Heading { get; }

The heading angle of the vessel relative to north, in degrees. A value between 0° and 360°.

 

It flips when the heading is no longer north or no longer south. 

 

I think this information about different reference frames would help 

https://krpc.github.io/krpc/csharp/api/space-center/vessel.html 

 

Edited by KerbalX
Link to comment
Share on other sites

8 hours ago, KerbalX said:

Based on the Docs. I think the Flight Direction is the unit tangent vector. 

I can't see your video (404) so I can only guess the strange flips behavior  when you get to the top and bottom of the hemispheres: are because of your vessel's heading

It flips when the heading is no longer north or no longer south. 

 

I think this information about different reference frames would help 

https://krpc.github.io/krpc/csharp/api/space-center/vessel.html 

Hmm.... This is interesting.

I've now tried with different reference frames, without much luck. I did however figure out how to use the Direction vector to rotate the navball instead of the pitch, heading and roll angles.

This, however, provides a different "flipping" problem, as seen in this video: http://sendvid.com/4nx5ry2e

This also doesn't include the roll of the vessel, which I presume is stored in the Rotation tuple (https://krpc.github.io/krpc/csharp/api/space-center/flight.html#property-KRPC.Client.Services.SpaceCenter.Flight.Rotation)

I'm lost as to how to fix this flipping and/or implement the roll. Progress at least, if not much.

 

Link to comment
Share on other sites

7 hours ago, Fillipuster said:

Hmm.... This is interesting.

I've now tried with different reference frames, without much luck. I did however figure out how to use the Direction vector to rotate the navball instead of the pitch, heading and roll angles.

This, however, provides a different "flipping" problem, as seen in this video: http://sendvid.com/4nx5ry2e

This also doesn't include the roll of the vessel, which I presume is stored in the Rotation tuple (https://krpc.github.io/krpc/csharp/api/space-center/flight.html#property-KRPC.Client.Services.SpaceCenter.Flight.Rotation)

I'm lost as to how to fix this flipping and/or implement the roll. Progress at least, if not much.

 

The "flipping" problem is because you're not taking the vessels roll into account.

I think the simplest way to achieve what you want is to use this to rotate the sphere: https://krpc.github.io/krpc/csharp/api/space-center/flight.html#property-KRPC.Client.Services.SpaceCenter.Flight.Rotation

It is a 4-element tuple describing the rotation of the vessel as a quaternion. A quaternion is a bit like a transformation matrix - it describes the rotation of an object, including it's roll. Unity has a Quaternion class that you should be able to use to transform the sphere so that it is rotated correctly: https://docs.unity3d.com/ScriptReference/Quaternion.html

Also, I've added a ticket to go through the docs and clarify what all these tuples are. The docs could certainly be improved to specify what the tuple means! https://github.com/krpc/krpc/issues/417

Edit: and off the top of my head I think you need the vessel's surface reference frame: https://krpc.github.io/krpc/csharp/api/space-center/vessel.html#property-KRPC.Client.Services.SpaceCenter.Vessel.SurfaceReferenceFrame

Edited by djungelorm
Comment on the reference frame
Link to comment
Share on other sites

36 minutes ago, djungelorm said:

The "flipping" problem is because you're not taking the vessels roll into account.

I think the simplest way to achieve what you want is to use this to rotate the sphere: https://krpc.github.io/krpc/csharp/api/space-center/flight.html#property-KRPC.Client.Services.SpaceCenter.Flight.Rotation

It is a 4-element tuple describing the rotation of the vessel as a quaternion. A quaternion is a bit like a transformation matrix - it describes the rotation of an object, including it's roll. Unity has a Quaternion class that you should be able to use to transform the sphere so that it is rotated correctly: https://docs.unity3d.com/ScriptReference/Quaternion.html

Also, I've added a ticket to go through the docs and clarify what all these tuples are. The docs could certainly be improved to specify what the tuple means! https://github.com/krpc/krpc/issues/417

Wow... I feel kind of stupid now. I didn't even notice that the Rotation tuple had 4 elements, which would probably have lead me to believe it was a quaternion - great idea with the ticket!

Simply setting the rotation quaternion to the tranform of the sphere in unity gets rid of the "flipping" (gimbal-lock I'm guessing), but now I've run in to (yet) another problem... I have my main unity camera pointing at the sphere I am rotating using the kRPC data, but no matter what side I look at the sphere from, or what way I rotate the camera, I cannot seem to get the same rotational results. If I place it in one spot, the heading matches. If I place it in another, the roll matches.

I feel like the solution is right in front of me, but no matter the perspective (get it? :P) I cannot seem to crack it. Any ideas?

Link to comment
Share on other sites

I originally posted this over in the PEGAS thread by @Reddy , but I thought it might be useful to mention it here as well.

I've been using kRPC to automate my rockets, and wanted to get this system integrated.

I ended up porting Noiredd's MATLAB repository to python, and made it available, in case it's useful to others

https://github.com/ubik2/PEGAS-kRPC

TL;DR: I took a system to automate launches and made it usable from kRPC. It's like a more advanced MechJeb ascent autopilot (though they're adding PEGAS there too).

 
Link to comment
Share on other sites

@ubik2 out of interest, how does PEGAS do the actual attitude control of the vessel? Does it do something custom or just use kRPC's built in autopilot? (I ask as I'm looking into alternatives for the sometimes sub-optimal PID based autopilot that is currently implemented)

21 hours ago, Fillipuster said:

Wow... I feel kind of stupid now. I didn't even notice that the Rotation tuple had 4 elements, which would probably have lead me to believe it was a quaternion - great idea with the ticket!

Simply setting the rotation quaternion to the tranform of the sphere in unity gets rid of the "flipping" (gimbal-lock I'm guessing), but now I've run in to (yet) another problem... I have my main unity camera pointing at the sphere I am rotating using the kRPC data, but no matter what side I look at the sphere from, or what way I rotate the camera, I cannot seem to get the same rotational results. If I place it in one spot, the heading matches. If I place it in another, the roll matches.

I feel like the solution is right in front of me, but no matter the perspective (get it? :P) I cannot seem to crack it. Any ideas?

Maybe you're applying the inverse of the desired rotation by accident? It's an easy mistake to make with quaternions. You could try inverting it using: https://docs.unity3d.com/ScriptReference/Quaternion.Inverse.html

Link to comment
Share on other sites

6 minutes ago, djungelorm said:

@ubik2 out of interest, how does PEGAS do the actual attitude control of the vessel? Does it do something custom or just use kRPC's built in autopilot? (I ask as I'm looking into alternatives for the sometimes sub-optimal PID based autopilot that is currently implemented)

On this topic, I got my quaternion-based attitude controller (Wie, Weiss, and Araposthathis) working, which works fairly well but my tuning of it isn't very good. It does let me do a 3D translation autopilot in a vertically-aligned gravitational field, though, which the built in one had trouble with due to the singularity. I can post a video or two if interested, but as mentioned before, my tuning is garbage.

Link to comment
Share on other sites

1 hour ago, djungelorm said:

@ubik2 out of interest, how does PEGAS do the actual attitude control of the vessel? Does it do something custom or just use kRPC's built in autopilot? (I ask as I'm looking into alternatives for the sometimes sub-optimal PID based autopilot that is currently implemented

@djungelorm It's just using the standard  vessel.auto_pilot.target_pitch (and target_heading) for actually applying the desired orientation. The throttle is also using the standard vessel.control.throttle.

Link to comment
Share on other sites

On 9/8/2017 at 7:03 PM, djungelorm said:

@ubik2 out of interest, how does PEGAS do the actual attitude control of the vessel? Does it do something custom or just use kRPC's built in autopilot? (I ask as I'm looking into alternatives for the sometimes sub-optimal PID based autopilot that is currently implemented)

Maybe you're applying the inverse of the desired rotation by accident? It's an easy mistake to make with quaternions. You could try inverting it using: https://docs.unity3d.com/ScriptReference/Quaternion.Inverse.html

Well... the inverse thing was not the problem, but I did figure it out. For some reason, I had to use a different ordering of the quaternion values. Because I didn't know anything about the math of quaternions, I brute-forced it, testing all different combinations using a little system I made. For me, it worked out to be no "x, y, z, w", but instead, "z, y, x, w".

I then went on to build a Linux application in Unity, only to be hit hard by the fact that the Raspberry Pi 3 doesn't run a x86 processor, and thus, cannot run a Unity application.

In essence... most of my work is wasted. I'm pondering what to do next now. I think the easiest solution would be to write the navball display in OpenGL instead (which does run on a rpi3 - and should run faster). But that provides the challenge of learning not only OpenGL, but also C++

Learned a lot... will probably learn a s*** ton more before this is working :P

Again, thanks for all the help djungleorm!

(you aren't a Dane by any chance? - your name pretty much translates to Jungle Worm in Danish)

Edited by Fillipuster
Link to comment
Share on other sites

I've released v0.3.10 :D Here's what's new:

  • Added various new methods to the CelestialBody and Orbit class for converting lat/long to positions, getting asc/desc nodes with a target vessel
  • Added methods for doing closest approach calculations
  • Added Flight.SimulateAerodynamicForceAt that can be used to compute trajectories for atmospheric reentry
  • A .NET 3.5 compatible builds of the C# client is now available, which lets you run the client from within the game (which could then connect to a server running in the same game, or a difference one!)
  • Added support for building the C++ client with cygwin.
  • Updated all the clients to use protobuf version 3.4.0

A full changelog can be found here: https://github.com/krpc/krpc/releases/tag/v0.3.10

Also, I'm planning to release a major update for the mod within the next week or two (dubbed version 0.4.0), with the following new features:

  • Revamped server architecture that allows multiple servers (using different protocols) to be running at the same time.
  • Two new communication protocols:
    • websockets - to communicate with the game from a javascript enabled browser. There is already a working client at the following link! https://www.npmjs.com/package/krpc-node
    • Serial IO - for communicating over a serial port, e.g. from an Arduino or Raspberry Pi. I'm also working on a C client library (targetting low-memory-budget embedded systems) but it probably won't be ready until after v0.4.0 drops.
  • The existing TCP/IP protobuf based protocol has also been improved, to reduce network traffic and to add some new functionality, such as...
  • Events - which will remove the need for active polling to wait for things to happen.
  • Exceptions - RPCs will be able to throw exceptions into the client (if the client language supports such a mechanism).
Link to comment
Share on other sites

17 hours ago, djungelorm said:

I've released v0.3.10 :D Here's what's new:

  • Added various new methods to the CelestialBody and Orbit class for converting lat/long to positions, getting asc/desc nodes with a target vessel
  • Added methods for doing closest approach calculations
  • Added Flight.SimulateAerodynamicForceAt that can be used to compute trajectories for atmospheric reentry
  • A .NET 3.5 compatible builds of the C# client is now available, which lets you run the client from within the game (which could then connect to a server running in the same game, or a difference one!)
  • Added support for building the C++ client with cygwin.
  • Updated all the clients to use protobuf version 3.4.0

A full changelog can be found here: https://github.com/krpc/krpc/releases/tag/v0.3.10

Also, I'm planning to release a major update for the mod within the next week or two (dubbed version 0.4.0), with the following new features:

  • Revamped server architecture that allows multiple servers (using different protocols) to be running at the same time.
  • Two new communication protocols:
    • websockets - to communicate with the game from a javascript enabled browser. There is already a working client at the following link! https://www.npmjs.com/package/krpc-node
    • Serial IO - for communicating over a serial port, e.g. from an Arduino or Raspberry Pi. I'm also working on a C client library (targetting low-memory-budget embedded systems) but it probably won't be ready until after v0.4.0 drops.
  • The existing TCP/IP protobuf based protocol has also been improved, to reduce network traffic and to add some new functionality, such as...
  • Events - which will remove the need for active polling to wait for things to happen.
  • Exceptions - RPCs will be able to throw exceptions into the client (if the client language supports such a mechanism).

Ah, amazing!

Really looking forward to the 040 update, and the things we will be able to do with serial connections, web sockets and events. Great work Jungle Worm!

Let me know if I can do anything to help. 

Link to comment
Share on other sites

  • 3 weeks later...

I was wondering, is there a convenient way to extract drag and lift coefficients as a function of angle of attack and velocity via kRPC when using FAR? I'm working on implementing Ping Lu's paper Nonlinear Trajectory Tracking Guidance with Application to a Launch Vehicle, which uses cubic spline fits to Cl and Cd vs. AoA and Mach to model aerodynamic effects, and would like to be able to derive this automatically.

Edited by lushr
Link to comment
Share on other sites

On 10/1/2017 at 10:01 PM, lushr said:

I was wondering, is there a convenient way to extract drag and lift coefficients as a function of angle of attack and velocity via kRPC when using FAR? I'm working on implementing Ping Lu's paper Nonlinear Trajectory Tracking Guidance with Application to a Launch Vehicle, which uses cubic spline fits to Cl and Cd vs. AoA and Mach to model aerodynamic effects, and would like to be able to derive this automatically.

Not currently. The only interaction with FAR is getting current drag/lift coefficients. The static analysis tools that FAR provides aren't exposed through the API. I can look into adding this though as it sounds very useful!

Link to comment
Share on other sites

1 hour ago, djungelorm said:

Not currently. The only interaction with FAR is getting current drag/lift coefficients. The static analysis tools that FAR provides aren't exposed through the API. I can look into adding this though as it sounds very useful!

That would be really nice - I found the internal endpoint in FAR that would be needed, here, which would be enough (sweep each along the relevant axis). If it's too annoying to add, I could probably submit a PR.

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...