Ejemplo n.º 1
0
SerialInterface::SerialInterface(const std::string& portname)
{
    // Open the port
    //clog(info) << "open_weatherstation" << std::endl;
    if ((_sp = open(portname.c_str(), O_RDWR | O_NOCTTY)) < 0)
        throw HardwareException("Unable to open serial device");
    if ( flock(_sp, LOCK_EX) < 0 )
        throw HardwareException("Serial device is locked by other program");

    // We want full control of what is set by simply resetting entire adtio
    // struct
    struct termios adtio;
    memset(&adtio, 0, sizeof(adtio));

    // Serial control options
    adtio.c_cflag &= ~PARENB;      // No parity
    adtio.c_cflag &= ~CSTOPB;      // One stop bit
    adtio.c_cflag &= ~CSIZE;       // Character size mask
    adtio.c_cflag |= CS8;          // Character size 8 bits
    adtio.c_cflag |= CREAD;        // Enable Receiver
    //adtio.c_cflag &= ~CREAD;        // Disable Receiver
    adtio.c_cflag &= ~HUPCL;       // No "hangup"
    adtio.c_cflag &= ~CRTSCTS;     // No flowcontrol
    adtio.c_cflag |= CLOCAL;       // Ignore modem control lines

    // Baudrate, for newer systems
    cfsetispeed(&adtio, BAUDRATE);
    cfsetospeed(&adtio, BAUDRATE);

    // Local options
    //   Raw input = clear ICANON, ECHO, ECHOE, and ISIG
    //   Disable misc other local features = clear FLUSHO, NOFLSH, TOSTOP, PENDIN, and IEXTEN
    // So we actually clear all flags in adtio.c_lflag
    adtio.c_lflag = 0;

    // Input options
    //   Disable parity check = clear INPCK, PARMRK, and ISTRIP
    //   Disable software flow control = clear IXON, IXOFF, and IXANY
    //   Disable any translation of CR and LF = clear INLCR, IGNCR, and ICRNL
    //   Ignore break condition on input = set IGNBRK
    //   Ignore parity errors just in case = set IGNPAR;
    // So we can clear all flags except IGNBRK and IGNPAR
    adtio.c_iflag = IGNBRK|IGNPAR;

    // Output options
    // Raw output should disable all other output options
    adtio.c_oflag &= ~OPOST;

    // Time-out options
    adtio.c_cc[VTIME] = 10;     // timer 1s
    adtio.c_cc[VMIN] = 0;       // blocking read until 1 char

    if (tcsetattr(_sp, TCSANOW, &adtio) < 0)
        throw HardwareException("Unable to initialize serial device");
    tcflush(_sp, TCIOFLUSH);
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------------
bool SolarPowerSystem::Initialize()
{
   #ifdef DEBUG_SOLAR_POWER
      MessageInterface::ShowMessage("Calling Initialization on %s\n",
            instanceName.c_str());
      MessageInterface::ShowMessage("number of shadow bodies = %d\n",
            (Integer) shadowBodyNames.size());
   #endif
   PowerSystem::Initialize();

   // Solar System is set by the spacecraft to which this is attached
   if (!solarSystem)
   {
      std::string errmsg = "SolarSystem has not been set on PowerSystem ";
      errmsg            += instanceName + ".\n";
      throw HardwareException(errmsg);
   }

   // if no names were added to the ShadowBodies list, add the Default body
   // This will cause "ShadowBodies = {'Earth'} to be written to the script <<
   if ((shadowBodyNames.empty()) && (!settingNoBodies))
      shadowBodyNames = defaultShadowBodyNames;
//      shadowBodyNames.push_back("Earth");

   // Set up the list of shadowBodies using current solarSystem
   shadowBodies.clear();
   for (unsigned int ii = 0; ii < shadowBodyNames.size(); ii++)
   {
      CelestialBody *body = solarSystem->GetBody(shadowBodyNames.at(ii));
      if (!body)
      {
         std::string errmsg = "SolarPowerSystem ";
         errmsg += instanceName + " cannot find body ";
         errmsg += shadowBodyNames.at(ii) + ".  ShadowBodies must be ";
         errmsg += "Celestial Bodies.\n";
         throw HardwareException(errmsg);
      }
      shadowBodies.push_back(body);
      #ifdef DEBUG_SOLAR_POWER
         MessageInterface::ShowMessage("Adding shadow body %s to %s\n",
               body->GetName().c_str(), instanceName.c_str());
      #endif
   }

   if (!shadowState)
      shadowState = new ShadowState();

   shadowState->SetSolarSystem(solarSystem);

   return isInitialized;
}
Ejemplo n.º 3
0
//---------------------------------------------------------------------------
bool ElectricThruster::SetStringParameter(const Integer id, const std::string &value)
{
   #ifdef DEBUG_ELECTRIC_THRUSTER_SET
   MessageInterface::ShowMessage
      ("ElectricThruster::SetStringParameter() '%s' entered, id=%d, value='%s'\n",
       GetName().c_str(), id, value.c_str());
   #endif

   switch (id)
   {
   case THRUST_MODEL:
      if (find(thrustModelLabels.begin(), thrustModelLabels.end(), value)
          == thrustModelLabels.end())
      {
         std::string modellist = thrustModelLabels[0];
         for (UnsignedInt n = 1; n < thrustModelLabels.size(); ++n)
            modellist += ", " + thrustModelLabels[n];

         std::string msg =
            "The value of \"" + value + "\" for field \"ThrustModel\""
            " on object \"" + instanceName + "\" is not an allowed value.\n"
            "The allowed values are: [ " + modellist + " ]. ";

         throw HardwareException(msg);
      }
      thrustModel = value;
      return true;
   default:
      return Thruster::SetStringParameter(id, value);
   }
}
Ejemplo n.º 4
0
bool ChemicalTank::Validate()
{
   if (density <= 0.0)
	  return false;
   if ((volume - fuelMass / density) < 0.0)
	   throw HardwareException("Fuel volume exceeds tank capacity\n");
   return true;
}
Ejemplo n.º 5
0
//------------------------------------------------------------------------------
void ChemicalTank::DepleteFuel(Real dm)
{
   fuelMass -= dm;

   if (fuelMass < 0.0)
      // For now, throw if the fuel goes below 0
      throw HardwareException("Fuel in tank " + instanceName +
                              " completely exhausted.\n");
}
Ejemplo n.º 6
0
//------------------------------------------------------------------------------
bool ElectricThruster::Initialize()
{
   #ifdef DEBUG_ELECTRIC_THRUSTER_INIT
   MessageInterface::ShowMessage
      ("ElectricThruster::Initialize() <%p>'%s' entered, thrustModel=%s\n",
       this, GetName().c_str(), thrustModel.c_str());
   #endif

   bool retval = Thruster::Initialize();
   if (!retval)
      return false;

   // CHECK maxUsablePower > minUsablePower
   if (maxUsablePower <= minUsablePower)
   {
      std::string msg =
         "The value of field \"MaximumUsablePower\" on Electric Thruster \"";
      msg += instanceName + "\" must be greater than ";
      msg += "the value of field \"MinimumUsablePower\".\n";
      throw HardwareException(msg);
   }

   // Check that all attached tanks are ElectricTanks
   for (UnsignedInt i=0; i<tanks.size(); i++)
   {
      if (!tanks.at(i)->IsOfType("ElectricTank"))
      {
         std::string errmsg = "All tanks set on ElectricThruster ";
         errmsg += instanceName + " must be of type ElectricTank.\n";
         throw HardwareException(errmsg);
      }
   }

   #ifdef DEBUG_ELECTRIC_THRUSTER_INIT
   MessageInterface::ShowMessage
      ("ElectricThruster::Initialize() <%p>'%s' returning %s\n", this, GetName().c_str(),
       retval ? "true" : "false");
   #endif

   return retval;
}
Ejemplo n.º 7
0
//---------------------------------------------------------------------------
bool ElectricThruster::CalculateThrustAndIsp()
{
   #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
      MessageInterface::ShowMessage(
            "Entering ElectricThruster::CalculateThrustAndIsp, power = %12.10f, minUsablePower = %12.10f\n",
            power, minUsablePower);
      MessageInterface::ShowMessage("    powerToUse  = %12.10f\n", powerToUse);
      MessageInterface::ShowMessage("    powerToUse2 = %12.10f\n", powerToUse2);
      MessageInterface::ShowMessage("    powerToUse3 = %12.10f\n", powerToUse3);
      MessageInterface::ShowMessage("    powerToUse4 = %12.10f\n", powerToUse4);
   #endif
   if (!thrusterFiring)
   {
      #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
         MessageInterface::ShowMessage(
               "In ElectricThruster::CalculateThrustAndIsp, thruster %s NOT FIRING!!\n",
               instanceName.c_str());
      #endif
      thrust  = 0.0;
      impulse = 0.0;
   }
   else
   {
      if (tanks.empty())
         throw HardwareException("ElectricThruster \"" + instanceName +
                                 "\" does not have a fuel tank");

      impulse = isp;   // CORRECT?
      if (thrustModel == "ThrustMassPolynomial")
      {
         thrust = ((thrustCoeff[4] * powerToUse4) +
                   (thrustCoeff[3] * powerToUse3) +
                   (thrustCoeff[2] * powerToUse2) +
                   (thrustCoeff[1] * powerToUse)  +
                   thrustCoeff[0]) / 1.0e3; // 1.0e6;
      }
      else if (thrustModel == "ConstantThrustAndIsp")
      {
         thrust = constantThrust; //  / 1.0e-3;
      }
      else // FixedEfficiency
      {
         thrust = (2.0 * efficiency * powerToUse) / //  * 0.001) /
                  (isp * gravityAccel * 0.001);
      }
   }

   return true;
}
Ejemplo n.º 8
0
//---------------------------------------------------------------------------
// std::string GetStringParameter(const Integer id,const Integer index) const
//---------------------------------------------------------------------------
std::string SolarPowerSystem::GetStringParameter(const Integer id,
                                                 const Integer index) const
{
   if (id == SHADOW_BODIES)
   {
      try
      {
         return shadowBodyNames.at(index);
      }
      catch (const std::exception &)
      {
         throw HardwareException("SolarPowerSystem error: index out-of-range.");
      }
   }

   return PowerSystem::GetStringParameter(id, index);
}
Ejemplo n.º 9
0
//---------------------------------------------------------------------------
// bool SetStringParameter(const Integer id, const std::string &value)
//---------------------------------------------------------------------------
bool ChemicalTank::SetStringParameter(const Integer id, const std::string &value)
{
   #ifdef DEBUG_FUELTANK_SET
   MessageInterface::ShowMessage
      ("ChemicalTank::SetStringParameter() entered, id=%d, value='%s'\n", id,
       value.c_str());
   #endif

   if (id == PRESSURE_MODEL)
   {
      if (find(pressureModelList.begin(), pressureModelList.end(), value) !=
          pressureModelList.end())
      {
         for (UnsignedInt i=0; i<pressureModelList.size(); i++)
            if (value == pressureModelList[i])
               pressureModel = i;
      }
      else
      {
         // write one warning per GMAT session
         static bool firstTimeWarning = true;
         std::string framelist = pressureModelList[0];
         for (UnsignedInt n = 1; n < pressureModelList.size(); ++n)
            framelist += ", " + pressureModelList[n];

         std::string msg =
            "The value of \"" + value + "\" for field \"PressureModel\""
            " on object \"" + instanceName + "\" is not an allowed value.\n"
            "The allowed values are: [ " + framelist + " ]. ";

         if (firstTimeWarning)
         {
            firstTimeWarning = false;
            throw HardwareException(msg);
         }
      }

      return true;
   }

   return FuelTank::SetStringParameter(id, value);
}
Ejemplo n.º 10
0
//---------------------------------------------------------------------------
// bool SetStringParameter(const Integer id, const std::string &value,
//                         const Integer index)
//---------------------------------------------------------------------------
bool SolarPowerSystem::SetStringParameter(const Integer id,
                                          const std::string &value,
                                          const Integer index)
{
   #ifdef DEBUG_SET
      MessageInterface::ShowMessage(
            "Entering SetStringParameter with id = %d, value = %s, and index = %d\n",
            id, value.c_str(), index);
   #endif
   if (id == SHADOW_BODIES)
   {
      // Check to see if we are setting a blank list here; if we are,
      // then we do NOT want to use the default list of bodies
      Integer sz = value.length();
      if ((sz <= 0) || (GmatStringUtil::IsBlank(value)) ||
          ((value[0] == '{') && (value[sz-1] == '}')))
      {
         settingNoBodies = true;
         #ifdef DEBUG_SET
            MessageInterface::ShowMessage(
                  "In SetStringParameter, settingNoBodies = true!!\n");
         #endif
         return true;
      }
      if ((index < 0) || (index > (Integer) shadowBodyNames.size()))
      {
         std::string errmsg = "For PowerSystem ";
         errmsg            += instanceName + ", index into ShadowBodies is ";
         errmsg            += "out-of-range\n";
         throw HardwareException(errmsg);
      }
      if (value == GmatSolarSystemDefaults::SUN_NAME)
      {
         std::string errmsg = "The Sun cannot be set as a Shadow body ";
         errmsg            += "on Power System " + instanceName;
         errmsg            += "\n";
         throw HardwareException(errmsg);
      }
      // Add to the end of the list ...
      if (index == (Integer) shadowBodyNames.size())
      {
         if (find(shadowBodyNames.begin(), shadowBodyNames.end(), value) == shadowBodyNames.end())
         {
               shadowBodyNames.push_back(GmatStringUtil::Trim(value));
               settingNoBodies = false;
               #ifdef DEBUG_SET
                  MessageInterface::ShowMessage(
                        "In SetStringParameter, settingNoBodies = false\n");
               #endif
         }
      }
      // ... or, replace current name
      else
      {
         shadowBodyNames.at(index) = GmatStringUtil::Trim(value);
         settingNoBodies = false;
         #ifdef DEBUG_SET
            MessageInterface::ShowMessage(
                  "In SetStringParameter, settingNoBodies = false (2)\n");
         #endif
      }
      return true;
   }

   return PowerSystem::SetStringParameter(id, value, index);
}
Ejemplo n.º 11
0
//---------------------------------------------------------------------------
Real ElectricThruster::CalculateMassFlow()
{
   #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
      MessageInterface::ShowMessage(
            "Entering ElectricThruster::CalculateMassFlow, power = %12.10f, minUsablePower = %12.10f\n",
            power, minUsablePower);
   #endif
   powerToUse = power; // power was set by FiniteBurn
   if (!thrusterFiring)
   {
      #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
         MessageInterface::ShowMessage("ElectricThruster %s is not firing\n",
               instanceName.c_str());
      #endif

      return 0.0;
   }
   else
   {
      if (tanks.empty())
         throw HardwareException("ElectricThruster \"" + instanceName +
                                 "\" does not have a fuel tank");

      if (powerToUse < minUsablePower)
      {
         #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
            MessageInterface::ShowMessage("RETURNING zero!!!!\n");
         #endif
         mDot   = 0.0;
         thrust = 0.0;
         return 0.0;
      }

      if (powerToUse > maxUsablePower)
         powerToUse = maxUsablePower;

      powerToUse2 = powerToUse  * powerToUse;
      powerToUse3 = powerToUse2 * powerToUse;
      powerToUse4 = powerToUse3 * powerToUse;

      #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
         MessageInterface::ShowMessage("power = %12.10f, powerToUse = %12.10f\n",
               power, powerToUse);
      #endif

      // For now, always calculate T and I_sp
      if (!CalculateThrustAndIsp())
         throw HardwareException("ElectricThruster \"" + instanceName +
                                 "\" could not calculate dm/dt");

      if (thrustModel == "ThrustMassPolynomial")
      {
         mDot = ((massFlowCoeff[4] * powerToUse4) +
                 (massFlowCoeff[3] * powerToUse3) +
                 (massFlowCoeff[2] * powerToUse2) +
                 (massFlowCoeff[1] * powerToUse) +
                  massFlowCoeff[0]) / 1.0e6;
      }
      else if (thrustModel == "ConstantThrustAndIsp")
      {
         mDot = constantThrust  / (isp * gravityAccel); // do I need to divide by 1.0e-3 here?  or put the 0.001 * in there?
      }
      else // "FixedEfficiency"
      {
         Real ispG  = (isp * gravityAccel * 0.001);
         Real ispG2 =  ispG * ispG;
         mDot = (2.0 * efficiency * powerToUse * 0.001) / ispG2;
      }

//         if (impulse == 0.0)
//            throw HardwareException("ElectricThruster \"" + instanceName +
//                                    "\" has specific impulse == 0.0");
   }

   #ifdef DEBUG_MASS_FLOW_THRUST_VECTOR
      MessageInterface::ShowMessage(
            "   Thrust = %15.10f, Isp = %15.10f, gravity accel = %12.10f, TSF = %12.10f, "
            "dutyCycle = %15.10f, MassFlow = %15.10f T/Isp =  %12.10f\n",
            thrust, impulse, gravityAccel, thrustScaleFactor, dutyCycle, mDot,
            thrust/impulse);
   #endif

   return mDot * -dutyCycle;  // Flow rate should be negative in ODEs - CORRECT?
}
Ejemplo n.º 12
0
//------------------------------------------------------------------------------
Real ElectricThruster::SetRealParameter(const Integer id, const Real value)
{
   #ifdef DEBUG_ELECTRIC_THRUSTER_SET
   MessageInterface::ShowMessage
      ("ElectricThruster::SetRealParameter() '%s' entered, id=%d, value=%f\n",
       GetName().c_str(), id, value);
   #endif

   switch (id)
   {
      case MAXIMUM_USABLE_POWER:
         if (value <= 0.0)
         {
            std::stringstream ss("");
            ss << value;
            std::string errmsg =
               "The value of \"" + ss.str() + "\" for field \"MaximumUsablePower\""
               " on object \"" + instanceName + "\" is not an allowed value.\n"
               "The allowed values are: [Real number > 0]. ";
            throw HardwareException(errmsg);
         }
         return maxUsablePower = value;
      case MINIMUM_USABLE_POWER:
         if (value <= 0.0)
         {
            std::stringstream ss("");
            ss << value;
            std::string errmsg =
               "The value of \"" + ss.str() + "\" for field \"MinimumUsablePower\""
               " on object \"" + instanceName + "\" is not an allowed value.\n"
               "The allowed values are: [Real number > 0]. ";
            throw HardwareException(errmsg);
         }
         return minUsablePower   = value;
      case THRUST_COEFF1:
         return thrustCoeff[0]   = value;
      case THRUST_COEFF2:
         return thrustCoeff[1]   = value;
      case THRUST_COEFF3:
         return thrustCoeff[2]   = value;
      case THRUST_COEFF4:
         return thrustCoeff[3]   = value;
      case THRUST_COEFF5:
         return thrustCoeff[4]   = value;
      case MASS_FLOW_COEFF1:
         return massFlowCoeff[0] = value;
      case MASS_FLOW_COEFF2:
         return massFlowCoeff[1] = value;
      case MASS_FLOW_COEFF3:
         return massFlowCoeff[2] = value;
      case MASS_FLOW_COEFF4:
         return massFlowCoeff[3] = value;
      case MASS_FLOW_COEFF5:
         return massFlowCoeff[4] = value;
      case EFFICIENCY:
         return efficiency       = value;
      case ISP:
         return isp              = value;
      case CONSTANT_THRUST:
         return constantThrust   = value;

      default:
         break;   // Default just drops through
   }

   return Thruster::SetRealParameter(id, value);
}