- Joined
- Jan 13, 2008
- Messages
- 2,302
- Reaction score
- 6
- Points
- 38
- Location
- Atlanta, GA, USA, North America
As some of you (mostly IRC loafers ) may know I've been working on a way to implement 3-axis engine gimbaling for a dual-engine vessel. I have succeeded. With the following code, it is possible to change the exhaust vector in response to combined pitch, roll, and yaw commands. The only weakness is that it relies on the status of pre-defined thrusters so (so far) pitch, roll, yaw thruster groups have to be defined and active.
To use the code, it should either be placed directly in clbkPreStep, or its own method which is called at clbkPreStep.
A couple of things about this code. First, a HUGE MASSIVE THANKS to Mindblast for supplying the math to rotate a vector, this would not have been possible without that key piece of info!
Second, there is no "time delay" such that the vessel designates an orientation for the engines to go to then over the next few timesteps, the dir vector gradually approaches the commanded orientation. I tried using code similar to an animation, but am still working on it. Right now, the engines just "snap" to the final orientation when you apply attitude thrust.
Third, the cascaded if statements for finding the individual pitch conditions relative to the roll condition looks messy to me and I've been trying to somehow combine the equations so a single line can direct an engine either up or down. The problem is that the engines will be doing two different things depending on whether they're pitched up or down so where I can add the roll angle to bring an engine up, I have to subtract the roll angle to bring the engine down.
Fourth, the gimbaling doesn't like the built-in autopilots as much as I was hoping. It works well enough and kept a docked stack more stable than on thrusters alone (this code infact is from my SSM), but when the ship was free, it constantly alternated between yaw left and yaw right thrusters and the resultant gimbaling when holding prograde. This could be due to the vessel mass, Inertia Tensors etc. or because of a delay between the thrusters firing and the gimbaling activating leading to an unstable solution.
I'm posting this not only to allow other people to enable 3-axis gimbaling on their ships, but to see what improvements might can be made over this current solution.
Code:
if(GetThrusterGroupLevel(THGROUP_MAIN) != 0) //prevents method from running unless main engines are firing.
{
pitch1 = GetThrusterGroupLevel(THGROUP_ATT_PITCHUP);
pitch2 = GetThrusterGroupLevel(THGROUP_ATT_PITCHDOWN);
yaw1 = GetThrusterGroupLevel(THGROUP_ATT_YAWLEFT);
yaw2 = GetThrusterGroupLevel(THGROUP_ATT_YAWRIGHT);
rollL = GetThrusterGroupLevel(THGROUP_ATT_BANKLEFT);
rollR = GetThrusterGroupLevel(THGROUP_ATT_BANKRIGHT);
//Gets the level of each thruster group and assigns the values to variables
pitch = pitch2*(-1) + pitch1;
lpitchangle = pitch*(PI/12); //PI/12 is the angle of deflection (15 degrees)
rpitchangle = lpitchangle;
//"normalizes" two groups into a single value on [-1,1] and sets the
//angle the engines should be at for pitch. Notice, I use two variables
//lpitchangle and rpitchangle so the engines can be manipulated later separately.
yaw = yaw2*(-1)+yaw1;
lyawangle = yaw*(PI/12);
ryawangle = lyawangle;
//"normalizes" two groups into a single value on [-1,1] and sets the
//angle the engines should be at for yaw. Notice, I use two variables
//lyawangle and ryawangle so the engines can be manipulated later separately.
rollA = rollR+((-1)*rollL);
//"normalizes" the two roll groups into a single value on [-1,1].
//No angle is directly derived for this because the roll condition
//affects the pitch condition of each engine separately.
//The following cascading if statements are for calculating pitch
//angle when roll is combined with pitch
if(rollA != 0)
{
if(pitch > 0) //pitching up
{
if(rollA > 0) //roll right
{
lpitchangle -= (rollA*lpitchangle);
//drop left engine; if the engines are pointed upwards,
//the left engine drops down to allow roll right, pitch up.
}
if(rollA < 0) //roll left
{
rpitchangle += (rollA*rpitchangle);
//drop right engine;
}
}
else if(pitch < 0)
{
if(rollA > 0) //roll right
{
rpitchangle -= (rollA*rpitchangle);
//raise right engine;
}
if(rollA < 0) //roll left
{
lpitchangle += (rollA*lpitchangle);
//raise left engine;
}
}
else //if there is no pitch, set the engines to diverge as much as possible.
{
lpitchangle = -rollA*(PI/12);
rpitchangle = rollA*(PI/12);
}
}
if( ryawangle != 0 || rpitchangle != 0 || rollA !=0) //only changes engine direction if there is any attitude input
{
SetThrusterDir(th_main[0],_V(sin(lyawangle)*cos(lpitchangle),-sin(lpitchangle),cos(lyawangle)*cos(lpitchangle)));//left
SetThrusterDir(th_main[1],_V(sin(ryawangle)*cos(rpitchangle),-sin(rpitchangle),cos(ryawangle)*cos(rpitchangle)));//right
}//Vector multiplied by rotation matrix supplied by Mindblast
else
{
SetThrusterDir(th_main[0],_V(0,0,1));
SetThrusterDir(th_main[1],_V(0,0,1));
}
//if there is no attitude input, will set engines to standard
//configuration. Neccessary incase there was attitude input in last timestep.
}
A couple of things about this code. First, a HUGE MASSIVE THANKS to Mindblast for supplying the math to rotate a vector, this would not have been possible without that key piece of info!
Second, there is no "time delay" such that the vessel designates an orientation for the engines to go to then over the next few timesteps, the dir vector gradually approaches the commanded orientation. I tried using code similar to an animation, but am still working on it. Right now, the engines just "snap" to the final orientation when you apply attitude thrust.
Third, the cascaded if statements for finding the individual pitch conditions relative to the roll condition looks messy to me and I've been trying to somehow combine the equations so a single line can direct an engine either up or down. The problem is that the engines will be doing two different things depending on whether they're pitched up or down so where I can add the roll angle to bring an engine up, I have to subtract the roll angle to bring the engine down.
Fourth, the gimbaling doesn't like the built-in autopilots as much as I was hoping. It works well enough and kept a docked stack more stable than on thrusters alone (this code infact is from my SSM), but when the ship was free, it constantly alternated between yaw left and yaw right thrusters and the resultant gimbaling when holding prograde. This could be due to the vessel mass, Inertia Tensors etc. or because of a delay between the thrusters firing and the gimbaling activating leading to an unstable solution.
I'm posting this not only to allow other people to enable 3-axis gimbaling on their ships, but to see what improvements might can be made over this current solution.