Jump to content

Question about craft attitude / coordinate transformations


Kertherina

Recommended Posts

Hi peeps

So, i recently started writing my own simulation / game and i am hitting my first real barrier.

I have two coordinate systems. One is fixed, with it's origin at the center of the sun at the time the simulation starts, and the other one is relative to the craft and thus also constantly rotating. (I would love to do all in one coordinate system but creation of crafts with wing and engine positions and orientations would get really ugly.)

To transform a vector from the global c system to the local one i obviously need a description of both systems. I have the x,y and z vectors of the global c system of course, but the problems begin with the other vectors. I have the direction the craft points at, but i would need a second, perpendicular vector (third vector would be cross product of first two) since how the craft is rolled matters for the coordinate system and thus the transformation. I plan to use the port ("left") vector, to give me "up" as the cross product of "forward" and "port".

Now, my problem is:

How do i get the second (i.e. port) vector for a complete description of the attitude? The only possibility i came up with so far is that i set it up manually once when the simulation begins, and then rotate it whenever the craft rotates. But that sounds quite dirty and i don't know if the accumulative error would not get noticeable after a while (although i do use the GNU MPFR C++ library for arbitrary precision arithmetic so i could just use more Bit if the error gets too big?).

An alternative might be introducing a value (angle) for roll and then get to the port vector with some rotation and cross product magic, but the problem with an angle would be that it breaks down for certain situations (flying straight up / down) so i really want to avoid that if possible.

So, any thoughts on how to tackle this issue?

(If you happen to know how KSP handles attitude that would of course be nice to know too.)

I hope i could describe my problem clearly, if not i apologize and i can try again.

Edited by Kertherina
Link to comment
Share on other sites

Can you describe the problem a bit better?

You could use the center of mass of the vehicle as the vehicles origin, and calculate that in the global coordinate plane. Then, move the axes as needed, to the orientation of the craft. Maybe use everybody's favorite, the point slope formula to get a slope for your vector, and then use the arc-trigonemetry functions to get angles, as well as the Pythagorean Theorem to get a vector intensity.

If this doesn't help at all, then, I must not understand the problem.

Link to comment
Share on other sites

Sorry, let me try again.

The problem is in the step "move the axes as needed", for which i would need to know how i have to rotate each axis. For that i have to know the three basis vectors in both coordinate systems: x,y,z, and the new x',y',z'.

Now, i have those vectors for the fixed coordinate system since that is the main coordinate system the craft also uses for position and direction.

Then, i have the vector for the direction the craft points at ("forward"). But that is only one axis for the new coordinate system (z'), i do need at least a second vector (y' or z'). With a second one the third one would be the cross product of the other two, and then with all vectors i could then determine the angles for the rotation with the dot product.

That is where the port ("left") vector comes in as the x' axis. But how do i get this vector? Without the axes of the local coordinate system of the rocket since that is what i want to determine in the first place, there is no way to just calculate them with a cross product or something.

The only way to determine the port vector i so far know of is to manually set the port vector at the beginning of the simulation, and then each time the rocket rotates you also rotate the port vector. Which would accumulate floating point errors over time, which is why i am unsure if this is the way to go.

Was that easier to understand?

Link to comment
Share on other sites

Maybe make it so that the initial axes are parallel to the global axes?

Then you get the initial axes relative to the craft.

Maybe a third coordinate plane is needed...? One for the craft, one for local craft space, and one for global space?

Perhaps you should make the craft "forward" the x-axis, and use starboard as the y-axis.

I'm still a bit confused...

Link to comment
Share on other sites

I think you're going to need vector maths here, I found this page that explains the dot product and cross product pretty well, it may help :)

Thanks, but dot and cross products are not the problem. My problem is how to determine / update a second vector like port / starboard, up / down for a complete description of the local craft coordinate system. Currently i just have the forward direction vector. If i have the second vector, i know how to get the third vector and all the angles for the rotation.

Maybe a third coordinate plane is needed...? One for the craft, one for local craft space, and one for global space?

I don't see how an extra local coordinate system would help me here, directions would be the exact same vector as in the global fixed system, only positions would change but positions are not a problem. The only reason to use this would be accuracy, but i am already using 25 digit accuracy for the position exactly because i did not want more coordinate systems than are necessary.

Perhaps you should make the craft "forward" the x-axis, and use starboard as the y-axis.

The same problem as before: Where do i get the starboard vector from? It's the negative of the port vector so if i have one, i have the other, which doesn't matter because either one would be enough. I could again set up the starboard vector at the start of the simulation and rotate it with the craft, getting floating point errors over time.

I'm still a bit confused...

Sorry, I really don't know how else to describe this problem. Just to make sure, it is clear how you need 2 vectors to fully describe the attitude of a craft?

Link to comment
Share on other sites

I think the problem you are fighting is that your coordinate systems track only current position, and change in current position (vector). You also need to worry about angular positions and velocities around your current CoM position. This will require 3 more numbers for current angle of each axis off from the local coordinate system. You might be able to reduce it to 2 numbers by using a polar coordinate system, but I think the calculations for a 3-axis system would be simpler and faster than having to do constant transforms.

Link to comment
Share on other sites

The problem is that it is super easy keeping track of forward direction, but not the roll around the longitudinal axis.

This will require 3 more numbers for current angle of each axis off from the local coordinate system.

Angles are bad because they break down for certain situations (if you fly perfectly upwards,what is your roll?), you can do it with a second vector perpendicular to the forward direction though, which is port / starboard, or up / down what i have been mentioning up to now. Still 3 numbers, but doesn't break down if it's perpendicular to axes.

Either way the same questions, how do you determine these extra numbers? For the angles you'd need the axis vectors first, so you're again where i am currently stuck because how exactly do you determine the port vector for example? You can't just do a cross product of forward direction with another basis vector because the basis vectors is what you have to determine.

And to reiterate what i have been saying so far, the only method that is halfway decent i know so far is to initialize the port vector (or starboard, up or down, it doesn't matter) and then rotate it each time the craft rotates, and i am wondering if this method is the best out there because floating point errors will accumulate over time.

Link to comment
Share on other sites

Hmm... Basic rotation transformation ? I mean, the direction of the attitudes don't change even if you do it wrt Sun / parent body... You can set a vector defining the direction of one part of the craft, then rotate the others accordingly ?

Or if you want, use spherical coordinate, with a fixed r ?

Edited by YNM
Link to comment
Share on other sites

The same problem as before: Where do i get the starboard vector from? It's the negative of the port vector so if i have one, i have the other, which doesn't matter because either one would be enough. I could again set up the starboard vector at the start of the simulation and rotate it with the craft, getting floating point errors over time.

If the x-axis moves by 45 degrees in a direction, the y-axis moves with it. If it moves two dimensionally, only the y-axis and x-axis really change, but if you change the orientation three dimensionally, the z-axis moves as well. Remember, they're all 90 degrees to each other. So, just pick one 90-degree vector as the y or x, if z is your forward.

Link to comment
Share on other sites

Hmm... Basic rotation transformation ? I mean, the direction of the attitudes don't change even if you do it wrt Sun / parent body... You can set a vector defining the direction of one part of the craft, then rotate the others accordingly ?

Or if you want, use spherical coordinate, with a fixed r ?

Sorry, i don't understand what you are saying. Especially the part where you say attitude vectors don't change, since that is exactly what i want to to: transform (rotate) the vectors into a different coordinate system.

So, just pick one 90-degree vector as the y or x, if z is your forward.

But i can't just pick any. To consider the roll around the longitudinal axis you have to pick a special vector as a basis vector for the local coordinate system, which is where the port (or starboard, up or down) vector i am talking about comes into play. With forward and port as two axes you can get the third one with the cross product, but you need at least two vectors for an unambiguous representation of the coordinate system.

So the question is, how exactly do you get / update the port vector?

Again, my only guess so far is set it up when simulation starts and then rotate it every time the rocket rotates, where it will accumulate an error over time.

Link to comment
Share on other sites

Make the local plane's axes parallel to their corresponding axes on the fixed plane, on startup. Would that help?

Not sure if i understand that correctly. If i make the local coordinate system fixed and the axes all parallel to the global fixed plane, that would mean i could just stay in the global coordinate system. The point of the transformation is to have something in a local frame of reference because the positions and directions of engines and wings are all relative to the rocket, so this coordinate system has to constantly rotate with the rocket too.

And generally, i need the local coordinate axes in forward, port and up direction to have a consistent coordinate system. Aligning them with the global axes is counter productive.

Link to comment
Share on other sites

Not sure if i understand that correctly. If i make the local coordinate system fixed and the axes all parallel to the global fixed plane, that would mean i could just stay in the global coordinate system. The point of the transformation is to have something in a local frame of reference because the positions and directions of engines and wings are all relative to the rocket, so this coordinate system has to constantly rotate with the rocket too.

And generally, i need the local coordinate axes in forward, port and up direction to have a consistent coordinate system. Aligning them with the global axes is counter productive.

Aligning them on startup, and when the craft rotates it changes with it. The local coordinate system wouldn't be fixed, it would move. It would just have the corresponding axes parallel until the craft rotates.

Link to comment
Share on other sites

Aligning them on startup, and when the craft rotates it changes with it. The local coordinate system wouldn't be fixed, it would move. It would just have the corresponding axes parallel until the craft rotates.

That would not work. The way this system works is that engine and wing positions and orientations are in the frame of reference where port is x, up is y and forward is z. If i choose different starting axes then the starting positions of the engines and wings would be different again, and i would not have gained anything because i get the same exact problem with a slightly different coordinate system and different part coordinates. Different numbers, same problem.

Also, by now i am guessing this is just how it works, you take the port vector at the beginning and rotate it and live with the error. At least i am sure enough that tomorrow i will try that and see if it works.

Link to comment
Share on other sites

That would not work. The way this system works is that engine and wing positions and orientations are in the frame of reference where port is x, up is y and forward is z. If i choose different starting axes then the starting positions of the engines and wings would be different again, and i would not have gained anything because i get the same exact problem with a slightly different coordinate system and different part coordinates. Different numbers, same problem.

Also, by now i am guessing this is just how it works, you take the port vector at the beginning and rotate it and live with the error. At least i am sure enough that tomorrow i will try that and see if it works.

Hmm?

How would it change anything? It's defining the axes beforehand really easily. Could you elaborate?

What's the root cause of the error? Diagnosing it could save you here...

Link to comment
Share on other sites

How would it change anything? It's defining the axes beforehand really easily. Could you elaborate?

What's the root cause of the error? Diagnosing it could save you here...

Getting the axes initially is not really a problem, as i am saying you can set up the port vector in the beginning and then rotate it with the craft.

What worries me is the error that accumulates over time, because if you rotate the port vector every tick the craft rotates you do get floating point errors. For long missions talking dozens of years there will be a lot of ticks and these errors will accumulate, both changing the value for roll and making the port vector not perpendicular to the forward vector any more. Which is where i asked myself if there is not a better way. Which vector exactly you take and how exactly the axes are oriented doesn't matter, because this problem is from the rotation of the extra vector so it's always there if you take the "initialize vector and then rotate it with the craft" approach.

Link to comment
Share on other sites

Getting the axes initially is not really a problem, as i am saying you can set up the port vector in the beginning and then rotate it with the craft.

What worries me is the error that accumulates over time, because if you rotate the port vector every tick the craft rotates you do get floating point errors. For long missions talking dozens of years there will be a lot of ticks and these errors will accumulate, both changing the value for roll and making the port vector not perpendicular to the forward vector any more. Which is where i asked myself if there is not a better way. Which vector exactly you take and how exactly the axes are oriented doesn't matter, because this problem is from the rotation of the extra vector so it's always there if you take the "initialize vector and then rotate it with the craft" approach.

Do you have a Patched-Conics Approximation set up, or at least one where the exact position can be determined beforehand? If so, skip certain ticks.

And what would these errors cause?

Link to comment
Share on other sites

How do i get the second (i.e. port) vector for a complete description of the attitude? The only possibility i came up with so far is that i set it up manually once when the simulation begins, and then rotate it whenever the craft rotates.

That depends. You need local coordinate system to draw the ship's parts. Also to simulate the forces on all of the ship's parts. Clearly, a real ship can rotate. So the side/port vector will change with the ship's roll. If you want to simulate flight, you should keep track of it. And yes, errors will accumulate, but if you have stable flight, that will be consistent with typical effects of things like parasitic drag and other sources of torque on the craft.

On the other hand, if your simulation doesn't care about the ship's roll, and you wish to simulate it as if the ship was maintaining constant attitude, your best bet is to simply choose a vector that's orthogonal to heading and the radial. In other words, just take ship's position vector in global coordinate system, which is along the radial, and cross it into ship's velocity vector, which I assume you treat as your forward vector. The resulting vector will be in the port direction. You just need to normalize it. The only potential problem is if ship's velocity becomes purely radial. You might want to check for that if you think it's ever a possibility.

Link to comment
Share on other sites

Do you have a Patched-Conics Approximation set up, or at least one where the exact position can be determined beforehand? If so, skip certain ticks.

And what would these errors cause?

No, i have full n-body physics. Not yet gravity torque, but that will be implemented later too. Anyway, tick times may go up to the order of seconds for no thrust, but that will still be a lot of ticks over decades.

As for the errors, it would cause an error in the value for roll (which would be negligible), but more importantly a changing port vector would mean a different orientation too - which has implications for everything, because it is used for transformations, and you have to transform everything for thrust and lift forces, so it can have an effect on both translation and rotation of the craft, which can be fatal if the errors become big enough.

And as for the order of magnitude of the error, if you assume something like 14-15 significant digits for a double and 1s ticks and saying that an error greater than 1E-6 is significant, it would only be a matter of single digit years.

EDIT:

If you want to simulate flight, you should keep track of it. And yes, errors will accumulate(...)

On the other hand, if your simulation doesn't care about the ship's roll (...)

First part is what seems to be the consensus. There's seemingly no other way.

And not caring about roll is not an option, while it is possible in theory it would be very limiting and i definitely don't want that since it is also supposed to become a game, besides a realistic as possible simulation.

Edited by Kertherina
Link to comment
Share on other sites

First part is what seems to be the consensus. There's seemingly no other way.

And not caring about roll is not an option, while it is possible in theory it would be very limiting and i definitely don't want that since it is also supposed to become a game, besides a realistic as possible simulation.

Yup. Then you have to do full rigid body simulation, which means keeping track of the body axies.

The only additional recommendations I can give are these.

1) If your moment of inertia is a tensor, Euler's Equations are probably your best bet for updating craft's orientation.

2) Precise integration isn't quite as important for rotation, but I'd still use at least Velocity Verlet method. It's a bit of work to derive equivalent for Euler's Laws, but it's worth it. The integration method for n-body gravity needs to be more robust.

3) Error on the 3 axies will not be exactly the same, and it's absolutely critical to keep them orthogonal. It's worth enforcing this with cross products every once in a while.

Link to comment
Share on other sites

What's the advantage of n-body physics in this case, then?

does the error stem from the equations used or the code itself?

N-body physics isn't really an advantage for this, neither is it a disadvantage. A more critical question is how i want to deal with gravity torque, if i cut that off once it is weak then i could maintain the orientation vectors over long periods of time without any rotations and thus without error. Can't be any more precise because i yet have to look into that topic, and i will not do that any time soon.

The error is floating point errors. It has nothing to do with the code or the equations, it is how the computer handles floating point numbers. Maximum precision for a double is around 15 digits. Beyond that, anything can and will happen. Also, the last digit isn't even rounded, everything beyond that is just cut off. Add to that a large number of ticks (10^9 - 10^10), and the error starts to become noticeable.

I do use GNU MPFR for arbitrary precision arithmetic so i can just use a higher precision variable, but i was asking because i wasn't sure there are other / better / more elegant methods of dealing with this since i am pretty new to programming an this is my first big project (the first "bigger than calculating prime numbers" project even).

EDIT:

@K^2:

Thank you, i wasn't aware of either and will look into those links tomorrow.

As for the cross products, sounds like a great idea too. I don't care about the exact roll value anyway, much more important is the orientation of the vector and that it doesn't mess up transformations. I will definitely implement that.

And yes, i plan to improve upon the n-body gravity anyway, currently i just have Cowell's method and i plan to use Encke

Edited by Kertherina
Link to comment
Share on other sites

Maybe rounding? I know it's a basic thing, but is there a function for it? I know there's one for cutting off the last digits. That would dividing the number sufficiently and taking it's integer. However, if you use an IF statement, you could round it with integers. Adding one if the decimal behind it is 5 or greater, and just using the INT function of the divided number if the first decimal place is less than 5.

But rounding seems too simple a solution...

Even if it is used, errors would mount up. But maybe slower?

Link to comment
Share on other sites

Maybe rounding? I know it's a basic thing, but is there a function for it? I know there's one for cutting off the last digits. That would dividing the number sufficiently and taking it's integer. However, if you use an IF statement, you could round it with integers. Adding one if the decimal behind it is 5 or greater, and just using the INT function of the divided number if the first decimal place is less than 5.

No, that doesn't work because you don't have those digits to be able to round. That's the thing, the numbers are only exact up to so many digits / Bits, after which they just stop. If you had the additional digits to round, then you could just use those in the first place.

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