Skip to content

Commit 87544ef

Browse files
committed
[#156] Separate atmospheric dynamics models
1 parent 42584ef commit 87544ef

File tree

2 files changed

+87
-54
lines changed

2 files changed

+87
-54
lines changed

src/bsk_rl/sim/dyn/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@
3939
from deprecated import deprecated
4040

4141
from bsk_rl.sim.dyn.base import (
42+
AtmosphericDragDynModel,
4243
BaseDynamicsModel,
4344
BasicDynamicsModel,
45+
DisturbanceTorqueDynModel,
4446
DynamicsModel,
4547
EclipseDynModel,
4648
)
@@ -74,6 +76,8 @@ def __init__(self, *args, **kwargs) -> None:
7476
"BaseDynamicsModel",
7577
"BasicDynamicsModel",
7678
"EclipseDynModel",
79+
"DisturbanceTorqueDynModel",
80+
"AtmosphericDragDynModel",
7781
"LOSCommDynModel",
7882
"ImagingDynModel",
7983
"ContinuousImagingDynModel",

src/bsk_rl/sim/dyn/base.py

Lines changed: 83 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -395,67 +395,16 @@ def setup_eclipse_object(self) -> None:
395395
self.eclipse_index = len(self.world.eclipseObject.eclipseOutMsgs) - 1
396396

397397

398-
class BasicDynamicsModel(EclipseDynModel, BaseDynamicsModel):
399-
"""Basic Dynamics model with minimum necessary Basilisk components."""
398+
class DisturbanceTorqueDynModel(BaseDynamicsModel):
399+
"""Dynamics model with constant disturbance torque."""
400400

401401
def __init__(self, *args, **kwargs) -> None:
402-
"""A dynamics model with a basic feature set.
403-
404-
Includes the following:
405-
406-
* Spacecraft hub physical properties
407-
* Gravity
408-
* Constant disturbance torque (defaults to none)
409-
* Aerodynamic drag
410-
* Eclipse checking for power generation
411-
* Reaction wheels
412-
* Momentum desaturation thrusters
413-
* Solar panels, battery, and power system
414-
415-
Args:
416-
*args: Passed to superclass
417-
**kwargs: Passed to superclass
418-
"""
402+
"""Dynamics model with constant disturbance torque."""
419403
super().__init__(*args, **kwargs)
420404

421-
@classmethod
422-
def _requires_world(cls) -> list[type["WorldModel"]]:
423-
return [
424-
world.AtmosphereWorldModel,
425-
] + super()._requires_world()
426-
427-
@property
428-
def battery_charge(self):
429-
"""Battery charge [W*s]."""
430-
return self.powerMonitor.batPowerOutMsg.read().storageLevel
431-
432-
@property
433-
def battery_charge_fraction(self):
434-
"""Battery charge as a fraction of capacity."""
435-
return self.battery_charge / self.powerMonitor.storageCapacity
436-
437-
@property
438-
def wheel_speeds(self):
439-
"""Wheel speeds [rad/s]."""
440-
return np.array(self.rwStateEffector.rwSpeedOutMsg.read().wheelSpeeds)[0:3]
441-
442-
@property
443-
def wheel_speeds_fraction(self):
444-
"""Wheel speeds normalized by maximum allowable speed."""
445-
return self.wheel_speeds / (self.maxWheelSpeed * macros.rpm2radsec)
446-
447405
def _setup_dynamics_objects(self, **kwargs) -> None:
448406
super()._setup_dynamics_objects(**kwargs)
449407
self.setup_disturbance_torque(**kwargs)
450-
self.setup_density_model()
451-
self.setup_drag_effector(**kwargs)
452-
self.setup_reaction_wheel_dyn_effector(**kwargs)
453-
self.setup_thruster_dyn_effector()
454-
self.setup_solar_panel(**kwargs)
455-
self.setup_battery(**kwargs)
456-
self.setup_power_sink(**kwargs)
457-
self.setup_reaction_wheel_power(**kwargs)
458-
self.setup_thruster_power(**kwargs)
459408

460409
@default_args(disturbance_vector=None)
461410
def setup_disturbance_torque(
@@ -474,6 +423,25 @@ def setup_disturbance_torque(
474423
self.extForceTorqueObject.extTorquePntB_B = disturbance_vector
475424
self.scObject.addDynamicEffector(self.extForceTorqueObject)
476425

426+
427+
class AtmosphericDragDynModel(BaseDynamicsModel):
428+
"""Dynamics model with atmospheric drag."""
429+
430+
def __init__(self, *args, **kwargs) -> None:
431+
"""Dynamics model with atmospheric drag."""
432+
super().__init__(*args, **kwargs)
433+
434+
@classmethod
435+
def _requires_world(cls) -> list[type["WorldModel"]]:
436+
return [
437+
world.AtmosphereWorldModel,
438+
] + super()._requires_world()
439+
440+
def _setup_dynamics_objects(self, **kwargs) -> None:
441+
super()._setup_dynamics_objects(**kwargs)
442+
self.setup_density_model()
443+
self.setup_drag_effector(**kwargs)
444+
477445
def setup_density_model(self) -> None:
478446
"""Set up the atmospheric density model effector."""
479447
self.world.densityModel.addSpacecraftToModel(self.scObject.scStateOutMsg)
@@ -547,6 +515,64 @@ def setup_drag_effector(
547515
self.task_name, self.dragEffector, ModelPriority=priority
548516
)
549517

518+
519+
class BasicDynamicsModel(EclipseDynModel, DisturbanceTorqueDynModel, BaseDynamicsModel):
520+
"""Basic Dynamics model with minimum necessary Basilisk components."""
521+
522+
def __init__(self, *args, **kwargs) -> None:
523+
"""A dynamics model with a basic feature set.
524+
525+
Includes the following:
526+
527+
* Spacecraft hub physical properties
528+
* Gravity
529+
* Constant disturbance torque (defaults to none)
530+
* Aerodynamic drag
531+
* Eclipse checking for power generation
532+
* Reaction wheels
533+
* Momentum desaturation thrusters
534+
* Solar panels, battery, and power system
535+
536+
Args:
537+
*args: Passed to superclass
538+
**kwargs: Passed to superclass
539+
"""
540+
super().__init__(*args, **kwargs)
541+
542+
@classmethod
543+
def _requires_world(cls) -> list[type["WorldModel"]]:
544+
return super()._requires_world()
545+
546+
@property
547+
def battery_charge(self):
548+
"""Battery charge [W*s]."""
549+
return self.powerMonitor.batPowerOutMsg.read().storageLevel
550+
551+
@property
552+
def battery_charge_fraction(self):
553+
"""Battery charge as a fraction of capacity."""
554+
return self.battery_charge / self.powerMonitor.storageCapacity
555+
556+
@property
557+
def wheel_speeds(self):
558+
"""Wheel speeds [rad/s]."""
559+
return np.array(self.rwStateEffector.rwSpeedOutMsg.read().wheelSpeeds)[0:3]
560+
561+
@property
562+
def wheel_speeds_fraction(self):
563+
"""Wheel speeds normalized by maximum allowable speed."""
564+
return self.wheel_speeds / (self.maxWheelSpeed * macros.rpm2radsec)
565+
566+
def _setup_dynamics_objects(self, **kwargs) -> None:
567+
super()._setup_dynamics_objects(**kwargs)
568+
self.setup_reaction_wheel_dyn_effector(**kwargs)
569+
self.setup_thruster_dyn_effector()
570+
self.setup_solar_panel(**kwargs)
571+
self.setup_battery(**kwargs)
572+
self.setup_power_sink(**kwargs)
573+
self.setup_reaction_wheel_power(**kwargs)
574+
self.setup_thruster_power(**kwargs)
575+
550576
@default_args(
551577
wheelSpeeds=lambda: np.random.uniform(-1500, 1500, 3),
552578
maxWheelSpeed=np.inf,
@@ -779,4 +805,7 @@ def setup_reaction_wheel_power(
779805
"DynamicsModel",
780806
"BaseDynamicsModel",
781807
"BasicDynamicsModel",
808+
"EclipseDynModel",
809+
"DisturbanceTorqueDynModel",
810+
"AtmosphericDragDynModel",
782811
]

0 commit comments

Comments
 (0)