Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Api v0 #88

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# API for the maneuvers calculation.

### Server

Run server:

```shell
export FLASK_APP=api/api_v0.py
export FLASK_ENV=development
flask run
```

### User

Generate protected satellite parameters (or use your own):

```shell
python api/generate_params.py --save_path <<save path .json>>
```

then just open [http://127.0.0.1:5000/](http://127.0.0.1:5000/), upload the satellite parameters and download your
maneuver example.

Here, the collision situation is generated with several dangerous debris. After that, it is calculated
the maneuver using CE-method. This calculated maneuver is downloaded after all.

### Additional

Also, you could visualize the maneuver and the environment:

```shell
python examples/collision.py -env api/data/generated_collision_api.env -model api/data/maneuvers.csv
```
79 changes: 79 additions & 0 deletions api/api_v0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import os
from flask import Flask, flash, request, redirect, url_for, send_file
from werkzeug.utils import secure_filename
from other import generate_env
import json

UPLOAD_FOLDER = '/home/dev/projects/satellite-collision-avoidance/api/data'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)

ALLOWED_EXTENSIONS = {'json'}
JSON_PATH = 'protected_params_api.json'

ENV_PATH = "generated_collision_api.env"
MANEUVERS_PATH = "maneuvers.csv"

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER


def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS


@app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# If the user does not select a file, the browser submits an
# empty file without a filename.
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
# file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
file.save(os.path.join(app.config['UPLOAD_FOLDER'], JSON_PATH))
return redirect(url_for('sent_result', name=filename))
return '''
<!doctype html>
<title>TensorLab</title>
<h1>Upload your satellite parameters in .json</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''


@app.route('/sent_result')
def sent_result():
with open(JSON_PATH, "r") as read_file:
protected_params = json.load(read_file)

env_path = os.path.join(app.config['UPLOAD_FOLDER'], ENV_PATH)
maneuvers_path = os.path.join(app.config['UPLOAD_FOLDER'], MANEUVERS_PATH)

generate_env(protected_params, env_path)

os.system(
f'python training/CE/CE_train_for_collision.py -env {env_path} -print true -save_path {maneuvers_path} \
-r false -n_m 1')
# os.system(f'python examples/collision.py -env {ENV_PATH} -model {MANEUVERS_PATH} -v False')

return send_file(
maneuvers_path,
mimetype='text/csv',
attachment_filename='maneuver.csv',
as_attachment=True
)


if __name__ == '__main__':
app.run(debug=True)
20 changes: 20 additions & 0 deletions api/generate_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from space_navigator.generator import Generator
import json
import click


@click.command()
@click.option('--save_path', default='protected_params_api.json', help='save path .json')
def main(save_path):
start_time = 6600 # TODO: start and end time to import json
end_time = 6600.1

generator = Generator(start_time, end_time)
generator.add_protected()
protected_params = generator.get_protected_params()
with open(save_path, 'w') as f:
json.dump(protected_params, f)


if __name__ == "__main__":
main()
42 changes: 42 additions & 0 deletions api/other.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from space_navigator.generator import Generator
import json

import os

start_time = 6600 # TODO: start and end time to import json
end_time = 6600.1

ENV_PATH = "generated_collision_api.env"
MANEUVERS_PATH = "maneuvers.csv"


def generate_env(protected_params, save_path=ENV_PATH):
n_debris = 5
time_before_start_time = 0.1
pos_sigma = 0
vel_ratio_sigma = 0.05
i_threshold = 0.5

generator = Generator(start_time, end_time)
generator.add_protected_by_params(protected_params)
for _ in range(n_debris):
generator.add_debris(pos_sigma, vel_ratio_sigma, i_threshold)
generator.save_env(save_path, time_before_start_time)


if __name__ == "__main__":
# generate debris
json_path = 'protected_params_api.json'
with open(json_path, "r") as read_file:
protected_params = json.load(read_file)
generate_env(protected_params)

# calculate maneuvers
# TODO: without OS
os.system(
f'python training/CE/CE_train_for_collision.py -env {ENV_PATH} -print true -save_path {MANEUVERS_PATH} \
-r false -n_m 1')

# TODO: sent graphs and gif
# run simulator
os.system(f'python examples/collision.py -env {ENV_PATH} -model {MANEUVERS_PATH} -v False')
17 changes: 10 additions & 7 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
numpy==1.14.5
pykep==2.1
pandas==0.20.3
matplotlib==2.1.0
scipy==1.0.1
torch==0.4.0
tqdm==4.23.4
numpy # ==1.14.5
pykep # ==2.1
pandas # ==0.20.3
matplotlib # ==2.1.0
scipy # ==1.0.1
torch #==0.4.0
tqdm # ==4.23.4
Flask
Flask-RESTful
Werkzeug
14 changes: 7 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
# What does your project relate to?
keywords='machine learning, reinforcement learning, collision avoidance, spacecraft',

install_requires=[
'pykep == 2.1',
'pandas >= 0.20.3',
'matplotlib >= 2.1.0',
'numpy >= 1.14.2',
'scipy >= 1.0.1'
],
# install_requires=[
# 'pykep == 2.1',
# 'pandas >= 0.20.3',
# 'matplotlib >= 2.1.0',
# 'numpy >= 1.14.2',
# 'scipy >= 1.0.1'
# ],
)
2 changes: 1 addition & 1 deletion space_navigator/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ def _update_reward(self):
[self.get_fuel_consumption()],
np.abs(self.get_trajectory_deviation()),
)
).astype(np.float)
).astype(np.float64)
reward_arr = reward_func(values, self._reward_thr)
coll_prob_r = reward_arr[0]
fuel_r = reward_arr[1]
Expand Down
33 changes: 24 additions & 9 deletions space_navigator/generator/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import numpy as np
import pykep as pk


from .generator_utils import SpaceObject2srt, rotate_velocity
from ..api import SpaceObject

Expand All @@ -22,13 +21,14 @@ class Generator:
def __init__(self, start_time, end_time):
# TODO - random start/end time with duration?
# TODO - random duration?
self.start_time = pk.epoch(start_time, "mjd2000")
self.end_time = pk.epoch(end_time, "mjd2000")
self.start_time = start_time # pk.epoch(start_time, "mjd2000")
self.end_time = end_time # pk.epoch(end_time, "mjd2000")

self.protected = None
self.debris = []

self.collision_epochs = []
self.protected_params = None

def add_protected(self):
"""Add protected object."""
Expand Down Expand Up @@ -70,8 +70,8 @@ def add_protected(self):
elements = [a, e, i, W, w, M]

# protected object parameters
params = {
"epoch": self.start_time,
protected_params = {
"start_time": self.start_time,
"elements": elements,
"mu_central_body": pk.MU_EARTH,
"mu_self": mu_self,
Expand All @@ -80,7 +80,14 @@ def add_protected(self):
"fuel": fuel
}

self.protected = SpaceObject("PROTECTED", "osc", params)
self.add_protected_by_params(protected_params)

def add_protected_by_params(self, protected_params):
self.protected_params = protected_params
protected_params_with_epoch = self.protected_params.copy()
protected_params_with_epoch["epoch"] = pk.epoch(protected_params_with_epoch['start_time'], "mjd2000")
del protected_params_with_epoch['start_time']
self.protected = SpaceObject("PROTECTED", "osc", protected_params_with_epoch)

def add_debris(self, pos_sigma=0, vel_ratio_sigma=0.05,
i_threshold=0.5):
Expand All @@ -104,9 +111,12 @@ def add_debris(self, pos_sigma=0, vel_ratio_sigma=0.05,
if not self.protected:
raise Exception("no protected object")

start_time = pk.epoch(self.start_time, "mjd2000")
end_time = pk.epoch(self.end_time, "mjd2000")

# TODO - indent?
collision_time = np.random.uniform(
self.start_time.mjd2000, self.end_time.mjd2000
start_time.mjd2000, end_time.mjd2000
)

collision_time = pk.epoch(collision_time, "mjd2000")
Expand Down Expand Up @@ -157,13 +167,18 @@ def add_debris(self, pos_sigma=0, vel_ratio_sigma=0.05,
self.debris.append(SpaceObject(name, "eph", params))

def save_env(self, save_path, time_before_start_time=0):
start_time = pk.epoch(self.start_time, "mjd2000")
end_time = pk.epoch(self.end_time, "mjd2000")
with open(save_path, 'w') as f:
f.write(f'{self.start_time.mjd2000 - time_before_start_time}, {self.end_time.mjd2000}\n')
f.write(f'{start_time.mjd2000 - time_before_start_time}, {end_time.mjd2000}\n')
f.write('osc\n')
f.write(SpaceObject2srt(self.protected, self.start_time))
f.write(SpaceObject2srt(self.protected, start_time))
for debr, epoch in zip(self.debris, self.collision_epochs):
f.write(SpaceObject2srt(debr, epoch))

def get_protected_params(self):
return self.protected_params

def env(self):
pass

Expand Down
4 changes: 2 additions & 2 deletions space_navigator/simulator/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def __init__(self, curr_time, prob, fuel_cons, traj_dev, reward_components, rewa
self.fig = plt.figure(figsize=[14, 12])
self.gs = gridspec.GridSpec(15, 2)
self.subplot_3d = self.fig.add_subplot(self.gs[:, 0], projection='3d')
self.subplot_3d.set_aspect("equal")
self.subplot_3d.set_aspect("auto")
self.subplot_p = self.fig.add_subplot(self.gs[:3, 1])
self.subplot_f = self.fig.add_subplot(self.gs[4:7, 1])
self.subplot_r_t = self.fig.add_subplot(self.gs[8:11, 1])
Expand Down Expand Up @@ -126,7 +126,7 @@ def update_data(self, curr_time, prob, fuel_cons, traj_dev, reward_components, r

def plot_planet(self, satellite, t, size, color):
""" Plot a pykep.planet object. """
plot_planet(satellite, ax=self.subplot_3d,
plot_planet(satellite, axes=self.subplot_3d,
t0=t, s=size, legend=True, color=color)

def plot_earth(self):
Expand Down