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

Tilt rotor model #70

Merged
merged 14 commits into from
May 17, 2021
Merged
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
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "Tools/visual_dataframe_selector"]
path = Tools/visual_dataframe_selector
[submodule "Tools/parametric_model/visual_dataframe_selector"]
path = Tools/parametric_model/visual_dataframe_selector
url = https://github.com/manumerous/visual_dataframe_selector
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ version?=latest
registry?=ethzasl/data-driven-dynamics
model?=quadrotor_model
log?=${root_dir}/resources/${model}.ulg
data_selection?=False

submodulesupdate:
git submodule update --init --recursive

install-dependencies:
pip3 install -r Tools/parametric_model/requirements.txt
pip3 install -r Tools/parametric_model/visual_dataframe_selector/requirements.txt

docker-build:
docker build -f docker/Dockerfile --tag ${registry}:${version} .
Expand All @@ -24,4 +26,5 @@ docker-run:
docker run -it --rm -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix ${registry}:${version} /bin/bash

estimate-model:
python3 Tools/parametric_model/generate_parametric_model.py --model ${model} ${log}
python3 Tools/parametric_model/generate_parametric_model.py --model ${model} ${log} --data_selection ${data_selection}

19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ source ~/.bashrc
The use the parametric model structure you need to install python 3.8 and the needed python libraries. It is strongly advised to install the pip packages in a [virtual enviroment](https://docs.python.org/3/tutorial/venv.html) setup for this project.

Update submodules:

```
make submodulesupdate
```
Expand Down Expand Up @@ -70,23 +71,25 @@ source setup.bash
Generate the parametric model using a log file (ulog or csv):

```
python3 Tools/parametric_model/generate_parametric_model model log_file
python3 Tools/parametric_model/generate_parametric_model --model <model> --data_selection <True/False> log_file
```

Or more simply from the root of the repository
Or more simply using the make command:

```
make estimate-model [model=<modeltype>] [log=<log path>]
make estimate-model [model=<modeltype>] [data_selection=<True/False>] [log=<log path>]
```

Hereby the arguments model and log_file can be used to specify the model and the log files respectively. As an example you could use the reference log_files:
Hereby the arguments model and log_file can be used to specify the model and the log files respectively. The data_selection argument is optional (per default False) and can be used to visually select a subportion of the data before running the model estimation.

As an example you could use the reference log_files:

```
python Tools/parametric_model/generate_parametric_model.py --model quad_plane_model resources/simple_quadplane_model.ulg
make estimate-model model=quad_plane_model log=resources/simple_quadplane_model.ulg
```

```
python3 Tools/parametric_model/generate_parametric_model.py --model quad_plane_model resources/simple_quadplane_model.csv
make estimate-model model=quad_plane_model log=resources/simple_quadplane_model.csv
```

Current model choices are:
Expand All @@ -95,6 +98,10 @@ Current model choices are:

- quad_plane_model

- delta_quad_plane_model

- tilt_wing_model

The results of the model estimation will be saved into the Tools/parametric_model/results folder as a yaml file.

## Testing the functionality of Parametric model
Expand Down
2 changes: 2 additions & 0 deletions Tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import parametric_model
from . import visual_dataframe_selector
1 change: 1 addition & 0 deletions Tools/parametric_model/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from . import src
from . import tests
from . import visual_dataframe_selector
30 changes: 27 additions & 3 deletions Tools/parametric_model/generate_parametric_model.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@


__author__ = "Manuel Galliker"
__maintainer__ = "Manuel Galliker"
__license__ = "BSD 3"


from src.models import QuadRotorModel, QuadPlaneModel, DeltaQuadPlaneModel
import os
import sys
import inspect
from src.models import QuadRotorModel, QuadPlaneModel, DeltaQuadPlaneModel, TiltWingModel
import argparse


def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')


def start_model_estimation(arg_list):
rel_ulog_path = arg_list.log_path
model = arg_list.model
data_selection_enabled = arg_list.data_selection
print("Visual Data selection enabled: ", data_selection_enabled)

if (model == "quadrotor_model"):
model = QuadRotorModel(rel_ulog_path)
Expand All @@ -21,9 +37,15 @@ def start_model_estimation(arg_list):
elif (model == "delta_quad_plane_model"):
model = DeltaQuadPlaneModel(rel_ulog_path)

elif (model == "tilt_wing_model"):
model = TiltWingModel(rel_ulog_path)

else:
print("no valid model selected")

if data_selection_enabled:
model.visually_select_data()

model.estimate_model()
model.plot_model_predicitons()

Expand All @@ -35,8 +57,10 @@ def start_model_estimation(arg_list):
description='Estimate dynamics model from flight log.')
parser.add_argument('--model', metavar='model', type=str,
default='quadrotor_model',
help='Parametric Model Type [quadrotor_model, quad_plane_model]')
help='Parametric Model Type [quadrotor_model, quad_plane_model, delta_quad_plane_model, tilt_wing_model]')
parser.add_argument('log_path', metavar='log_path', type=str,
help='The path of the log to process relative to the project directory.')
parser.add_argument('--data_selection', metavar='data_selection', type=str2bool, default=False,
help='the path of the log to process relative to the project directory.')
arg_list = parser.parse_args()
start_model_estimation(arg_list)
2 changes: 2 additions & 0 deletions Tools/parametric_model/src/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@
from .quadrotor_model import QuadRotorModel
from . import model_config
from . model_config import ModelConfig
from . import tilt_wing_model
from . tilt_wing_model import TiltWingModel
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
__maintainer__ = "Manuel Galliker"
__license__ = "BSD 3"

from . import aero_model_AAE

from .aero_model_AAE import AeroModelAAE
from . import aero_model_Delta
from .aero_model_Delta import AeroModelDelta
from . import simple_drag_model
from .simple_drag_model import SimpleDragModel
from .tilt_wing_section_aero_model import TiltWingSection
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import math
import numpy as np

from ...tools import cropped_sym_sigmoid
from src.tools.math_tools import cropped_sym_sigmoid
from scipy.spatial.transform import Rotation
from progress.bar import Bar

Expand Down Expand Up @@ -41,7 +41,7 @@ def compute_main_wing_feature(self, v_airspeed, angle_of_attack):
if abs(AoA) > stall_angle: cropped_sym_sigmoid(AoA) = 1
"""
v_xz = math.sqrt(v_airspeed[0]**2 + v_airspeed[2]**2)
F_xz_aero_frame = np.zeros((3, 7))
F_xz_aero_frame = np.zeros((3, 8))

# Compute Drag force coeffiecients:
F_xz_aero_frame[0, 0] = -(
Expand All @@ -51,16 +51,16 @@ def compute_main_wing_feature(self, v_airspeed, angle_of_attack):
F_xz_aero_frame[0, 2] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack**2*v_xz**2
F_xz_aero_frame[0, 3] = -(cropped_sym_sigmoid(angle_of_attack,
x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*math.sin(angle_of_attack)*v_xz**2

x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*(1 - math.sin(angle_of_attack)**2)*v_xz**2
F_xz_aero_frame[0, 4] = -(cropped_sym_sigmoid(angle_of_attack,
x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*(math.sin(angle_of_attack)**2)*v_xz**2
# Compute Lift force coefficients:
F_xz_aero_frame[2, 4] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack*v_xz**2
F_xz_aero_frame[2, 5] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack*v_xz**2
F_xz_aero_frame[2, 6] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*v_xz**2
F_xz_aero_frame[2, 6] = -2 * \
cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac) \
* math.sin(angle_of_attack)*math.cos(angle_of_attack)*v_xz**2
F_xz_aero_frame[2, 7] = -cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac) \
* math.sin(2*angle_of_attack)*v_xz**2

# Transorm from stability axis frame to body FRD frame
R_aero_to_body = Rotation.from_rotvec(
Expand Down Expand Up @@ -138,13 +138,9 @@ def compute_aero_features(self, v_airspeed_mat, angle_of_attack_vec, flap_comman
X_aero = np.vstack((X_aero, X_curr))
aero_features_bar.next()
aero_features_bar.finish()
wing_coef_list = ["c_d_wing_xz_offset", "c_d_wing_xz_lin", "c_d_wing_xz_quad", "c_d_wing_xz_stall",
wing_coef_list = ["c_d_wing_xz_offset", "c_d_wing_xz_lin", "c_d_wing_xz_quad", "c_d_wing_xz_stall_min", "c_d_wing_xz_stall_90_deg",
"c_l_wing_xz_offset", "c_l_wing_xz_lin", "c_l_wing_xz_stall", "c_d_wing_y_offset"]
flap_coef_list = ["c_d_ail_lin",
"c_d_ail_quad", "c_d_ele_lin", "c_d_ele_quad", "c_l_ele_lin"]
aero_coef_list = wing_coef_list + flap_coef_list
return X_aero, aero_coef_list


if __name__ == "__main__":
linearPlateAeroModel = AeroModelAAE(20.0)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import math
import numpy as np

from ...tools import cropped_sym_sigmoid
from src.tools.math_tools import cropped_sym_sigmoid
from scipy.spatial.transform import Rotation
from progress.bar import Bar

Expand Down Expand Up @@ -41,7 +41,7 @@ def compute_main_wing_feature(self, v_airspeed, angle_of_attack):
if abs(AoA) > stall_angle: cropped_sym_sigmoid(AoA) = 1
"""
v_xz = math.sqrt(v_airspeed[0]**2 + v_airspeed[2]**2)
F_xz_aero_frame = np.zeros((3, 7))
F_xz_aero_frame = np.zeros((3, 8))

# Compute Drag force coeffiecients:
F_xz_aero_frame[0, 0] = -(
Expand All @@ -51,16 +51,17 @@ def compute_main_wing_feature(self, v_airspeed, angle_of_attack):
F_xz_aero_frame[0, 2] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack**2*v_xz**2
F_xz_aero_frame[0, 3] = -(cropped_sym_sigmoid(angle_of_attack,
x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*math.sin(angle_of_attack)*v_xz**2
x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*(1 - math.sin(angle_of_attack)**2)*v_xz**2
F_xz_aero_frame[0, 4] = -(cropped_sym_sigmoid(angle_of_attack,
x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*(math.sin(angle_of_attack)**2)*v_xz**2

# Compute Lift force coefficients:
F_xz_aero_frame[2, 4] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack*v_xz**2
F_xz_aero_frame[2, 5] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*angle_of_attack*v_xz**2
F_xz_aero_frame[2, 6] = -(
1 - cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac))*v_xz**2
F_xz_aero_frame[2, 6] = -2 * \
cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac) \
* math.sin(angle_of_attack)*math.cos(angle_of_attack)*v_xz**2
F_xz_aero_frame[2, 7] = -cropped_sym_sigmoid(angle_of_attack, x_offset=self.stall_angle, scale_fac=self.sig_scale_fac) \
* math.sin(2*angle_of_attack)*v_xz**2

# Transorm from stability axis frame to body FRD frame
R_aero_to_body = Rotation.from_rotvec(
Expand Down Expand Up @@ -134,13 +135,9 @@ def compute_aero_features(self, v_airspeed_mat, angle_of_attack_vec, flap_comman
X_aero = np.vstack((X_aero, X_curr))
aero_features_bar.next()
aero_features_bar.finish()
wing_coef_list = ["c_d_wing_xz_offset", "c_d_wing_xz_lin", "c_d_wing_xz_quad", "c_d_wing_xz_stall",
wing_coef_list = ["c_d_wing_xz_offset", "c_d_wing_xz_lin", "c_d_wing_xz_quad", "c_d_wing_xz_stall_min", "c_d_wing_xz_stall_90_deg",
"c_l_wing_xz_offset", "c_l_wing_xz_lin", "c_l_wing_xz_stall", "c_d_wing_y_offset"]
flap_coef_list = ["c_d_ail_lin",
"c_d_ail_quad", "c_d_ele_lin", "c_d_ele_quad", "c_l_ele_lin"]
aero_coef_list = wing_coef_list + flap_coef_list
return X_aero, aero_coef_list


if __name__ == "__main__":
linearPlateAeroModel = AeroModelDelta(20.0)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import math
import numpy as np

from ...tools import sym_sigmoid
from src.tools.math_tools import sym_sigmoid
from scipy.spatial.transform import Rotation


Expand Down Expand Up @@ -81,7 +81,3 @@ def compute_aero_features(self, v_airspeed_mat, angle_of_attack_vec):
fuselage_coef_list = ["c_d_wing_xy_offset", "c_d_wing_xy_lin", "c_d_wing_xy_quad", "c_d_wing_xy_stall",
"c_d_wing_y_offset"]
return X_aero, fuselage_coef_list


if __name__ == "__main__":
simpleDragModelModel = SimpleDragModel(35.0)
Loading