Skip to main content
The power system in Basilisk is built around a node-and-storage pattern. Power nodes (solar panels, sinks, reaction wheel loads, antenna loads) each write a PowerNodeUsageMsgPayload that one or more power storage nodes (batteries, monitors) accumulate.
See the scenarioPowerDemo example for a complete worked power system using a solar panel, battery, and power sink.

Power generation

Models power generation from a solar panel using a cosine-law illumination model. The module computes output power as:
W_out = W_base * C_eclipse * C_panel * (nHat · sHat) * A_panel
where W_base is the solar irradiance at the spacecraft location, C_eclipse is the eclipse factor (0–1), C_panel is the panel efficiency, nHat is the panel normal in body frame, sHat is the spacecraft–sun unit vector, and A_panel is the panel area.Messages
MessageTypeDirectionDescription
sunInMsgSpicePlanetStateMsgPayloadInputSun position
stateInMsgSCStatesMsgPayloadInputSpacecraft position and attitude
sunEclipseInMsgEclipseMsgPayloadInput (optional)Eclipse illumination factor
nodePowerOutMsgPowerNodeUsageMsgPayloadOutputGenerated power
from Basilisk.simulation import simpleSolarPanel

panel = simpleSolarPanel.SimpleSolarPanel()
panel.ModelTag = 'solarPanel'
panel.setPanelParameters(
    [0.0, 0.0, 1.0],  # nHat_B — panel normal in body frame
    2.0,              # panelArea [m^2]
    0.20              # panelEfficiency [-]
)
panel.sunInMsg.subscribeTo(sunMsg)
panel.stateInMsg.subscribeTo(scObject.scStateOutMsg)
panel.sunEclipseInMsg.subscribeTo(eclipseObject.eclipseOutMsgs[0])

battery.addPowerNodeToModel(panel.nodePowerOutMsg)
sim.AddModelToTask(taskName, panel)

Power storage

A minimal battery model that integrates net power input using Euler integration:
W_stored += W_net * (t_current - t_previous)
The total stored energy is clamped to storageCapacity. Supports an optional fault message that reduces the effective capacity.Key parameters
ParameterDescription
storageCapacityMaximum energy storage [J]
storedCharge_InitInitial charge [J]
from Basilisk.simulation import simpleBattery
from Basilisk.architecture import messaging

battery = simpleBattery.SimpleBattery()
battery.ModelTag = 'batteryModel'
battery.storageCapacity = 10.0  # [J] or [W*s]
battery.storedCharge_Init = 5.0 # [J] start at 50%

# Attach power nodes
battery.addPowerNodeToModel(panel.nodePowerOutMsg)
battery.addPowerNodeToModel(load.nodePowerOutMsg)

sim.AddModelToTask(taskName, battery)

# Optional: simulate a degraded battery
faultMsg = messaging.PowerStorageFaultMsgPayload()
faultMsg.faultCapacityRatio = 0.3  # 30% of nominal capacity
faultStatusMsg = messaging.PowerStorageFaultMsg().write(faultMsg)
battery.batteryFaultInMsg.subscribeTo(faultStatusMsg)
A power storage node that tracks net power flow without a storage capacity limit. Use this module to monitor total power balance across a subsystem without modelling battery state of charge.

Power loads

A constant-power load node. Connect it to a battery or monitor to account for baseline power draw from avionics, heaters, or any other fixed-consumption device.The device can be switched on or off via an optional DeviceStatusMsgPayload input message.
from Basilisk.simulation import simplePowerSink

sink = simplePowerSink.SimplePowerSink()
sink.ModelTag = 'avionics'
sink.nodePowerOut = -10.0  # [W] negative = power drawn from bus

battery.addPowerNodeToModel(sink.nodePowerOutMsg)
sim.AddModelToTask(taskName, sink)
Computes the electrical power consumed by a single reaction wheel. The power model accounts for a constant base power draw plus the mechanical power needed to change wheel speed.Two efficiency parameters govern the model:
  • elecToMechEfficiency (η_e2m): efficiency converting electrical to mechanical power when accelerating the wheel.
  • mechToElecEfficiency (η_m2e): fraction of mechanical energy recovered when braking. Set to 0 if no energy recovery.
Messages
MessageTypeDirectionDescription
rwStateInMsgRWConfigLogMsgPayloadInputRW wheel speed and motor torque
nodePowerOutMsgPowerNodeUsageMsgPayloadOutputRW power draw
from Basilisk.simulation import ReactionWheelPower

rwPower = ReactionWheelPower.ReactionWheelPower()
rwPower.ModelTag = 'rwPower_0'
rwPower.basePowerNeed = 10.0         # [W] baseline power when on
rwPower.elecToMechEfficiency = 0.9   # 90% electrical-to-mechanical
rwPower.mechToElecEfficiency = 0.0   # no energy recovery during braking
rwPower.rwStateInMsg.subscribeTo(rwStateEffector.rwOutMsgs[0])

battery.addPowerNodeToModel(rwPower.nodePowerOutMsg)
sim.AddModelToTask(taskName, rwPower)
Computes the electrical power draw of an antenna based on its operational state. Power draw depends on whether the antenna is in ANTENNA_OFF, ANTENNA_RX, ANTENNA_TX, or ANTENNA_RXTX mode.Messages
MessageTypeDirectionDescription
antennaSetStateInMsgAntennaLogMsgPayloadInputAntenna state including Tx and Rx power
nodePowerOutMsgPowerNodeUsageMsgPayloadOutputAntenna power draw
from Basilisk.simulation import antennaPower

antPower = antennaPower.AntennaPower()
antPower.ModelTag = 'antennaPower'
antPower.basePowerNeed = 5.0  # [W] base power when on
antPower.antennaSetStateInMsg.subscribeTo(antenna.antennaOutMsg)

battery.addPowerNodeToModel(antPower.nodePowerOutMsg)
sim.AddModelToTask(taskName, antPower)

Build docs developers (and LLMs) love