//------------------------------------------------------------------------------ bool ImpulsiveBurn::Fire(Real *burnData, Real epoch, bool backwards) { #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage ("ImpulsiveBurn::Fire() <%p>'%s' entered\n", this, instanceName.c_str()); MessageInterface::ShowMessage (" deltaV: %18le %18le %18le\n", deltaV[0], deltaV[1], deltaV[2]); #endif #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (" usingLocalCoordSys=%d, spacecraft=<%p>, " "localCoordSystem=<%p>\n", usingLocalCoordSys, spacecraft, localCoordSystem); #endif // By this time, the spacecraft should have been set if (usingLocalCoordSys && spacecraft == NULL) throw BurnException ("Unable to initialize the ImpulsiveBurn object " + instanceName + " " + satName + " was not set for the burn."); if (!isInitialized || localCoordSystem == NULL) { if (Initialize()) isInitialized = true; } if (epoch == GmatTimeConstants::MJD_OF_J2000) epoch = spacecraft->GetRealParameter("A1Epoch"); Real *satState = spacecraft->GetState().GetState(); // Update tank of the spacecraft if (decrementMass) SetTankFromSpacecraft(); #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (" Maneuvering spacecraft %s\n", spacecraft->GetName().c_str()); MessageInterface::ShowMessage (" Position for burn: %18le %18le %18le\n", satState[0], satState[1], satState[2]); MessageInterface::ShowMessage (" Velocity before burn: %18le %18le %18le\n", satState[3], satState[4], satState[5]); #endif // The returned vector here is not rotated correctly because one of the bodies is not centered correctly ConvertDeltaVToInertial(deltaV, deltaVInertial, epoch); if (backwards) { // theDv is the burn we will apply, in the burn frame Real theV[3], trialBurn[3], endState[3]; theV[0] = satState[3]; theV[1] = satState[4]; theV[2] = satState[5]; // Seed the burn to be applied trialBurn[0] = -deltaVInertial[0]; trialBurn[1] = -deltaVInertial[1]; trialBurn[2] = -deltaVInertial[2]; // ConvertDeltaVToInertial(theDv, trialBurn, epoch); Real eps = 0.0, mag, tbMag; Integer count = 0; mag = sqrt(deltaV[0]*deltaV[0] + deltaV[1]*deltaV[1] + deltaV[2]*deltaV[2]); #ifdef DEBUG_BACKPROP MessageInterface::ShowMessage("BackProp Seed dv: [%lf %lf %lf]\n", trialBurn[0], trialBurn[1], trialBurn[2]); #endif // For BackProp, iterate the coordinate system conversion do { if (eps != 0.0) // After the first pass through... { // Reset spacecraft V satState[3] = theV[0]; satState[4] = theV[1]; satState[5] = theV[2]; // Calc how different achieved was from desired trialBurn[0] += satState[3] - endState[0]; trialBurn[1] += satState[4] - endState[1]; trialBurn[2] += satState[5] - endState[2]; // Apply dV with right mag in the adjusted direction tbMag = sqrt(trialBurn[0]*trialBurn[0] + trialBurn[1]*trialBurn[1] + trialBurn[2]*trialBurn[2]); trialBurn[0] *= mag/tbMag; trialBurn[1] *= mag/tbMag; trialBurn[2] *= mag/tbMag; } #ifdef DEBUG_BACKPROP MessageInterface::ShowMessage("%d dv: [%lf %lf %lf]\n", count, trialBurn[0], trialBurn[1], trialBurn[2]); #endif satState[3] += trialBurn[0]; satState[4] += trialBurn[1]; satState[5] += trialBurn[2]; // Now apply the forward burn ConvertDeltaVToInertial(deltaV, deltaVInertial, epoch); endState[0] = satState[3] + deltaVInertial[0]; endState[1] = satState[4] + deltaVInertial[1]; endState[2] = satState[5] + deltaVInertial[2]; // and see how different it is from the starting velocity eps = fabs(theV[0] - endState[0]) + fabs(theV[1] - endState[1]) + fabs(theV[2] - endState[2]); ++count; #ifdef DEBUG_BACKPROP MessageInterface::ShowMessage("%d: eps = %le\n", count, eps); #endif } while ((eps > BACKPROP_PRECISION) && (count < BACKPROP_ITERATIONS)); if (count == BACKPROP_ITERATIONS) { MessageInterface::ShowMessage("Warning!!! Maneuver BackProp did not " "converge to a solution that inverts the forward maneuver in " "direction,\nso the raw maneuver has been applied for the " "ImpulsiveBurn %s\n", instanceName.c_str()); satState[3] = theV[0] - deltaVInertial[0]; satState[4] = theV[1] - deltaVInertial[1]; satState[5] = theV[2] - deltaVInertial[2]; } } else { #ifdef DEBUG_BACKPROP MessageInterface::ShowMessage("FrwdProp used dv: [%lf %lf %lf]\n", deltaVInertial[0], deltaVInertial[1], deltaVInertial[2]); #endif satState[3] += deltaVInertial[0]; satState[4] += deltaVInertial[1]; satState[5] += deltaVInertial[2]; } #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (" Velocity after burn: %18le %18le %18le\n", satState[3], satState[4], satState[5]); MessageInterface::ShowMessage (" %s tank mass computation\n", decrementMass ? "Continue with " : "Skipping"); #endif if (decrementMass) DecrementMass(backwards); #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage("ImpulsiveBurn::Fire() returning true\n"); #endif hasFired = true; epochAtLastFire = epoch; return true; }
//------------------------------------------------------------------------------ bool ImpulsiveBurn::Fire(Real *burnData, Real epoch) { #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (wxT("ImpulsiveBurn::Fire() <%p>'%s' entered\n"), this, instanceName.c_str()); MessageInterface::ShowMessage (wxT(" deltaV: %18le %18le %18le\n"), deltaV[0], deltaV[1], deltaV[2]); #endif #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (wxT(" usingLocalCoordSys=%d, spacecraft=<%p>, initialized=%d, ") wxT("localCoordSystem=<%p>\n"), usingLocalCoordSys, spacecraft, initialized, localCoordSystem); #endif // By this time, the spacecraft should have been set if (usingLocalCoordSys && spacecraft == NULL) throw BurnException (wxT("Unable to initialize the ImpulsiveBurn object ") + instanceName + wxT(" ") + satName + wxT(" was not set for the burn.")); if (!initialized || localCoordSystem == NULL) { if (Initialize()) initialized = true; } if (epoch == GmatTimeConstants::MJD_OF_J2000) epoch = spacecraft->GetRealParameter(wxT("A1Epoch")); Real *satState = spacecraft->GetState().GetState(); // Update tank of the spacecraft if (decrementMass) SetTankFromSpacecraft(); #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (wxT(" Maneuvering spacecraft %s\n"), spacecraft->GetName().c_str()); MessageInterface::ShowMessage (wxT(" Position for burn: %18le %18le %18le\n"), satState[0], satState[1], satState[2]); MessageInterface::ShowMessage (wxT(" Velocity before burn: %18le %18le %18le\n"), satState[3], satState[4], satState[5]); #endif // The returned vector here is not rotated correctly because one of the bodies is not centered correctly ConvertDeltaVToInertial(deltaV, deltaVInertial, epoch); satState[3] += deltaVInertial[0]; satState[4] += deltaVInertial[1]; satState[5] += deltaVInertial[2]; #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage (wxT(" Velocity after burn: %18le %18le %18le\n"), satState[3], satState[4], satState[5]); MessageInterface::ShowMessage (wxT(" %s tank mass computation\n"), decrementMass ? wxT("Continue with ") : wxT("Skipping")); #endif if (decrementMass) DecrementMass(); #ifdef DEBUG_IMPBURN_FIRE MessageInterface::ShowMessage(wxT("ImpulsiveBurn::Fire() returning true\n")); #endif return true; }