Skip to content

Commit

Permalink
Merge pull request #1266 from indy91/MCCLineOfSightFix
Browse files Browse the repository at this point in the history
Fix bug in MCC line-of-sight to ground station calculation
  • Loading branch information
indy91 authored Jul 15, 2024
2 parents d804ded + 2476ab0 commit 3b54522
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
20 changes: 7 additions & 13 deletions Orbitersdk/samples/ProjectApollo/src_launch/mcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,11 +950,10 @@ void MCC::TimeStep(double simdt){

void MCC::AutoUpdateXmitGroundStation(VESSEL* Ves, TrackingVesselType Type, TrackingSlot Slot)
{
double Moonrelang;
double LOSRange;
VECTOR3 GSGlobalVector = _V(0, 0, 0);
VECTOR3 GSVector = _V(0, 0, 0);
bool MoonInTheWay, Sight;
bool Sight;

// Bail out if we failed to find either major body
if (Earth == NULL) { addMessage("Can't find Earth"); GT_Enabled = false; return; }
Expand All @@ -974,7 +973,7 @@ void MCC::AutoUpdateXmitGroundStation(VESSEL* Ves, TrackingVesselType Type, Trac
sin(GroundStations[StationIndex].Position[1] * RAD) * cos(GroundStations[StationIndex].Position[0] * RAD)) * R_E;

oapiLocalToGlobal(Earth, &GSVector, &GSGlobalVector);
MoonInTheWay = false;

if (GroundStations[StationIndex].StationPurpose & GSPT_LUNAR)
{
LOSRange = 5e8;
Expand All @@ -983,16 +982,11 @@ void MCC::AutoUpdateXmitGroundStation(VESSEL* Ves, TrackingVesselType Type, Trac
{
LOSRange = 2e7;
}
//Check if there is line-of-sight between vessel and station
Sight = OrbMech::sight(Vessel_Vector[Slot], GSVector, R_E);
//Moon in the way
Moonrelang = dotp(unit(MoonGlobalPos - VesselGlobalPos[Slot]), unit(GSGlobalVector - VesselGlobalPos[Slot]));
if (Moonrelang > cos(asin(R_M / length(MoonGlobalPos - VesselGlobalPos[Slot]))))
{
MoonInTheWay = true;
}
//Check if there is line-of-sight between vessel and station and that the Moon is not in the way either
Sight = OrbMech::sight(Vessel_Vector[Slot], GSVector, R_E) && OrbMech::sight(VesselGlobalPos[Slot] - MoonGlobalPos, GSGlobalVector - MoonGlobalPos, R_M);

if (Sight && GroundStations[StationIndex].AOS[Slot] == 0 && ((GroundStations[StationIndex].USBCaps & GSSC_VOICE) || (GroundStations[StationIndex].CommCaps & GSGC_VHFAG_VOICE))) {
if (length(Vessel_Vector[Slot] - GSVector) < LOSRange && !MoonInTheWay)
if (length(Vessel_Vector[Slot] - GSVector) < LOSRange)
{
//Dont switch to a new station if we're transmitting an uplink;
bool uplinking = false;
Expand Down Expand Up @@ -1022,7 +1016,7 @@ void MCC::AutoUpdateXmitGroundStation(VESSEL* Ves, TrackingVesselType Type, Trac

}
}
if ((!Sight || length(Vessel_Vector[Slot] - GSVector) > LOSRange || MoonInTheWay) && GroundStations[StationIndex].AOS[Slot] == 1) {
if ((!Sight || length(Vessel_Vector[Slot] - GSVector) > LOSRange) && GroundStations[StationIndex].AOS[Slot] == 1) {
GroundStations[StationIndex].AOS[Slot] = 0;

if (Type == TrackingVesselType::TypeCM && GT_Enabled == true) {
Expand Down
23 changes: 18 additions & 5 deletions Orbitersdk/samples/ProjectApollo/src_rtccmfd/OrbMech.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2398,21 +2398,34 @@ void umbra(VECTOR3 R, VECTOR3 V, VECTOR3 sun, OBJHANDLE planet, bool rise, doubl

bool sight(VECTOR3 R1, VECTOR3 R2, double R_E)
{
//Returns true if position vectors R1 and R2 have a line-of-sight, considering the body radius R_E
VECTOR3 R1n, R2n;
bool los;
double tau_min;
double r12, r22, tau_min, dot_r1r2;

//Preliminary calculations
//Normalized position vectors
R1n = R1 / R_E;
R2n = R2 / R_E;

tau_min = (length(R1n)*length(R1n) - dotp(R1n, R2n)) / (length(R1n)*length(R1n) + length(R2n)*length(R2n) - 2.0*dotp(R1n,R2n));
//Squares of radius magnitudes
r12 = dotp(R1n, R1n);
r22 = dotp(R2n, R2n);
//Dot product between normalized vectors
dot_r1r2 = dotp(R1n, R2n);

//Location on line connecting R1 and R2 where the distance from the center of the body to the line is minimized
tau_min = (r12 - dot_r1r2) / (r12 + r22 - 2.0*dot_r1r2);
//Default to no line-of-sight
los = false;
if (tau_min < 0 || tau_min>1)
//Is there a line of sight?
if (tau_min < 0.0 || tau_min > 1.0)
{
//Yes, because both vectors have to be in the same quadrant
los = true;
}
else if ((1.0 - tau_min)*length(R1n)*length(R1n) + dotp(R1n, R2n)*tau_min >= 1.0)
else if ((1.0 - tau_min)*r12 + dot_r1r2 * tau_min >= 1.0)
{
//Yes, because minimum distance from center of body to line connecting R1 and R2 is greater than R_E (R1 and R2 having been normalized)
los = true;
}
return los;
Expand Down

0 comments on commit 3b54522

Please sign in to comment.