Skip to content

Commit

Permalink
Merge pull request #195 from aidotse/geometric_model
Browse files Browse the repository at this point in the history
Creating Geometric Model
  • Loading branch information
GabrieleMeoni committed Jan 12, 2024
2 parents e5bb071 + 199040d commit c7a9030
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 1 deletion.
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dependencies:
- sphinx_rtd_theme # for docs
- toml>=0.10.2 # core non-optional dependency
- tqdm>=4.64.1 # core non-optional dependency
- trimesh>=4.0.7 # for geometric model
29 changes: 29 additions & 0 deletions paseos/actors/actor_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from ..thermal.thermal_model import ThermalModel
from ..power.power_device_type import PowerDeviceType
from ..radiation.radiation_model import RadiationModel
from paseos.geometric_model.geometric_model import GeometricModel


class ActorBuilder:
Expand Down Expand Up @@ -305,6 +306,34 @@ def set_position(actor: BaseActor, position: list):
actor._position = position
logger.debug(f"Setting position {position} on actor {actor}")

@staticmethod
def set_geometric_model(
actor: SpacecraftActor, mass: float, vertices=None, faces=None, scale: float = 1
):
"""Define geometry of the spacecraft actor. This is done in the spacecraft body reference frame, and can be
transformed to the inertial/PASEOS reference frame using the reference frane transformations in the attitude
model. When used in the attitude model, the geometric model is in the body reference frame.
Args:
actor (SpacecraftActor): Actor to update.
mass (float): Mass of the spacecraft in kg.
vertices (list): List of all vertices of the mesh in terms of distance (in m) from origin of body frame.
Coordinates of the corners of the object. If not selected, it will default to a cube that can be scaled.
by the scale. Uses Trimesh to create the mesh from this and the list of faces.
faces (list): List of the indexes of the vertices of a face. This builds the faces of the satellite by
defining the three vertices to form a triangular face. For a cuboid each face is split into two
triangles. Uses Trimesh to create the mesh from this and the list of vertices.
scale (float): Parameter to scale the cuboid by, defaults to 1.
"""
assert mass > 0, "Mass is > 0"

actor._mass = mass
geometric_model = GeometricModel(
local_actor=actor, actor_mass=mass, vertices=vertices, faces=faces, scale=scale
)
actor._mesh = geometric_model.set_mesh()
actor._moment_of_inertia = geometric_model.find_moment_of_inertia

@staticmethod
def set_power_devices(
actor: SpacecraftActor,
Expand Down
102 changes: 102 additions & 0 deletions paseos/geometric_model/geometric_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from loguru import logger
import trimesh


class GeometricModel:
"""This model describes the geometry of the spacecraft
Currently it assumes the spacecraft to be a cuboid shape, with width, length and height
"""

_actor = None
_actor_mesh = None
_actor_center_of_gravity = None
_actor_moment_of_inertia = None

def __init__(self, local_actor, actor_mass, vertices=None, faces=None, scale=1) -> None:
"""Describes the geometry of the spacecraft and outputs relevant parameters related to the spacecraft body.
If no vertices or faces are provided, defaults to a cube with unit length sides. This is in the spacecraft body
reference frame and can be transformed to the inertial/PASEOS reference frame by using the transformations in the
attitude model.
Args:
local_actor (SpacecraftActor): Actor to model.
actor_mass (float): Actor's mass in kg.
vertices (list): List of all vertices of the mesh in terms of distance (in m) from origin of body frame.
Coordinates of the corners of the object. If not selected, it will default to a cube that can be scaled
by the scale. Uses Trimesh to create the mesh from this and the list of faces.
faces (list): List of the indexes of the vertices of a face. This builds the faces of the satellite by
defining the three vertices to form a triangular face. For a cuboid each face is split into two
triangles. Uses Trimesh to create the mesh from this and the list of vertices.
scale (float): Parameter to scale the cuboid by, defaults to 1.
"""
logger.trace("Initializing cuboid geometrical model.")

self._actor = local_actor
self._actor_mass = actor_mass
self.vertices = vertices
self.faces = faces
self.scale = scale

def set_mesh(self):
"""Creates the mesh of the satellite. If no vertices input is given, it defaults to a cuboid scaled by the
scale value. The default without scale values is a cube with 1m sides. This uses the python module Trimesh.
Returns:
mesh: Trimesh mesh of the satellite
"""
if self.vertices is None:
# Defines the corners of the mesh, values are in meters, from the origin of the body frame.
self.vertices = [
[-0.5, -0.5, -0.5],
[-0.5, -0.5, 0.5],
[-0.5, 0.5, -0.5],
[-0.5, 0.5, 0.5],
[0.5, -0.5, -0.5],
[0.5, -0.5, 0.5],
[0.5, 0.5, -0.5],
[0.5, 0.5, 0.5],
]
# List of three vertices to form a triangular face of the satellite.
# Two triangular faces are used per side of the cuboid.
self.faces = [
[0, 1, 3],
[0, 3, 2],
[0, 2, 6],
[0, 6, 4],
[1, 5, 3],
[3, 5, 7],
[2, 3, 7],
[2, 7, 6],
[4, 6, 7],
[4, 7, 5],
[0, 4, 1],
[1, 4, 5],
]

mesh = trimesh.Trimesh(self.vertices, self.faces)
# Scales the mesh by the scale factor.
self._actor_mesh = mesh.apply_scale(self.scale)
return self._actor_mesh

@property
def find_moment_of_inertia(self):
"""Gives the moment of inertia of the actor, assuming constant density.
Returns:
np.array: Mass moments of inertia for the actor
I is the moment of inertia, in the form of [[Ixx Ixy Ixz]
[Iyx Iyy Iyx]
[Izx Izy Izz]]
"""
self._actor_moment_of_inertia = self._actor_mesh.moment_inertia
return self._actor_moment_of_inertia

def find_center_of_gravity(self):
"""Gives the volumetric center of mass of the actor.
Returns:
np.array: Coordinates of the center of gravity of the mesh.
"""
self._actor_center_of_gravity = self._actor_mesh.center_mass
return self._actor_center_of_gravity
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ pyquaternion>=0.9.9
scikit-spatial>=6.5.0
skyfield>=1.45
toml>=0.10.2
tqdm>=4.64.1
tqdm>=4.64.1
trimesh>=4.0.7
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"skyfield>=1.45",
"toml>=0.10.2",
"tqdm>=4.64.1",
"trimesh>=4.0.7",
],
classifiers=[
"Development Status :: 3 - Alpha",
Expand Down

0 comments on commit c7a9030

Please sign in to comment.