Esempio n. 1
0
//------------------------------------------------------------------------------
bool FiniteBurn::SetStringParameter(const Integer id, const std::string &value,
                                    const Integer index)
{
    if (id == FUEL_TANK)
        return true;     // just to ignore

    Integer count;

    if (id == THRUSTER)
    {
        count = thrusterNames.size();
        if (index > count)
            throw BurnException("Attempting to write thruster " + value +
                                " past the allowed range for FiniteBurn " + instanceName);
        if (find(thrusterNames.begin(), thrusterNames.end(), value) != thrusterNames.end())
        {
            if (thrusterNames[index] == value)
                return true;
            throw BurnException("Thruster " + value +
                                " already set for FiniteBurn " + instanceName);
        }
        if (index == count)
            thrusterNames.push_back(value);
        else
            thrusterNames[index] = value;

        isInitialized = false;
        return true;
    }

    return Burn::SetStringParameter(id, value, index);
}
Esempio n. 2
0
//------------------------------------------------------------------------------
bool Burn::Initialize()
{
   #ifdef DEBUG_BURN_INIT
   MessageInterface::ShowMessage
      ("Burn::Initialize() <%p>'%s' entered, spacecraft=<%p>\n", this,
       GetName().c_str(), spacecraft);
   #endif
   
   bool retval = GmatBase::Initialize();
   
   if (retval)
   {
      if ((!solarSystem))
         throw BurnException("Unable to initialize the burn object \"" + 
            instanceName + "\"; the SolarSystem was not set.");
      
      j2000Body = solarSystem->GetBody(j2000BodyName);
      if (!localOrigin)
         localOrigin = solarSystem->GetBody(localOriginName);
      
      if ((!localOrigin) || (!j2000Body))
         throw BurnException("Unable to initialize the burn object " + 
            instanceName + "; either " + j2000BodyName + " or " + 
            localOriginName + " was not set for the burn.");
   }
   
   // delete old local coordinate system
   if (usingLocalCoordSys && localCoordSystem != NULL)
   {
      #ifdef DEBUG_MEMORY
      MemoryTracker::Instance()->Remove
         (localCoordSystem, "localCoordSystem", "Burn::Initialize()",
          "deleting localCoordSystem");
      #endif
      delete localCoordSystem;
      localCoordSystem = NULL;
   }
   
   // If spacecraft is available, create new local coordinate system
   if (usingLocalCoordSys && spacecraft != NULL)
      localCoordSystem = CreateLocalCoordinateSystem();
   
   if (usingLocalCoordSys && localCoordSystem == NULL)
      retval = false;
   
   #ifdef DEBUG_BURN_INIT
   MessageInterface::ShowMessage
      ("Burn::Initialize() <%p>'%s' returning %d, localCoordSystem=<%p>\n",
       this, GetName().c_str(), retval, localCoordSystem);
   #endif
   
//   hasFired = false;    // do I want this here?
   return retval;
}
Esempio n. 3
0
//------------------------------------------------------------------------------
bool ImpulsiveBurn::Validate()
{
   if (decrementMass)
   {
      if (tankNames.empty())
      {
         throw BurnException("The ImpulsiveBurn \"" + instanceName +
               "\" is set to deplete mass, but no tank is identified as the "
               "mass source for mass depletion.  Please specify a fuel tank "
               "on the panel or by using the scripting\n   " + instanceName +
               ".Tank = {<tankName>};");
      }
   }

   return Burn::Validate();
}
Esempio n. 4
0
//------------------------------------------------------------------------------
bool Burn::SetStringParameter(const Integer id, const std::string &value)
{
   #ifdef DEBUG_BURN_SET
   MessageInterface::ShowMessage
      ("Burn::SetStringParameter() this=<%p> '%s', id=%d, value='%s'\n", this,
       GetName().c_str(), id, value.c_str());
   #endif
   
   switch (id)
   {
   case COORDINATESYSTEM:
      coordSystemName = value;
      if (coordSystemName == "Local")
         usingLocalCoordSys = true;
      else
         usingLocalCoordSys = false;
      return true;
   case BURNORIGIN:
      localOriginName = value;
      #ifdef DEBUG_BURN_SET
      MessageInterface::ShowMessage
         ("Burn::SetStringParameter() exiting, localOriginName set to '%s'\n",
          value.c_str());
      #endif
      return true;
   case BURNAXES:
      {
         localAxesName = value;
         
         // Do we need to determine Local CS here?
         // Yes, old ImpulsiveBurn script doesn't have CoordinateSystem field, 
         // so Axes should be used to determine Local CS or not
         if (find(localAxesLabels.begin(), localAxesLabels.end(), localAxesName)
             != localAxesLabels.end())
         {
            #ifdef DEBUG_BURN_SET
            MessageInterface::ShowMessage
               ("   Local axes '%s' found, so setting coordSystemName to Local\n",
                localAxesName.c_str());
            #endif
            if (usingLocalCoordSys)
               coordSystemName = "Local";
         }
         else
         {
            // write one warning per GMAT session
            static bool firstTimeWarning = true;
            std::string framelist = localAxesLabels[0];
            for (UnsignedInt n = 1; n < localAxesLabels.size(); ++n)
               framelist += ", " + localAxesLabels[n];
            
            std::string msg =
               "The value of \"" + value + "\" for field \"Axes\""
               " on object \"" + instanceName + "\" is not an allowed value.\n"
               "The allowed values are: [ " + framelist + " ]. ";
            
            if (firstTimeWarning)
            {
               firstTimeWarning = false;
               
               if (value == "Inertial")
                  MessageInterface::ShowMessage("*** WARNING *** " + msg + "\n");
               else
                  throw BurnException(msg);
            }
            
            if (value == "Inertial")
            {
               coordSystemName = "EarthMJ2000Eq";
               usingLocalCoordSys = false;
            }
            else
               throw BurnException(msg);
            
         }
         
         return true;
      }
   case VECTORFORMAT: // deprecated
      vectorFormat = value;
      return true;
   default:
      break;
   }
   
   return GmatBase::SetStringParameter(id, value);
}
Esempio n. 5
0
//------------------------------------------------------------------------------
// void ConvertDeltaVToInertial(Real *dv, Real *dvInertial, Real epoch)
//------------------------------------------------------------------------------
void Burn::ConvertDeltaVToInertial(Real *dv, Real *dvInertial, Real epoch)
{
   #ifdef DEBUG_BURN_CONVERT
   MessageInterface::ShowMessage
      ("Burn::ConvertDeltaVToInertial(), usingLocalCoordSys=%d, coordSystemName='%s', "
       "coordSystem=<%p>'%s'\n", usingLocalCoordSys, coordSystemName.c_str(),
       coordSystem, coordSystem ? coordSystem->GetName().c_str() : "NULL");
   #endif
   
   if (usingLocalCoordSys && localCoordSystem == NULL)
   {      
      throw BurnException
         ("Unable to convert burn elements to Inertial, the local Coordinate "
          "System has not been created");
   }
   else if (!usingLocalCoordSys && coordSystem == NULL)
   {
      throw BurnException
         ("Unable to convert burn elements to Inertial, the Coordinate "
          "System has not been set");      
   }
   
   Real inDeltaV[6], outDeltaV[6];
   for (Integer i=0; i<3; i++)
      inDeltaV[i] = dv[i];
   for (Integer i=3; i<6; i++)
      inDeltaV[i] = 0.0;
   
   // if not using local CS, use ref CoordinateSystem
   if (!usingLocalCoordSys)
   {     
      // Now rotate to MJ2000Eq axes, we don't want to translate so
      // set coincident to true
      coordSystem->ToBaseSystem(epoch, inDeltaV, outDeltaV, true);  // @todo - need ToMJ2000Eq here?
      
      #ifdef DEBUG_BURN_CONVERT_ROTMAT
      Rmatrix33 rotMat = coordSystem->GetLastRotationMatrix();
      MessageInterface::ShowMessage
         ("rotMat=\n%s\n", rotMat.ToString(16, 20).c_str());
      #endif
      
      dvInertial[0] = outDeltaV[0];
      dvInertial[1] = outDeltaV[1];
      dvInertial[2] = outDeltaV[2];
   }
   else
   {
      // if MJ2000Eq axes rotation matrix is always identity matrix
      if (isMJ2000EqAxes)
      {
         dvInertial[0] = dv[0];
         dvInertial[1] = dv[1];
         dvInertial[2] = dv[2];
      }
      else if (isSpacecraftBodyAxes)
      {
         Rvector3 inDeltaV(dv[0], dv[1], dv[2]);
         Rvector3 outDeltaV;
         // Get attitude matrix from Spacecraft and transpose since
         // attitude matrix from spacecraft gives rotation matrix from
         // inertial to body
         Rmatrix33 inertialToBody = spacecraft->GetAttitude(epoch);
         Rmatrix33 rotMat = inertialToBody.Transpose();
         #ifdef DEBUG_BURN_CONVERT_ROTMAT
         MessageInterface::ShowMessage
            ("for local Spacecraft body ----- rotMat=\n%s\n", rotMat.ToString(16, 20).c_str());
         #endif
         outDeltaV = inDeltaV * rotMat;
         for (Integer i=0; i<3; i++)
            dvInertial[i] = outDeltaV[i];
      }
      else
      {         
//         // Now rotate to MJ2000Eq axes
//         localCoordSystem->ToMJ2000Eq(epoch, inDeltaV, outDeltaV, true);
         // Now rotate to base system axes
         localCoordSystem->ToBaseSystem(epoch, inDeltaV, outDeltaV, true);   // @todo - need ToMJ2000Eq here?

         dvInertial[0] = outDeltaV[0];
         dvInertial[1] = outDeltaV[1];
         dvInertial[2] = outDeltaV[2];
      }
   }
   
   #ifdef DEBUG_BURN_CONVERT
   MessageInterface::ShowMessage
      ("Burn::ConvertDeltaVToInertial() returning\n"
       "           dv = %f %f %f\n   dvInertial = %f %f %f\n",
       dv[0], dv[1], dv[2], dvInertial[0], dvInertial[1], dvInertial[2]);
   #endif
}
Esempio n. 6
0
//------------------------------------------------------------------------------
// CoordinateSystem* CreateLocalCoordinateSystem()
//------------------------------------------------------------------------------
CoordinateSystem* Burn::CreateLocalCoordinateSystem()
{
   #ifdef DEBUG_BURN_INIT
   MessageInterface::ShowMessage
      ("Burn::CreateLocalCoordinateSystem() '%s' entered, usingLocalCoordSys=%d, "
       "spacecraft=<%p>, solarSystem=<%p>\n", GetName().c_str(), usingLocalCoordSys,
       spacecraft, solarSystem);
   #endif
   
   // Why solarSystem gets NULL when running MMS script?
   // Added a check here for now (LOJ: 2009.04.22)
   if (solarSystem == NULL)
   {
      #ifdef DEBUG_BURN_INIT
      MessageInterface::ShowMessage
         ("*** WARNING *** Burn::CreateLocalCoordinateSystem() Unable to create local "
          "coordiante system, SolarSystem is NULL\n");
      #endif
      throw BurnException
         ("*** WARNING *** Burn::CreateLocalCoordinateSystem() Unable to create "
          "local coordiante system, SolarSystem is NULL\n");
   }
   
   CoordinateSystem *localCS = NULL;
   
   // If coordinate system being used is local, then create
   if (usingLocalCoordSys)
   {
      if (spacecraft == NULL)
      {
         // Since spacecraft is set later, just return NULL for now
         #ifdef DEBUG_BURN_INIT
         MessageInterface::ShowMessage
            ("Burn::CreateLocalCoordinateSystem() spacecraft is not set so, "
             "returning NULL\n");
         #endif
         return NULL;
         //throw BurnException("Unable to initialize the Burn object " + 
         //   instanceName + " " + satName + " was not set for the burn.");
      }
      
      // Call CoordinateSystem static method to create a local coordinate system
      localOrigin = solarSystem->GetBody(localOriginName);
      localCS = CoordinateSystem::CreateLocalCoordinateSystem
         ("Local", localAxesName, spacecraft, localOrigin, spacecraft,
          j2000Body, solarSystem);
      
      if (localCS == NULL)
         return NULL;
      
      if (localAxesName == "MJ2000Eq")
         isMJ2000EqAxes = true;
      else if (localAxesName == "SpacecraftBody")
         isSpacecraftBodyAxes = true;
      
   }
   else
   {
      // If not using local cooordinate system, then it is using configured CS and
      // it should have been set by this time
      if (coordSystem)
      {
         throw BurnException
            ("Unable to initialize the Burn object " + 
             instanceName + " " + coordSystemName + " was not set for the burn.");
      }
      localCS = coordSystem;
   }
   
   #ifdef DEBUG_BURN_INIT
   MessageInterface::ShowMessage
      ("Burn::CreateLocalCoordinateSystem() returning <%p>\n", localCS);
   #endif
   
   return localCS;
}
Esempio n. 7
0
//------------------------------------------------------------------------------
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;
}
Esempio n. 8
0
//------------------------------------------------------------------------------
// void DecrementMass()
//------------------------------------------------------------------------------
void ImpulsiveBurn::DecrementMass(bool backwards)
{
   #ifdef DEBUG_IMPBURN_DECMASS
   MessageInterface::ShowMessage
      ("ImpulsiveBurn::DecrementMass() <%p>'%s' entered. There are %d tank(s)\n",
       this, instanceName.c_str(), tankMap.size());
   #endif
   totalTankMass = spacecraft->GetRealParameter("TotalMass");
   
   #ifdef DEBUG_IMPBURN_DECMASS
   MessageInterface::ShowMessage
      ("   Now decrementing mass\n      before maneuver totalTankMass = %f\n",
       totalTankMass);
   #endif
   
   Real dv = sqrt( deltaV[0]*deltaV[0] + deltaV[1]*deltaV[1] + deltaV[2]*deltaV[2]);
   if (!backwards)
      deltaTankMass = totalTankMass * (exp(-dv * 1000/(isp * gravityAccel)) - 1.0);
   else
      deltaTankMass = totalTankMass * (exp(dv * 1000/(isp * gravityAccel)) - 1.0);
   
   #ifdef DEBUG_IMPBURN_DECMASS
   MessageInterface::ShowMessage
      ("       after maneuver deltaTankMass = %f\n", deltaTankMass);
   #endif
   
   totalTankMass = totalTankMass + deltaTankMass;
   
   #ifdef DEBUG_IMPBURN_DECMASS
   MessageInterface::ShowMessage
      ("       after maneuver totalTankMass = %f\n", totalTankMass);
   #endif

   // Update tank mass
   if (!tankMap.empty())
   {
      if (tankMap.size() > 1)
         throw BurnException("The ImpulsiveBorn object " + instanceName +
               " is configured to draw mass from multiple tanks, but only one "
               "tank is supported in the current implementation.");

      // This code is set up to draw from multiple tanks, but the amount drawn
      // is not calculated to draw proportionally.  Instead, it reduces each
      // tank by deltaTankMass.  We need to check this code before enabling
      // mass reduction from multiple tanks in a single impulsive burn.
      for (ObjectMap::iterator tankPos = tankMap.begin();
           tankPos != tankMap.end(); ++tankPos)
      {
         GmatBase *currTank = tankPos->second;

         #ifdef DEBUG_IMPBURN_DECMASS
         MessageInterface::ShowMessage
            ("       Decrementing tank mass for <%p>'%s'\n", currTank,
             (tankPos->first).c_str());
         #endif
         Integer paramID = currTank->GetParameterID("FuelMass");
         Real oldTankMass = currTank->GetRealParameter(paramID);
         Real currTankMass = oldTankMass + deltaTankMass;
         #ifdef DEBUG_IMPBURN_DECMASS
         MessageInterface::ShowMessage
            ("       it was %f, it is now %f\n", oldTankMass, currTankMass);
         #endif
         //@todo What should we do if decremented tank mass is below zero?
         currTank->SetRealParameter(paramID, currTankMass);
      }
   }
   else
      throw BurnException("Impulsive Burn " + instanceName +
            " is set to decrement mass from a tank named "  + tankNames[0] +
            ", but the Spacecraft " + spacecraft->GetName() +
            " does not have the selected fuel tank.");

   #ifdef DEBUG_IMPBURN_DECMASS
   MessageInterface::ShowMessage
      ("ImpulsiveBurn::DecrementMass() <%p>'%s' returning\n", this, GetName().c_str());
   #endif
}
Esempio n. 9
0
//------------------------------------------------------------------------------
// bool SetTankFromSpacecraft()
//------------------------------------------------------------------------------
bool ImpulsiveBurn::SetTankFromSpacecraft()
{
   #ifdef DEBUG_IMPBURN_SET
   MessageInterface::ShowMessage
      ("ImpulsiveBurn::SetTankFromSpacecraft() entered, spacecraft=<%p>'%s'\n",
       spacecraft, spacecraft ? spacecraft->GetName().c_str() : "NULL");
   MessageInterface::ShowMessage("   tankNames.size()=%d\n", tankNames.size());
   #endif
   
   if (spacecraft == NULL)
      return false;
   
   if (tankNames.empty())
      throw BurnException("ImpulsiveBurn::Initialize() " + instanceName +
                          " has no associated tank");
   
   ObjectArray tankArray = spacecraft->GetRefObjectArray(Gmat::FUEL_TANK);
   
   #ifdef DEBUG_IMPBURN_SET
   MessageInterface::ShowMessage
      ("   spacecraft tankArray.size()=%d\n", tankArray.size());
   #endif
   
   if (!tankNames.empty() && !tankArray.empty())
   {
      ObjectArray::iterator scTank = tankArray.begin();
      
      // Find the tank on the spacecraft
      for (StringArray::iterator tankName = tankNames.begin();
           tankName != tankNames.end(); ++tankName)
      {
         while (scTank != tankArray.end())
         {
            #ifdef DEBUG_IMPBURN_SET
            MessageInterface::ShowMessage
               ("   The tank '%s' associated with spacecraft is <%p>'%s'\n",
                (*tankName).c_str(), (*scTank),
                (*scTank) ? (*scTank)->GetName().c_str() : "NULL");
            #endif
            
            // Just in case, check for NULL tank pointer
            if (*scTank == NULL)
               continue;
            
            // Assign the tank
            if ((*scTank)->GetName() == *tankName)
            {
               tankMap[*tankName] = (*scTank);
               #ifdef DEBUG_IMPBURN_SET
               MessageInterface::ShowMessage
                  ("   Assigned <%p>'%s' to tankMap\n", *scTank, (*tankName).c_str());
               #endif
            }
            ++scTank;
         }
      }
      if (tankNames.size() != tankMap.size())
         throw BurnException("The impulsive burn " + instanceName +
               " could not find the fuel tank needed to deplete mass; please "
               "attach the tank to the spacecraft " + spacecraft->GetName() +
               " or turn off mass depletion.");
   }
   
   #ifdef DEBUG_IMPBURN_SET
   MessageInterface::ShowMessage
      ("ImpulsiveBurn::SetTankFromSpacecraft() returning true\n");
   #endif
   
   return true;
}
Esempio n. 10
0
//------------------------------------------------------------------------------
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;
}
Esempio n. 11
0
//------------------------------------------------------------------------------
// bool SetThrustersFromSpacecraft()
//------------------------------------------------------------------------------
bool FiniteBurn::SetThrustersFromSpacecraft()
{
#ifdef DEBUG_FINITEBURN_SET
    MessageInterface::ShowMessage
    ("FiniteBurn::SetThrustersFromSpacecraft() entered, spacecraft=<%p>'%s'\n",
     spacecraft, spacecraft ? spacecraft->GetName().c_str() : "NULL");
    MessageInterface::ShowMessage("   thrusterNames.size()=%d\n", thrusterNames.size());
#endif

    // Get thrusters and tanks associated to spacecraft
    ObjectArray thrusterArray = spacecraft->GetRefObjectArray(Gmat::THRUSTER);
    ObjectArray tankArray = spacecraft->GetRefObjectArray(Gmat::FUEL_TANK);

    // Look up the thruster(s)
    for (ObjectArray::iterator th = thrusterArray.begin();
            th != thrusterArray.end(); ++th)
    {
        for (StringArray::iterator thName = thrusterNames.begin();
                thName != thrusterNames.end(); ++thName)
        {
            // Only act on thrusters assigned to this burn
            if ((*th)->GetName() == *thName)
            {
                Integer paramId = (*th)->GetParameterID("Tank");
                StringArray tankNames = (*th)->GetStringArrayParameter(paramId);
                // Setup the tankNames
                (*th)->TakeAction("ClearTankNames");
                // Loop through each tank for the burn
                for (StringArray::iterator tankName = tankNames.begin();
                        tankName != tankNames.end(); ++tankName)
                {
                    ObjectArray::iterator tnk = tankArray.begin();
                    // Find the tank on the spacecraft
                    while (tnk != tankArray.end())
                    {
                        if ((*tnk)->GetName() == *tankName)
                        {
                            // Make the assignment
                            (*th)->SetStringParameter("Tank", *tankName);
                            (*th)->SetRefObject(*tnk, (*tnk)->GetType(),
                                                (*tnk)->GetName());
                            break;
                        }
                        // Not found; keep looking
                        ++tnk;
                        if (tnk == tankArray.end())
                            throw BurnException
                            ("FiniteBurn::Initialize() cannot find tank " +
                             (*tankName) + " for burn " + instanceName);
                    }
                }
            }
        }
    }

#ifdef DEBUG_FINITEBURN_SET
    MessageInterface::ShowMessage
    ("FiniteBurn::SetThrustersFromSpacecraft() returning true\n");
#endif

    return true;
}
Esempio n. 12
0
//------------------------------------------------------------------------------
bool FiniteBurn::Fire(Real *burnData, Real epoch)
{
#ifdef DEBUG_FINITEBURN_FIRE
    MessageInterface::ShowMessage
    ("FiniteBurn::Fire() this<%p>'%s' entered, epoch=%f, spacecraft=<%p>'%s'\n",
     this, instanceName.c_str(), epoch, spacecraft,
     spacecraft ? spacecraft->GetName().c_str() : "NULL");
#endif

    if (isInitialized == false)
        Initialize();

    if (!spacecraft)
        throw BurnException("Maneuver initial state undefined (No spacecraft?)");

    // Accumulate the individual accelerations from the thrusters
    Real dm = 0.0, tMass, tOverM, *dir, norm;
    deltaV[0] = deltaV[1] = deltaV[2] = 0.0;
    Thruster *current;

    tMass = spacecraft->GetRealParameter("TotalMass");

#ifdef DEBUG_BURN_ORIGIN
    Real *satState = spacecraft->GetState().GetState();
    MessageInterface::ShowMessage
    ("FiniteBurn Vectors:\n   "
     "Sat   = [%.15f %.15f %.15f %.15f %.15f %.15f]\n   "
     "Frame = [%.15f %.15f %.15f\n   "
     "         %.15f %.15f %.15f\n   "
     "         %.15f %.15f %.15f]\n\n",
     satState[0], satState[1], satState[2], satState[3], satState[4], satState[5],
     frameBasis[0][0], frameBasis[0][1], frameBasis[0][2],
     frameBasis[1][0], frameBasis[1][1], frameBasis[1][2],
     frameBasis[2][0], frameBasis[2][1], frameBasis[2][2]);
#endif

    for (StringArray::iterator i = thrusterNames.begin();
            i != thrusterNames.end(); ++i)
    {
#ifdef DEBUG_FINITE_BURN
        MessageInterface::ShowMessage
        ("   Accessing thruster '%s' from spacecraft <%p>'%s'\n", (*i).c_str(),
         spacecraft, spacecraft->GetName().c_str());
#endif

        current = (Thruster *)spacecraft->GetRefObject(Gmat::THRUSTER, *i);
        if (!current)
            throw BurnException("FiniteBurn::Fire requires thruster named \"" +
                                (*i) + "\" on spacecraft " + spacecraft->GetName());

        // Save current thruster so that GetRefObject() can return it (LOJ: 2009.08.28)
        thrusterMap[current->GetName()] = current;

        // FiniteBurn class is friend of Thruster class, so we can access
        // member data directly
        current->ComputeInertialDirection(epoch);
        dir = current->inertialDirection;
        norm = sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);

#ifdef DEBUG_FINITE_BURN
        MessageInterface::ShowMessage
        ("   Thruster Direction: %.15f  %.15f  %.15f\n"
         "                 norm: %.15f\n", dir[0], dir[1], dir[2], norm);
#endif

        if (norm == 0.0)
            throw BurnException("FiniteBurn::Fire thruster " + (*i) +
                                " on spacecraft " + spacecraft->GetName() +
                                " has no direction.");

        dm += current->CalculateMassFlow();
        //tOverM = current->thrust / (tMass * norm * 1000.0); //old code
        tOverM = current->thrust * current->thrustScaleFactor *
                 current->dutyCycle / (tMass * norm * 1000.0);

        deltaV[0] += dir[0] * tOverM;
        deltaV[1] += dir[1] * tOverM;
        deltaV[2] += dir[2] * tOverM;

#ifdef DEBUG_FINITE_BURN
        MessageInterface::ShowMessage("   Thruster %s = %s details:\n",
                                      (*i).c_str(), current->GetName().c_str());
        MessageInterface::ShowMessage(
            "   thrust   = %.15f\n"
            "       dM   = %.15e\n      Mass  = %.15f\n"
            "      TSF   = %.15f\n      |Acc| = %.15e\n      "
            "Acc   = [%.15e   %.15e   %.15e]\n", current->thrust,
            dm, tMass, current->thrustScaleFactor, tOverM,
            deltaV[0], deltaV[1], deltaV[2]);
#endif
    }

    // Build the acceleration
    burnData[0] = deltaV[0]*frameBasis[0][0] +
                  deltaV[1]*frameBasis[0][1] +
                  deltaV[2]*frameBasis[0][2];
    burnData[1] = deltaV[0]*frameBasis[1][0] +
                  deltaV[1]*frameBasis[1][1] +
                  deltaV[2]*frameBasis[1][2];
    burnData[2] = deltaV[0]*frameBasis[2][0] +
                  deltaV[1]*frameBasis[2][1] +
                  deltaV[2]*frameBasis[2][2];
    burnData[3] = dm;

#ifdef DEBUG_FINITEBURN_FIRE
    MessageInterface::ShowMessage(
        "FiniteBurn::Fire() this<%p>'%s' returning\n"
        "   Acceleration:  %.15e  %.15e  %.15e  dm: %.15e\n", this,
        GetName().c_str(), burnData[0], burnData[1], burnData[2], dm);
#endif

    hasFired = true;
    epochAtLastFire = epoch;
    return true;
}