Skip to content

Commit

Permalink
Preliminary Interplanetary Transfers (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
itchono authored Dec 30, 2022
1 parent 7732e52 commit 6c7e801
Show file tree
Hide file tree
Showing 46 changed files with 1,135 additions and 182 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,6 @@ dmypy.json

# VS Code
.vscode/

# Versioning from setuptools_scm
src/trajectorize/_version.py
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ KSP Trajectory Optimizer.
This project is a reduced-scope version of [one of my other (currently incomplete) projects](https://github.com/itchono/gravity-assist-flyby-optimizer), as an intermediate stepping stone.

This tool computes trajectories between celestial bodies in KSP based on on-rails two-body patched conics, incorporating trajectory correction maneuvers for a variety of mission scenarios, such as:

* Ballistic Hohmann transfers for other planets
* Gravity assist flyby routes

Computationally-intensive code is implemented in C, with a Python wrapper made using `cffi`.
C code follows mostly C89, with some C99 features used. It has been tested against the latest versions of GCC (on Linux) and MSVC (on Windows 10).

# Installation

The simplest way to install is from PyPI:

`pip install trajectorize`
Expand All @@ -35,18 +37,34 @@ The following platforms/compilers have been tested:
|Ubuntu 20.04 LTS (Dev Machine) | GCC 9.4.0 |

# Demos

Right now, full functionality is incomplete. There are, however, some cool demos showing off the capabilities of the package.

## Full Model of KSP Planetary System and Ephemerides

`python -m trajectorize.demos.kerbol_system_anim`

![Kerbol System Animation](https://raw.githubusercontent.com/itchono/trajectorize/assets/kerbol_system.gif)

## Calculation of Ballistic Interplanetary Transfers Using Lambert's Problem

`python -m trajectorize.demos.kerbin_duna_transfer`

![Transfer](https://raw.githubusercontent.com/itchono/trajectorize/assets/kerbin_duna_transfer.png)

## Propagation of Two-Body Trajectories Using Universal Keplerian Elements

`python -m trajectorize.demos.orbit`

![Orbit Demo](https://raw.githubusercontent.com/itchono/trajectorize/assets/orbit_universal.png)

## Calculations of Optimal Transfers, Porkchop Plots

`python -m trajectorize.demos.kerbin_duna_porkchop`

![Porkchop](https://raw.githubusercontent.com/itchono/trajectorize/assets/kerbin_duna_porkchop.png)

# Inspirations

* [Interactive illustrated interplanetary guide and calculator for KSP](https://ksp.olex.biz/), by Olex
* [AlexMoon's Hohmann Transfer Calculator](https://alexmoon.github.io/ksp/), by AlexMoon
* [Launch Window Planner](https://alexmoon.github.io/ksp/), by AlexMoon
6 changes: 5 additions & 1 deletion include/conic_kepler.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ double orbital_period(double semi_major_axis, double mu);
double theta_from_E(double E, double e);
double E_from_M(double M, double e); // Kepler's equation
double theta_from_M(double M, double e); // Kepler's equation, but with theta instead of E
double E_from_theta(double theta, double e);
double M_from_theta(double theta, double e);
double M_from_E(double E, double e);

KeplerianElements ke_from_state_vector(StateVector state_vector, double mu);
StateVector state_vector_from_ke(KeplerianElements orbit, double mu);
StateVectorArray ke_state_locus(KeplerianElements orbit, double mu, int n);
KeplerianElements ke_orbit_prop(KeplerianElements orbit, double dt, double mu);
KeplerianElements ke_orbit_prop(double t, KeplerianElements orbit, double mu);
StateVectorArray ke_orbit_prop_many(int n, double times[], KeplerianElements orbit, double mu);

#endif // CONIC_KEPLER_H
15 changes: 15 additions & 0 deletions include/delta_v_estimate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
Trajectorize
Delta v estimator
*/

#ifndef DELTA_V_ESTIMATE_H
#define DELTA_V_ESTIMATE_H

#include "kerbol_system_types.h"
#include "vec_math_types.h"

double delta_v_req(Body body, double excess_velocity, double periapsis);

#endif // DELTA_V_ESTIMATE_H
13 changes: 7 additions & 6 deletions include/lambert.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ This header file contains definitions for Lambert's Problem
#ifndef LAMBERT_H
#define LAMBERT_H

#include "orbit_math_types.h"
#include "vec_math_types.h"

typedef struct LambertSolution {
double v1[3];
double v2[3];
typedef struct LambertSolution
{
Vector3 v1;
Vector3 v2;
double dt;
} LambertSolution;

// Lambert's Problem

enum TrajectoryType {
enum TrajectoryType
{
PROGRADE,
RETROGRADE
};

LambertSolution lambert(Vector3 R1, Vector3 R2, double dt, double mu, enum TrajectoryType type);


#endif // LAMBERT_H
2 changes: 1 addition & 1 deletion include/rotations.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "orbit_math.h"
#include "vec_math.h"

#ifndef _ROTATIONS_H
#define _ROTATIONS_H
Expand Down
2 changes: 1 addition & 1 deletion include/state_vector_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This file contains typedefs related to state vector types.
#ifndef STATE_VECTOR_TYPES_H
#define STATE_VECTOR_TYPES_H

#include "orbit_math_types.h"
#include "vec_math_types.h"

typedef struct StateVector
{
Expand Down
19 changes: 19 additions & 0 deletions include/transfer_orbit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Trajectorize
Transfer Orbit Calculator
Header file for functions to calculate transfer orbits between two bodies in the Kerbol system.
*/

#ifndef TRANSFER_ORBIT_H
#define TRANSFER_ORBIT_H

#include "keplerian_element_types.h"
#include "kerbol_system_types.h"
#include "vec_math_types.h"

KeplerianElements planetary_transfer_orbit(Body body1, Body body2, double t1, double t2);
Vector3 excess_velocity_at_body(Body body, KeplerianElements transfer_orbit, double ut);

#endif // TRANSFER_ORBIT_H
12 changes: 6 additions & 6 deletions include/orbit_math.h → include/vec_math.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
/*
Trajectorize
Math Library
Vector Math Library
This header file contains a library of math functions.
*/

#ifndef ORBIT_MATH_H
#define ORBIT_MATH_H
#ifndef VEC_MATH_H
#define VEC_MATH_H

#include <stdbool.h>
#include "orbit_math_types.h"
#include "vec_math_types.h"

double vec_norm(Vector3 v);
double vec_dot(Vector3 v1, Vector3 v2);
Vector3 vec_cross(Vector3 v1, Vector3 v2);
Vector3 vec_normalize(Vector3 v);
Vector3 vec_normalized(Vector3 v);
Vector3 vec_zero();

Vector3 vec_add(Vector3 v1, Vector3 v2);
Expand All @@ -38,4 +38,4 @@ bool mat_equal(Matrix3 m1, Matrix3 m2);
void print_vec(Vector3 v);
void print_mat(Matrix3 m);

#endif // ORBIT_MATH_H
#endif // VEC_MATH_H
6 changes: 3 additions & 3 deletions include/orbit_math_types.h → include/vec_math_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ This header file contains typedefs and initializers
for the various math types used in Trajectorize.
*/

#ifndef ORBIT_MATH_TYPES_H
#define ORBIT_MATH_TYPES_H
#ifndef VEC_MATH_TYPES_H
#define VEC_MATH_TYPES_H

typedef union Vector3
{
Expand All @@ -32,4 +32,4 @@ typedef union Matrix3
double m[3][3];
} Matrix3;

#endif // ORBIT_MATH_TYPES_H
#endif // VEC_MATH_TYPES_H
3 changes: 3 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ src/trajectorize/_c_extension.so: src/trajectorize/c_ext_utils/build_c_extension
autoformat:
autopep8 --in-place --recursive --aggressive --aggressive src/trajectorize/ -v

plots:
bash ./scripts/generate_plots.sh

clean:
# Remove all .o and .so files under trajectorize/
# Also remove CFFI generated C files with name like _c_kerbol_system.c
Expand Down
43 changes: 42 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
[build-system]
requires = ["setuptools>=61", "wheel", "cffi>=1.15.0"]
requires = [
"setuptools>=64",
"wheel",
"cffi>=1.15.0",
"setuptools_scm[toml]>=6.0",
]
build-backend = "setuptools.build_meta"

[project]
name = "trajectorize"
description = "KSP Trajectory Optimization"
readme = "README.md"
requires-python = ">=3.8"
license = { text = "LGPLv3" }
authors = [{ name = "Mingde Yin", email = "[email protected]" }]
maintainers = [{ name = "Mingde Yin", email = "[email protected]" }]
keywords = ["kerbal space program", "trajectory", "optimization"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Operating System :: OS Independent",
"Programming Language :: C",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Topic :: Scientific/Engineering",
"Topic :: Scientific/Engineering :: Mathematics",
"Topic :: Scientific/Engineering :: Physics",
"Topic :: Scientific/Engineering :: Astronomy",
]
dependencies = ["numpy >= 1.23.0", "matplotlib >= 3.4.0", "cffi >= 1.15.0"]
dynamic = ["version"]

[project.urls]
homepage = "https://github.com/itchono/trajectorize"

[tool.setuptools.packages.find]
include = ["trajectorize"]
where = ["src"]

[tool.setuptools_scm]
write_to = "src/trajectorize/_version.py"
11 changes: 11 additions & 0 deletions scripts/generate_plots.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

# Make sure trajectorize is installed
# Temporarily set env to make matplotlib use Agg backend
export MPLBACKEND=Agg

# Generate plots
python -m trajectorize.demos.orbit
python -m trajectorize.demos.kerbin_duna_transfer
python -m trajectorize.demos.kerbin_duna_porkchop
python -m trajectorize.demos.kerbol_system_anim --save
40 changes: 0 additions & 40 deletions setup.cfg

This file was deleted.

6 changes: 6 additions & 0 deletions src/trajectorize/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from importlib.metadata import version, PackageNotFoundError

try:
__version__ = version("trajectorize")
except PackageNotFoundError:
__version__ = "unknown version"
13 changes: 10 additions & 3 deletions src/trajectorize/c_ext_utils/build_c_extension.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys

from cffi import FFI

include_dir = "include" if __name__ != "__main__" else "../include"
Expand Down Expand Up @@ -39,15 +40,17 @@ def read_and_cleanse_many_headers(*filenames: str) -> str:
This is because header files further down the list may depend on types defined
upstream.
'''
ffi.cdef(read_and_cleanse_many_headers("orbit_math_types.h",
ffi.cdef(read_and_cleanse_many_headers("vec_math_types.h",
"state_vector_types.h",
"keplerian_element_types.h",
"kerbol_system_types.h",
"kerbol_system_bodies.h",
"kerbol_system_ephemeris.h",
"conic_kepler.h",
"universal_kepler.h",
"lambert.h"))
"lambert.h",
"transfer_orbit.h",
"delta_v_estimate.h"))

'''
Determine compiler flags and linker args depending on platform.
Expand Down Expand Up @@ -79,6 +82,8 @@ def read_and_cleanse_many_headers(*filenames: str) -> str:
#include "conic_kepler.h"
#include "universal_kepler.h"
#include "lambert.h"
#include "transfer_orbit.h"
#include "delta_v_estimate.h"
''',
sources=[f"{src_path}/math_lib/orbit_math.c",
f"{src_path}/math_lib/rotations.c",
Expand All @@ -87,7 +92,9 @@ def read_and_cleanse_many_headers(*filenames: str) -> str:
f"{src_path}/ephemeris/kerbol_system_ephemeris.c",
f"{src_path}/orbit/conic_kepler.c",
f"{src_path}/orbit/universal_kepler.c",
f"{src_path}/trajectory/lambert.c"],
f"{src_path}/trajectory/lambert.c",
f"{src_path}/trajectory/transfer_orbit.c",
f"{src_path}/trajectory/delta_v_estimate.c"],
include_dirs=[include_dir],
extra_compile_args=extra_compile_args)

Expand Down
17 changes: 17 additions & 0 deletions src/trajectorize/c_ext_utils/process_sva_buffer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import numpy as np

from trajectorize._c_extension import ffi, lib


def process_sva_buffer(sva_struct, length: int) -> np.ndarray:
# Process memory buffer
# Format: [x, y, z, vx, vy, vz, t] x n
arr = np.frombuffer(ffi.buffer(sva_struct.mem_buffer, 7 *
8 * length), dtype=np.float64)
arr.shape = (length, 7)
copied_arr = np.copy(arr)

# Free memory
lib.free_StateVectorArray(sva_struct)

return copied_arr
Loading

0 comments on commit 6c7e801

Please sign in to comment.