API Question Vessel Rotations

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
Still doesn't work... the trouble is, I have to rotate the heading (see the second code I posted above), and I'll probably have to rotate the three vectors differently so they add up to something meaningfull in the end... the question is just how?
Sorry, I pretty much ignored your edit because I couldn't understand what you were trying to do and concentrated on getting the first part right...

So, on to your code.
Code:
                            VECTOR3 HeadX, HeadY, HeadZ;    
                            VECTOR3 mROT;
                            MATRIX3 HeadMatrix;

                            ship->GlobalRot(_V(1,0,0), HeadX);     
                            ship->GlobalRot(_V(0,1,0), HeadY);     
                            ship->GlobalRot(_V(0,0,1), HeadZ);
At this point, HeadX, HeadY, HeadZ are vectors in the ecliptic frame that point in the direction of your vessel's principle axes.
Code:
                            double phi = data.SourceStar->EclipticRot.X *RAD;
                            double theta = data.SourceStar->EclipticRot.Y *RAD;
                            double lambda = data.SourceStar->EclipticRot.Z *RAD;    

                            double sint = sin(theta), cost = cos(theta);
                            double sinp = sin(phi), cosp = cos(phi);
                            double sinl = sin(lambda), cosl = cos(lambda);

                            MATRIX3 gal2ecl =  mul(mul(_M(cosp,0,sinp, 0,1,0, -sinp,0,cosp),
                                   _M(1,0,0, 0,cost,sint, 0,-sint,cost)),
                                   _M(cosl,0,-sinl, 0,1,0, sinl,0,cosl));
                            HeadX = tmul (gal2ecl, HeadX);        
                            HeadY = tmul (gal2ecl, HeadY);        
                            HeadZ = tmul (gal2ecl, HeadZ);
At this point your have the direction of the vessel's principle axes relative to some other reference frame. I think you want to use mul(gal2ecl, HeadX) to convert the reference frame from ecliptic to galactic instead of tmul. To clarify, if gal2ecl is a rotation matrix that defines a rotation from the galactic frame to the ecliptic frame, then mul(gal2ecl, _V(0,0,1) gives you a vector that defines the ecliptic north for your source star system relative to the galactic frame. By extension, mul(gal2ecl, someVec) will return a vector that represents someVec relative to the galactic frame.

Code:
                            phi = data.TargetStar->EclipticRot.X *RAD;
                            theta = data.TargetStar->EclipticRot.Y *RAD;
                            lambda = data.TargetStar->EclipticRot.Z *RAD;    

                            sint = sin(theta), cost = cos(theta);
                            sinp = sin(phi), cosp = cos(phi);
                            sinl = sin(lambda), cosl = cos(lambda);

                            gal2ecl =  mul(mul(_M(cosp,0,sinp, 0,1,0, -sinp,0,cosp),
                                   _M(1,0,0, 0,cost,sint, 0,-sint,cost)),
                                   _M(cosl,0,-sinl, 0,1,0, sinl,0,cosl));
                            HeadX = mul (gal2ecl, HeadX);    
                            HeadY = mul (gal2ecl, HeadY);    
                            HeadZ = mul (gal2ecl, HeadZ);
Again, I think you want to use tmul here instead of mul to convert from galactic frame to the ecliptic frame of your target star system.

Code:
                            HeadMatrix.m11 = HeadX.x;
                            HeadMatrix.m12 = HeadY.x;
                            HeadMatrix.m13 = HeadZ.x;

                            HeadMatrix.m21 = HeadX.y;
                            HeadMatrix.m22 = HeadY.y;
                            HeadMatrix.m23 = HeadZ.y;
                            
                            HeadMatrix.m31 = HeadX.z;
                            HeadMatrix.m32 = HeadY.z;
                            HeadMatrix.m33 = HeadZ.z;

                            ship->SetRotationMatrix(HeadMatrix);
SetRotationMatrix expects the rotation matrix passed to it to be relative to the ecliptic frame. Your rotation matrix is currently in the ecliptic reference frame of the target star system (where you are going?), not the ecliptic reference frame of the source star system (where you currently are?) but you have not yet moved your vessel (unless I missed something?). I know you said you think your transformations are correct because it works for velocity/position but they look wrong (but perhaps I have misunderstood what gal2ecl is?).
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,866
Reaction score
2,127
Points
203
Location
between the planets
I think you want to use mul(gal2ecl, HeadX) to convert the reference frame from ecliptic to galactic instead of tmul.

mul gal2ecl transforms a vector from galactic frame to ecliptic frame (works, since all the stars are shown in the right position when I'm in Sol). As far as I understood it, tmul should rotate it backwards (i.e. from the ecliptic frame to the galactic frame). So what I'm doing is taking the vessels orientation vector relative to the ecliptic, and rotating it around into the galactic frame. Then rotate that vector into alignement with the new ecliptic frame.

SetRotationMatrix expects the rotation matrix passed to it to be relative to the ecliptic frame.

relative to the new ecliptic frame, yes. following right after this is a termination of orbiter and a reload with the new scenario containing the new system. So, you never get to see the current orientation of the vessel anymore, I simply feed it to the vessel to get the new global orientation that I write to the scenario file.

but you have not yet moved your vessel (unless I missed something?)

No, you haven't missed anything, moving the vessel and recalculating the velocity vector (based on the same rotation matrices) is in another code block (they actually get executed before). As far as I can tell, they are alright. The velocity vector is pretty easy to check, and it's ok for sure. Checking the position is a bit more difficult, but since it uses the same rotations as the velocity vector, it should be ok. The only difference is that the position gets inverted, the switch happens pretty exactly at the center between the two systems.

So, the situation is like this: The prograde vector before the switch usually points at the targeted star. The nose of the vessel too. Then comes the switch, and afterwards the prograde velocity still points at the target star, while the nose of the vessel points somewhere else. Hence I think something with the rotation goes wrong. If the transformation would be correct, it should still point prograde. Even if the position would be wrong, and the velocity vector pointing the wrong direction, the nose should still be aligned with the prograde vector, because I'm using the exact same transformations. Except, of course, if I'm using the transformation wrong in this context, which is what I suspect is happening (since for position and velocity, I only have to rotate one vector, not three of them).
 

tblaxland

O-F Administrator
Administrator
Addon Developer
Webmaster
Joined
Jan 1, 2008
Messages
7,320
Reaction score
25
Points
113
Location
Sydney, Australia
OK, I misunderstood the definition of gal2ecl it seems - it is the inverse of what I expected, but all I had to go on was the variable name :). On that basis, your code seems OK to me. :shrug:
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,866
Reaction score
2,127
Points
203
Location
between the planets
too bad it doesn't give the results I'm expecting, then. Probably a problem with the whole rotation after all, will have to take another look at it.
 

jedidia

shoemaker without legs
Addon Developer
Joined
Mar 19, 2008
Messages
10,866
Reaction score
2,127
Points
203
Location
between the planets
Okay, here's another try to fix my Problem. I restructured the code a bit to show exactly what I'm doing.

Problem: The vessel switches systems at a certain distance. Velocity vector, position and orientation are suposed to be rotated first to galactic frame, and then to the ecliptic frame of the target system, so the ship aproaches the system from the right direction. While I can't really chack the position, it seems to work ok. At least the velocity vector is pointing at the star, which means that velocity and probably position where rotated right, else the velocity vector would be off. The rotation however, is not pointing along the prograde vector anymore, where it pointed before the switch. So something goes wrong. Here's the code (or what's important of it for this problem):

Code:
//building rotation matrices for alignement with target system
    double phi = data.SourceStar->EclipticRot.X *RAD;
    double theta = data.SourceStar->EclipticRot.Y *RAD;
    double lambda = data.SourceStar->EclipticRot.Z *RAD;    

    double sint = sin(theta), cost = cos(theta);
    double sinp = sin(phi), cosp = cos(phi);
    double sinl = sin(lambda), cosl = cos(lambda);

    MATRIX3 gal2ecl =  mul(mul(_M(cosp,0,sinp, 0,1,0, -sinp,0,cosp),
                               _M(1,0,0, 0,cost,sint, 0,-sint,cost)),
                               _M(cosl,0,-sinl, 0,1,0, sinl,0,cosl));

    phi = data.TargetStar->EclipticRot.X *RAD;
    theta = data.TargetStar->EclipticRot.Y *RAD;
    lambda = data.TargetStar->EclipticRot.Z *RAD;    

    sint = sin(theta), cost = cos(theta);
    sinp = sin(phi), cosp = cos(phi);
    sinl = sin(lambda), cosl = cos(lambda);

    MATRIX3 gal2Target =  mul(mul(_M(cosp,0,sinp, 0,1,0, -sinp,0,cosp),
                           _M(1,0,0, 0,cost,sint, 0,-sint,cost)),
                          _M(cosl,0,-sinl, 0,1,0, sinl,0,cosl));
.
.
.
.
.  
                        else if (!_strnicmp (line, "RPOS", 4)) //rotating the position and writing to scenario file
                        {
                            VECTOR3 mRPOS;
                            ship->GetRelativePos(h_star, mRPOS);
 
                                VECTOR3 EcTarPos = _V(data.TargetStar->EclipticPos.X,
                                                        data.TargetStar->EclipticPos.Y,
                                                        data.TargetStar->EclipticPos.Z);
                                mRPOS = EcTarPos - mRPOS;
 
                            mRPOS = tmul (gal2ecl, mRPOS);        
                            mRPOS = mul (gal2Target, mRPOS);        

                            oapiWriteScenario_vec( ScenarioOut, "RPOS", mRPOS); 
                        }


                      else if (!_strnicmp (line, "RVEL", 4)) //rotating the velocity and writing to scenario file
                        {
                            VECTOR3 mRVEL;
                            ship->GetRelativeVel(h_star, mRVEL);

                            mRVEL = tmul (gal2ecl, mRVEL);        
                            mRVEL = mul (gal2Target, mRVEL);        

                            oapiWriteScenario_vec( ScenarioOut, "RVEL", mRVEL); 
                        }
                        else if (!_strnicmp (line, "AROT", 4)) //finally, the same for rotation
                        {
                            VECTOR3 HeadX, HeadY, HeadZ;    
                            VECTOR3 mROT;
                            MATRIX3 HeadMatrix;

                            ship->GlobalRot(_V(1,0,0), HeadX);     
                            ship->GlobalRot(_V(0,1,0), HeadY);     
                            ship->GlobalRot(_V(0,0,1), HeadZ);     

                            HeadX = tmul (gal2ecl, HeadX);        
                            HeadY = tmul (gal2ecl, HeadY);        
                            HeadZ = tmul (gal2ecl, HeadZ);        

                            HeadX = mul (gal2Target, HeadX);    
                            HeadY = mul (gal2Target, HeadY);    
                            HeadZ = mul (gal2Target, HeadZ);    

                            HeadMatrix.m11 = HeadX.x;
                            HeadMatrix.m21 = HeadY.y;
                            HeadMatrix.m31 = HeadZ.z;

                            HeadMatrix.m12 = HeadX.x;
                            HeadMatrix.m22 = HeadY.y;
                            HeadMatrix.m32 = HeadZ.z;
                            
                            HeadMatrix.m13 = HeadX.x;
                            HeadMatrix.m23 = HeadY.y;
                            HeadMatrix.m33 = HeadZ.z;

                            ship->SetRotationMatrix(HeadMatrix); //after a rotation matrix for the complete rotation was created, aplying it to the ship for getting the new vector back
                            ship->GetGlobalOrientation(mROT);

                            oapiWriteScenario_vec( ScenarioOut, "AROT", mROT); 
                        }
 
Top