//------------------------------------------------------------------------------ void AveragedDoppler::InitializeMeasurement() { PhysicalMeasurement::InitializeMeasurement(); // Load the current delay data from the hardware SetHardwareDelays(false); // Set the coordinate systems for the uplink and downlink events uplinkLegS.AddCoordinateSystem(j2k); // Base CS for the event downlinkLegS.AddCoordinateSystem(j2k); // Base CS for the event uplinkLegE.AddCoordinateSystem(j2k); // Base CS for the event downlinkLegE.AddCoordinateSystem(j2k); // Base CS for the event // Because of the participant ordering, F1 is the fixed CS Integer index = uplinkLegS.GetParticipantIndex(participants[0]); uplinkLegS.AddCoordinateSystem(F1, index); // Participant 1 CS for the event index = downlinkLegS.GetParticipantIndex(participants[0]); downlinkLegS.AddCoordinateSystem(F1, index);// Participant 2 CS for the event index = uplinkLegE.GetParticipantIndex(participants[0]); uplinkLegE.AddCoordinateSystem(F1, index); // Participant 1 CS for the event index = downlinkLegE.GetParticipantIndex(participants[0]); downlinkLegE.AddCoordinateSystem(F1, index);// Participant 2 CS for the event index = uplinkLegS.GetParticipantIndex(participants[1]); uplinkLegS.AddCoordinateSystem(F2, index); // Participant 1 CS for the event index = downlinkLegS.GetParticipantIndex(participants[1]); downlinkLegS.AddCoordinateSystem(F2, index);// Participant 2 CS for the event index = uplinkLegE.GetParticipantIndex(participants[1]); uplinkLegE.AddCoordinateSystem(F2, index); // Participant 1 CS for the event index = downlinkLegE.GetParticipantIndex(participants[1]); downlinkLegE.AddCoordinateSystem(F2, index);// Participant 2 CS for the event SetupTimeIntervals(); }
//------------------------------------------------------------------------------ bool AveragedDoppler::Initialize() { bool retval = false; if (PhysicalMeasurement::Initialize()) { if (participants.size() < 2) MessageInterface::ShowMessage("Averaged Doppler calculations require " "2 participants; cannot initialize\n"); else { // For now, require specific order for the participants // todo: Allow arbitrary participant ordering if ((participants[0]->IsOfType(Gmat::SPACE_POINT)) && (participants[1]->IsOfType(Gmat::SPACECRAFT))) { satEpochID = participants[1]->GetParameterID("A1Epoch"); // Reserve space and set IDs for each participant currentMeasurement.participantIDs.assign(participants.size(), ""); for (UnsignedInt i = 0; i < participants.size(); ++i) { currentMeasurement.participantIDs[i] = participants[i]->GetStringParameter("Id"); } SetHardwareDelays(false); retval = true; } else { MessageInterface::ShowMessage("Participant mismatch in averaged " "Doppler measurement: Current code requires one Spacecraft " "and one other SpacePoint participant; cannot initialize\n"); } } } return retval; }
//------------------------------------------------------------------------------ bool TDRSSTwoWayRange::Initialize() { #ifdef DEBUG_RANGE_CALC MessageInterface::ShowMessage("Entered RangeMeasurement::Initialize(); " "this = %p\n", this); #endif bool retval = false; if (TwoWayRange::Initialize()) { if (participants.size() < 3) MessageInterface::ShowMessage("TDRSS Range vector calculations " "require 3 participants; cannot initialize\n"); else { // For now, require specific order for the participants // todo: Allow arbitrary participant ordering if ((participants[0]->IsOfType(Gmat::SPACE_POINT)) && (participants[1]->IsOfType(Gmat::SPACECRAFT)) && (participants[2]->IsOfType(Gmat::SPACECRAFT))) { satEpochID = participants[1]->GetParameterID("A1Epoch"); for (UnsignedInt i = 0; i < participants.size(); ++i) currentMeasurement.participantIDs[i] = participants[i]->GetStringParameter("Id"); // Update the delay parameters SetHardwareDelays(false); // Groundstation -> TDRS uplinkLeg.AddParticipant(participants[0]); uplinkLeg.AddParticipant(participants[1]); uplinkLeg.FixState(participants[1], false); // TDRS -> target forwardlinkLeg.AddParticipant(participants[1]); forwardlinkLeg.AddParticipant(participants[2]); forwardlinkLeg.FixState(participants[2], false); forwardlinkLeg.SetFixedTimestep(-tdrssUplinkDelay); // target -> TDRS backlinkLeg.AddParticipant(participants[2]); backlinkLeg.AddParticipant(participants[1]); backlinkLeg.FixState(participants[1], false); backlinkLeg.SetFixedTimestep(-targetDelay); // TDRS -> Groundstation downlinkLeg.AddParticipant(participants[1]); downlinkLeg.AddParticipant(participants[0]); downlinkLeg.FixState(participants[0], false); downlinkLeg.SetFixedTimestep(-tdrssDownlinkDelay); retval = true; } else { MessageInterface::ShowMessage("Participant mismatch in TDRSS Range " "measurement: Current code requires two Spacecraft and one " "other SpacePoint participant; cannot initialize\n"); } } } #ifdef DEBUG_RANGE_CALC MessageInterface::ShowMessage(" Initialization %s with %d " "participants\n", (retval ? "succeeded" : "failed"), participants.size()); #endif return retval; }
//------------------------------------------------------------------------------ bool DSNTwoWayRange::Evaluate(bool withEvents) { bool retval = false; if (!initialized) InitializeMeasurement(); #ifdef DEBUG_RANGE_CALC MessageInterface::ShowMessage("Entered DSNTwoWayRange::Evaluate(%s)\n", (withEvents ? "true" : "false")); MessageInterface::ShowMessage(" ParticipantCount: %d\n", participants.size()); #endif if (withEvents == false) { #ifdef DEBUG_RANGE_CALC MessageInterface::ShowMessage("DSN 2-Way Range Calculation without " "events\n"); #endif #ifdef VIEW_PARTICIPANT_STATES DumpParticipantStates("++++++++++++++++++++++++++++++++++++++++++++\n" "Evaluating DSN 2-Way Range without events"); #endif CalculateRangeVectorInertial(); Rvector3 outState; // Set feasibility off of topocentric horizon, set by the Z value in topo // coords std::string updateAll = "All"; UpdateRotationMatrix(currentMeasurement.epoch, updateAll); outState = R_o_j2k * rangeVecInertial; currentMeasurement.feasibilityValue = outState[2]; #ifdef CHECK_PARTICIPANT_LOCATIONS MessageInterface::ShowMessage("Evaluating without events\n"); MessageInterface::ShowMessage("Calculating DSN 2-Way Range at epoch " "%.12lf\n", currentMeasurement.epoch); MessageInterface::ShowMessage(" J2K Location of %s, id = '%s': %s", participants[0]->GetName().c_str(), currentMeasurement.participantIDs[0].c_str(), p1Loc.ToString().c_str()); MessageInterface::ShowMessage(" J2K Location of %s, id = '%s': %s", participants[1]->GetName().c_str(), currentMeasurement.participantIDs[1].c_str(), p2Loc.ToString().c_str()); Rvector3 bfLoc = R_o_j2k * p1Loc; MessageInterface::ShowMessage(" BodyFixed Location of %s: %s", participants[0]->GetName().c_str(), bfLoc.ToString().c_str()); bfLoc = R_o_j2k * p2Loc; MessageInterface::ShowMessage(" BodyFixed Location of %s: %s\n", participants[1]->GetName().c_str(), bfLoc.ToString().c_str()); #endif if (currentMeasurement.feasibilityValue > 0.0) { currentMeasurement.isFeasible = true; currentMeasurement.value[0] = rangeVecInertial.GetMagnitude(); currentMeasurement.eventCount = 2; SetHardwareDelays(false); retval = true; } else { currentMeasurement.isFeasible = false; currentMeasurement.value[0] = 0.0; currentMeasurement.eventCount = 0; } #ifdef DEBUG_RANGE_CALC MessageInterface::ShowMessage("Calculating Range at epoch %.12lf\n", currentMeasurement.epoch); MessageInterface::ShowMessage(" Location of %s, id = '%s': %s", participants[0]->GetName().c_str(), currentMeasurement.participantIDs[0].c_str(), p1Loc.ToString().c_str()); MessageInterface::ShowMessage(" Location of %s, id = '%s': %s", participants[1]->GetName().c_str(), currentMeasurement.participantIDs[1].c_str(), p2Loc.ToString().c_str()); MessageInterface::ShowMessage(" Range Vector: %s\n", rangeVecInertial.ToString().c_str()); MessageInterface::ShowMessage(" R(Groundstation) dot RangeVec = %lf\n", currentMeasurement.feasibilityValue); MessageInterface::ShowMessage(" Feasibility: %s\n", (currentMeasurement.isFeasible ? "true" : "false")); MessageInterface::ShowMessage(" Range is %.12lf\n", currentMeasurement.value[0]); MessageInterface::ShowMessage(" EventCount is %d\n", currentMeasurement.eventCount); #endif #ifdef SHOW_RANGE_CALC MessageInterface::ShowMessage("Range at epoch %.12lf is ", currentMeasurement.epoch); if (currentMeasurement.isFeasible) MessageInterface::ShowMessage("feasible, value = %.12lf\n", currentMeasurement.value[0]); else MessageInterface::ShowMessage("not feasible\n"); #endif } else { // Calculate the corrected range measurement #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("\n\n DSN 2-Way Range Calculation:\n"); #endif #ifdef VIEW_PARTICIPANT_STATES_WITH_EVENTS DumpParticipantStates("********************************************\n" "Evaluating DSN 2-Way Range with located events"); #endif // 1. Get the range from the down link Rvector3 r1, r2; Real t1, t2; r1 = downlinkLeg.GetPosition(participants[0]); r2 = downlinkLeg.GetPosition(participants[1]); t1 = downlinkLeg.GetEventData((GmatBase*) participants[0]).epoch; t2 = downlinkLeg.GetEventData((GmatBase*) participants[1]).epoch; Rmatrix33 mt = downlinkLeg.GetEventData((GmatBase*) participants[0]).rInertial2obj.Transpose(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("1. Get downlink leg range:\n"); MessageInterface::ShowMessage(" Ground station position in FK5: r1 = (%f, %f, %f)km at epoch = %18.12lf\n", r1.Get(0), r1.Get(1), r1.Get(2), t1); MessageInterface::ShowMessage(" Spacecraft position in FK5 : r2 = (%f, %f, %f)km at epoch = %18.12lf\n", r2.Get(0), r2.Get(1), r2.Get(2), t2); MessageInterface::ShowMessage(" Transformation matrix from Earth fixed coordinate system to FK5 coordinate system at epoch = %18.12lf:\n", t1); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt(0,0), mt(0,1), mt(0,2)); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt(1,0), mt(1,1), mt(1,2)); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt(2,0), mt(2,1), mt(2,2)); #endif Rvector3 downlinkVector = r2 - r1; // rVector = r2 - r1; downlinkRange = downlinkVector.GetMagnitude(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Downlink Range = r2-r1: %.12lf km\n", downlinkRange); #endif // 2. Calculate down link range rate: Rvector3 p1V = downlinkLeg.GetVelocity(participants[0]); Rvector3 p2V = downlinkLeg.GetVelocity(participants[1]); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("2. Get downlink leg range rate:\n"); MessageInterface::ShowMessage(" Ground station velocity in FK5: p1V = (%f, %f, %f)km/s\n", p1V.Get(0), p1V.Get(1), p1V.Get(2)); MessageInterface::ShowMessage(" Spacecraft velocity in FK5 : p2V = (%f, %f, %f)km/s\n", p2V.Get(0), p2V.Get(1), p2V.Get(2)); #endif // @todo Relative origin velocities need to be subtracted when the origins // differ; check and fix that part using r12_j2k_vel here. It's not yet // incorporated because we need to handle the different epochs for the // bodies, and we ought to do this part in barycentric coordinates Rvector downRRateVec = p2V - p1V /* - r12_j2k_vel*/; Rvector3 rangeUnit = downlinkVector.GetUnitVector(); downlinkRangeRate = downRRateVec * rangeUnit; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Downlink Range Rate: %.12lf km/s\n", downlinkRangeRate); #endif // 3. Get the range from the uplink Rvector3 r3, r4; Real t3, t4; r3 = uplinkLeg.GetPosition(participants[0]); r4 = uplinkLeg.GetPosition(participants[1]); t3 = uplinkLeg.GetEventData((GmatBase*) participants[0]).epoch; t4 = uplinkLeg.GetEventData((GmatBase*) participants[1]).epoch; Rmatrix33 mt1 = uplinkLeg.GetEventData((GmatBase*) participants[0]).rInertial2obj.Transpose(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("3. Get uplink leg range:\n"); MessageInterface::ShowMessage(" Spacecraft position in FK5 : r4 = (%f, %f, %f)km at epoch = %18.12lf\n", r4.Get(0), r4.Get(1), r4.Get(2), t4); MessageInterface::ShowMessage(" Ground station position in FK5: r3 = (%f, %f, %f)km at epoch = %18.12lf\n", r3.Get(0), r3.Get(1), r3.Get(2), t3); MessageInterface::ShowMessage(" Transformation matrix from Earth fixed coordinate system to FK5 coordinate system at epoch = %18.12lf:\n", t3); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt1(0,0), mt1(0,1), mt1(0,2)); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt1(1,0), mt1(1,1), mt1(1,2)); MessageInterface::ShowMessage(" %18.12lf %18.12lf %18.12lf\n", mt1(2,0), mt1(2,1), mt1(2,2)); #endif Rvector3 uplinkVector = r4 - r3; uplinkRange = uplinkVector.GetMagnitude(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Uplink Range = r4-r3: %.12lf km\n", uplinkRange); #endif // 4. Calculate up link range rate Rvector3 p3V = uplinkLeg.GetVelocity(participants[0]); Rvector3 p4V = uplinkLeg.GetVelocity(participants[1]); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("4. Get uplink leg range rate:\n"); MessageInterface::ShowMessage(" Ground station velocity in FK5: p3V = (%f, %f, %f)km/s\n", p3V.Get(0), p3V.Get(1), p3V.Get(2)); MessageInterface::ShowMessage(" Spacecraft velocity in FK5 : p4V = (%f, %f, %f)km/s\n", p4V.Get(0), p4V.Get(1), p4V.Get(2)); #endif // @todo Relative origin velocities need to be subtracted when the origins // differ; check and fix that part using r12_j2k_vel here. It's not yet // incorporated because we need to handle the different epochs for the // bodies, and we ought to do this part in barycentric coordinates Rvector upRRateVec = p4V - p3V /* - r12_j2k_vel*/ ; rangeUnit = uplinkVector.GetUnitVector(); uplinkRangeRate = upRRateVec * rangeUnit; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Uplink Range Rate: %.12lf km/s\n", uplinkRangeRate); #endif // 4.1. Target range rate: Do we need this as well? targetRangeRate = (downlinkRangeRate + uplinkRangeRate) / 2.0; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Target Range Rate: %.12lf km/s\n", targetRangeRate); #endif // 5. Get sensors used in DSN 2-ways range if (participantHardware.empty()|| ((!participantHardware.empty())&& participantHardware[0].empty()&& participantHardware[1].empty() ) ) { // DO NOT LEAVE THIS RAW IN A SOURCE FILE!!! // MessageInterface::ShowMessage(" Ideal measurement (no hardware delay and no media correction involve):\n"); // Calculate uplink time and down link time: (Is it needed???) uplinkTime = uplinkRange*GmatMathConstants::KM_TO_M / GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM; downlinkTime = downlinkRange*GmatMathConstants::KM_TO_M / GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Ideal measurement (no hardware delay and no media correction involve):\n"); MessageInterface::ShowMessage(" Uplink time = %.12lf s\n",uplinkTime); MessageInterface::ShowMessage(" Downlink time = %.12lf s\n",downlinkTime); #endif // Calculate real range Real freqFactor = GetFrequencyFactor(frequency); // Notice that: unit of "frequency" varaibel is Hz (not MHz) Real realTravelTime = uplinkTime + downlinkTime + receiveDelay + transmitDelay + targetDelay; // unit: second Real realRangeKm = 0.5 *realTravelTime * GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM/1000.0; // unit: km Real realRange = realTravelTime * freqFactor; // unit: no unit #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Frequency = %.12lf MHz (This value is set to the default value in PhysicalMeasurement class due to no hardware used.)\n", frequency/1.0e6); MessageInterface::ShowMessage(" Frequency factor = %.12lf MHz\n", freqFactor/1.0e6); MessageInterface::ShowMessage(" Range in km = %.12lf km\n", realRangeKm); MessageInterface::ShowMessage(" uplinkRange = %lfkm downlinkRange = %lfkm\n", uplinkRange, downlinkRange); MessageInterface::ShowMessage(" receiveDelay = %lfm transmitDelay = %lfm targetDelay = %lfm\n", receiveDelay*GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM, transmitDelay*GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM, targetDelay*GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM); MessageInterface::ShowMessage(" Range = %.12lf (It has no unit)\n", realRange); #endif // Set value for currentMeasurement currentMeasurement.value[0] = realRange; currentMeasurement.isFeasible = true; return true; } ObjectArray objList1; ObjectArray objList2; ObjectArray objList3; // objList1 := all transmitters in participantHardware list // objList2 := all receivers in participantHardware list // objList3 := all transponders in participantHardware list for(std::vector<Hardware*>::iterator hw = this->participantHardware[0].begin(); hw != this->participantHardware[0].end(); ++hw) { if ((*hw) != NULL) { if ((*hw)->GetTypeName() == "Transmitter") objList1.push_back(*hw); if ((*hw)->GetTypeName() == "Receiver") objList2.push_back(*hw); } else MessageInterface::ShowMessage(" sensor = NULL\n"); } for(std::vector<Hardware*>::iterator hw = this->participantHardware[1].begin(); hw != this->participantHardware[1].end(); ++hw) { if ((*hw) != NULL) { if ((*hw)->GetTypeName() == "Transponder") objList3.push_back(*hw); } else MessageInterface::ShowMessage(" sensor = NULL\n"); } if (objList1.size() != 1) { MessageInterface::ShowMessage("The first participant does not have only 1 transmitter to send signal.\n"); throw new MeasurementException("The first participant does not have only 1 transmitter to send signal.\n"); } if (objList2.size() != 1) { MessageInterface::ShowMessage("The first participant does not have only 1 receiver to receive signal.\n"); throw new MeasurementException("The first participant does not have only 1 receiver to receive signal.\n"); } if (objList3.size() != 1) { MessageInterface::ShowMessage("The second participant does not have only 1 transponder to transpond signal.\n"); throw new MeasurementException("The second participant does not have only 1 transponder to transpond signal.\n"); } Transmitter* gsTransmitter = (Transmitter*)objList1[0]; Receiver* gsReceiver = (Receiver*)objList2[0]; Transponder* scTransponder = (Transponder*)objList3[0]; if (gsTransmitter == NULL) { MessageInterface::ShowMessage("Transmitter is NULL object.\n"); throw new GmatBaseException("Transmitter is NULL object.\n"); } if (gsReceiver == NULL) { MessageInterface::ShowMessage("Receiver is NULL object.\n"); throw new GmatBaseException("Receiver is NULL object.\n"); } if (scTransponder == NULL) { MessageInterface::ShowMessage("Transponder is NULL object.\n"); throw new GmatBaseException("Transponder is NULL object.\n"); } #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("5. Sensors, delays, and signals:\n"); MessageInterface::ShowMessage(" List of sensors: %s, %s, %s\n", gsTransmitter->GetName().c_str(), gsReceiver->GetName().c_str(), scTransponder->GetName().c_str()); #endif // 6. Get transmitter, receiver, and transponder delays: transmitDelay = gsTransmitter->GetDelay(); receiveDelay = gsReceiver->GetDelay(); targetDelay = scTransponder->GetDelay(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Transmitter delay = %le s\n", gsTransmitter->GetDelay()); MessageInterface::ShowMessage(" Receiver delay = %le s\n", gsReceiver->GetDelay()); MessageInterface::ShowMessage(" Transponder delay = %le s\n", scTransponder->GetDelay()); #endif // 7. Get frequency from transmitter of ground station (participants[0]) Signal* uplinkSignal = gsTransmitter->GetSignal(); Real uplinkFreq = uplinkSignal->GetValue(); // 8. Calculate media correction for uplink leg: #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("6. Media correction for uplink leg\n"); MessageInterface::ShowMessage(" UpLink signal frequency = %.12lf MHz\n", uplinkFreq); #endif Real roundTripTime = ((uplinkRange + downlinkRange)*GmatMathConstants::KM_TO_M/GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM)/GmatTimeConstants::SECS_PER_DAY; RealArray uplinkCorrection = CalculateMediaCorrection(uplinkFreq, r1, r2, currentMeasurement.epoch - roundTripTime); Real uplinkRangeCorrection = uplinkCorrection[0]/GmatMathConstants::KM_TO_M; Real uplinkRealRange = uplinkRange + uplinkRangeCorrection; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Uplink range correction = %.12lf km\n",uplinkRangeCorrection); MessageInterface::ShowMessage(" Uplink real range = %.12lf km\n",uplinkRealRange); #endif // 9. Doppler shift the frequency from the transmitter using uplinkRangeRate: Real uplinkDSFreq = (1 - uplinkRangeRate*GmatMathConstants::KM_TO_M/GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM)*uplinkFreq; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("7. Transponder input and output frequencies\n"); MessageInterface::ShowMessage(" Uplink Doppler shift frequency = %.12lf MHz\n", uplinkDSFreq); #endif // 10.Set frequency for the input signal of transponder Signal* inputSignal = scTransponder->GetSignal(0); inputSignal->SetValue(uplinkDSFreq); scTransponder->SetSignal(inputSignal, 0); // 11. Check the transponder feasibility to receive the input signal: if (scTransponder->IsFeasible(0) == false) { currentMeasurement.isFeasible = false; currentMeasurement.value[0] = 0; MessageInterface::ShowMessage("The transponder is unfeasible to receive uplink signal.\n"); throw new GmatBaseException("The transponder is unfeasible to receive uplink signal.\n"); } // 12. Get frequency of transponder output signal Signal* outputSignal = scTransponder->GetSignal(1); Real downlinkFreq = outputSignal->GetValue(); #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Downlink frequency = %.12lf Mhz\n", downlinkFreq); #endif // 13. Doppler shift the transponder output frequency by the downlinkRangeRate: Real downlinkDSFreq = (1 - downlinkRangeRate*GmatMathConstants::KM_TO_M/GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM)*downlinkFreq; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Downlink Doppler shift frequency = %.12lf MHz\n", downlinkDSFreq); #endif // 14. Set frequency on receiver Signal* downlinkSignal = gsReceiver->GetSignal(); downlinkSignal->SetValue(downlinkDSFreq); // 15. Check the receiver feasibility to receive the downlink signal if (gsReceiver->IsFeasible() == false) { currentMeasurement.isFeasible = false; currentMeasurement.value[0] = 0; MessageInterface::ShowMessage("The receiver is unfeasible to receive downlink signal.\n"); throw new MeasurementException("The receiver is unfeasible to receive downlink signal.\n"); } // 16. Calculate media correction for downlink leg: #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("8. Media correction for downlink leg\n"); #endif RealArray downlinkCorrection = CalculateMediaCorrection(downlinkDSFreq, r3, r4, currentMeasurement.epoch); Real downlinkRangeCorrection = downlinkCorrection[0]/GmatMathConstants::KM_TO_M; Real downlinkRealRange = downlinkRange + downlinkRangeCorrection; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Downlink range correction = %.12lf km\n",downlinkRangeCorrection); MessageInterface::ShowMessage(" Downlink real range = %.12lf km\n",downlinkRealRange); #endif // 17. Calculate uplink time and down link time: (Is it needed???) uplinkTime = uplinkRealRange*GmatMathConstants::KM_TO_M / GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM; downlinkTime = downlinkRealRange*GmatMathConstants::KM_TO_M / GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM; #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage("9. Travel time:\n"); MessageInterface::ShowMessage(" Uplink time = %.12lf s\n",uplinkTime); MessageInterface::ShowMessage(" Downlink time = %.12lf s\n",downlinkTime); #endif // 18. Calculate real range // Real realRange = ((upRange + downRange) / // (GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM / GmatMathConstants::KM_TO_M) + // receiveDelay + transmitDelay + targetDelay) * freqFactor; // Real freqFactor = GetFrequencyFactor(frequency); Real freqFactor = GetFrequencyFactor(uplinkFreq*1.0e6); // Notice that: unit of "uplinkFreq" is MHz (not Hz) Real realTravelTime = uplinkTime + downlinkTime + receiveDelay + transmitDelay + targetDelay; // unit: second Real realRangeKm = 0.5*realTravelTime * GmatPhysicalConstants::SPEED_OF_LIGHT_VACUUM/1000.0; // unit: km Real realRange = realTravelTime * freqFactor; // unit: no unit #ifdef DEBUG_RANGE_CALC_WITH_EVENTS MessageInterface::ShowMessage(" Frequency factor = %.12lf MHz\n", freqFactor/1.0e6); MessageInterface::ShowMessage(" Calculated real range in km = %.12lf km\n", realRangeKm); MessageInterface::ShowMessage(" Calculated real range = %.12lf (It has no unit)\n", realRange); #endif // 19. Set value for currentMeasurement // currentMeasurement.value[0] = realRange; currentMeasurement.value[0] = realRangeKm; currentMeasurement.isFeasible = true; retval = true; } return retval; }