//RCS thruster direct control algorithm
void RcsManager::RCS_CTRL(double simdt) {
int ThCount = hParent->GetThrusterCount();
VECTOR3 Position;
VECTOR3 Direction;
std::vector<VECTOR3> Potential_Acc, Potential_Tor;
std::vector<double> Thruster_Level;
VECTOR3 NetAccelerationSum = -RCS_Thruster_Target_Acceleration;
VECTOR3 NetTorqueSum = -RCS_Thruster_Target_Torque;
for (int i = 0 ; i < ThCount ; i++) {
//Variable Declarations
double MaxTh;
double Level;
//Initialize Values:
hParent->GetThrusterRef(hParent->GetThrusterHandleByIndex(i), Position);
hParent->GetThrusterDir(hParent->GetThrusterHandleByIndex(i), Direction);
MaxTh = hParent->GetThrusterMax(hParent->GetThrusterHandleByIndex(i));
Level = hParent->GetThrusterLevel(hParent->GetThrusterHandleByIndex(i));
//Calculating Vectors and Constants
Potential_Acc.push_back(Direction*MaxTh);
Potential_Tor.push_back(crossp(Position, Potential_Acc[i]));
Thruster_Level.push_back(Level);
//Calculating Summations
NetAccelerationSum += Potential_Acc[i]*Level;
NetTorqueSum += Potential_Tor[i]*Level;
}
//Variable[Index][Thruster Parameter]
std::vector<MotionConstants> A, B;
//Generate (ax-b)^2 Terms (a,b);
for (int i = 0 ; i < ThCount ; i++) {
VECTOR3 SubASum = NetAccelerationSum - Potential_Acc[i]*Thruster_Level[i];
VECTOR3 SubTSum = NetTorqueSum - Potential_Tor[i]*Thruster_Level[i];
MotionConstants TempA, TempB;
TempA.X_LIN = Potential_Acc[i].x;
TempA.Y_LIN = Potential_Acc[i].y;
TempA.Z_LIN = Potential_Acc[i].z;
TempA.X_ROT = Potential_Tor[i].x;
TempA.Y_ROT = Potential_Tor[i].y;
TempA.Z_ROT = Potential_Tor[i].z;
TempB.X_LIN = SubASum.x;
TempB.Y_LIN = SubASum.y;
TempB.Z_LIN = SubASum.z;
TempB.X_ROT = SubTSum.x;
TempB.Y_ROT = SubTSum.y;
TempB.Z_ROT = SubTSum.z;
A.push_back(TempA);
B.push_back(TempB);
}
std::vector<double> Target;
//y = (ax-b)^2 = (ax)^2-2abx+b^2 = aaxx-2abx+bb
//y'= 2aax-2ab, at y' = 0:
//x = 2ab/2aa = ab/aa
//Calculate Derivatives and Targets;
for (int i = 0 ; i < ThCount ; i++) {
double numer = 0;
double denom = 0;
numer += A[i].X_LIN*B[i].X_LIN + A[i].Y_LIN*B[i].Y_LIN + A[i].Z_LIN*B[i].Z_LIN;
denom += A[i].X_LIN*A[i].X_LIN + A[i].Y_LIN*A[i].Y_LIN + A[i].Z_LIN*A[i].Z_LIN;
numer += A[i].X_ROT*B[i].X_ROT + A[i].Y_ROT*B[i].Y_ROT + A[i].Z_ROT*B[i].Z_ROT;
denom += A[i].X_ROT*A[i].X_ROT + A[i].Y_ROT*A[i].Y_ROT + A[i].Z_ROT*A[i].Z_ROT;
Target.push_back(min(max(numer/denom, 0.0), MaxLevel));
}
for (int i = 0 ; i < ThCount ; i++) {
double deltaT = abs(Target[i] - hParent->GetThrusterLevel(hParent->GetThrusterHandleByIndex(i)));
if (deltaT > 0.01) {
hParent->SetThrusterLevel(hParent->GetThrusterHandleByIndex(i), Target[i]);
}
}
}