The complete code description of the generic ElectricalPowerSystem
is shown below. It shows all the basic structural components used to create a custom component.
namespace D2S2.Model.Satellite
{
public class ElectricalPowerSystem : SatellitePhysicalComponent, IInitialisable
{
private double powerIn = 0.0;
private double powerOut = 0.0;
private double currentBatteryPower = 0.0;
private double initialBatteryPower = 0.0;
private double maximumPowerStorage = 22.5;
private double powUsage = 0;
// ---------- array properties for dependent object binding --------------
private ModelList<D2S2.Model.Satellite.SolarPanel> solarPanels;
private ModelList<D2S2.Model.Satellite.SatelliteElectricalComponent> consumers;
[ModelDependency(DependencyType.Link, false)]
[Description("List of all power generating components")]
public ModelList<D2S2.Model.Satellite.SolarPanel> SolarPanels { get { return solarPanels; } }
[ModelDependency(DependencyType.Link, false)]
[Description("List of all power consuming components")]
public ModelList<D2S2.Model.Satellite.SatelliteElectricalComponent> PowerConsumers { get { return consumers; } }
// ------------- read-only properties for exposing model state -----------------
[ModelValue(ModelValueType.State)]
[DisplayName("Generated Power")]
[Description("Total power generated [W]")]
[Category("Measurement")]
public UDouble<W> PowerInUnit { get { return new UDouble<W>(powerIn); } }
[ModelValue(ModelValueType.State)]
[DisplayName("Consumed Power")]
[Description("Total power consumption [W]")]
[Category("Measurement")]
public UDouble<W> PowerOutUnit { get { return new UDouble<W>(powerOut); } }
[ModelValue(ModelValueType.State)]
[DisplayName("Battery Capacity")]
[Description("Current capacity of the battery [W.hr]")]
[Category("Measurement")]
public UDouble<Whr> CurrentBatteryPower { get { return new UDouble<Whr>(currentBatteryPower); } }
// ------------- adjustable/input properties -----------------
[ModelValue(ModelValueType.Initial)]
[DisplayName("Maximum Energy Storage")]
[Category("Battery Settings")]
[Description("Maximum energy storage capacity of batteries [W.hr]")]
public double MaximumPowerStorage
{
get
{
return maximumPowerStorage;
}
set
{
maximumPowerStorage = value;
OnPropertyValueChanged(GetProperty((ElectricalPowerSystem m) => m.MaximumPowerStorage));
}
}
[ModelValue(ModelValueType.Initial)]
[DisplayName("Initial Battery Energy")]
[Category("Battery Settings")]
[Description("Initial energy stored in batteries [W.hr]")]
public double InitialPowerStorage
{
get
{
return initialBatteryPower;
}
set
{
initialBatteryPower = value;
OnPropertyValueChanged(GetProperty((ElectricalPowerSystem m) => m.InitialPowerStorage));
}
}
[ModelValue(ModelValueType.Initial)]
[Category("Parameters")]
[DisplayName("Power Usage")]
[Description("Power usage [W]")]
public double PowerUsage
{
get
{
return powUsage;
}
set
{
powUsage = value;
OnPropertyValueChanged(GetProperty((ElectricalPowerSystem m) => m.PowerUsage));
}
}
public ElectricalPowerSystem()
{
solarPanels = new ModelList<SolarPanel>(OnLinkDependencyChanged, GetProperty((ElectricalPowerSystem m) => m.SolarPanels));
consumers = new ModelList<SatelliteElectricalComponent>(OnLinkDependencyChanged, GetProperty((ElectricalPowerSystem m) => m.PowerConsumers));
}
public void Initialise(DateTime time)
{
currentBatteryPower = initialBatteryPower;
if (currentBatteryPower > maximumPowerStorage)
currentBatteryPower = maximumPowerStorage;
powerIn = 0;
powerOut = 0;
}
public override Vector3d GetForce(SatelliteEnvironmentState environment)
{
return Vector3d.Zero;
}
public override Vector3d GetTorque(SatelliteEnvironmentState environment)
{
return Vector3d.Zero;
}
public override void UpdateEnvironment(DateTime time, SatelliteEnvironmentState environment, SatelliteKinematicState state, SurfaceModel surfaceModel)
{
base.UpdateEnvironment(time, environment, state, surfaceModel);
// if satellite is in sunlit part of orbit query the current power generated by all connected solar panels
if (!environment.SunLit)
{
powerIn = 0;
}
else
{
powerIn = 0;
for (int i = 0; i < SolarPanels.Count; i++)
{
powerIn += SolarPanels[i].GetPowerGenerated();
}
}
// power consumption of EPS itself
powerOut = PowerUsage;
// Go through all satellite components and request their power usage (have a list of all power consumers, electrical satellite components)
for (int i = 0; i < PowerConsumers.Count; i++)
{
powerOut += PowerConsumers[i].GetPowerConsumption();
}
}
public override void UpdateEnd(TimeSpan timeDelta)
{
base.UpdateEnd(timeDelta);
// Simplified battery model, simply determine the maximum power density, use simple integration
currentBatteryPower += timeDelta.TotalHours * (powerIn - powerOut);
// Set battery storage limits
if (currentBatteryPower > maximumPowerStorage)
{
currentBatteryPower = maximumPowerStorage;
}
else if (currentBatteryPower < 0)
{
currentBatteryPower = 0;
}
}
}
}