Skip to content

Commit

Permalink
Merge pull request #182 from aidotse/allow-custom-meshes
Browse files Browse the repository at this point in the history
Allow custom meshes & rotations
  • Loading branch information
gomezzz committed Aug 11, 2023
2 parents 74baf61 + ffc64b3 commit 61d0610
Show file tree
Hide file tree
Showing 30 changed files with 966 additions and 281 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,4 @@ thermal_test.csv
results
pytest-coverage.txt
pytest.xml
examples/Orekit_example/orekit-data.zip
examples/Orekit_example/orekit-data.zip
122 changes: 100 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Disclaimer: This project is currently under development. Use at your own risk.
<li><a href="#thermal-modelling">Thermal Modelling</a></li>
<li><a href="#radiation-modelling">Radiation Modelling</a></li>
<li><a href="#custom-modelling">Custom Modelling</a></li>
<li><a href="#simulation-settings">Custom Central Bodies</a></li>
</ul>
<li><a href="#simulation-settings">Simulation Settings</a></li>
<ul>
Expand Down Expand Up @@ -501,6 +502,83 @@ ActorBuilder.add_custom_property(
print(local_actor.get_custom_property("altitude"))
```

#### Custom Central Bodies

In most examples here you will see Earth via the pykep API being used as a spherical, central body for Keplerian orbits. For Keplerian orbits around spherical bodies, you can simply use pykep with an type of [pykep planet](https://esa.github.io/pykep/documentation/planets.html) just as the above examples used Earth. E.g.

```py
import pykep as pk
from paseos import ActorBuilder, SpacecraftActor
# Define an actor of type SpacecraftActor of name mySat
sat_actor = ActorBuilder.get_actor_scaffold(name="mySat",
actor_type=SpacecraftActor,
epoch=pk.epoch(0))

# Define the central body as Mars by using pykep APIs.
mars = pk.planet.jpl_lp("mars")

# Let's set the orbit of sat_actor.
ActorBuilder.set_orbit(actor=sat_actor,
position=[10000000, 1, 1],
velocity=[1, 1000.0, 1],
epoch=pk.epoch(0),
central_body=mars)
```

However, you can also use any other central body defined via a mesh. This is especially useful in conjunction with [custom propagators](#custom-propagators). To use a custom central body, you need to define a mesh and add it to the simulation configuration. The following example shows how to do this for the comet 67P/Churyumov–Gerasimenko.

We assume `polyhedral_propagator` to be a custom propagator as explained in [Custom Propagators](#custom-propagators).

To correctly compute eclipses, we also need to know the orbit of the custom central body around the Sun. In this case we use the [orbital elements](https://en.wikipedia.org/wiki/Orbital_elements) one [can find online for 67P/Churyumov–Gerasimenko](https://en.wikipedia.org/wiki/67P/Churyumov–Gerasimenko).

```py
import pykep as pk
from paseos import ActorBuilder, SpacecraftActor

# Define the epoch and orbital elements
epoch = pk.epoch(2460000.5, "jd")
elements = (3.457 * pk.AU, 0.64989, 3.8719 * pk.DEG2RAD, 36.33 * pk.DEG2RAD, 22.15 * pk.DEG2RAD, 73.57 * pk.DEG2RAD)

# Create a planet object from pykep for 67P
comet = pk.planet.keplerian(epoch, elements, pk.MU_SUN, 666.19868, 2000, 2000, "67P")

# Load the 67P mesh with pickle
with open(mesh_path, "rb") as f:
mesh_points, mesh_triangles = pickle.load(f)
mesh_points = np.array(mesh_points)
mesh_triangles = np.array(mesh_triangles)

# Define local actor
my_sat = ActorBuilder.get_actor_scaffold("my_sat", SpacecraftActor, epoch=epoch)

# Set the custom propagator
ActorBuilder.set_custom_orbit(my_sat, polyhedral_propagator, epoch)

# Set the mesh
ActorBuilder.set_central_body(my_sat, comet, (mesh_points, mesh_triangles))

# Below computations will now use the mesh instead spherical approximations
print(my_sat.is_in_eclipse())
print(my_sat.is_in_line_of_sight(some_other_actor))

# You could even specify a rotation of the central body.
# Set a rotation period of 1 second around the z axis
ActorBuilder.set_central_body(
my_sat,
comet,
(mesh_points, mesh_triangles),
rotation_declination=90,
rotation_right_ascension=0,
rotation_period=1,
)

```

This is particularly useful if you want to use a central body that is not included in pykep or if you want to use a central body that is not a planet (e.g. an asteroid).

N.B. `get_altitude` computes the altitude above [0,0,0] in the central body's frame, thus is not affected by the central body's rotation or mesh.
N.B. #2 Any custom central body still has to orbit the Sun for PASEOS to function correctly.

### Simulation Settings

#### Initializing PASEOS
Expand Down Expand Up @@ -1076,28 +1154,28 @@ print(local_actor.get_custom_property("channel_bandwidth"))

Description of the physical model parameters and default values in PASEOS with indications on sensitivity of parameters and suggested ranges.

| Name | Datatype | Description | Default | Suggested Range | Sensitivity |
|:---------------------------------:|:--------:|:---------------------------------------------------------------------------:|:----------:|:---------------:|:-----------:|
| Battery Level [Ws] | float | Current battery level | - | > 0 | high |
| Maximum Battery Level [Ws] | float | Maximum battery level | - | > 0 | high |
| Charging Rate [W] | float | Charging rate of the battery | - | > 0 | high |
| Power Device Type | enum | Type of power device. Can be either "SolarPanel" or "RTG" | SolarPanel | - | medium |
| Data Corruption Events [Hz] | float | Rate of single bit of data being corrupted, i.e. a Single Event Upset (SEU) | - | >= 0 | low |
| Restart Events [Hz] | float | Rate of device restart being triggered | - | >= 0 | medium |
| Failure Events [Hz] | float | Rate of complete device failure due to a Single Event Latch-Up (SEL) | - | >= 0 | high |
| Mass [kg] | float | Actor's mass | - | > 0 | low |
| Initial Temperature [K] | float | Actor's initial temperature | - | >= 0 | medium |
| Sun Absorptance | float | Actor's absorptance of solar light | - | [0,1] | high |
| Infrared Absorptance | float | Actor's absportance of infrared light | - | [0,1] | medium |
| Sun-Facing Area [$m^2$] | float | Actor's area facing the sun | - | >= 0 | high |
| Central Body-Facing Area [$m^2$] | float | Actor's area facing central body | - | >= 0 | medium |
| Emissive Area [$m^2$] | float | Actor's area emitting (radiating) heat | - | >= 0 | high |
| Thermal Capacity [$J / (kg * K)$] | float | Actor's thermal capacity | - | >= 0 | low |
| Body Solar Irradiance [W] | float | Irradiance from the sun | 1360 | >= 0 | medium |
| Body Surface Temperature [K] | float | Central body surface temperature | 288 | >= 0 | low |
| Body Emissivity | float | Central body emissivity in infrared | 0.6 | [0,1] | medium |
| Body Reflectance | float | Central body reflectance of sunlight | 0.3 | [0,1] | medium |
| Heat Conversion Ratio [-] | float | Conversion ratio for activities, 0 leads to know heat-up due to activity | 0.5 | [0,1] | high |
| Name | Datatype | Description | Default | Suggested Range | Sensitivity |
| :-------------------------------: | :------: | :-------------------------------------------------------------------------: | :--------: | :-------------: | :---------: |
| Battery Level [Ws] | float | Current battery level | - | > 0 | high |
| Maximum Battery Level [Ws] | float | Maximum battery level | - | > 0 | high |
| Charging Rate [W] | float | Charging rate of the battery | - | > 0 | high |
| Power Device Type | enum | Type of power device. Can be either "SolarPanel" or "RTG" | SolarPanel | - | medium |
| Data Corruption Events [Hz] | float | Rate of single bit of data being corrupted, i.e. a Single Event Upset (SEU) | - | >= 0 | low |
| Restart Events [Hz] | float | Rate of device restart being triggered | - | >= 0 | medium |
| Failure Events [Hz] | float | Rate of complete device failure due to a Single Event Latch-Up (SEL) | - | >= 0 | high |
| Mass [kg] | float | Actor's mass | - | > 0 | low |
| Initial Temperature [K] | float | Actor's initial temperature | - | >= 0 | medium |
| Sun Absorptance | float | Actor's absorptance of solar light | - | [0,1] | high |
| Infrared Absorptance | float | Actor's absportance of infrared light | - | [0,1] | medium |
| Sun-Facing Area [$m^2$] | float | Actor's area facing the sun | - | >= 0 | high |
| Central Body-Facing Area [$m^2$] | float | Actor's area facing central body | - | >= 0 | medium |
| Emissive Area [$m^2$] | float | Actor's area emitting (radiating) heat | - | >= 0 | high |
| Thermal Capacity [$J / (kg * K)$] | float | Actor's thermal capacity | - | >= 0 | low |
| Body Solar Irradiance [W] | float | Irradiance from the sun | 1360 | >= 0 | medium |
| Body Surface Temperature [K] | float | Central body surface temperature | 288 | >= 0 | low |
| Body Emissivity | float | Central body emissivity in infrared | 0.6 | [0,1] | medium |
| Body Reflectance | float | Central body reflectance of sunlight | 0.3 | [0,1] | medium |
| Heat Conversion Ratio [-] | float | Conversion ratio for activities, 0 leads to know heat-up due to activity | 0.5 | [0,1] | high |


## Contributing
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
- numpy==1.23.5 # core non-optional depedency
- myst-parser # for markdown math in docs
- pykep>=2.6 # core non-optional dependency
- pyquaternion>=0.9.9 # core non-optional dependency
- pytest # for tests
- pytest-asyncio # for tests involving activities
- python>=3.8 # core non-optional dependency
Expand Down
4 changes: 4 additions & 0 deletions paseos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
from .actors.actor_builder import ActorBuilder
from .actors.ground_station_actor import GroundstationActor
from .actors.spacecraft_actor import SpacecraftActor
from .central_body.central_body import CentralBody
from .communication.get_communication_window import get_communication_window
from .communication.find_next_window import find_next_window
from .power.power_device_type import PowerDeviceType
from .utils.reference_frame import ReferenceFrame
from .utils.set_log_level import set_log_level
from .visualization.plot import plot, PlotType

Expand Down Expand Up @@ -56,6 +58,7 @@ def init_sim(local_actor: BaseActor, cfg: DotMap = None, starting_epoch: pk.epoc
__all__ = [
"ActorBuilder",
"BaseActor",
"CentralBody",
"find_next_window",
"get_communication_window",
"GroundstationActor",
Expand All @@ -64,6 +67,7 @@ def init_sim(local_actor: BaseActor, cfg: DotMap = None, starting_epoch: pk.epoc
"plot",
"PlotType",
"PowerDeviceType",
"ReferenceFrame",
"set_log_level",
"SpacecraftActor",
]
Loading

0 comments on commit 61d0610

Please sign in to comment.