From 3d7bfe9546e50b92a04f4c1066b16356212732a2 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 10:28:05 -0700 Subject: [PATCH 01/15] ground trim; only mass information --- Aircraft/WaveRipper/WaveRipper.xml | 465 +------------------------- scripts/simple-body.ipynb | 503 +++++++++++++++++++++++++++++ 2 files changed, 505 insertions(+), 463 deletions(-) create mode 100644 scripts/simple-body.ipynb diff --git a/Aircraft/WaveRipper/WaveRipper.xml b/Aircraft/WaveRipper/WaveRipper.xml index 31d6b1e..0ba8fed 100644 --- a/Aircraft/WaveRipper/WaveRipper.xml +++ b/Aircraft/WaveRipper/WaveRipper.xml @@ -1,8 +1,8 @@ - + - @@ -146,470 +146,9 @@ - - - - - Lift due to alpha - - aero/qbar-psf - metrics/Sw-sqft - - aero/alpha-deg - velocities/mach - - 0.1 0.3 0.5 0.7 - -8 -0.23976340051 -0.2748769035 -0.316141543 -0.3828169 - -3 -0.06166552793 -0.08849472518 -0.1042104699 -0.1881149 - 2 0.066333954 0.07985344752 0.09227948938 0.01569465477 - 7 0.2387339012 0.2495874496 0.3064670956 0.2164789582 - 12 0.3868915515 0.4173733774 0.455385058 0.4061997669 - 17 0.4882973544 0.5383389038 0.6039227228 0.5734467743 - -
-
-
- - - Lift due to pitch rate - - aero/qbar-psf - metrics/Sw-sqft - velocities/q-aero-rad_sec - aero/ci2vel - 5.2089 - - - - - Lift due to alpha rate - - aero/qbar-psf - metrics/Sw-sqft - aero/alphadot-rad_sec - aero/ci2vel - 2.3823 - - - - - Lift due to Elevator Deflection - - aero/qbar-psf - metrics/Sw-sqft - fcs/elevator-pos-rad - 0.5378 - - - - - Delta Lift due to flaps - - aero/qbar-psf - metrics/Sw-sqft - fcs/flap-pos-deg - 0.0099 - - - - -
- - - - Minimum drag - - aero/qbar-psf - metrics/Sw-sqft - 0.012472 - - - - - Drag due to alpha - - aero/qbar-psf - metrics/Sw-sqft - - aero/alpha-deg - velocities/mach - - 0.1 0.3 0.5 0.7 - -8 0.033 0.03976340051 0.04649906181 0.05726257 - -3 0.011 0.01166552793 0.01314749555 0.02074335332 - 2 0.012 0.0110333957 0.01241672081 0.01247228127 - 7 0.027 0.02987339012 0.03952692937 0.02060622746 - 12 0.079 0.08399357497 0.09437848307 0.058298882 - 17 0.138 0.159593753 0.1806859284 0.1216733945 - -
-
-
- - - Induced drag - - aero/qbar-psf - metrics/Sw-sqft - aero/cl-squared - 0.0400 - - - - - Drag due to mach - - aero/qbar-psf - metrics/Sw-sqft - - velocities/mach - - 0.00 0.0000 - 0.81 0.0000 - 1.10 0.0230 - 1.80 0.0150 - -
-
-
- - - Drag due to sideslip - - aero/qbar-psf - metrics/Sw-sqft - - aero/beta-rad - - -1.57 1.2300 - -0.26 0.0500 - 0.00 0.0000 - 0.26 0.0500 - 1.57 1.2300 - -
-
-
- - - Drag due to Elevator Deflection - - aero/qbar-psf - metrics/Sw-sqft - fcs/elevator-pos-rad - 0.0400 - - - - - Drag due to gear - - aero/qbar-psf - metrics/Sw-sqft - gear/gear-pos-norm - 0.0200 - - - - - Drag due to flaps - - aero/qbar-psf - metrics/Sw-sqft - fcs/flap-pos-deg - 0.0023 - - -
- - - - - - Side force due to roll rate - - aero/qbar-psf - metrics/Sw-sqft - aero/bi2vel - velocities/p-aero-rad_sec - - aero/Re - - 746432 -1.0341 - 821076 -0.0867 - 1119649 -0.0385 - -
-
-
- - - Side force due to yaw rate - - aero/qbar-psf - metrics/Sw-sqft - aero/bi2vel - velocities/r-aero-rad_sec - -1.9169 - - - - - Side force due to rudder - - aero/qbar-psf - metrics/Sw-sqft - fcs/rudder-pos-rad - 0.2820 - - -
- - - - Pitch moment due to alpha - - aero/qbar-psf - metrics/Sw-sqft - metrics/cbarw-ft - - aero/alpha-deg - velocities/mach - - 0.1 0.3 0.5 0.7 - -8 0.0400 0.05038236499 0.05851795421 0.06842443572 - -3 0.0000 0.01783156553 0.0203095624 0.02840352615 - 2 -0.011 -0.01254904696 -0.01355446643 0.0007018651187 - 7 -0.052 -0.04788754724 -0.04925798115 -0.03112826299 - 12 -0.077 -0.08151075808 -0.1013066704 -0.06821505873 - 17 -0.094 -0.1041613393 -0.1355838714 -0.111192846 - -
-
-
- - - Pitch moment due to elevator - - aero/qbar-psf - metrics/Sw-sqft - metrics/cbarw-ft - fcs/elevator-pos-rad - - velocities/mach - - 0.0 1.0454 - 2.0 0.2613 - -
-
-
- - -
- - - - Roll moment due to beta - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - aero/beta-rad - - - aero/alpha-rad - aero/Re - - 746432 821076 1119649-2147483648 - -0.0349 -79.0109 -9.0032 -5.4455-nan(ind) - 0.3491 -88.3173 -9.8461 -5.8600-nan(ind) - -
-
-
- - - - - Roll moment due to aileron - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - fcs/left-aileron-pos-rad - - velocities/mach - - 0.0 0.1100 - 2.0 0.0275 - -
-
-
- - - Roll moment due to rudder - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - fcs/rudder-pos-rad - 0.0100 - - -
- - - - - Yaw moment due to alpha - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - aero/alpha-rad - - - aero/beta-rad - aero/Re - - 746432 821076 - -0.3491 -1.0000 0.0000 - 0.3491 1.0000 0.0000 - -
-
-
- - - - - Yaw moment due to rudder - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - fcs/rudder-pos-rad - -0.1701 - - - - - Adverse yaw - - aero/qbar-psf - metrics/Sw-sqft - metrics/bw-ft - fcs/left-aileron-pos-rad - 0.0000 - - -
- diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb new file mode 100644 index 0000000..f3ea3e3 --- /dev/null +++ b/scripts/simple-body.ipynb @@ -0,0 +1,503 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Simple, Phase 1, approximate flight profile simulation" + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 10, + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import control\n", + "\n", + "# Purdue AA451 library\n", + "from scripts.jsbsim_utils import Logger, trim, simulate, linearize, rootlocus, clean_tf" + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 11, + "source": [ + "aircraft_model = 'WaveRipper'" + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "# Ground Trim" + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 12, + "source": [ + "op_ground, props = trim(\n", + " aircraft=aircraft_model,\n", + " ic={\n", + " 'ic/vt-fps': 0,\n", + " 'ic/h-agl-ft': 5,\n", + " 'ic/psi-true-deg': 280,\n", + " 'fcs/left-brake-cmd-norm': 1,\n", + " 'fcs/right-brake-cmd-norm': 1,\n", + " 'fcs/center-brake-cmd-norm': 1,\n", + " },\n", + " design_vector=['ic/theta-rad', 'ic/h-agl-ft'],\n", + " x0=[0, 0],\n", + " verbose=True,\n", + " method='Nelder-Mead', # works better with ground interaction\n", + " ftol=1e-2,\n", + ")\n", + "op_ground" + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " final_simplex: (array([[-0.0345507 , 0.06439891],\n", + " [-0.03458697, 0.0644949 ],\n", + " [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n", + " fun: 0.001012183546600445\n", + " message: 'Optimization terminated successfully.'\n", + " nfev: 91\n", + " nit: 48\n", + " status: 0\n", + " success: True\n", + " x: array([-0.0345507 , 0.06439891])\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\n", + " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "\n", + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + ] + }, + { + "output_type": "error", + "ename": "RuntimeError", + "evalue": "trim failed:\n final_simplex: (array([[-0.0345507 , 0.06439891],\n [-0.03458697, 0.0644949 ],\n [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n fun: 0.001012183546600445\n message: 'Optimization terminated successfully.'\n nfev: 91\n nit: 48\n status: 0\n success: True\n x: array([-0.0345507 , 0.06439891])\n{'accelerations/a-pilot-x-ft_sec2': -1.1108579711719817, 'accelerations/a-pilot-y-ft_sec2': -3.794503730205625e-06, 'accelerations/a-pilot-z-ft_sec2': -32.138382691666095, 'accelerations/n-pilot-x-norm': -0.03452652124968466, 'accelerations/n-pilot-y-norm': -1.1793678136434711e-07, 'accelerations/n-pilot-z-norm': -0.9988914710344334, 'accelerations/Nx': -0.034526520905789185, 'accelerations/Ny': -1.277256636801932e-07, 'accelerations/Nz': 0.9989839055752421, 'accelerations/pdot-rad_sec2': 1.470095283222809e-05, 'accelerations/qdot-rad_sec2': -0.0014120579470234818, 'accelerations/rdot-rad_sec2': 1.3520516234706842e-07, 'accelerations/udot-ft_sec2': -1.9341280919515924e-05, 'accelerations/vdot-ft_sec2': -1.0399249578684788e-06, 'accelerations/wdot-ft_sec2': -0.0031920287673839615, 'accelerations/gravity-ft_sec2': 32.222006412476496}", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/3102752839.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_ground, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/h-agl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[0m\u001b[1;32m 124\u001b[0m str(fdm.get_property_catalog('acceleration')))\n\u001b[1;32m 125\u001b[0m \u001b[0mprops\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfdm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_property_catalog\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n final_simplex: (array([[-0.0345507 , 0.06439891],\n [-0.03458697, 0.0644949 ],\n [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n fun: 0.001012183546600445\n message: 'Optimization terminated successfully.'\n nfev: 91\n nit: 48\n status: 0\n success: True\n x: array([-0.0345507 , 0.06439891])\n{'accelerations/a-pilot-x-ft_sec2': -1.1108579711719817, 'accelerations/a-pilot-y-ft_sec2': -3.794503730205625e-06, 'accelerations/a-pilot-z-ft_sec2': -32.138382691666095, 'accelerations/n-pilot-x-norm': -0.03452652124968466, 'accelerations/n-pilot-y-norm': -1.1793678136434711e-07, 'accelerations/n-pilot-z-norm': -0.9988914710344334, 'accelerations/Nx': -0.034526520905789185, 'accelerations/Ny': -1.277256636801932e-07, 'accelerations/Nz': 0.9989839055752421, 'accelerations/pdot-rad_sec2': 1.470095283222809e-05, 'accelerations/qdot-rad_sec2': -0.0014120579470234818, 'accelerations/rdot-rad_sec2': 1.3520516234706842e-07, 'accelerations/udot-ft_sec2': -1.9341280919515924e-05, 'accelerations/vdot-ft_sec2': -1.0399249578684788e-06, 'accelerations/wdot-ft_sec2': -0.0031920287673839615, 'accelerations/gravity-ft_sec2': 32.222006412476496}" + ] + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 9, + "source": [ + "op_ground" + ], + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "name 'op_ground' is not defined", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/1089983896.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mop_ground\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'op_ground' is not defined" + ] + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 6, + "source": [ + "log_ground = simulate(\n", + " aircraft=aircraft_model,\n", + " op_0=op_ground,\n", + " tf=5,\n", + " realtime=False, verbose=True)" + ], + "outputs": [ + { + "output_type": "error", + "ename": "NameError", + "evalue": "name 'op_ground' is not defined", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27214/1673139056.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m log_ground = simulate(\n\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mop_0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mop_ground\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mtf\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m realtime=False, verbose=True)\n", + "\u001b[0;31mNameError\u001b[0m: name 'op_ground' is not defined" + ] + } + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "## Hover Trim" + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 31, + "source": [ + "op_hover, props = trim(\n", + " aircraft=aircraft_model,\n", + " ic={\n", + " 'ic/h-sl-ft': 650,\n", + " 'ic/vt-fps': 0,\n", + " 'ic/psi-true-deg': 280,\n", + " 'ap/gear-enable': 1,\n", + " },\n", + " eq_constraints = [\n", + " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", + " #lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", + " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", + " #lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", + " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", + " #lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", + " ],\n", + " design_vector=[\n", + " 'fcs/throttle-cmd-norm',\n", + " 'fcs/elevator-cmd-norm',\n", + " 'propulsion/engine/pitch-angle-rad',\n", + " ],\n", + " x0=[0.9, 0.5, np.deg2rad(90)],\n", + " cost= lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", + " verbose=True,\n", + " method='SLSQP',\n", + " bounds=[[0, 1], [-1, 1], [np.deg2rad(0), np.deg2rad(120)]],\n", + ")\n", + "op_hover" + ], + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " fun: 0.8644525429644134\n", + " jac: array([1., 0., 0.])\n", + " message: 'Optimization terminated successfully'\n", + " nfev: 30\n", + " nit: 7\n", + " njev: 7\n", + " status: 0\n", + " success: True\n", + " x: array([0.86445254, 0.03362766, 1.57079635])\n", + "constraint eq 1.177877240188252e-15\n", + "constraint eq -2.301472790122716e-08\n", + "constraint eq 3.591704833301481e-09\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/h-sl-ft': 650,\n", + " 'ic/vt-fps': 0,\n", + " 'ic/psi-true-deg': 280,\n", + " 'ap/gear-enable': 1,\n", + " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", + " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", + " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" + ] + }, + "metadata": {}, + "execution_count": 31 + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 32, + "source": [ + "log_hover = simulate(\n", + " aircraft=aircraft_model,\n", + " op_0=op_hover,\n", + " tf=10,\n", + " realtime=False)" + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 33, + "source": [ + "op_hover" + ], + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/h-sl-ft': 650,\n", + " 'ic/vt-fps': 0,\n", + " 'ic/psi-true-deg': 280,\n", + " 'ap/gear-enable': 1,\n", + " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", + " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", + " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" + ] + }, + "metadata": {}, + "execution_count": 33 + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 34, + "source": [ + "op_hover_auto = dict(op_hover)\n", + "op_hover_auto['ic/theta-deg'] = 0\n", + "op_hover_auto['ic/phi-deg'] = 0\n", + "op_hover_auto['ic/h-agl-ft'] = 60\n", + "\n", + "op_hover_auto['ap/heading-cmd-deg'] = 280\n", + "op_hover_auto['ap/gear-enable'] = 1\n", + "op_hover_auto['ap/roll-enable'] = 0\n", + "op_hover_auto['ap/pitch-enable'] = 1\n", + "op_hover_auto['ap/yaw-enable'] = 0\n", + "op_hover_auto['ap/h-enable'] = 1\n", + "op_hover_auto['ap/h-sl-cmd-ft'] = 700\n", + "\n", + "log_hover_auto = simulate(\n", + " aircraft='F-35B-2',\n", + " op_0=op_hover_auto,\n", + " tf=50,\n", + " realtime=False, verbose=True)" + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 35, + "source": [ + "log_hover_auto['fcs/throttle-pos-norm'].plot(label='0')\n", + "log_hover_auto['fcs/throttle-pos-norm[1]'].plot(label='1')\n", + "log_hover_auto['fcs/throttle-pos-norm[2]'].plot(label='2')\n", + "log_hover_auto['fcs/throttle-pos-norm[3]'].plot(label='3')\n", + "\n", + "plt.legend()" + ], + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 35 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 9, + "source": [ + "log_hover_auto['ap/h-error'].plot()" + ], + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "execution_count": 9 + }, + { + "output_type": "display_data", + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + } + } + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "## Transition" + ], + "metadata": {} + }, + { + "cell_type": "markdown", + "source": [ + "## Cruise Trim" + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 38, + "source": [ + "op_cruise, props = trim(\n", + " aircraft=aircraft_model,\n", + " ic={\n", + " 'ic/gamma-deg': 0,\n", + " 'ic/vt-fps': 600,\n", + " 'ic/h-sl-ft': 10000,\n", + " 'gear/gear-cmd-norm': 0,\n", + " 'fcs/left-brake-cmd-norm': 0,\n", + " 'fcs/right-brake-cmd-norm': 0,\n", + " 'fcs/center-brake-cmd-norm': 0,\n", + " 'propulsion/engine/pitch-angle-rad': 0,\n", + " },\n", + " design_vector=[\n", + " 'fcs/throttle-cmd-norm',\n", + " 'fcs/elevator-cmd-norm',\n", + " 'fcs/rudder-cmd-norm',\n", + " 'fcs/aileron-cmd-norm',\n", + " 'ic/alpha-rad',\n", + " 'ic/beta-rad',\n", + " ],\n", + " method='SLSQP',\n", + " eq_constraints= [\n", + " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", + " lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", + " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", + " lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", + " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", + " lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", + " ],\n", + " cost=lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", + " x0=[0.5, 0, 0, 0, 0, 0],\n", + " verbose=False,\n", + " bounds=[[0, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1]],\n", + " tol=1e-3\n", + ")\n", + "op_cruise" + ], + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/gamma-deg': 0,\n", + " 'ic/vt-fps': 600,\n", + " 'ic/h-sl-ft': 10000,\n", + " 'gear/gear-cmd-norm': 0,\n", + " 'fcs/left-brake-cmd-norm': 0,\n", + " 'fcs/right-brake-cmd-norm': 0,\n", + " 'fcs/center-brake-cmd-norm': 0,\n", + " 'propulsion/engine/pitch-angle-rad': 0,\n", + " 'fcs/throttle-cmd-norm': 0.517034845422154,\n", + " 'fcs/elevator-cmd-norm': 0.016566403310709667,\n", + " 'fcs/rudder-cmd-norm': 0.0005789895577208944,\n", + " 'fcs/aileron-cmd-norm': -7.475797765000361e-06,\n", + " 'ic/alpha-rad': 0.0306927317348206,\n", + " 'ic/beta-rad': 0.00042105315200845336}" + ] + }, + "metadata": {}, + "execution_count": 38 + } + ], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 39, + "source": [ + "log_cruise = simulate(\n", + " aircraft='F-35B-2',\n", + " op_0=op_cruise,\n", + " tf=10,\n", + " realtime=False)" + ], + "outputs": [], + "metadata": {} + }, + { + "cell_type": "code", + "execution_count": 40, + "source": [ + "op_cruise_auto = dict(op_cruise)\n", + "#op_cruise_auto['ic/theta-deg'] = 0\n", + "#op_cruise_auto['ic/phi-deg'] = 0\n", + "op_cruise_auto['ap/roll-enable'] = 1\n", + "op_cruise_auto['ap/pitch-enable'] = 1\n", + "op_cruise_auto['ap/yaw-enable'] = 1\n", + "op_cruise_auto['ap/h-enable'] = 1\n", + "op_cruise_auto['ap/heading-cmd-deg'] = 260\n", + "op_cruise_auto['ap/h-sl-cmd-ft'] = 10000\n", + "\n", + "log_cruise_auto = simulate(\n", + " aircraft='F-35B-2',\n", + " op_0=op_cruise_auto,\n", + " tf=40,\n", + " realtime=False)" + ], + "outputs": [], + "metadata": {} + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "name": "python", + "version": "3.9.6", + "mimetype": "text/x-python", + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "pygments_lexer": "ipython3", + "nbconvert_exporter": "python", + "file_extension": ".py" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} \ No newline at end of file From d0a6c56abc0574ea183ba0e5104ca7a7039ad924 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 10:37:35 -0700 Subject: [PATCH 02/15] git hell, this file causes git rebase, etc to fail --- Aircraft/Boomy/Engines/p300.xml | 57 ++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/Aircraft/Boomy/Engines/p300.xml b/Aircraft/Boomy/Engines/p300.xml index 517f89d..d515a5a 100644 --- a/Aircraft/Boomy/Engines/p300.xml +++ b/Aircraft/Boomy/Engines/p300.xml @@ -1,20 +1,31 @@ + - 67.4 - 1.0 - 0.8 + 290 + 1.000 + 0.875 0.03 30.0 60.0 @@ -28,13 +39,13 @@ velocities/mach atmosphere/density-altitude - -10000 0 10000 20000 30000 40000 50000 60000 + -10000 0 10000 20000 30000 40000 50000 90000 0.0 0.0430 0.0488 0.0528 0.0694 0.0899 0.1183 0.1467 0 0.2 0.0500 0.0501 0.0335 0.0544 0.0797 0.1049 0.1342 0 0.4 0.0040 0.0047 0.0020 0.0272 0.0595 0.0891 0.1203 0 - 0.6 0.0 0.0 0.0 0.0 0.0276 0.0718 0.1073 0 - 0.8 0.0 0.0 0.0 0.0 0.0474 0.0868 0.0900 0 - 1.0 0.0 0.0 0.0 0.0 0.0 0.0552 0.0800 0 + 0.6 -0.0804 -0.0804 -0.0560 -0.0237 0.0276 0.0718 0.1073 0 + 0.8 -0.2129 -0.2129 -0.1498 -0.1025 0.0474 0.0868 0.0900 0 + 1.0 -0.2839 -0.2839 -0.1104 -0.0469 -0.0270 0.0552 0.0800 0 @@ -44,15 +55,15 @@ velocities/mach atmosphere/density-altitude - -10000 0 10000 20000 30000 40000 50000 60000 - 0.0 1.2600 1.0000 0.7400 0.5340 0.3720 0.2410 0.1490 0 - 0.2 1.1710 0.9340 0.6970 0.5060 0.3550 0.2310 0.1430 0 - 0.4 1.1500 0.9210 0.6920 0.5060 0.3570 0.2330 0.1450 0 - 0.6 1.1810 0.9510 0.7210 0.5320 0.3780 0.2480 0.1540 0 - 0.8 1.2580 1.0200 0.7820 0.5820 0.4170 0.2750 0.1700 0 - 1.0 1.3690 1.1200 0.8710 0.6510 0.4750 0.3150 0.1950 0 - 1.2 1.4850 1.2300 0.9750 0.7440 0.5450 0.3640 0.2250 0 - 1.4 1.5941 1.3400 1.0860 0.8450 0.6280 0.4240 0.2630 0 + -10000 0 10000 20000 30000 40000 50000 60000 90000 + 0.0 1.2600 1.0000 0.7400 0.5340 0.3720 0.2410 0.1490 0.0580 0 + 0.2 1.1452 0.9135 0.6817 0.4949 0.3472 0.2259 0.1399 0.0391 0 + 0.4 1.0994 0.8805 0.6616 0.4837 0.3413 0.2227 0.1386 0.0411 0 + 0.6 1.1031 0.8882 0.6734 0.4969 0.3531 0.2316 0.1438 0.0439 0 + 0.8 1.1473 0.9302 0.7132 0.5308 0.3803 0.2508 0.1550 0.0483 0 + 1.0 1.2184 0.9968 0.7752 0.5794 0.4227 0.2803 0.1735 0.0561 0 + 1.2 1.2890 1.0676 0.8463 0.6458 0.4731 0.3160 0.1953 0.0642 0 + 1.4 1.3486 1.1336 0.9188 0.7149 0.5313 0.3587 0.2225 0.0761 0 From 274c12381b8d651fe8910490d1771f25f93a32e2 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 10:57:25 -0700 Subject: [PATCH 03/15] update notebook --- scripts/simple-body.ipynb | 130 ++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index f3ea3e3..55db737 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 22, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 23, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 24, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -65,16 +65,16 @@ "output_type": "stream", "name": "stdout", "text": [ - " final_simplex: (array([[-0.0345507 , 0.06439891],\n", - " [-0.03458697, 0.0644949 ],\n", - " [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n", - " fun: 0.001012183546600445\n", + " final_simplex: (array([[-0.00398416, -0.0198497 ],\n", + " [-0.00397723, -0.01982051],\n", + " [-0.00397813, -0.01978912]]), array([0.0010305 , 0.00103479, 0.00109463]))\n", + " fun: 0.0010305007323130465\n", " message: 'Optimization terminated successfully.'\n", - " nfev: 91\n", - " nit: 48\n", + " nfev: 78\n", + " nit: 41\n", " status: 0\n", " success: True\n", - " x: array([-0.0345507 , 0.06439891])\n" + " x: array([-0.00398416, -0.0198497 ])\n" ] }, { @@ -88,44 +88,53 @@ ] }, { - "output_type": "error", - "ename": "RuntimeError", - "evalue": "trim failed:\n final_simplex: (array([[-0.0345507 , 0.06439891],\n [-0.03458697, 0.0644949 ],\n [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n fun: 0.001012183546600445\n message: 'Optimization terminated successfully.'\n nfev: 91\n nit: 48\n status: 0\n success: True\n x: array([-0.0345507 , 0.06439891])\n{'accelerations/a-pilot-x-ft_sec2': -1.1108579711719817, 'accelerations/a-pilot-y-ft_sec2': -3.794503730205625e-06, 'accelerations/a-pilot-z-ft_sec2': -32.138382691666095, 'accelerations/n-pilot-x-norm': -0.03452652124968466, 'accelerations/n-pilot-y-norm': -1.1793678136434711e-07, 'accelerations/n-pilot-z-norm': -0.9988914710344334, 'accelerations/Nx': -0.034526520905789185, 'accelerations/Ny': -1.277256636801932e-07, 'accelerations/Nz': 0.9989839055752421, 'accelerations/pdot-rad_sec2': 1.470095283222809e-05, 'accelerations/qdot-rad_sec2': -0.0014120579470234818, 'accelerations/rdot-rad_sec2': 1.3520516234706842e-07, 'accelerations/udot-ft_sec2': -1.9341280919515924e-05, 'accelerations/vdot-ft_sec2': -1.0399249578684788e-06, 'accelerations/wdot-ft_sec2': -0.0031920287673839615, 'accelerations/gravity-ft_sec2': 32.222006412476496}", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/3102752839.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_ground, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/h-agl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[0m\u001b[1;32m 124\u001b[0m str(fdm.get_property_catalog('acceleration')))\n\u001b[1;32m 125\u001b[0m \u001b[0mprops\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfdm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_property_catalog\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n final_simplex: (array([[-0.0345507 , 0.06439891],\n [-0.03458697, 0.0644949 ],\n [-0.03455205, 0.0644294 ]]), array([0.00101218, 0.00105623, 0.00106142]))\n fun: 0.001012183546600445\n message: 'Optimization terminated successfully.'\n nfev: 91\n nit: 48\n status: 0\n success: True\n x: array([-0.0345507 , 0.06439891])\n{'accelerations/a-pilot-x-ft_sec2': -1.1108579711719817, 'accelerations/a-pilot-y-ft_sec2': -3.794503730205625e-06, 'accelerations/a-pilot-z-ft_sec2': -32.138382691666095, 'accelerations/n-pilot-x-norm': -0.03452652124968466, 'accelerations/n-pilot-y-norm': -1.1793678136434711e-07, 'accelerations/n-pilot-z-norm': -0.9988914710344334, 'accelerations/Nx': -0.034526520905789185, 'accelerations/Ny': -1.277256636801932e-07, 'accelerations/Nz': 0.9989839055752421, 'accelerations/pdot-rad_sec2': 1.470095283222809e-05, 'accelerations/qdot-rad_sec2': -0.0014120579470234818, 'accelerations/rdot-rad_sec2': 1.3520516234706842e-07, 'accelerations/udot-ft_sec2': -1.9341280919515924e-05, 'accelerations/vdot-ft_sec2': -1.0399249578684788e-06, 'accelerations/wdot-ft_sec2': -0.0031920287673839615, 'accelerations/gravity-ft_sec2': 32.222006412476496}" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/vt-fps': 0,\n", + " 'ic/h-agl-ft': -0.01984969996708967,\n", + " 'ic/psi-true-deg': 280,\n", + " 'fcs/left-brake-cmd-norm': 1,\n", + " 'fcs/right-brake-cmd-norm': 1,\n", + " 'fcs/center-brake-cmd-norm': 1,\n", + " 'ic/theta-rad': -0.0039841619774816615}" + ] + }, + "metadata": {}, + "execution_count": 24 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 25, "source": [ "op_ground" ], "outputs": [ { - "output_type": "error", - "ename": "NameError", - "evalue": "name 'op_ground' is not defined", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/1089983896.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mop_ground\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mNameError\u001b[0m: name 'op_ground' is not defined" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/vt-fps': 0,\n", + " 'ic/h-agl-ft': -0.01984969996708967,\n", + " 'ic/psi-true-deg': 280,\n", + " 'fcs/left-brake-cmd-norm': 1,\n", + " 'fcs/right-brake-cmd-norm': 1,\n", + " 'fcs/center-brake-cmd-norm': 1,\n", + " 'ic/theta-rad': -0.0039841619774816615}" + ] + }, + "metadata": {}, + "execution_count": 25 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 26, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -135,14 +144,13 @@ ], "outputs": [ { - "output_type": "error", - "ename": "NameError", - "evalue": "name 'op_ground' is not defined", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27214/1673139056.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m log_ground = simulate(\n\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mop_0\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mop_ground\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mtf\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m realtime=False, verbose=True)\n", - "\u001b[0;31mNameError\u001b[0m: name 'op_ground' is not defined" + "output_type": "stream", + "name": "stderr", + "text": [ + "\n", + " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "\n", + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" ] } ], @@ -157,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 16, "source": [ "op_hover, props = trim(\n", " aircraft=aircraft_model,\n", @@ -191,37 +199,25 @@ "outputs": [ { "output_type": "stream", - "name": "stdout", + "name": "stderr", "text": [ - " fun: 0.8644525429644134\n", - " jac: array([1., 0., 0.])\n", - " message: 'Optimization terminated successfully'\n", - " nfev: 30\n", - " nit: 7\n", - " njev: 7\n", - " status: 0\n", - " success: True\n", - " x: array([0.86445254, 0.03362766, 1.57079635])\n", - "constraint eq 1.177877240188252e-15\n", - "constraint eq -2.301472790122716e-08\n", - "constraint eq 3.591704833301481e-09\n" + "\n", + " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "\n", + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" ] }, { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", - " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", - " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", - " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" - ] - }, - "metadata": {}, - "execution_count": 31 + "output_type": "error", + "ename": "KeyError", + "evalue": "'ap/gear-enable'", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/1935956583.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m650\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdesign_vector\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mic\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfdm_props\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 59\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 60\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcost\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyError\u001b[0m: 'ap/gear-enable'" + ] } ], "metadata": {} From 163a6590d9e1ab0822401fd864d44c3e343307bf Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 11:04:57 -0700 Subject: [PATCH 04/15] clear old outputs --- scripts/simple-body.ipynb | 48 +++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index 55db737..ecf259d 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 27, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 28, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 29, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -101,14 +101,14 @@ ] }, "metadata": {}, - "execution_count": 24 + "execution_count": 29 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 30, "source": [ "op_ground" ], @@ -127,14 +127,14 @@ ] }, "metadata": {}, - "execution_count": 25 + "execution_count": 30 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 31, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -165,7 +165,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 34, "source": [ "op_hover, props = trim(\n", " aircraft=aircraft_model,\n", @@ -173,7 +173,7 @@ " 'ic/h-sl-ft': 650,\n", " 'ic/vt-fps': 0,\n", " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", + " # 'ap/gear-enable': 1,\n", " },\n", " eq_constraints = [\n", " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", @@ -197,6 +197,24 @@ "op_hover" ], "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " fun: 0.6164453353280344\n", + " jac: array([1., 0., 0.])\n", + " message: 'Positive directional derivative for linesearch'\n", + " nfev: 439\n", + " nit: 37\n", + " njev: 33\n", + " status: 8\n", + " success: False\n", + " x: array([0.61644534, 0.58239133, 1.09086184])\n", + "constraint eq -41.595277408061534\n", + "constraint eq -142903.92068414448\n", + "constraint eq -0.07156562722229864\n" + ] + }, { "output_type": "stream", "name": "stderr", @@ -209,14 +227,14 @@ }, { "output_type": "error", - "ename": "KeyError", - "evalue": "'ap/gear-enable'", + "ename": "RuntimeError", + "evalue": "trim failed:\n fun: 0.6164453353280344\n jac: array([1., 0., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 439\n nit: 37\n njev: 33\n status: 8\n success: False\n x: array([0.61644534, 0.58239133, 1.09086184])\n{'accelerations/a-pilot-x-ft_sec2': -41.59527876392836, 'accelerations/a-pilot-y-ft_sec2': -0.0012879597558687313, 'accelerations/a-pilot-z-ft_sec2': -142935.915294194, 'accelerations/n-pilot-x-norm': -1.292820786634107, 'accelerations/n-pilot-y-norm': -4.003101299513997e-05, 'accelerations/n-pilot-z-norm': -4442.5840609862025, 'accelerations/Nx': -1.2928207862607637, 'accelerations/Ny': -2.6659698126250696e-08, 'accelerations/Nz': 4442.58917503757, 'accelerations/pdot-rad_sec2': -2.240623954446845e-06, 'accelerations/qdot-rad_sec2': -0.07156562722229864, 'accelerations/rdot-rad_sec2': -0.0005599533054066842, 'accelerations/udot-ft_sec2': -41.59527740806153, 'accelerations/vdot-ft_sec2': 6.763629175141679e-06, 'accelerations/wdot-ft_sec2': -142903.92068414448, 'accelerations/gravity-ft_sec2': 32.22379771078389}", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/1935956583.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m650\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mdesign_vector\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mic\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mkey\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfdm_props\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkeys\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 59\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 60\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcost\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyError\u001b[0m: 'ap/gear-enable'" + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/4199646828.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[1;32m 125\u001b[0m str(fdm.get_property_catalog('acceleration')))\n", + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.6164453353280344\n jac: array([1., 0., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 439\n nit: 37\n njev: 33\n status: 8\n success: False\n x: array([0.61644534, 0.58239133, 1.09086184])\n{'accelerations/a-pilot-x-ft_sec2': -41.59527876392836, 'accelerations/a-pilot-y-ft_sec2': -0.0012879597558687313, 'accelerations/a-pilot-z-ft_sec2': -142935.915294194, 'accelerations/n-pilot-x-norm': -1.292820786634107, 'accelerations/n-pilot-y-norm': -4.003101299513997e-05, 'accelerations/n-pilot-z-norm': -4442.5840609862025, 'accelerations/Nx': -1.2928207862607637, 'accelerations/Ny': -2.6659698126250696e-08, 'accelerations/Nz': 4442.58917503757, 'accelerations/pdot-rad_sec2': -2.240623954446845e-06, 'accelerations/qdot-rad_sec2': -0.07156562722229864, 'accelerations/rdot-rad_sec2': -0.0005599533054066842, 'accelerations/udot-ft_sec2': -41.59527740806153, 'accelerations/vdot-ft_sec2': 6.763629175141679e-06, 'accelerations/wdot-ft_sec2': -142903.92068414448, 'accelerations/gravity-ft_sec2': 32.22379771078389}" ] } ], From 2d0b5bb9760fbbea89be180d74d05b708cdde2f3 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 11:12:35 -0700 Subject: [PATCH 05/15] add gitignore file --- scripts/.gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 scripts/.gitignore diff --git a/scripts/.gitignore b/scripts/.gitignore new file mode 100644 index 0000000..febeedb --- /dev/null +++ b/scripts/.gitignore @@ -0,0 +1,2 @@ +.ipynb_checkpoints +scipy/ \ No newline at end of file From 0de017845af4b1fbbf31ca01b13aa19c2ce418f7 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 11:12:52 -0700 Subject: [PATCH 06/15] hover trim initial condition --- scripts/simple-body.ipynb | 164 +++++++++----------------------------- 1 file changed, 36 insertions(+), 128 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index ecf259d..2d5479e 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 39, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 40, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 41, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -101,14 +101,14 @@ ] }, "metadata": {}, - "execution_count": 29 + "execution_count": 41 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 42, "source": [ "op_ground" ], @@ -127,14 +127,14 @@ ] }, "metadata": {}, - "execution_count": 30 + "execution_count": 42 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 43, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -165,34 +165,30 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 49, "source": [ "op_hover, props = trim(\n", " aircraft=aircraft_model,\n", " ic={\n", - " 'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " # 'ap/gear-enable': 1,\n", + " 'ic/h-sl-ft': 650, # Height above sea level initial condition in feet\n", + " 'ic/vt-fps': 500, # True airspeed initial condition in feet/second\n", + " 'ic/psi-true-deg': 280, # Heading angle initial condition in degrees\n", " },\n", " eq_constraints = [\n", " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", " #lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", " #lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", - " #lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", " ],\n", " design_vector=[\n", " 'fcs/throttle-cmd-norm',\n", " 'fcs/elevator-cmd-norm',\n", - " 'propulsion/engine/pitch-angle-rad',\n", " ],\n", - " x0=[0.9, 0.5, np.deg2rad(90)],\n", + " x0=[0.9, 0.5],\n", " cost= lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", " verbose=True,\n", " method='SLSQP',\n", - " bounds=[[0, 1], [-1, 1], [np.deg2rad(0), np.deg2rad(120)]],\n", + " bounds=[[0, 1], [-1, 1]],\n", ")\n", "op_hover" ], @@ -201,18 +197,17 @@ "output_type": "stream", "name": "stdout", "text": [ - " fun: 0.6164453353280344\n", - " jac: array([1., 0., 0.])\n", + " fun: 0.8999999999999997\n", + " jac: array([1., 0.])\n", " message: 'Positive directional derivative for linesearch'\n", - " nfev: 439\n", - " nit: 37\n", - " njev: 33\n", + " nfev: 347\n", + " nit: 53\n", + " njev: 49\n", " status: 8\n", " success: False\n", - " x: array([0.61644534, 0.58239133, 1.09086184])\n", - "constraint eq -41.595277408061534\n", - "constraint eq -142903.92068414448\n", - "constraint eq -0.07156562722229864\n" + " x: array([ 0.9 , -0.79099763])\n", + "constraint eq 42.76133080578421\n", + "constraint eq 32.21183905857108\n" ] }, { @@ -228,13 +223,13 @@ { "output_type": "error", "ename": "RuntimeError", - "evalue": "trim failed:\n fun: 0.6164453353280344\n jac: array([1., 0., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 439\n nit: 37\n njev: 33\n status: 8\n success: False\n x: array([0.61644534, 0.58239133, 1.09086184])\n{'accelerations/a-pilot-x-ft_sec2': -41.59527876392836, 'accelerations/a-pilot-y-ft_sec2': -0.0012879597558687313, 'accelerations/a-pilot-z-ft_sec2': -142935.915294194, 'accelerations/n-pilot-x-norm': -1.292820786634107, 'accelerations/n-pilot-y-norm': -4.003101299513997e-05, 'accelerations/n-pilot-z-norm': -4442.5840609862025, 'accelerations/Nx': -1.2928207862607637, 'accelerations/Ny': -2.6659698126250696e-08, 'accelerations/Nz': 4442.58917503757, 'accelerations/pdot-rad_sec2': -2.240623954446845e-06, 'accelerations/qdot-rad_sec2': -0.07156562722229864, 'accelerations/rdot-rad_sec2': -0.0005599533054066842, 'accelerations/udot-ft_sec2': -41.59527740806153, 'accelerations/vdot-ft_sec2': 6.763629175141679e-06, 'accelerations/wdot-ft_sec2': -142903.92068414448, 'accelerations/gravity-ft_sec2': 32.22379771078389}", + "evalue": "trim failed:\n fun: 0.8999999999999997\n jac: array([1., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 347\n nit: 53\n njev: 49\n status: 8\n success: False\n x: array([ 0.9 , -0.79099763])\n{'accelerations/a-pilot-x-ft_sec2': 42.76133035077288, 'accelerations/a-pilot-y-ft_sec2': 3.6409805536435045e-11, 'accelerations/a-pilot-z-ft_sec2': -4.1359030627651384e-25, 'accelerations/n-pilot-x-norm': 1.3290627779022985, 'accelerations/n-pilot-y-norm': 1.1316513516343913e-12, 'accelerations/n-pilot-z-norm': -1.2854779700823567e-26, 'accelerations/Nx': 1.329062778275642, 'accelerations/Ny': 0.0, 'accelerations/Nz': -0.0, 'accelerations/pdot-rad_sec2': 2.5848337571834437e-09, 'accelerations/qdot-rad_sec2': -4.557759320374709e-10, 'accelerations/rdot-rad_sec2': -5.113571937046131e-10, 'accelerations/udot-ft_sec2': 42.76133080578421, 'accelerations/vdot-ft_sec2': 0.047274842150382745, 'accelerations/wdot-ft_sec2': 32.21183905857108, 'accelerations/gravity-ft_sec2': 32.221809332708204}", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/4199646828.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/2447792778.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m650\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;31m# Height above sea level initial condition in feet\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m500\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;31m# True airspeed initial condition in feet/second\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[1;32m 125\u001b[0m str(fdm.get_property_catalog('acceleration')))\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.6164453353280344\n jac: array([1., 0., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 439\n nit: 37\n njev: 33\n status: 8\n success: False\n x: array([0.61644534, 0.58239133, 1.09086184])\n{'accelerations/a-pilot-x-ft_sec2': -41.59527876392836, 'accelerations/a-pilot-y-ft_sec2': -0.0012879597558687313, 'accelerations/a-pilot-z-ft_sec2': -142935.915294194, 'accelerations/n-pilot-x-norm': -1.292820786634107, 'accelerations/n-pilot-y-norm': -4.003101299513997e-05, 'accelerations/n-pilot-z-norm': -4442.5840609862025, 'accelerations/Nx': -1.2928207862607637, 'accelerations/Ny': -2.6659698126250696e-08, 'accelerations/Nz': 4442.58917503757, 'accelerations/pdot-rad_sec2': -2.240623954446845e-06, 'accelerations/qdot-rad_sec2': -0.07156562722229864, 'accelerations/rdot-rad_sec2': -0.0005599533054066842, 'accelerations/udot-ft_sec2': -41.59527740806153, 'accelerations/vdot-ft_sec2': 6.763629175141679e-06, 'accelerations/wdot-ft_sec2': -142903.92068414448, 'accelerations/gravity-ft_sec2': 32.22379771078389}" + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.8999999999999997\n jac: array([1., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 347\n nit: 53\n njev: 49\n status: 8\n success: False\n x: array([ 0.9 , -0.79099763])\n{'accelerations/a-pilot-x-ft_sec2': 42.76133035077288, 'accelerations/a-pilot-y-ft_sec2': 3.6409805536435045e-11, 'accelerations/a-pilot-z-ft_sec2': -4.1359030627651384e-25, 'accelerations/n-pilot-x-norm': 1.3290627779022985, 'accelerations/n-pilot-y-norm': 1.1316513516343913e-12, 'accelerations/n-pilot-z-norm': -1.2854779700823567e-26, 'accelerations/Nx': 1.329062778275642, 'accelerations/Ny': 0.0, 'accelerations/Nz': -0.0, 'accelerations/pdot-rad_sec2': 2.5848337571834437e-09, 'accelerations/qdot-rad_sec2': -4.557759320374709e-10, 'accelerations/rdot-rad_sec2': -5.113571937046131e-10, 'accelerations/udot-ft_sec2': 42.76133080578421, 'accelerations/vdot-ft_sec2': 0.047274842150382745, 'accelerations/wdot-ft_sec2': 32.21183905857108, 'accelerations/gravity-ft_sec2': 32.221809332708204}" ] } ], @@ -242,7 +237,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": null, "source": [ "log_hover = simulate(\n", " aircraft=aircraft_model,\n", @@ -255,33 +250,16 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": null, "source": [ "op_hover" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", - " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", - " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", - " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" - ] - }, - "metadata": {}, - "execution_count": 33 - } - ], + "outputs": [], "metadata": {} }, { "cell_type": "code", - "execution_count": 34, + "execution_count": null, "source": [ "op_hover_auto = dict(op_hover)\n", "op_hover_auto['ic/theta-deg'] = 0\n", @@ -307,7 +285,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": null, "source": [ "log_hover_auto['fcs/throttle-pos-norm'].plot(label='0')\n", "log_hover_auto['fcs/throttle-pos-norm[1]'].plot(label='1')\n", @@ -316,62 +294,16 @@ "\n", "plt.legend()" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 35 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], + "outputs": [], "metadata": {} }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "source": [ "log_hover_auto['ap/h-error'].plot()" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 9 - }, - { - "output_type": "display_data", - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - } - } - ], + "outputs": [], "metadata": {} }, { @@ -390,7 +322,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": null, "source": [ "op_cruise, props = trim(\n", " aircraft=aircraft_model,\n", @@ -429,36 +361,12 @@ ")\n", "op_cruise" ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/gamma-deg': 0,\n", - " 'ic/vt-fps': 600,\n", - " 'ic/h-sl-ft': 10000,\n", - " 'gear/gear-cmd-norm': 0,\n", - " 'fcs/left-brake-cmd-norm': 0,\n", - " 'fcs/right-brake-cmd-norm': 0,\n", - " 'fcs/center-brake-cmd-norm': 0,\n", - " 'propulsion/engine/pitch-angle-rad': 0,\n", - " 'fcs/throttle-cmd-norm': 0.517034845422154,\n", - " 'fcs/elevator-cmd-norm': 0.016566403310709667,\n", - " 'fcs/rudder-cmd-norm': 0.0005789895577208944,\n", - " 'fcs/aileron-cmd-norm': -7.475797765000361e-06,\n", - " 'ic/alpha-rad': 0.0306927317348206,\n", - " 'ic/beta-rad': 0.00042105315200845336}" - ] - }, - "metadata": {}, - "execution_count": 38 - } - ], + "outputs": [], "metadata": {} }, { "cell_type": "code", - "execution_count": 39, + "execution_count": null, "source": [ "log_cruise = simulate(\n", " aircraft='F-35B-2',\n", @@ -471,7 +379,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": null, "source": [ "op_cruise_auto = dict(op_cruise)\n", "#op_cruise_auto['ic/theta-deg'] = 0\n", From e7366e4dc1d754f19303250a56d51c50ce416201 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sun, 3 Oct 2021 12:08:55 -0700 Subject: [PATCH 07/15] list of initial conditions comment --- scripts/simple-body.ipynb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index 2d5479e..4c6ff87 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -169,6 +169,8 @@ "source": [ "op_hover, props = trim(\n", " aircraft=aircraft_model,\n", + " # For a list of initial conditions available:\n", + " # https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\n", " ic={\n", " 'ic/h-sl-ft': 650, # Height above sea level initial condition in feet\n", " 'ic/vt-fps': 500, # True airspeed initial condition in feet/second\n", From dbcc32d8543c0516301e8422b8dc004442939a43 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 7 Oct 2021 08:18:15 -0700 Subject: [PATCH 08/15] for cobyla method, remove contraints creation --- scripts/jsbsim_utils.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/scripts/jsbsim_utils.py b/scripts/jsbsim_utils.py index 9d5401a..cb2ab42 100644 --- a/scripts/jsbsim_utils.py +++ b/scripts/jsbsim_utils.py @@ -98,12 +98,13 @@ def eval_fdm_func(xd, fdm, ic, fdm_func): constraints = [] if eq_constraints is None: eq_constraints = [] - for con in eq_constraints: - constraints.append({ - 'type': 'eq', - 'fun': eval_fdm_func, - 'args': (fdm, ic, con) - }) + else: + for con in eq_constraints: + constraints.append({ + 'type': 'eq', + 'fun': eval_fdm_func, + 'args': (fdm, ic, con) + }) # solve res = scipy.optimize.minimize( From 6ec08ab3c858f1f9a1009d255f8d50ac4af95c13 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 7 Oct 2021 08:18:46 -0700 Subject: [PATCH 09/15] add baseline aerocoefficients --- Aircraft/WaveRipper/WaveRipper.xml | 192 ++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-) diff --git a/Aircraft/WaveRipper/WaveRipper.xml b/Aircraft/WaveRipper/WaveRipper.xml index 0ba8fed..b99384e 100644 --- a/Aircraft/WaveRipper/WaveRipper.xml +++ b/Aircraft/WaveRipper/WaveRipper.xml @@ -46,7 +46,7 @@ 0.00 0.00 - + 0.015 0.893 0.908 @@ -147,6 +147,196 @@ + + + + + Lift_due_to_alpha + + + 4.846 + + + + + + + + Drag_at_zero_lift + + + 0.012472 + + + + + + + Side_force_due_to_beta + + + -0.972 + + + + + + + Roll_moment_due_to_beta + + + 0.0 + + + + Roll_moment_due_to_roll_rate + + + -0.477 + + + + Roll_moment_due_to_yaw_rate + + + 0.225 + + + + Roll_moment_due_to_aileron + + + 0.585 + + + + Roll_moment_due_to_rudder + + + 0.1 + + + + + + + Pitch_moment_due_to_alpha + + + -0.385 + + + + Pitch_moment_due_to_elevator + + 0.539 + + + Pitch_moment_due_to_pitch_rate + + -3.928 + + + Pitch_moment_due_to_alpha_rate + + -1.796 + + + + + + Yaw_moment_due_to_beta + + + 1.42 + + + + Yaw_moment_due_to_yaw_rate + + + -1.73 + + + + Yaw_moment_due_to_rudder + + + -0.861 + + + + Adverse_yaw + + + -0.016 + + + From d36e363ac01eca7595a1a6d828ab68e50cc65afb Mon Sep 17 00:00:00 2001 From: Minos Park Date: Thu, 7 Oct 2021 08:19:02 -0700 Subject: [PATCH 10/15] update jupyter notebook --- scripts/simple-body.ipynb | 242 ++++++++++++++++++++++++++++++-------- 1 file changed, 192 insertions(+), 50 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index 4c6ff87..c0e9ba5 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 75, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 76, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 77, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -65,16 +65,16 @@ "output_type": "stream", "name": "stdout", "text": [ - " final_simplex: (array([[-0.00398416, -0.0198497 ],\n", - " [-0.00397723, -0.01982051],\n", - " [-0.00397813, -0.01978912]]), array([0.0010305 , 0.00103479, 0.00109463]))\n", - " fun: 0.0010305007323130465\n", + " final_simplex: (array([[-0.06305111, 0.17624348],\n", + " [-0.06304254, 0.17621589],\n", + " [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n", + " fun: 476.0019582057659\n", " message: 'Optimization terminated successfully.'\n", - " nfev: 78\n", - " nit: 41\n", + " nfev: 106\n", + " nit: 57\n", " status: 0\n", " success: True\n", - " x: array([-0.00398416, -0.0198497 ])\n" + " x: array([-0.06305111, 0.17624348])\n" ] }, { @@ -82,33 +82,77 @@ "name": "stderr", "text": [ "\n", - " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", "\n", - " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" ] }, { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/vt-fps': 0,\n", - " 'ic/h-agl-ft': -0.01984969996708967,\n", - " 'ic/psi-true-deg': 280,\n", - " 'fcs/left-brake-cmd-norm': 1,\n", - " 'fcs/right-brake-cmd-norm': 1,\n", - " 'fcs/center-brake-cmd-norm': 1,\n", - " 'ic/theta-rad': -0.0039841619774816615}" - ] - }, - "metadata": {}, - "execution_count": 41 + "output_type": "error", + "ename": "RuntimeError", + "evalue": "trim failed:\n final_simplex: (array([[-0.06305111, 0.17624348],\n [-0.06304254, 0.17621589],\n [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n fun: 476.0019582057659\n message: 'Optimization terminated successfully.'\n nfev: 106\n nit: 57\n status: 0\n success: True\n x: array([-0.06305111, 0.17624348])\n{'accelerations/a-pilot-x-ft_sec2': -1.1887984221204722, 'accelerations/a-pilot-y-ft_sec2': -1.5877559249554671, 'accelerations/a-pilot-z-ft_sec2': -21.075090116438524, 'accelerations/n-pilot-x-norm': -0.03694898452196417, 'accelerations/n-pilot-y-norm': -0.049348962788151554, 'accelerations/n-pilot-z-norm': -0.6550338257703153, 'accelerations/Nx': -0.03694898414513271, 'accelerations/Ny': 0.012089443581904002, 'accelerations/Nz': 0.698537845313642, 'accelerations/pdot-rad_sec2': 19.53253661033347, 'accelerations/qdot-rad_sec2': -0.6087917782359302, 'accelerations/rdot-rad_sec2': -0.8597641563914715, 'accelerations/udot-ft_sec2': 0.8371410653344071, 'accelerations/vdot-ft_sec2': 0.38896936270718196, 'accelerations/wdot-ft_sec2': 9.61868443684593, 'accelerations/gravity-ft_sec2': 32.22200606778288}", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/467642672.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_ground, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/h-agl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n final_simplex: (array([[-0.06305111, 0.17624348],\n [-0.06304254, 0.17621589],\n [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n fun: 476.0019582057659\n message: 'Optimization terminated successfully.'\n nfev: 106\n nit: 57\n status: 0\n success: True\n x: array([-0.06305111, 0.17624348])\n{'accelerations/a-pilot-x-ft_sec2': -1.1887984221204722, 'accelerations/a-pilot-y-ft_sec2': -1.5877559249554671, 'accelerations/a-pilot-z-ft_sec2': -21.075090116438524, 'accelerations/n-pilot-x-norm': -0.03694898452196417, 'accelerations/n-pilot-y-norm': -0.049348962788151554, 'accelerations/n-pilot-z-norm': -0.6550338257703153, 'accelerations/Nx': -0.03694898414513271, 'accelerations/Ny': 0.012089443581904002, 'accelerations/Nz': 0.698537845313642, 'accelerations/pdot-rad_sec2': 19.53253661033347, 'accelerations/qdot-rad_sec2': -0.6087917782359302, 'accelerations/rdot-rad_sec2': -0.8597641563914715, 'accelerations/udot-ft_sec2': 0.8371410653344071, 'accelerations/vdot-ft_sec2': 0.38896936270718196, 'accelerations/wdot-ft_sec2': 9.61868443684593, 'accelerations/gravity-ft_sec2': 32.22200606778288}" + ] } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 78, "source": [ "op_ground" ], @@ -127,14 +171,14 @@ ] }, "metadata": {}, - "execution_count": 42 + "execution_count": 78 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 79, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -148,9 +192,57 @@ "name": "stderr", "text": [ "\n", - " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", "\n", - " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" ] } ], @@ -165,7 +257,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 88, "source": [ "op_hover, props = trim(\n", " aircraft=aircraft_model,\n", @@ -178,18 +270,20 @@ " },\n", " eq_constraints = [\n", " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", - " #lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", + " # lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", - " #lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", + " # lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", " ],\n", " design_vector=[\n", " 'fcs/throttle-cmd-norm',\n", " 'fcs/elevator-cmd-norm',\n", " ],\n", - " x0=[0.9, 0.5],\n", + " x0=[0.9],\n", " cost= lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", " verbose=True,\n", " method='SLSQP',\n", + " # method=\"cobyla\",\n", + " # bounds=[[0, 1]],\n", " bounds=[[0, 1], [-1, 1]],\n", ")\n", "op_hover" @@ -199,17 +293,17 @@ "output_type": "stream", "name": "stdout", "text": [ - " fun: 0.8999999999999997\n", + " fun: 0.9\n", " jac: array([1., 0.])\n", - " message: 'Positive directional derivative for linesearch'\n", - " nfev: 347\n", - " nit: 53\n", - " njev: 49\n", - " status: 8\n", + " message: 'Inequality constraints incompatible'\n", + " nfev: 57\n", + " nit: 6\n", + " njev: 6\n", + " status: 4\n", " success: False\n", - " x: array([ 0.9 , -0.79099763])\n", - "constraint eq 42.76133080578421\n", - "constraint eq 32.21183905857108\n" + " x: array([ 0.9 , -0.15950893])\n", + "constraint eq 42.751376462883385\n", + "constraint eq 28.344075612647305\n" ] }, { @@ -217,21 +311,69 @@ "name": "stderr", "text": [ "\n", - " The aerodynamic axis system has been set by default to the Lift/Side/Drag system.\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", + "\n", + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", "\n", - " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", + "\u001b[31m only has one argument which makes it a no-op.\n", + "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" ] }, { "output_type": "error", "ename": "RuntimeError", - "evalue": "trim failed:\n fun: 0.8999999999999997\n jac: array([1., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 347\n nit: 53\n njev: 49\n status: 8\n success: False\n x: array([ 0.9 , -0.79099763])\n{'accelerations/a-pilot-x-ft_sec2': 42.76133035077288, 'accelerations/a-pilot-y-ft_sec2': 3.6409805536435045e-11, 'accelerations/a-pilot-z-ft_sec2': -4.1359030627651384e-25, 'accelerations/n-pilot-x-norm': 1.3290627779022985, 'accelerations/n-pilot-y-norm': 1.1316513516343913e-12, 'accelerations/n-pilot-z-norm': -1.2854779700823567e-26, 'accelerations/Nx': 1.329062778275642, 'accelerations/Ny': 0.0, 'accelerations/Nz': -0.0, 'accelerations/pdot-rad_sec2': 2.5848337571834437e-09, 'accelerations/qdot-rad_sec2': -4.557759320374709e-10, 'accelerations/rdot-rad_sec2': -5.113571937046131e-10, 'accelerations/udot-ft_sec2': 42.76133080578421, 'accelerations/vdot-ft_sec2': 0.047274842150382745, 'accelerations/wdot-ft_sec2': 32.21183905857108, 'accelerations/gravity-ft_sec2': 32.221809332708204}", + "evalue": "trim failed:\n fun: 0.9\n jac: array([1., 0.])\n message: 'Inequality constraints incompatible'\n nfev: 57\n nit: 6\n njev: 6\n status: 4\n success: False\n x: array([ 0.9 , -0.15950893])\n{'accelerations/a-pilot-x-ft_sec2': 42.751376007872054, 'accelerations/a-pilot-y-ft_sec2': -4.767527641235084, 'accelerations/a-pilot-z-ft_sec2': 12.3342143428962, 'accelerations/n-pilot-x-norm': 1.328753387466607, 'accelerations/n-pilot-y-norm': -0.1481792890587972, 'accelerations/n-pilot-z-norm': 0.383359101396987, 'accelerations/Nx': 1.3287533878399505, 'accelerations/Ny': -0.024112211633490973, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 39.14146800258483, 'accelerations/qdot-rad_sec2': -7.046958479424707, 'accelerations/rdot-rad_sec2': -1.736184781606401, 'accelerations/udot-ft_sec2': 42.751376462883385, 'accelerations/vdot-ft_sec2': -0.7285126257484911, 'accelerations/wdot-ft_sec2': 28.344075612647305, 'accelerations/gravity-ft_sec2': 32.221809332708204}", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/2447792778.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/h-sl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m650\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;31m# Height above sea level initial condition in feet\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m500\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;31m# True airspeed initial condition in feet/second\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[1;32m 125\u001b[0m str(fdm.get_property_catalog('acceleration')))\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.8999999999999997\n jac: array([1., 0.])\n message: 'Positive directional derivative for linesearch'\n nfev: 347\n nit: 53\n njev: 49\n status: 8\n success: False\n x: array([ 0.9 , -0.79099763])\n{'accelerations/a-pilot-x-ft_sec2': 42.76133035077288, 'accelerations/a-pilot-y-ft_sec2': 3.6409805536435045e-11, 'accelerations/a-pilot-z-ft_sec2': -4.1359030627651384e-25, 'accelerations/n-pilot-x-norm': 1.3290627779022985, 'accelerations/n-pilot-y-norm': 1.1316513516343913e-12, 'accelerations/n-pilot-z-norm': -1.2854779700823567e-26, 'accelerations/Nx': 1.329062778275642, 'accelerations/Ny': 0.0, 'accelerations/Nz': -0.0, 'accelerations/pdot-rad_sec2': 2.5848337571834437e-09, 'accelerations/qdot-rad_sec2': -4.557759320374709e-10, 'accelerations/rdot-rad_sec2': -5.113571937046131e-10, 'accelerations/udot-ft_sec2': 42.76133080578421, 'accelerations/vdot-ft_sec2': 0.047274842150382745, 'accelerations/wdot-ft_sec2': 32.21183905857108, 'accelerations/gravity-ft_sec2': 32.221809332708204}" + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/66356430.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# For a list of initial conditions available:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m ic={\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.9\n jac: array([1., 0.])\n message: 'Inequality constraints incompatible'\n nfev: 57\n nit: 6\n njev: 6\n status: 4\n success: False\n x: array([ 0.9 , -0.15950893])\n{'accelerations/a-pilot-x-ft_sec2': 42.751376007872054, 'accelerations/a-pilot-y-ft_sec2': -4.767527641235084, 'accelerations/a-pilot-z-ft_sec2': 12.3342143428962, 'accelerations/n-pilot-x-norm': 1.328753387466607, 'accelerations/n-pilot-y-norm': -0.1481792890587972, 'accelerations/n-pilot-z-norm': 0.383359101396987, 'accelerations/Nx': 1.3287533878399505, 'accelerations/Ny': -0.024112211633490973, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 39.14146800258483, 'accelerations/qdot-rad_sec2': -7.046958479424707, 'accelerations/rdot-rad_sec2': -1.736184781606401, 'accelerations/udot-ft_sec2': 42.751376462883385, 'accelerations/vdot-ft_sec2': -0.7285126257484911, 'accelerations/wdot-ft_sec2': 28.344075612647305, 'accelerations/gravity-ft_sec2': 32.221809332708204}" ] } ], From b87824bfbbbac93bcd5865dbcd05761f448c1f21 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 9 Oct 2021 19:24:15 -0700 Subject: [PATCH 11/15] remove hover trim --- scripts/simple-body.ipynb | 405 ++++++-------------------------------- 1 file changed, 60 insertions(+), 345 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index c0e9ba5..2cc1985 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 107, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 108, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 112, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -56,7 +56,7 @@ " x0=[0, 0],\n", " verbose=True,\n", " method='Nelder-Mead', # works better with ground interaction\n", - " ftol=1e-2,\n", + " ftol=1e-1,\n", ")\n", "op_ground" ], @@ -65,16 +65,16 @@ "output_type": "stream", "name": "stdout", "text": [ - " final_simplex: (array([[-0.06305111, 0.17624348],\n", - " [-0.06304254, 0.17621589],\n", - " [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n", - " fun: 476.0019582057659\n", + " final_simplex: (array([[-0.0036453 , -0.00151608],\n", + " [-0.0036714 , -0.00144496],\n", + " [-0.00367275, -0.00142257]]), array([0.09572609, 0.09572946, 0.09573725]))\n", + " fun: 0.095726085184104\n", " message: 'Optimization terminated successfully.'\n", - " nfev: 106\n", - " nit: 57\n", + " nfev: 55\n", + " nit: 29\n", " status: 0\n", " success: True\n", - " x: array([-0.06305111, 0.17624348])\n" + " x: array([-0.0036453 , -0.00151608])\n" ] }, { @@ -82,77 +82,31 @@ "name": "stderr", "text": [ "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" ] }, { - "output_type": "error", - "ename": "RuntimeError", - "evalue": "trim failed:\n final_simplex: (array([[-0.06305111, 0.17624348],\n [-0.06304254, 0.17621589],\n [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n fun: 476.0019582057659\n message: 'Optimization terminated successfully.'\n nfev: 106\n nit: 57\n status: 0\n success: True\n x: array([-0.06305111, 0.17624348])\n{'accelerations/a-pilot-x-ft_sec2': -1.1887984221204722, 'accelerations/a-pilot-y-ft_sec2': -1.5877559249554671, 'accelerations/a-pilot-z-ft_sec2': -21.075090116438524, 'accelerations/n-pilot-x-norm': -0.03694898452196417, 'accelerations/n-pilot-y-norm': -0.049348962788151554, 'accelerations/n-pilot-z-norm': -0.6550338257703153, 'accelerations/Nx': -0.03694898414513271, 'accelerations/Ny': 0.012089443581904002, 'accelerations/Nz': 0.698537845313642, 'accelerations/pdot-rad_sec2': 19.53253661033347, 'accelerations/qdot-rad_sec2': -0.6087917782359302, 'accelerations/rdot-rad_sec2': -0.8597641563914715, 'accelerations/udot-ft_sec2': 0.8371410653344071, 'accelerations/vdot-ft_sec2': 0.38896936270718196, 'accelerations/wdot-ft_sec2': 9.61868443684593, 'accelerations/gravity-ft_sec2': 32.22200606778288}", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/467642672.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_ground, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/h-agl-ft'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n final_simplex: (array([[-0.06305111, 0.17624348],\n [-0.06304254, 0.17621589],\n [-0.06305026, 0.17623362]]), array([476.00195821, 476.00200089, 476.00205581]))\n fun: 476.0019582057659\n message: 'Optimization terminated successfully.'\n nfev: 106\n nit: 57\n status: 0\n success: True\n x: array([-0.06305111, 0.17624348])\n{'accelerations/a-pilot-x-ft_sec2': -1.1887984221204722, 'accelerations/a-pilot-y-ft_sec2': -1.5877559249554671, 'accelerations/a-pilot-z-ft_sec2': -21.075090116438524, 'accelerations/n-pilot-x-norm': -0.03694898452196417, 'accelerations/n-pilot-y-norm': -0.049348962788151554, 'accelerations/n-pilot-z-norm': -0.6550338257703153, 'accelerations/Nx': -0.03694898414513271, 'accelerations/Ny': 0.012089443581904002, 'accelerations/Nz': 0.698537845313642, 'accelerations/pdot-rad_sec2': 19.53253661033347, 'accelerations/qdot-rad_sec2': -0.6087917782359302, 'accelerations/rdot-rad_sec2': -0.8597641563914715, 'accelerations/udot-ft_sec2': 0.8371410653344071, 'accelerations/vdot-ft_sec2': 0.38896936270718196, 'accelerations/wdot-ft_sec2': 9.61868443684593, 'accelerations/gravity-ft_sec2': 32.22200606778288}" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/vt-fps': 0,\n", + " 'ic/h-agl-ft': -0.0015160835740243772,\n", + " 'ic/psi-true-deg': 280,\n", + " 'fcs/left-brake-cmd-norm': 1,\n", + " 'fcs/right-brake-cmd-norm': 1,\n", + " 'fcs/center-brake-cmd-norm': 1,\n", + " 'ic/theta-rad': -0.003645302904478732}" + ] + }, + "metadata": {}, + "execution_count": 112 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 113, "source": [ "op_ground" ], @@ -162,23 +116,23 @@ "data": { "text/plain": [ "{'ic/vt-fps': 0,\n", - " 'ic/h-agl-ft': -0.01984969996708967,\n", + " 'ic/h-agl-ft': -0.0015160835740243772,\n", " 'ic/psi-true-deg': 280,\n", " 'fcs/left-brake-cmd-norm': 1,\n", " 'fcs/right-brake-cmd-norm': 1,\n", " 'fcs/center-brake-cmd-norm': 1,\n", - " 'ic/theta-rad': -0.0039841619774816615}" + " 'ic/theta-rad': -0.003645302904478732}" ] }, "metadata": {}, - "execution_count": 78 + "execution_count": 113 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 114, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -192,271 +146,12 @@ "name": "stderr", "text": [ "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" ] } ], "metadata": {} }, - { - "cell_type": "markdown", - "source": [ - "## Hover Trim" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 88, - "source": [ - "op_hover, props = trim(\n", - " aircraft=aircraft_model,\n", - " # For a list of initial conditions available:\n", - " # https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\n", - " ic={\n", - " 'ic/h-sl-ft': 650, # Height above sea level initial condition in feet\n", - " 'ic/vt-fps': 500, # True airspeed initial condition in feet/second\n", - " 'ic/psi-true-deg': 280, # Heading angle initial condition in degrees\n", - " },\n", - " eq_constraints = [\n", - " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", - " # lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", - " # lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " ],\n", - " design_vector=[\n", - " 'fcs/throttle-cmd-norm',\n", - " 'fcs/elevator-cmd-norm',\n", - " ],\n", - " x0=[0.9],\n", - " cost= lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", - " verbose=True,\n", - " method='SLSQP',\n", - " # method=\"cobyla\",\n", - " # bounds=[[0, 1]],\n", - " bounds=[[0, 1], [-1, 1]],\n", - ")\n", - "op_hover" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - " fun: 0.9\n", - " jac: array([1., 0.])\n", - " message: 'Inequality constraints incompatible'\n", - " nfev: 57\n", - " nit: 6\n", - " njev: 6\n", - " status: 4\n", - " success: False\n", - " x: array([ 0.9 , -0.15950893])\n", - "constraint eq 42.751376462883385\n", - "constraint eq 28.344075612647305\n" - ] - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 155\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 175\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 186\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 198\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 208\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 219\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 230\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 240\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 253\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 300\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 310\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 321\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n", - "\n", - "In file /Users/dev273/workfolder/boom/engine/aircraft/WaveRipper/WaveRipper.xml: line 331\n", - "\u001b[31m only has one argument which makes it a no-op.\n", - "Its argument will be evaluated but will not be applied to the result.\u001b[0m\n" - ] - }, - { - "output_type": "error", - "ename": "RuntimeError", - "evalue": "trim failed:\n fun: 0.9\n jac: array([1., 0.])\n message: 'Inequality constraints incompatible'\n nfev: 57\n nit: 6\n njev: 6\n status: 4\n success: False\n x: array([ 0.9 , -0.15950893])\n{'accelerations/a-pilot-x-ft_sec2': 42.751376007872054, 'accelerations/a-pilot-y-ft_sec2': -4.767527641235084, 'accelerations/a-pilot-z-ft_sec2': 12.3342143428962, 'accelerations/n-pilot-x-norm': 1.328753387466607, 'accelerations/n-pilot-y-norm': -0.1481792890587972, 'accelerations/n-pilot-z-norm': 0.383359101396987, 'accelerations/Nx': 1.3287533878399505, 'accelerations/Ny': -0.024112211633490973, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 39.14146800258483, 'accelerations/qdot-rad_sec2': -7.046958479424707, 'accelerations/rdot-rad_sec2': -1.736184781606401, 'accelerations/udot-ft_sec2': 42.751376462883385, 'accelerations/vdot-ft_sec2': -0.7285126257484911, 'accelerations/wdot-ft_sec2': 28.344075612647305, 'accelerations/gravity-ft_sec2': 32.221809332708204}", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/66356430.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_hover, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# For a list of initial conditions available:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m ic={\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.9\n jac: array([1., 0.])\n message: 'Inequality constraints incompatible'\n nfev: 57\n nit: 6\n njev: 6\n status: 4\n success: False\n x: array([ 0.9 , -0.15950893])\n{'accelerations/a-pilot-x-ft_sec2': 42.751376007872054, 'accelerations/a-pilot-y-ft_sec2': -4.767527641235084, 'accelerations/a-pilot-z-ft_sec2': 12.3342143428962, 'accelerations/n-pilot-x-norm': 1.328753387466607, 'accelerations/n-pilot-y-norm': -0.1481792890587972, 'accelerations/n-pilot-z-norm': 0.383359101396987, 'accelerations/Nx': 1.3287533878399505, 'accelerations/Ny': -0.024112211633490973, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 39.14146800258483, 'accelerations/qdot-rad_sec2': -7.046958479424707, 'accelerations/rdot-rad_sec2': -1.736184781606401, 'accelerations/udot-ft_sec2': 42.751376462883385, 'accelerations/vdot-ft_sec2': -0.7285126257484911, 'accelerations/wdot-ft_sec2': 28.344075612647305, 'accelerations/gravity-ft_sec2': 32.221809332708204}" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "log_hover = simulate(\n", - " aircraft=aircraft_model,\n", - " op_0=op_hover,\n", - " tf=10,\n", - " realtime=False)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "op_hover" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "op_hover_auto = dict(op_hover)\n", - "op_hover_auto['ic/theta-deg'] = 0\n", - "op_hover_auto['ic/phi-deg'] = 0\n", - "op_hover_auto['ic/h-agl-ft'] = 60\n", - "\n", - "op_hover_auto['ap/heading-cmd-deg'] = 280\n", - "op_hover_auto['ap/gear-enable'] = 1\n", - "op_hover_auto['ap/roll-enable'] = 0\n", - "op_hover_auto['ap/pitch-enable'] = 1\n", - "op_hover_auto['ap/yaw-enable'] = 0\n", - "op_hover_auto['ap/h-enable'] = 1\n", - "op_hover_auto['ap/h-sl-cmd-ft'] = 700\n", - "\n", - "log_hover_auto = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_hover_auto,\n", - " tf=50,\n", - " realtime=False, verbose=True)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "log_hover_auto['fcs/throttle-pos-norm'].plot(label='0')\n", - "log_hover_auto['fcs/throttle-pos-norm[1]'].plot(label='1')\n", - "log_hover_auto['fcs/throttle-pos-norm[2]'].plot(label='2')\n", - "log_hover_auto['fcs/throttle-pos-norm[3]'].plot(label='3')\n", - "\n", - "plt.legend()" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "log_hover_auto['ap/h-error'].plot()" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Transition" - ], - "metadata": {} - }, { "cell_type": "markdown", "source": [ @@ -466,18 +161,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 116, "source": [ "op_cruise, props = trim(\n", " aircraft=aircraft_model,\n", + " # For a list of initial conditions available:\n", + " # https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\n", " ic={\n", - " 'ic/gamma-deg': 0,\n", - " 'ic/vt-fps': 600,\n", - " 'ic/h-sl-ft': 10000,\n", + " 'ic/gamma-deg': 0, # Flightpath angle initial condition in degrees\n", + " 'ic/vt-fps': 600, # True airspeed initial condition in feet/second\n", + " 'ic/h-sl-ft': 10000, # Height above sea level initial condition in feet\n", " 'gear/gear-cmd-norm': 0,\n", - " 'fcs/left-brake-cmd-norm': 0,\n", - " 'fcs/right-brake-cmd-norm': 0,\n", - " 'fcs/center-brake-cmd-norm': 0,\n", " 'propulsion/engine/pitch-angle-rad': 0,\n", " },\n", " design_vector=[\n", @@ -505,7 +199,28 @@ ")\n", "op_cruise" ], - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\n", + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + ] + }, + { + "output_type": "error", + "ename": "RuntimeError", + "evalue": "trim failed:\n fun: 0.5\n jac: array([1., 0., 0., 0., 0., 0.])\n message: 'Singular matrix C in LSQ subproblem'\n nfev: 7\n nit: 1\n njev: 1\n status: 6\n success: False\n x: array([0.5, 0. , 0. , 0. , 0. , 0. ])\n{'accelerations/a-pilot-x-ft_sec2': 14.88468803876103, 'accelerations/a-pilot-y-ft_sec2': -1.062270911025521, 'accelerations/a-pilot-z-ft_sec2': -5.3178335117001145, 'accelerations/n-pilot-x-norm': 0.46263024725205476, 'accelerations/n-pilot-y-norm': -0.033016389254289576, 'accelerations/n-pilot-z-norm': -0.16528331839784177, 'accelerations/Nx': 0.462630247625398, 'accelerations/Ny': -0.024112211638101243, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 2.584833763975e-09, 'accelerations/qdot-rad_sec2': 0.6306997621480777, 'accelerations/rdot-rad_sec2': -0.12460435154496835, 'accelerations/udot-ft_sec2': 14.884675438581564, 'accelerations/vdot-ft_sec2': -0.7191321948201836, 'accelerations/wdot-ft_sec2': 28.326179640783543, 'accelerations/gravity-ft_sec2': 32.19300621350804}", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/2166325290.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_cruise, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# For a list of initial conditions available:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m ic={\n", + "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", + "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.5\n jac: array([1., 0., 0., 0., 0., 0.])\n message: 'Singular matrix C in LSQ subproblem'\n nfev: 7\n nit: 1\n njev: 1\n status: 6\n success: False\n x: array([0.5, 0. , 0. , 0. , 0. , 0. ])\n{'accelerations/a-pilot-x-ft_sec2': 14.88468803876103, 'accelerations/a-pilot-y-ft_sec2': -1.062270911025521, 'accelerations/a-pilot-z-ft_sec2': -5.3178335117001145, 'accelerations/n-pilot-x-norm': 0.46263024725205476, 'accelerations/n-pilot-y-norm': -0.033016389254289576, 'accelerations/n-pilot-z-norm': -0.16528331839784177, 'accelerations/Nx': 0.462630247625398, 'accelerations/Ny': -0.024112211638101243, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 2.584833763975e-09, 'accelerations/qdot-rad_sec2': 0.6306997621480777, 'accelerations/rdot-rad_sec2': -0.12460435154496835, 'accelerations/udot-ft_sec2': 14.884675438581564, 'accelerations/vdot-ft_sec2': -0.7191321948201836, 'accelerations/wdot-ft_sec2': 28.326179640783543, 'accelerations/gravity-ft_sec2': 32.19300621350804}" + ] + } + ], "metadata": {} }, { From 4c7180a1d2e9c6778aed2941ff6166a72d811760 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 9 Oct 2021 20:57:28 -0700 Subject: [PATCH 12/15] Narrow down the aerodynamics for cruise condition --- Aircraft/WaveRipper/WaveRipper.xml | 182 +++-------------------------- 1 file changed, 16 insertions(+), 166 deletions(-) diff --git a/Aircraft/WaveRipper/WaveRipper.xml b/Aircraft/WaveRipper/WaveRipper.xml index b99384e..7e3048a 100644 --- a/Aircraft/WaveRipper/WaveRipper.xml +++ b/Aircraft/WaveRipper/WaveRipper.xml @@ -149,194 +149,44 @@ + + + - - Lift_due_to_alpha - - - 4.846 - - - + Drag_at_zero_lift - - 0.012472 + aero/qbar-psf + metrics/Sw-sqft + 0.012472 - + - -0.972 - - - - - - - Roll_moment_due_to_beta - - - 0.0 - - - - Roll_moment_due_to_roll_rate - - - -0.477 - - - - Roll_moment_due_to_yaw_rate - - - 0.225 - - - - Roll_moment_due_to_aileron - - - 0.585 - - - - Roll_moment_due_to_rudder - - - 0.1 - - - - - - - Pitch_moment_due_to_alpha - - - -0.385 - - - - Pitch_moment_due_to_elevator - - 0.539 - - - Pitch_moment_due_to_pitch_rate - - -3.928 - - - Pitch_moment_due_to_alpha_rate - - -1.796 - - - - - - Yaw_moment_due_to_beta - - - 1.42 - - - - Yaw_moment_due_to_yaw_rate - - - -1.73 - - - - Yaw_moment_due_to_rudder - - - -0.861 - - - - Adverse_yaw - - - -0.016 + aero/beta-rad + -0.972 - + --> From 83507b8cb5df792d8a09dcedcd47166c39a6b92d Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 9 Oct 2021 20:58:18 -0700 Subject: [PATCH 13/15] cruise trim with Nelder-Mead method --- scripts/simple-body.ipynb | 112 +++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 45 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index 2cc1985..0dac257 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 1, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 2, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 3, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -56,7 +56,7 @@ " x0=[0, 0],\n", " verbose=True,\n", " method='Nelder-Mead', # works better with ground interaction\n", - " ftol=1e-1,\n", + " ftol=1e-1, # TODO: once full aircraft params are specified, we can have finer fun tolerence\n", ")\n", "op_ground" ], @@ -65,16 +65,23 @@ "output_type": "stream", "name": "stdout", "text": [ - " final_simplex: (array([[-0.0036453 , -0.00151608],\n", - " [-0.0036714 , -0.00144496],\n", - " [-0.00367275, -0.00142257]]), array([0.09572609, 0.09572946, 0.09573725]))\n", - " fun: 0.095726085184104\n", + "\n", + "\n", + " JSBSim Flight Dynamics Model v1.1.8 [GitHub build 588/commit c943f83deeb3e14bed7939ac65dfac789a7a0181] Jul 30 2021 15:04:27\n", + " [JSBSim-ML v2.0]\n", + "\n", + "JSBSim startup beginning ...\n", + "\n", + " final_simplex: (array([[-0.00398416, -0.0198497 ],\n", + " [-0.00397723, -0.01982051],\n", + " [-0.00397813, -0.01978912]]), array([0.0010305 , 0.00103479, 0.00109463]))\n", + " fun: 0.0010305007323130465\n", " message: 'Optimization terminated successfully.'\n", - " nfev: 55\n", - " nit: 29\n", + " nfev: 78\n", + " nit: 41\n", " status: 0\n", " success: True\n", - " x: array([-0.0036453 , -0.00151608])\n" + " x: array([-0.00398416, -0.0198497 ])\n" ] }, { @@ -90,23 +97,23 @@ "data": { "text/plain": [ "{'ic/vt-fps': 0,\n", - " 'ic/h-agl-ft': -0.0015160835740243772,\n", + " 'ic/h-agl-ft': -0.01984969996708967,\n", " 'ic/psi-true-deg': 280,\n", " 'fcs/left-brake-cmd-norm': 1,\n", " 'fcs/right-brake-cmd-norm': 1,\n", " 'fcs/center-brake-cmd-norm': 1,\n", - " 'ic/theta-rad': -0.003645302904478732}" + " 'ic/theta-rad': -0.0039841619774816615}" ] }, "metadata": {}, - "execution_count": 112 + "execution_count": 3 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 4, "source": [ "op_ground" ], @@ -116,23 +123,23 @@ "data": { "text/plain": [ "{'ic/vt-fps': 0,\n", - " 'ic/h-agl-ft': -0.0015160835740243772,\n", + " 'ic/h-agl-ft': -0.01984969996708967,\n", " 'ic/psi-true-deg': 280,\n", " 'fcs/left-brake-cmd-norm': 1,\n", " 'fcs/right-brake-cmd-norm': 1,\n", " 'fcs/center-brake-cmd-norm': 1,\n", - " 'ic/theta-rad': -0.003645302904478732}" + " 'ic/theta-rad': -0.0039841619774816615}" ] }, "metadata": {}, - "execution_count": 113 + "execution_count": 4 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 5, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -161,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 6, "source": [ "op_cruise, props = trim(\n", " aircraft=aircraft_model,\n", @@ -171,8 +178,7 @@ " 'ic/gamma-deg': 0, # Flightpath angle initial condition in degrees\n", " 'ic/vt-fps': 600, # True airspeed initial condition in feet/second\n", " 'ic/h-sl-ft': 10000, # Height above sea level initial condition in feet\n", - " 'gear/gear-cmd-norm': 0,\n", - " 'propulsion/engine/pitch-angle-rad': 0,\n", + " # 'gear/gear-cmd-norm': 0,\n", " },\n", " design_vector=[\n", " 'fcs/throttle-cmd-norm',\n", @@ -182,15 +188,16 @@ " 'ic/alpha-rad',\n", " 'ic/beta-rad',\n", " ],\n", - " method='SLSQP',\n", - " eq_constraints= [\n", - " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", - " ],\n", + " # method='SLSQP',\n", + " method='Nelder-Mead',\n", + " # eq_constraints= [\n", + " # lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", + " # lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", + " # # lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", + " # # lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", + " # lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", + " # lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", + " # ],\n", " cost=lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", " x0=[0.5, 0, 0, 0, 0, 0],\n", " verbose=False,\n", @@ -209,36 +216,51 @@ ] }, { - "output_type": "error", - "ename": "RuntimeError", - "evalue": "trim failed:\n fun: 0.5\n jac: array([1., 0., 0., 0., 0., 0.])\n message: 'Singular matrix C in LSQ subproblem'\n nfev: 7\n nit: 1\n njev: 1\n status: 6\n success: False\n x: array([0.5, 0. , 0. , 0. , 0. , 0. ])\n{'accelerations/a-pilot-x-ft_sec2': 14.88468803876103, 'accelerations/a-pilot-y-ft_sec2': -1.062270911025521, 'accelerations/a-pilot-z-ft_sec2': -5.3178335117001145, 'accelerations/n-pilot-x-norm': 0.46263024725205476, 'accelerations/n-pilot-y-norm': -0.033016389254289576, 'accelerations/n-pilot-z-norm': -0.16528331839784177, 'accelerations/Nx': 0.462630247625398, 'accelerations/Ny': -0.024112211638101243, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 2.584833763975e-09, 'accelerations/qdot-rad_sec2': 0.6306997621480777, 'accelerations/rdot-rad_sec2': -0.12460435154496835, 'accelerations/udot-ft_sec2': 14.884675438581564, 'accelerations/vdot-ft_sec2': -0.7191321948201836, 'accelerations/wdot-ft_sec2': 28.326179640783543, 'accelerations/gravity-ft_sec2': 32.19300621350804}", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_27249/2166325290.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_cruise, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0maircraft_model\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;31m# For a list of initial conditions available:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;31m# https://jsbsim-team.github.io/jsbsim/classJSBSim_1_1FGInitialCondition.html\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m ic={\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mcon\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mconstraints\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'constraint'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'type'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'x'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mcon\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'args'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n fun: 0.5\n jac: array([1., 0., 0., 0., 0., 0.])\n message: 'Singular matrix C in LSQ subproblem'\n nfev: 7\n nit: 1\n njev: 1\n status: 6\n success: False\n x: array([0.5, 0. , 0. , 0. , 0. , 0. ])\n{'accelerations/a-pilot-x-ft_sec2': 14.88468803876103, 'accelerations/a-pilot-y-ft_sec2': -1.062270911025521, 'accelerations/a-pilot-z-ft_sec2': -5.3178335117001145, 'accelerations/n-pilot-x-norm': 0.46263024725205476, 'accelerations/n-pilot-y-norm': -0.033016389254289576, 'accelerations/n-pilot-z-norm': -0.16528331839784177, 'accelerations/Nx': 0.462630247625398, 'accelerations/Ny': -0.024112211638101243, 'accelerations/Nz': 0.12021376293816591, 'accelerations/pdot-rad_sec2': 2.584833763975e-09, 'accelerations/qdot-rad_sec2': 0.6306997621480777, 'accelerations/rdot-rad_sec2': -0.12460435154496835, 'accelerations/udot-ft_sec2': 14.884675438581564, 'accelerations/vdot-ft_sec2': -0.7191321948201836, 'accelerations/wdot-ft_sec2': 28.326179640783543, 'accelerations/gravity-ft_sec2': 32.19300621350804}" - ] + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'ic/gamma-deg': 0,\n", + " 'ic/vt-fps': 600,\n", + " 'ic/h-sl-ft': 10000,\n", + " 'fcs/throttle-cmd-norm': 0.0,\n", + " 'fcs/elevator-cmd-norm': 7.79320987654322e-05,\n", + " 'fcs/rudder-cmd-norm': 0.0008557098765432094,\n", + " 'fcs/aileron-cmd-norm': 0.0013742283950617285,\n", + " 'ic/alpha-rad': 0.0003804012345679012,\n", + " 'ic/beta-rad': 0.0005367798353909464}" + ] + }, + "metadata": {}, + "execution_count": 6 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "source": [ "log_cruise = simulate(\n", - " aircraft='F-35B-2',\n", + " aircraft=aircraft_model,\n", " op_0=op_cruise,\n", " tf=10,\n", " realtime=False)" ], - "outputs": [], + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "\n", + " The aerodynamic moment axis system has been set by default to the bodyXYZ system.\n" + ] + } + ], "metadata": {} }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "source": [ "op_cruise_auto = dict(op_cruise)\n", "#op_cruise_auto['ic/theta-deg'] = 0\n", From 843d518d7db92eaf384679c1f859bc4a5c18c8aa Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 9 Oct 2021 21:05:21 -0700 Subject: [PATCH 14/15] verbose output for cruise trim --- scripts/simple-body.ipynb | 59 ++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/scripts/simple-body.ipynb b/scripts/simple-body.ipynb index 0dac257..00f4892 100644 --- a/scripts/simple-body.ipynb +++ b/scripts/simple-body.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 9, "source": [ "import numpy as np\n", "import pandas as pd\n", @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 10, "source": [ "aircraft_model = 'WaveRipper'" ], @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 11, "source": [ "op_ground, props = trim(\n", " aircraft=aircraft_model,\n", @@ -65,13 +65,6 @@ "output_type": "stream", "name": "stdout", "text": [ - "\n", - "\n", - " JSBSim Flight Dynamics Model v1.1.8 [GitHub build 588/commit c943f83deeb3e14bed7939ac65dfac789a7a0181] Jul 30 2021 15:04:27\n", - " [JSBSim-ML v2.0]\n", - "\n", - "JSBSim startup beginning ...\n", - "\n", " final_simplex: (array([[-0.00398416, -0.0198497 ],\n", " [-0.00397723, -0.01982051],\n", " [-0.00397813, -0.01978912]]), array([0.0010305 , 0.00103479, 0.00109463]))\n", @@ -106,14 +99,14 @@ ] }, "metadata": {}, - "execution_count": 3 + "execution_count": 11 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 12, "source": [ "op_ground" ], @@ -132,14 +125,14 @@ ] }, "metadata": {}, - "execution_count": 4 + "execution_count": 12 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 13, "source": [ "log_ground = simulate(\n", " aircraft=aircraft_model,\n", @@ -168,7 +161,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 17, "source": [ "op_cruise, props = trim(\n", " aircraft=aircraft_model,\n", @@ -200,13 +193,41 @@ " # ],\n", " cost=lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", " x0=[0.5, 0, 0, 0, 0, 0],\n", - " verbose=False,\n", + " verbose=True,\n", " bounds=[[0, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1]],\n", " tol=1e-3\n", ")\n", "op_cruise" ], "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + " final_simplex: (array([[0.00000000e+00, 7.79320988e-05, 8.55709877e-04, 1.37422840e-03,\n", + " 3.80401235e-04, 5.36779835e-04],\n", + " [0.00000000e+00, 9.51271005e-05, 8.67503644e-04, 1.34718471e-03,\n", + " 3.53561171e-04, 5.54578547e-04],\n", + " [0.00000000e+00, 1.10616355e-04, 8.64988783e-04, 1.37300490e-03,\n", + " 3.56847637e-04, 5.53797416e-04],\n", + " [0.00000000e+00, 1.03089039e-04, 8.57761536e-04, 1.38455695e-03,\n", + " 3.61631468e-04, 5.87665673e-04],\n", + " [0.00000000e+00, 1.10478030e-04, 8.65550618e-04, 1.38227706e-03,\n", + " 3.77204869e-04, 5.69830379e-04],\n", + " [0.00000000e+00, 8.86781397e-05, 8.81321220e-04, 1.41567947e-03,\n", + " 3.71172207e-04, 5.59161913e-04],\n", + " [0.00000000e+00, 9.80941312e-05, 8.79452489e-04, 1.39160298e-03,\n", + " 3.71738854e-04, 5.68280515e-04]]), array([0., 0., 0., 0., 0., 0., 0.]))\n", + " fun: 0.0\n", + " message: 'Optimization terminated successfully.'\n", + " nfev: 70\n", + " nit: 28\n", + " status: 0\n", + " success: True\n", + " x: array([0.00000000e+00, 7.79320988e-05, 8.55709877e-04, 1.37422840e-03,\n", + " 3.80401235e-04, 5.36779835e-04])\n" + ] + }, { "output_type": "stream", "name": "stderr", @@ -231,14 +252,14 @@ ] }, "metadata": {}, - "execution_count": 6 + "execution_count": 17 } ], "metadata": {} }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 15, "source": [ "log_cruise = simulate(\n", " aircraft=aircraft_model,\n", @@ -260,7 +281,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 16, "source": [ "op_cruise_auto = dict(op_cruise)\n", "#op_cruise_auto['ic/theta-deg'] = 0\n", From 81d03f95dc7356cb9fea25cd8d450523d192b145 Mon Sep 17 00:00:00 2001 From: Minos Park Date: Sat, 23 Oct 2021 13:42:18 -0700 Subject: [PATCH 15/15] remove unsed notebook --- scripts/trim.ipynb | 1035 -------------------------------------------- 1 file changed, 1035 deletions(-) delete mode 100644 scripts/trim.ipynb diff --git a/scripts/trim.ipynb b/scripts/trim.ipynb deleted file mode 100644 index 2d5fb27..0000000 --- a/scripts/trim.ipynb +++ /dev/null @@ -1,1035 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "source": [ - "## AA451 Course Material" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 9, - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "# pull in new changes to python modules without having to restart notebook\n", - "\n", - "import numpy as np\n", - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "import control\n", - "\n", - "from scripts.jsbsim_utils import Logger, trim, simulate, linearize, rootlocus, clean_tf" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "The autoreload extension is already loaded. To reload it, use:\n", - " %reload_ext autoreload\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "Nonlinear-dynamics of aircraft\n", - "\n", - "$$\\dot{x} = f(x, u) \\approx f(x_0, u_0) + A(x-x0) + B(u - u0)$$\n", - "\n", - "Find equilibrium:\n", - "\n", - "Minimize $\\dot{x}$, or a subset for your problem, by changeing $x_0$, $u_0$\n", - "\n", - "$$0 = f(x_0, u_0)$$\n", - "\n", - "This is an optimization problem.\n", - "\n", - "* Matlab: fmincon, fminsearch\n", - "* Python: scipy.minimize (Nelder-Mead, SLSQP)\n", - "\n", - "Can simplify this problem with mixing matrices, to decouple the dynamcis into SISO (single-input-single output) systems." - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "Due to Taylor series error on the order of (dx^2). We know the linear model approx, does well near the equilibrium point. " - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "$\\dot{\\vec{x}} = \\vec{f}(x, u) = A \\vec{x} + B \\vec{u}$\n", - "\n", - "$\\dot{\\vec{y}} = C \\vec{x} + D \\vec{u}$\n", - "\n", - "\n", - "$A = \\dfrac{\\delta \\vec{f}(x0, u0)}{\\delta \\vec{x}}$\n", - "\n", - "$B = \\dfrac{\\delta \\vec{f}(x0, u0)}{\\delta \\vec{u}}$\n", - "\n", - "$C = \\dfrac{\\delta \\vec{y}(x0, u0)}{\\delta \\vec{x}}$\n", - "\n", - "$D = \\dfrac{\\delta \\vec{y}(x0, u0)}{\\delta \\vec{u}}$\n", - "\n", - "## Relative Stability\n", - "\n", - "* Measure of relative stability. Phase margin of 90 degrees.\n", - "\n", - "\n", - "* sin(2*pi*f*t), where f = 10 Hz, what does a phase of 90 degrees mean -> 0.025 delay in your feedback will destabilize your system\n", - "\n", - "* gain margin of 2 on pitch control -> if elevator genertes twice your predicted force, you destabilize your aircraft" - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# Ground Trim" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 14, - "source": [ - "op_ground, props = trim(\n", - " aircraft='WaveRipper',\n", - " ic={\n", - " 'ic/vt-fps': 0,\n", - " 'ic/h-agl-ft': 5,\n", - " 'ic/psi-true-deg': 280,\n", - " 'fcs/left-brake-cmd-norm': 1,\n", - " 'fcs/right-brake-cmd-norm': 1,\n", - " 'fcs/center-brake-cmd-norm': 1,\n", - " },\n", - " design_vector=['ic/theta-rad', 'ic/h-agl-ft'],\n", - " x0=[0, 0],\n", - " verbose=True,\n", - " method='Nelder-Mead', # works better with ground interaction\n", - " ftol=1e-3,\n", - ")\n", - "op_ground" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - " final_simplex: (array([[0.00000000e+00, 0.00000000e+00],\n", - " [1.97215226e-34, 0.00000000e+00],\n", - " [0.00000000e+00, 1.97215226e-34]]), array([nan, nan, nan]))\n", - " fun: nan\n", - " message: 'Maximum number of function evaluations has been exceeded.'\n", - " nfev: 403\n", - " nit: 101\n", - " status: 1\n", - " success: False\n", - " x: array([0., 0.])\n" - ] - }, - { - "output_type": "stream", - "name": "stderr", - "text": [ - "\n", - "\u001b[31mYOU HAVE AN INCOMPATIBLE CFG FILE FOR THIS AIRCRAFT. RESULTS WILL BE UNPREDICTABLE !!\n", - "Current version needed is: 2.0\n", - " You have version: 1.0\n", - "\u001b[39m\n" - ] - }, - { - "output_type": "error", - "ename": "RuntimeError", - "evalue": "trim failed:\n final_simplex: (array([[0.00000000e+00, 0.00000000e+00],\n [1.97215226e-34, 0.00000000e+00],\n [0.00000000e+00, 1.97215226e-34]]), array([nan, nan, nan]))\n fun: nan\n message: 'Maximum number of function evaluations has been exceeded.'\n nfev: 403\n nit: 101\n status: 1\n success: False\n x: array([0., 0.])\n{'accelerations/a-pilot-x-ft_sec2': nan, 'accelerations/a-pilot-y-ft_sec2': nan, 'accelerations/a-pilot-z-ft_sec2': nan, 'accelerations/n-pilot-x-norm': nan, 'accelerations/n-pilot-y-norm': nan, 'accelerations/n-pilot-z-norm': nan, 'accelerations/Nx': nan, 'accelerations/Ny': nan, 'accelerations/Nz': nan, 'accelerations/pdot-rad_sec2': nan, 'accelerations/qdot-rad_sec2': nan, 'accelerations/rdot-rad_sec2': nan, 'accelerations/udot-ft_sec2': nan, 'accelerations/vdot-ft_sec2': nan, 'accelerations/wdot-ft_sec2': nan, 'accelerations/gravity-ft_sec2': 32.2220066109964}", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m/var/folders/0y/ty6zvtq53lq_qltzlh53bf6w0000gn/T/ipykernel_40305/3580395665.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m op_ground, props = trim(\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0maircraft\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'WaveRipper'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m ic={\n\u001b[1;32m 4\u001b[0m \u001b[0;34m'ic/vt-fps'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m'ic/psi-true-deg'\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m280\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/workfolder/boom/engine/scripts/jsbsim_utils.py\u001b[0m in \u001b[0;36mtrim\u001b[0;34m(aircraft, ic, design_vector, x0, verbose, cost, eq_constraints, tol, ftol, show, **kwargs)\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'success'\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mftol\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mabs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mres\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'fun'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0mftol\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 124\u001b[0;31m raise RuntimeError('trim failed:\\n' + str(res) + '\\n' + \\\n\u001b[0m\u001b[1;32m 125\u001b[0m str(fdm.get_property_catalog('acceleration')))\n\u001b[1;32m 126\u001b[0m \u001b[0mprops\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfdm\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_property_catalog\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mRuntimeError\u001b[0m: trim failed:\n final_simplex: (array([[0.00000000e+00, 0.00000000e+00],\n [1.97215226e-34, 0.00000000e+00],\n [0.00000000e+00, 1.97215226e-34]]), array([nan, nan, nan]))\n fun: nan\n message: 'Maximum number of function evaluations has been exceeded.'\n nfev: 403\n nit: 101\n status: 1\n success: False\n x: array([0., 0.])\n{'accelerations/a-pilot-x-ft_sec2': nan, 'accelerations/a-pilot-y-ft_sec2': nan, 'accelerations/a-pilot-z-ft_sec2': nan, 'accelerations/n-pilot-x-norm': nan, 'accelerations/n-pilot-y-norm': nan, 'accelerations/n-pilot-z-norm': nan, 'accelerations/Nx': nan, 'accelerations/Ny': nan, 'accelerations/Nz': nan, 'accelerations/pdot-rad_sec2': nan, 'accelerations/qdot-rad_sec2': nan, 'accelerations/rdot-rad_sec2': nan, 'accelerations/udot-ft_sec2': nan, 'accelerations/vdot-ft_sec2': nan, 'accelerations/wdot-ft_sec2': nan, 'accelerations/gravity-ft_sec2': 32.2220066109964}" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 3, - "source": [ - "log_ground = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_ground,\n", - " tf=5,\n", - " realtime=False, verbose=True)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Hover Trim" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 4, - "source": [ - "op_hover, props = trim(\n", - " aircraft='F-35B-2',\n", - " ic={\n", - " 'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", - " },\n", - " eq_constraints = [\n", - " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", - " #lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", - " #lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", - " #lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", - " ],\n", - " design_vector=[\n", - " 'fcs/throttle-cmd-norm',\n", - " 'fcs/elevator-cmd-norm',\n", - " 'propulsion/engine/pitch-angle-rad',\n", - " ],\n", - " x0=[0.9, 0.5, np.deg2rad(90)],\n", - " cost= lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", - " verbose=True,\n", - " method='SLSQP',\n", - " bounds=[[0, 1], [-1, 1], [np.deg2rad(0), np.deg2rad(120)]],\n", - ")\n", - "op_hover" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - " fun: 0.8644525429644134\n", - " jac: array([1., 0., 0.])\n", - " message: 'Optimization terminated successfully'\n", - " nfev: 30\n", - " nit: 7\n", - " njev: 7\n", - " status: 0\n", - " success: True\n", - " x: array([0.86445254, 0.03362766, 1.57079635])\n", - "constraint eq 1.177877240188252e-15\n", - "constraint eq -2.301472790122716e-08\n", - "constraint eq 3.591704833301481e-09\n" - ] - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", - " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", - " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", - " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" - ] - }, - "metadata": {}, - "execution_count": 4 - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 5, - "source": [ - "log_hover = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_hover,\n", - " tf=10,\n", - " realtime=False)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 6, - "source": [ - "op_hover" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "{'ic/h-sl-ft': 650,\n", - " 'ic/vt-fps': 0,\n", - " 'ic/psi-true-deg': 280,\n", - " 'ap/gear-enable': 1,\n", - " 'fcs/throttle-cmd-norm': 0.8644525429644134,\n", - " 'fcs/elevator-cmd-norm': 0.033627661805235735,\n", - " 'propulsion/engine/pitch-angle-rad': 1.5707963530780742}" - ] - }, - "metadata": {}, - "execution_count": 6 - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 7, - "source": [ - "op_hover_auto = dict(op_hover)\n", - "op_hover_auto['ic/theta-deg'] = 0\n", - "op_hover_auto['ic/phi-deg'] = 0\n", - "op_hover_auto['ic/h-agl-ft'] = 60\n", - "\n", - "op_hover_auto['ap/heading-cmd-deg'] = 280\n", - "op_hover_auto['ap/gear-enable'] = 1\n", - "op_hover_auto['ap/roll-enable'] = 0\n", - "op_hover_auto['ap/pitch-enable'] = 1\n", - "op_hover_auto['ap/yaw-enable'] = 0\n", - "op_hover_auto['ap/h-enable'] = 1\n", - "op_hover_auto['ap/h-sl-cmd-ft'] = 700\n", - "\n", - "log_hover_auto = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_hover_auto,\n", - " tf=50,\n", - " realtime=False, verbose=True)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 8, - "source": [ - "log_hover_auto['fcs/throttle-pos-norm'].plot(label='0')\n", - "log_hover_auto['fcs/throttle-pos-norm[1]'].plot(label='1')\n", - "log_hover_auto['fcs/throttle-pos-norm[2]'].plot(label='2')\n", - "log_hover_auto['fcs/throttle-pos-norm[3]'].plot(label='3')\n", - "\n", - "plt.legend()" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 8 - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAEGCAYAAABrQF4qAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAqEUlEQVR4nO3dfZwd1X3f8c9v5j7so7R6WAHWSkgEbCQwJiALuybG2HUMxIHYpLzAdmtqN7SNyStNzKvBqV+2Q+KGtHFi9xUnfdHEwcEJlLp1Q2sZTAKJHb9cg4gMBmGMzIO1Eg+LpJW02od7Z+bXP2Z2dbXahyvt3QfNfN+vTObMmTOzZ/DV75x75twZc3dERCS/gsWugIiIzC8FehGRnFOgFxHJOQV6EZGcU6AXEcm50mJXYLLVq1f7hg0bFrsaIiKnlMcee+w1d++dat+SC/QbNmxg+/bti10NEZFTipm9ON0+Dd2IiOScAr2ISM4p0IuI5NySG6MXEVks9Xqd/v5+RkdHF7sq02pra6Ovr49yudz0MQr0IiKZ/v5+uru72bBhA2a22NU5jruzb98++vv72bhxY9PHaehGRCQzOjrKqlWrlmSQBzAzVq1adcLfOBToRUQaLNUgP+5k6pevQL/zPhgaWOxaiIgsKfkJ9KOH4N5/Dn957WLXRETkpN1///284Q1v4Oyzz+b2229vyTnzE+jjWroe3L249RAROUlxHPOxj32Mb3zjG+zcuZO7776bnTt3zvm8+Qn0nqTrIFzceoiInKRHHnmEs88+m7POOotKpcL111/PX//1X8/5vPmZXjke6C0/bZeILJ7f+j9PsXPvoZaec/PrlvHpnz9v2v179uxh3bp1E9t9fX1873vfm/PfzU9UbF+Rrs997+LWQ0RkiWmqR29mVwBfAELgT9399kn7zwS+BPQC+4EPuXt/w/5lwE7gf7v7zS2q+7HCSrrunPIpnSIiJ2Smnvd8Wbt2Lbt3H73P2N/fz9q1a+d83ll79GYWAl8ErgQ2AzeY2eZJxX4f+At3vwC4DfjdSft/G/jWnGs7c0UBOzqEIyJyinnzm9/Ms88+y/PPP0+tVuOee+7h6quvnvN5mxm62Qrscvfn3L0G3ANcM6nMZuChLP1w434zuxg4DfjmnGs7G1OgF5FTV6lU4o/+6I94z3vew6ZNm7juuus477y5f7NoZuhmLdA4Z7EfuGRSmceB95MO77wP6DazVcAB4HPAh4B/Ot0fMLObgJsA1q9f32zdpzhRAPjJHy8issiuuuoqrrrqqpaes1U3Y28BLjOzHcBlwB4gBn4Z2NY4Xj8Vd7/D3be4+5be3jmMsVugHr2IyCTN9Oj3AOsatvuyvAnuvpe0R4+ZdQHXuvugmb0V+Bkz+2WgC6iY2ZC739qS2h9HQzciIpM1E+gfBc4xs42kAf564AONBcxsNbDf3RPgE6QzcHD3DzaUuRHYMn9BnqxHr6EbEZFGsw7duHsE3Aw8ADwN3OvuT5nZbWY2fjv4HcAzZvYj0huvn52n+s5MQzciIsdpah69u28Dtk3K+1RD+qvAV2c5x53AnSdcwxNhph69iMgk+fllLGjWjYjIFPIV6HUzVkROcR/5yEdYs2YN559/fsvOma9Ar6EbETnF3Xjjjdx///0tPWfOAr1uxorIqe3tb387K1eubOk58/OYYtAjEESkdb5xK7z8g9ae8/Q3wpWteWvUichfj143Y0VEjpGzHr2GbkSkRRah5z1f8tWj16wbEZHj5CvQ6xEIInKKu+GGG3jrW9/KM888Q19fH3/2Z38253PmcOhGgV5ETl133313y8+Zsx69hm5ERCbLX6DXrBsRkWPkLNBr1o2IyGT5CvSadSMicpx8BXrdjBUROU4OA7169CIijXIW6DV0IyKntt27d3P55ZezefNmzjvvPL7whS/M+Zz5m0evWTcicgorlUp87nOf46KLLuLw4cNcfPHFvPvd72bz5s0nfc589eh1M1ZETnFnnHEGF110EQDd3d1s2rSJPXv2zOmc+evR62asiLTA7z3ye/xw/w9bes5zV57Lb2z9jabLv/DCC+zYsYNLLrlkTn83Xz16BXoRyYmhoSGuvfZaPv/5z7Ns2bI5nStnPXo0dCMiLXEiPe9Wq9frXHvttXzwgx/k/e9//5zPl78evW7GisgpzN356Ec/yqZNm/j1X//1lpwzf4FePXoROYV95zvf4a677uKhhx7iwgsv5MILL2Tbtm1zOmdTQzdmdgXwBSAE/tTdb5+0/0zgS0AvsB/4kLv3m9mFwJ8Ay4AY+Ky7//c51Xgme3fM26lFRBbCpZdeirf4XuOsPXozC4EvAlcCm4EbzGzyhM7fB/7C3S8AbgN+N8sfBv6Fu58HXAF83sx6WlR3ERFpQjNDN1uBXe7+nLvXgHuAayaV2Qw8lKUfHt/v7j9y92ez9F7gVdJe//z6yi/CE/fC8P55/1MiIktdM0M3a4HdDdv9wORJnY8D7ycd3nkf0G1mq9x933gBM9sKVIAfT/4DZnYTcBPA+vXrT6T+U9v7j7DrwXTMft1b4PXvgddfAb1vyJ5ZLyJSHK26GXsLcJmZ7QAuA/aQjskDYGZnAHcB/9L9+Lul7n6Hu29x9y29vS3o8N+yC/7VQ/Azt0BtCP7m0/DHl8AX3gTP/f3czy8icgpppke/B1jXsN2X5U3IhmXeD2BmXcC17j6YbS8Dvg78B3f/fy2o8+yCAPouTpd3/gc4uAeefQC+fgvs+hs467IFqYaIyFLQTI/+UeAcM9toZhXgeuC+xgJmttrMxs/1CdIZOGTlv0Z6o/arrav2CVq+FrZ8BEpVNM9eRIpm1kDv7hFwM/AA8DRwr7s/ZWa3mdnVWbF3AM+Y2Y+A04DPZvnXAW8HbjSz72fLhS2+hubpEQkissSNjo6ydetW3vSmN3Heeefx6U9/es7nbGoevbtvA7ZNyvtUQ/qrwHE9dnf/CvCVOdaxhfR0SxFZ2qrVKg899BBdXV3U63UuvfRSrrzySt7ylrec9Dnz9cvY2ahHLyJLnJnR1dUFpM+8qdfr2BxnC+broWa3PAtJPP1+vYFKRJr08n/8j4w93drHFFc3ncvpv/mbs5aL45iLL76YXbt28bGPfUyPKT5G1xpYdsb0+xXoReQUEIYh3//+9+nv7+eRRx7hySefnNP58tWjn42ebikiTWqm5z3fenp6uPzyy7n//vs5//zzT/o8+erRz0ZPtxSRJW5gYIDBwUEARkZGePDBBzn33HPndM5i9eg160ZElriXXnqJD3/4w8RxTJIkXHfddbz3ve+d0zmLFeg160ZElrgLLriAHTta+8h1Dd2IiORcwQK9qUcvIoVTsECvWTciMrNWv92p1U6mfgUL9LoZKyLTa2trY9++fUs22Ls7+/bto62t7YSOK9bNWM26EZEZ9PX10d/fz8DAwGJXZVptbW309fWd0DHFCvSadSMiMyiXy2zcuHGxq9FyBRu60awbESmeggV6Dd2ISPEULNBr1o2IFE/xAr169CJSMMUK9Jp1IyIFVKxAr1k3IlJACvQiIjlXsECPhm5EpHAKFug160ZEiqd4gV49ehEpmGIFes26EZECairQm9kVZvaMme0ys1un2H+mmf2tmT1hZn9nZn0N+z5sZs9my4dbWfkTppuxIlJAswZ6MwuBLwJXApuBG8xs86Rivw/8hbtfANwG/G527Erg08AlwFbg02a2onXVP0EauhGRAmqmR78V2OXuz7l7DbgHuGZSmc3AQ1n64Yb97wEedPf97n4AeBC4Yu7VPkl61o2IFFAzgX4tsLthuz/La/Q48P4s/T6g28xWNXksZnaTmW03s+3z+hxozboRkQJq1c3YW4DLzGwHcBmwB4ibPdjd73D3Le6+pbe3t0VVmoLG6EWkgJp58cgeYF3Ddl+WN8Hd95L16M2sC7jW3QfNbA/wjknH/t0c6jtHGroRkeJppkf/KHCOmW00swpwPXBfYwEzW21m4+f6BPClLP0A8LNmtiK7CfuzWd7iMFOPXkQKZ9ZA7+4RcDNpgH4auNfdnzKz28zs6qzYO4BnzOxHwGnAZ7Nj9wO/TdpYPArcluUtDs26EZECauqdse6+Ddg2Ke9TDemvAl+d5tgvcbSHv7g060ZECqhYv4zVrBsRKaDiBXr16EWkYIoV6DXrRkQKqFiBXvPoRaSAChjo1aMXkWIpWKDXPHoRKZ6CBXrNuhGR4ilYoNfNWBEpnmIFes26EZECKlag16wbESmgAgZ69ehFpFgKFug1dCMixVOwQK9ZNyJSPMUL9OrRi0jBFCvQa9aNiBRQbgJ9kiTc/9s3seObf0ltZHjqQhZo5EZECqepF4+cCvbs2sG6v/o2wV9+m6fKv8PL56wkePObWH/5z/P6N7+bMCxp6EZECik3gX7d6y/mwLe+yc4H/wcHvvP3dD/xPGu+/DB8+WEe6zAGNp1Oda1zycqE7sWurIjIAjJfYj8g2rJli2/fvr0l53rp+Sf54YP/gyPf/X+serKfnsMJz18CV3356ZacX0RkqTCzx9x9y1T7ctOjB/i7Z16lHjvv3nwaAGdsPJ8zbjofbkrH8J+44Dw8WuRKiogssFwF+hv//FEAXrj9547bFwQBbugRCCJSOLmZddMM1+xKESmgwgV6EZGiKV6g19CNiBRMU4HezK4ws2fMbJeZ3TrF/vVm9rCZ7TCzJ8zsqiy/bGZfNrMfmNnTZvaJVl/AiUgD/WLWQERk4c0a6M0sBL4IXAlsBm4ws82Tin0SuNfdfxq4HvjjLP+fAVV3fyNwMfCvzWxDi+p+wnzi/4mIFEczPfqtwC53f87da8A9wDWTyjiwLEsvB/Y25HeaWQloB2rAoTnXehb/9e9/zA/6DxLFx9551dCNiBRRM9Mr1wK7G7b7gUsmlfkM8E0z+xWgE/inWf5XSRuFl4AO4Nfcff/kP2BmNwE3Aaxfv/4Eqj+127/xQwA6KyEXnbmCN29YyZs3rMTM0kDvnj6bXkSkAFo1j/4G4E53/5yZvRW4y8zOJ/02EAOvA1YA3zazv3H35xoPdvc7gDsg/WXsXCvz3U+8k0ee38+jL+zn0ecP8AcP/giAv8LT7xhJBGF5rn9GROSU0Eyg3wOsa9juy/IafRS4AsDdv2tmbcBq4APA/e5eB141s+8AW4DnmAenLasyPBZzxvJ2rrlwLddcuBaAg8N1tr+4H/+brBcf1xToRaQwmhmjfxQ4x8w2mlmF9GbrfZPK/AR4F4CZbQLagIEs/51ZfifwFuCHran68dZ0t/HmjSuPy1/eUeZdm047Ousmrs1XFURElpxZA727R8DNwAPA06Sza54ys9vM7Oqs2MeBXzKzx4G7gRs9fVraF4EuM3uKtMH4c3d/Yj4uBCBxZ6aR94lZN5ECvYgUR1Nj9O6+Ddg2Ke9TDemdwNumOG6IdIrlgkjvsU4f6tMevalHLyKFkqtfxibuM06mmXgEggK9iBRIrgI9QDBjoDeN0YtI4eQq0CfuBLMN3YACvYgUSs4C/cy/g3ID081YESmYXAV6d5/xZmyChm5EpHhyFuiZceiGiVk3YwtWJxGRxZarQD/bPPrE0lhPXF+gGomILL5cBXpHs25ERCbLVaBvataNA5GGbkSkOPIV6BOYaexmYmBn9OCC1EdEZClo1WOKl4yZevSJGYEDo4MLVp9Tnnt6TyOuZctU6Vn2JxF4DJ5k7wNIjl2SuGG7cX98fNnx/ckU+yCbX2tgQUM62x5PT+TZFHlTlWvm2ODYdFCCsARBOUtn68b0RF45KzuenqLsRLoMQaj3KcgJyVWgT4dupt8/MUY/MrhQVZp/0RiMDcHYIRg7DLWhdD2+1IezZWTSkuVFow37h6E+muZNBOnFvHFtWVALplgMLDx2G7I3iPnRBmE8PZHnk/KSmfOWqmMahXCaBiLbN54+rjGZj+MmN3AzNV7l4xtDNWDzIneB3mYYu3EDJ1haPfokSYP0yH4YOQDDB9L1xHa2Hh3MgvekoN7sjWULoNwJ5XYot0G5I0t3QFsPdJ+R5bVBqT39RxdWsmWO6SBMg3IwKTAfE7gnB3RbOv/ofYoGYcpGZDwv+8YR19NvM0kd4mydRJPSk9YTZcfT4/nRFOnJZWc5Lq5DbfjEjvN4Yf9bW9jkt55mvi2VoVRp4jPaxGe4VJ25TBAu7H+nE5SrQO8OwQx3HRxLo/189+jrozD0ytHl8MtH10cGsuCdBfCRA0eHHabSthzaV6TBuNoNPeuh2pWmK9l6fJnYXpaWqXRBpTMN4Ootnbzxbw9FlGRDaOMNS9KQjrPtKRuWqRq1mRqvE2kMpzguGp3ib9SPH16MxpiXb2oWTtEwjDcEjempGo3q0fwVG+At/7bl1ctVoE+aeEyxYzD4k5P8Awkcfik9/tCeLIC/DIdfSddDr6Z5U31jsAA6e6FrDbSvhOVvTAN4+0roWHk03b7i6HZbT9pzEVksQQAE+XojWxJPfU8pqk2dP226dnwjMrG/IR1NKj8yPHV+VIMzLlCgn43P9uIRs3To5rUfpUF7cvffHY68BoMvwoEX0oA++CIceDFNH9x9/FBJWIXu06DrdFh1Nmy4NE2P53WfBl2npUF+iX+9EymEIISgPR26LIh8BXpmnnXjBokH6U3Hh25Le9AHd2eBPAvm9eFjD+pYBT1nwulvhE3vTdM9Z8LyvjSIt/VoSERElrRcBfpmZt0klKBvK/zDH6aZ1WVp4F51NvzUO9P0iiyY96xLx7xFRE5h+Qr0ycxPr3SzdMjmIw/A4b1Hb1yqRy4iOZarQO808Tx6SMfml/ctUK1ERBZXrh6BMNtjit0MS5bwj2BEROZBrgL9bI8phuwNUyIiBZKrQJ/+YGrmZ93YUv5Zu4jIPMhVoJ+tR+9m6tGLSOE0FejN7Aoze8bMdpnZrVPsX29mD5vZDjN7wsyuath3gZl918yeMrMfmFlbKy+gkTfxy1hzRXoRKZZZZ92YWQh8EXg30A88amb3ufvOhmKfBO519z8xs83ANmCDmZWArwD/3N0fN7NVwLw9DtGZeR496tGLSAE106PfCuxy9+fcvQbcA1wzqYwDy7L0cmBvlv5Z4Al3fxzA3fe5z9/j8NJn3Uy/3zVGLyIF1EygXwvsbtjuz/IafQb4kJn1k/bmfyXLfz3gZvaAmf2jmf37qf6Amd1kZtvNbPvAwMAJXUAjn/VVgurRi0jxtOpm7A3Ane7eB1wF3GVmAenQ0KXAB7P1+8zsXZMPdvc73H2Lu2/p7e096Uo08/RKjdGLSNE0E+j3AOsatvuyvEYfBe4FcPfvAm3AatLe/7fc/TV3Hybt7V8010pPxbMAPuM8evXoRaSAmgn0jwLnmNlGM6sA1wP3TSrzE+BdAGa2iTTQDwAPAG80s47sxuxlwE7mweBweo/34WdenbaMhm5EpIhmnXXj7pGZ3UwatEPgS+7+lJndBmx39/uAjwP/zcx+jfTG7I2edrEPmNkfkDYWDmxz96/Px4XUk/QtTXsHR6e/FkxDNyJSOE091Mzdt5EOuzTmfaohvRN42zTHfoV0iuW8Gr8Jm8wUyAP16EWkeHLzy9iwiUDv5OiCRUSalJu411lNv5zcfPnZ0xcKgnl5L7CIyFKWm+fRV0oBL9z+czOWcYNAY/QiUjC56dE3xQKN0YtI4RQq0Dt6Hr2IFE+xAn0YEGroRkQKplCBPglCgmSxayEisrAKFeg9DCnF6tGLSLEUKtAnQUCgOC8iBVOoQO9hSKihGxEpmGIF+iAknLfXnoiILE2FC/QBEMfRYldFRGTBFCvQh+kPgeNabZFrIiKycAoW6NPLrdVGFrkmIiILp2CBPuvRR+rRi0hxFCrQMx7o6wr0IlIchQr0HoQARPXp30IlIpI3hQr0lNIefaQevYgUSLECvcboRaSAChbo06Gb+piGbkSkOAoW6MsARFF9kSsiIrJwChboszH62tgiV0REZOEUMtDXFehFpEAKFeitlA3daNaNiBRIU4HezK4ws2fMbJeZ3TrF/vVm9rCZ7TCzJ8zsqin2D5nZLa2q+MkIFOhFpIBmDfRmFgJfBK4ENgM3mNnmScU+Cdzr7j8NXA/88aT9fwB8Y+7VnZugVAGgNqpZNyJSHM306LcCu9z9OXevAfcA10wq48CyLL0c2Du+w8x+AXgeeGrOtZ2jsL0LgNqRoUWuiYjIwmkm0K8Fdjds92d5jT4DfMjM+oFtwK8AmFkX8BvAb830B8zsJjPbbmbbBwYGmqz6iSt3pG3R2JHD8/Y3RESWmlbdjL0BuNPd+4CrgLvMLCBtAP7Q3WfsQrv7He6+xd239Pb2tqhKxyt1dAMQKdCLSIGUmiizB1jXsN2X5TX6KHAFgLt/18zagNXAJcAvmtl/AnqAxMxG3f2P5lrxk1Ht7AEgGh5ejD8vIrIomgn0jwLnmNlG0gB/PfCBSWV+ArwLuNPMNgFtwIC7/8x4ATP7DDC0WEEeoK2rB4B4RIFeRIpj1qEbd4+Am4EHgKdJZ9c8ZWa3mdnVWbGPA79kZo8DdwM3urvPV6VPVnvWo3cFehEpkGZ69Lj7NtKbrI15n2pI7wTeNss5PnMS9WupSqXCWAkY0fTKhZAkCXFUI4pqxPUaUX2MuF5L87J1EkVEUY2kXiOO6mlevU4c14nrdZKojkd1kmZe6G42y+7p+zVmhoUhFoQEQZimw5AgLGEWEoRBmg7SvCAMsbBEkJUPSlk6y7MwJAzLBGFIkK3NQsJymdBKafmwRBAU6jeLskiaCvR5UQ6MsbJhOZ1HnyQJI0cGOTI4wJGD+xg5tJ/ayBD14SHqI8NEo0eIR0bSZXSEZHSUZGwURsfwsTEYq2O1GjZWJ6hFWD0iiBMsdixJsMQJYidI/Jh0ukCQOGEClkCYQHgS3+mCbFmqH0wH4mxphcQgDrIlNJKJtZGE40uAB+k6CQ0Pg3QpBXgYQpiuvZSmKZWgFKZPay2FWKkEYYiVyliphJWydLlMUCphpTJBuUxQKmOlctoYlatpY1SuEJYrBKUypUqVsFwlLJUJK1VK5WypVCmV27L9FcqVNkrlNjViS8hS/fc0L8qlgINtAaVDS28efRxHHBzYw+DAbg4P7GXkwAC1QwepHT5IfOQw8dAQydARGB7BjowQjIwRjtQoj0ZURiKqYwltY35McDWgmi3TSYB6Geolo14OiMoBUSUgLock5ZC4WsZDS9/OlQWYiXUQZgElSINKEGBhOBFkLCxNbFtYyoJM2pO1MA1AQamU7SsTZoEoKJUISmXCUmUiHQQhzNAjx5MZ//s6M7c6Hid4EpMkMR6PryM8yfLjGM/2eZJk6xj35Jg8svIeJ7gn0LjPEzxJsjIJZH+TKMKjCOIEogiiOF3iGItiLI4hTrA4xqIEixOCWkQwkjbAQewE8fj6aOMbxhDGaeMbJhC0YDDVgShbZntiVGwQh2kjlgSWpkPDA0sbs/EGrBSkSxjgpRAvh9m6hJdKUM4arnIZK5eyddo4WblCUKkQNKzDSpWgkjZAYaWNsFqlVGmbWMptHZSr7ccslWpH+nnLaeNUqEBfCox9nVWWD85/oB8eGuS1/mc5sOd5Dr/8E0YHXqE+uJ948CAcPEx4+Ailw6NUh2q0D0d0jPjEDZNKtkw2UoGxakCtLaTeViZqLzPS08mR9jbobMc6Owm7Ogk7uyl1L6PS1U25o4tyeyeVji4q7V1UOrpp6+im2rmM9s7llKsduf1wy7HiOCKqjVKvjRHVR4lqoxNDalFtLB1iq40R18fSYbRaui+J6unQWj0dYkviOkk9XTyKsnWa9qiO16O08YuitBGL46MNWDypEYvi9NtiPU2Ho3WCoVGC2AmjhCBOCCNPG6zYKcVQik5uXrgD9WyZSgJEIRMNUlRKv1HFYUBSMuKGxigpZY1S6WijxMSSdljGGySrNDRK5TJBpUpQqaSNUKWafjuqthNWq3T29HLOxe866f+Np1OoQF8OA/Z1tLP2lcGTOj5JEg7u28OrLzzNwZde5MjL/Yy9+jLRwGvY/kFK+w/TdmiUrkMRHWNp96kCrGo4x0gFRtpDRrvK1LvaONy7nEPLOgl6lhMu76G6chVtK3vpWHUaHctX0bF8NV09vXQuX00YFup/LmmxMCwRtndRzX4hfiqL6jVqY8PUx0aoT6xHqNdGicZGiGqjRGOjRLUx4tooSS1rxGpjJPUx4lqNpFbDs8bL6/V0qdXwegT1OtSjiQbK6tFEwxREMUE9JhipE0w0Ruk3qjB2SlFDozTzF83jvLC+g3O++VjL/3sVKnKUw4CXulZw2bP7GHxtDz2rj/2BbxxHDPT/iFd+/CQHX9zFcP8LRC+9TPjKPtpfG2LZgRrt2fPQurMFYLQMh5eVGF3eztC6VRxevYJw9Sqqa06n87S1LH/dBlacfiY9a9bl4h+ZyGIrlSuUyhXIpkwvVUmSEI2NUqsNTzRItdF0HWWN00SjNDbCms7l81KPggV64/EVb+QDvot/+M2bCE5fQ7L3ZUqvHKBz3xGWH4wox2kvfPz3uUfajEMrqwyftpyhN62mfMbptK9dR/fp6+l53UZ6172eruWrF/OyRGSJCoKASnsHlfaORa1HwQJ9wA+6LuHJN36H87/1HPAcg90BQyvbOfRTazh0ei+VM9bSvf4sVm54A2ecfQHdPWsWu9oiInNSuEDvVqJ+y12cfpZRbe9m0xL/6iciMleFCvQd1RCA4VrEit6zFrk2IiILo1Dz6jorabs2NNbEryxFRHKiUIE+DIz2csgRBXoRKZBCBXqArraSevQiUiiFGqMH6KqWGBpr1ZNK8imKE2pxQpQ4UexESUI8kXbiJKEee5qXOFFWNk6cepw05J/gsUmCe/roBgwMwyzdtsZts+PzxrfNps7PtgECa9x3NE123mP3p8fSUD6w48/ZWKegIU1DPQIzwtAoBUYYGOUwIAyObpeCSdvh8fmlMN0OsmsVaUbhAn1n9dQfuhmLYo6MxQyNRhweqzM0GnGkFnF4NOLIWMxoPWakHjNWjxmNEkZqad54eiw6Wma0nqT7GtJRsvBPmA6z4Baa4TiJA54+o8Y9/fm6u2frBa/eknS0gRhvGCY3HEcblHIYUArH0+m6FARUSmnDcUx+aFSOKZ/uKwUB5VJAOZhc7uix5Unp484VBJQn/qapsVoghQv0y9rKHByZ7mkXC8PdGanHHBiuc+BIjcHhOgeGawwO19K84RoHh+sMjtSzYB5xZCxiaCxiaDSiFjf/u+q2ckB7OaStHNJeDqmWw4m87rZylhdM7G8rB7SV0rwwCBqChU1slyZ6pUFD+vgeauN2KWw4VxAc07MtBSf+D9596gZgomGYqZFwSCa2jz02+790f+OxPv53mWiIjm14Gss3Hn/02MT9mG87afroN6Cj66Rh//HflI4plzhxPHX++Deq8W9T9TihHieM1pPsc5R+o0rz0/1R4tSjhHrDN6/5VDqu0Wi2cZlULgyohAGV0tGGplJK88oT+em+6kQ6OLZcyY4pn+alx1TC4JRulAoX6F/X084/PPtay897ZCxi4PAYA0NjvHpojIHDowwMjbH/SD0L4EcD+oHhOrVo+mDdWQnp6ajQ01Gmq1pibU8bXdUSXW0lOqsluqulbDvdP76vq1qisxpOBPZq6dT+cM5kfMgl21rMquRakg2pRVlDUIuPpicah9iz/CwvSahHSUPjMl4umbZxqUUJUZJQj3yikZlcrh4njNSP/s16nDVIUdqgjUVH8+fjW2ljA1KepmGZLr/SuD9bVxsakXJWpre7yjve0PofaRYu0PetaOeVw6OMRTHVUjhr+ThxBg6PsffgCHsHx5fRNKgfHuPVw2n6SO34cf9SYPR0VFjRUWZFR4X1Kzu4oG85KzoqE/kT+zsr9LSXWd5RbqpeIgshCIxqEFI9xSJF3PANphYdbSxqE9vpMja+L0r3NZavRXG6nnRMLUobrGPPn+bVonRI9NBoPSvXsH/ivMm038p/en2PAn0rnLOmG3d4fPdBtm5cyWg9pv/ACLsPDLPnQEMwPzjK3sERXj44elzvoKtaYs2yKr1dVd7Y10NvV3Vie82yKr3dVdZ0t9HTXiYI1NsUWWjpPZ/0m+1S5O4TjUi9oUGYr3hRuED/9tevprta4iN3Pkp7JWTg8LGvTygFxunL23hdTztbzlzB63raeV1PO2t72jmjJ81f1lZepNqLSB6YGZWSUSkFM78ZqEUKF+i728rc+ZGt3P3ITwjNWLuinXUr21m3ooO1K9pZ091GqF64iORI4QI9wMVnruDiM1csdjVERBZE4X4ZKyJSNAr0IiI5p0AvIpJzTQV6M7vCzJ4xs11mdusU+9eb2cNmtsPMnjCzq7L8d5vZY2b2g2z9zlZfgIiIzGzWm7FmFgJfBN4N9AOPmtl97r6zodgngXvd/U/MbDOwDdgAvAb8vLvvNbPzgQeAY9/ILSIi86qZHv1WYJe7P+fuNeAe4JpJZRxYlqWXA3sB3H2Hu+/N8p8C2s1sAWaNiojIuGYC/Vpgd8N2P8f3yj8DfMjM+kl7878yxXmuBf7R3ccm7zCzm8xsu5ltHxgYaKriIiLSnFbdjL0BuNPd+4CrgLvMbOLcZnYe8HvAv57qYHe/w923uPuW3t7eFlVJRESguR9M7QHWNWz3ZXmNPgpcAeDu3zWzNmA18KqZ9QFfA/6Fu/94tj/22GOPvWZmLzZT+WmsJr03UCRFu+aiXS/omotiLtd85nQ7mgn0jwLnmNlG0gB/PfCBSWV+ArwLuNPMNgFtwICZ9QBfB2519+80U1N3n1OX3sy2u/uWuZzjVFO0ay7a9YKuuSjm65pnHbpx9wi4mXTGzNOks2ueMrPbzOzqrNjHgV8ys8eBu4Eb3d2z484GPmVm38+W1j+DU0REptXUs27cfRvpTdbGvE81pHcCb5viuN8BfmeOdRQRkTnI4y9j71jsCiyCol1z0a4XdM1FMS/XbK43LYuI5Foee/QiItJAgV5EJOdyE+hne/BaHpjZl8zsVTN7siFvpZk9aGbPZutcvVHFzNZlD8zbaWZPmdmvZvm5vW4zazOzR8zs8eyafyvL32hm38s+4//dzCqLXddWMrMwezDi/822c329AGb2QvbQx++b2fYsr+Wf7VwE+oYHr10JbAZuyB6uljd3kv0wrcGtwN+6+znA32bbeRIBH3f3zcBbgI9l/9vm+brHgHe6+5uAC4ErzOwtpL8u/0N3Pxs4QPpDxTz5VdIp3OPyfr3jLnf3Cxvmz7f8s52LQE9zD1475bn7t4D9k7KvAb6cpb8M/MJC1mm+uftL7v6PWfowaSBYS46v21ND2WY5Wxx4J/DVLD9X15z9gv7ngD/Nto0cX+8sWv7Zzkugb+bBa3l1mru/lKVfBk5bzMrMJzPbAPw08D1yft3ZMMb3gVeBB4EfA4PZDxghf5/xzwP/Hkiy7VXk+3rHOfDN7H0dN2V5Lf9sF/Ll4Hnl7m5muZwva2ZdwP8E/p27H0o7fKk8Xre7x8CF2WNEvgacu7g1mj9m9l7gVXd/zMzescjVWWiXuvue7IkBD5rZDxt3tuqznZcefTMPXsurV8zsDIBs/eoi16flzKxMGuT/0t3/V5ad++sGcPdB4GHgrUCPmY13zvL0GX8bcLWZvUA67PpO4Avk93onuPuebP0qaYO+lXn4bOcl0E88eC27M389cN8i12mh3Ad8OEt/GPjrRaxLy2VjtX8GPO3uf9CwK7fXbWa9WU8eM2snfbvb06QB/xezYrm5Znf/hLv3ufsG0n+7D7n7B8np9Y4zs04z6x5PAz8LPMk8fLZz88tYS99T+3kgBL7k7p9d3Bq1npndDbyD9FGmrwCfBv43cC+wHngRuM7dJ9+wPWWZ2aXAt4EfcHT89jdJx+lzed1mdgHpTbiQtDN2r7vfZmZnkfZ4VwI7gA9N9SKfU1k2dHOLu78379ebXd/Xss0S8Ffu/lkzW0WLP9u5CfQiIjK1vAzdiIjINBToRURyToFeRCTnFOhFRHJOgV5EJOcU6KWQzKzHzH55seshshAU6KWoegAFeikEBXopqtuBn8qeA/6fpyuUPVzsTjN7Mntu+K9l+T9lZvdnD6P6tpmdm+WfZmZfy54l/7iZ/ZMFuh6RaemhZlJUtwLnu/uFs5S7EFjr7udDOuST5d8B/Bt3f9bMLgH+mPQZLf8F+Ht3f1/2noSueai7yAnRL2OlkLJHHv/f8QA+Q7kVwHZgG/B14JtABzAAPNNQtOrum8xsAOjL00/15dSnHr3IDNz9gJm9CXgP8G+A64B/R/qs9AsXsWoiTdMYvRTVYaC7MWPys8CzvNVA4O7/E/gkcJG7HwKeN7N/lpWxrDGA9NVv/zbLD81s+Txeg0hTFOilkNx9H/Cd7Cbrf84Cuk1RdC3wd9nbnr4CfCLL/yDwUTN7HHiKo6+u/FXgcjP7AfAY6TuMRRaVxuhFmHjL0Vnu/l8Wuy4iraZALyKScxq6ERHJOQV6EZGcU6AXEck5BXoRkZxToBcRyTkFehGRnPv/ncwi7/DyCAUAAAAASUVORK5CYII=" - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 9, - "source": [ - "log_hover_auto['ap/h-error'].plot()" - ], - "outputs": [ - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "" - ] - }, - "metadata": {}, - "execution_count": 9 - }, - { - "output_type": "display_data", - "data": { - "text/plain": [ - "
" - ], - "image/png": "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" - }, - "metadata": { - "needs_background": "light" - } - } - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Transition" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 10, - "source": [ - "def trim_transition(vt_fps, gamma_deg, accel_g):\n", - " print('trimming @ Vt=', vt_fps, 'fps', 'gamma = ', gamma_deg, 'deg')\n", - " \n", - " def accel_gamma(fdm, accel_g, gamma_deg):\n", - " gamma = np.deg2rad(gamma_deg)\n", - " g = 32.2\n", - " theta = fdm['attitude/theta-rad']\n", - " C_nb = np.array([\n", - " [np.cos(theta), -np.sin(theta)],\n", - " [np.sin(theta), np.cos(theta)]\n", - " ])\n", - " a_n = accel_g*g*np.array([np.cos(gamma), np.sin(gamma)])\n", - " a_b = C_nb.T.dot(a_n)\n", - " return a_b\n", - " \n", - " if vt_fps < 300:\n", - " x0 = [0.9, 0, 0, 0, np.deg2rad(90), np.deg2rad(0), 0],\n", - " else:\n", - " x0 = [0.9, 0, 0, 0, np.deg2rad(0), np.deg2rad(0), 0],\n", - "\n", - " op, props = trim(\n", - " aircraft='F-35B-2',\n", - " ic={\n", - " 'ic/h-sl-ft': 800,\n", - " 'ic/vt-fps': vt_fps,\n", - " 'ic/gamma-deg': gamma_deg,\n", - " 'ap/gear-enable': 1,\n", - " },\n", - " design_vector=[\n", - " 'fcs/throttle-cmd-norm',\n", - " 'fcs/elevator-cmd-norm',\n", - " 'fcs/rudder-cmd-norm',\n", - " 'fcs/aileron-cmd-norm',\n", - " 'propulsion/engine/pitch-angle-rad',\n", - " 'ic/alpha-rad',\n", - " 'ic/beta-rad',\n", - " ],\n", - " x0=x0,\n", - " verbose=False,\n", - " method='SLSQP',\n", - " eq_constraints= [\n", - " lambda fdm: fdm['accelerations/udot-ft_sec2'] - accel_gamma(fdm, accel_g, gamma_deg)[0],\n", - " lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/wdot-ft_sec2'] - accel_gamma(fdm, accel_g, gamma_deg)[1],\n", - " lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", - " ],\n", - " cost=lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", - " bounds=[[0, 1], [-1, 1], [-1, 1], [-1, 1],\n", - " [np.deg2rad(0), np.deg2rad(120)],\n", - " [-0.1, 0.1], [-0.1, 0.1]],\n", - " tol=1e-12)\n", - " return op\n", - "\n", - "ops_trim = [trim_transition(vt_fps=vt, gamma_deg=0, accel_g=0)\n", - " for vt in [10, 50, 100, 150, 200, 250, 300, 400, 500, 600]]\n", - "for op in ops_trim:\n", - " print('\\nvt fps', op['ic/vt-fps'])\n", - " print('theta deg', op['ic/gamma-deg'] + np.rad2deg(op['ic/alpha-rad']))\n", - " print('elevator', op['fcs/elevator-cmd-norm'])\n", - " print('throttle', op['fcs/throttle-cmd-norm'])" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "trimming @ Vt= 10 fps gamma = 0 deg\n", - "trimming @ Vt= 50 fps gamma = 0 deg\n", - "trimming @ Vt= 100 fps gamma = 0 deg\n", - "trimming @ Vt= 150 fps gamma = 0 deg\n", - "trimming @ Vt= 200 fps gamma = 0 deg\n", - "trimming @ Vt= 250 fps gamma = 0 deg\n", - "trimming @ Vt= 300 fps gamma = 0 deg\n", - "trimming @ Vt= 400 fps gamma = 0 deg\n", - "trimming @ Vt= 500 fps gamma = 0 deg\n", - "trimming @ Vt= 600 fps gamma = 0 deg\n", - "\n", - "vt fps 10\n", - "theta deg 0.6630839330060437\n", - "elevator 0.03352916967242737\n", - "throttle 0.8671969353634096\n", - "\n", - "vt fps 50\n", - "theta deg 5.729577951308233\n", - "elevator 0.02912588154189014\n", - "throttle 0.8627591079955563\n", - "\n", - "vt fps 100\n", - "theta deg 5.729577951308232\n", - "elevator 0.027914265581305345\n", - "throttle 0.8355302509100837\n", - "\n", - "vt fps 150\n", - "theta deg 5.729577951308233\n", - "elevator 0.04522476334750353\n", - "throttle 0.7827816325785829\n", - "\n", - "vt fps 200\n", - "theta deg 5.729577951308232\n", - "elevator 0.08422325538967168\n", - "throttle 0.6983592936110139\n", - "\n", - "vt fps 250\n", - "theta deg 5.729577951308233\n", - "elevator 0.022227694185888432\n", - "throttle 0.5731558958847474\n", - "\n", - "vt fps 300\n", - "theta deg 5.729577951308233\n", - "elevator 0.16795831639460848\n", - "throttle 0.5548637679177907\n", - "\n", - "vt fps 400\n", - "theta deg 3.495803078765276\n", - "elevator 0.02522499217623794\n", - "throttle 0.42836182220646796\n", - "\n", - "vt fps 500\n", - "theta deg 1.9790094801217257\n", - "elevator 0.01700135814807383\n", - "throttle 0.44946603365623344\n", - "\n", - "vt fps 600\n", - "theta deg 1.1338679534798424\n", - "elevator 0.010409610011731551\n", - "throttle 0.47826941728479677\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 11, - "source": [ - "ops_transition = [trim_transition(vt_fps=vt, gamma_deg=10, accel_g=0.1)\n", - " for vt in [10, 50, 100, 150, 200, 250, 300, 400, 500, 600]]\n", - "\n", - "ops_transition_auto = []\n", - "for op in ops_transition:\n", - " op = dict(op)\n", - " print('\\nvt fps', op['ic/vt-fps'])\n", - " print('theta deg', op['ic/gamma-deg'] + np.rad2deg(op['ic/alpha-rad']))\n", - " print('elevator', op['fcs/elevator-cmd-norm'])\n", - " print('throttle', op['fcs/throttle-cmd-norm'])\n", - " op['ap/roll-enable'] = 1\n", - " op['ap/pitch-enable'] = 1\n", - " op['ap/yaw-enable'] = 1\n", - " op['ap/h-enable'] = 0\n", - " op['ap/h-sl-cmd-ft'] = 1000\n", - " ops_transition_auto.append(op)" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "trimming @ Vt= 10 fps gamma = 10 deg\n", - "trimming @ Vt= 50 fps gamma = 10 deg\n", - "trimming @ Vt= 100 fps gamma = 10 deg\n", - "trimming @ Vt= 150 fps gamma = 10 deg\n", - "trimming @ Vt= 200 fps gamma = 10 deg\n", - "trimming @ Vt= 250 fps gamma = 10 deg\n", - "trimming @ Vt= 300 fps gamma = 10 deg\n", - "trimming @ Vt= 400 fps gamma = 10 deg\n", - "trimming @ Vt= 500 fps gamma = 10 deg\n", - "trimming @ Vt= 600 fps gamma = 10 deg\n", - "\n", - "vt fps 10\n", - "theta deg 4.270422048691767\n", - "elevator 0.021883019636598007\n", - "throttle 0.8733477919612395\n", - "\n", - "vt fps 50\n", - "theta deg 4.270422048691767\n", - "elevator 0.020799121019119904\n", - "throttle 0.8875853703793402\n", - "\n", - "vt fps 100\n", - "theta deg 15.729577951308233\n", - "elevator -0.02436320065882229\n", - "throttle 0.8752803347408201\n", - "\n", - "vt fps 150\n", - "theta deg 15.729577951308233\n", - "elevator -0.06567102087823912\n", - "throttle 0.8337169135357859\n", - "\n", - "vt fps 200\n", - "theta deg 15.729577951308233\n", - "elevator -0.35431717033926424\n", - "throttle 0.7896349122837022\n", - "\n", - "vt fps 250\n", - "theta deg 14.984728865609426\n", - "elevator -0.34709572877816375\n", - "throttle 0.7546353858364139\n", - "\n", - "vt fps 300\n", - "theta deg 15.729577951308233\n", - "elevator 0.14237217314941022\n", - "throttle 0.7964905685324654\n", - "\n", - "vt fps 400\n", - "theta deg 13.411136946047922\n", - "elevator 0.02425960985998646\n", - "throttle 0.7649760429818303\n", - "\n", - "vt fps 500\n", - "theta deg 11.929750451412872\n", - "elevator 0.016469740899173763\n", - "throttle 0.7739733324760297\n", - "\n", - "vt fps 600\n", - "theta deg 11.101626203387996\n", - "elevator 0.010070440450282742\n", - "throttle 0.7873235812571895\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": 12, - "source": [ - "log_transition_auto = []\n", - "for op in ops_transition_auto:\n", - " log = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op,\n", - " tf=10,\n", - " realtime=False)\n", - " log_transition_auto.append(log)" - ], - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "warning: LOW FUEL 5.72 lbs, restart simulation\n" - ] - } - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Cruise Trim" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "op_cruise, props = trim(\n", - " aircraft='F-35B-2',\n", - " ic={\n", - " 'ic/gamma-deg': 0,\n", - " 'ic/vt-fps': 600,\n", - " 'ic/h-sl-ft': 10000,\n", - " 'gear/gear-cmd-norm': 0,\n", - " 'fcs/left-brake-cmd-norm': 0,\n", - " 'fcs/right-brake-cmd-norm': 0,\n", - " 'fcs/center-brake-cmd-norm': 0,\n", - " 'propulsion/engine/pitch-angle-rad': 0,\n", - " },\n", - " design_vector=[\n", - " 'fcs/throttle-cmd-norm',\n", - " 'fcs/elevator-cmd-norm',\n", - " 'fcs/rudder-cmd-norm',\n", - " 'fcs/aileron-cmd-norm',\n", - " 'ic/alpha-rad',\n", - " 'ic/beta-rad',\n", - " ],\n", - " method='SLSQP',\n", - " eq_constraints= [\n", - " lambda fdm: fdm['accelerations/udot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/vdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/wdot-ft_sec2'],\n", - " lambda fdm: fdm['accelerations/pdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/qdot-rad_sec2'],\n", - " lambda fdm: fdm['accelerations/rdot-rad_sec2'],\n", - " ],\n", - " cost=lambda fdm: fdm['fcs/throttle-cmd-norm'],\n", - " x0=[0.5, 0, 0, 0, 0, 0],\n", - " verbose=False,\n", - " bounds=[[0, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1], [-1, 1]],\n", - " tol=1e-3\n", - ")\n", - "op_cruise" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "log_cruise = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_cruise,\n", - " tf=10,\n", - " realtime=False)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "op_cruise_auto = dict(op_cruise)\n", - "#op_cruise_auto['ic/theta-deg'] = 0\n", - "#op_cruise_auto['ic/phi-deg'] = 0\n", - "op_cruise_auto['ap/roll-enable'] = 1\n", - "op_cruise_auto['ap/pitch-enable'] = 1\n", - "op_cruise_auto['ap/yaw-enable'] = 1\n", - "op_cruise_auto['ap/h-enable'] = 1\n", - "op_cruise_auto['ap/heading-cmd-deg'] = 260\n", - "op_cruise_auto['ap/h-sl-cmd-ft'] = 10000\n", - "\n", - "log_cruise_auto = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_cruise_auto,\n", - " tf=40,\n", - " realtime=False)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Auto Takeoff" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "log_takeoff_auto = simulate(\n", - " aircraft='F-35B-2',\n", - " op_0=op_ground,\n", - " op_list=[('hover', op_hover_auto, lambda fdm: fdm.get_sim_time() > 1),\n", - " ('10 fps', ops_transition_auto[0], lambda fdm: fdm.get_sim_time() > 10),\n", - " ('50 fps', ops_transition_auto[1], lambda fdm: fdm['velocities/vt-fps'] > 50),\n", - " ('100 fps', ops_transition_auto[2], lambda fdm: fdm['velocities/vt-fps'] > 100),\n", - " ('150 fps', ops_transition_auto[3], lambda fdm: fdm['velocities/vt-fps'] > 150),\n", - " ('200 fps', ops_transition_auto[4], lambda fdm: fdm['velocities/vt-fps'] > 200),\n", - " ('250 fps', ops_transition_auto[5], lambda fdm: fdm['velocities/vt-fps'] > 250),\n", - " ('300 fps', ops_transition_auto[6], lambda fdm: fdm['velocities/vt-fps'] > 300),\n", - " ('400 fps', ops_transition_auto[7], lambda fdm: fdm['velocities/vt-fps'] > 400),\n", - " ('500 fps', ops_transition_auto[7], lambda fdm: fdm['velocities/vt-fps'] > 500),\n", - " ('600 fps', ops_transition_auto[7], lambda fdm: fdm['velocities/vt-fps'] > 600),\n", - " ],\n", - " tf=120,\n", - " realtime=True, verbose=True)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "# Control Design" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "sys = control.ss(*linearize(\n", - " aircraft='F-35B-2',\n", - " states=['ic/q-rad_sec'],\n", - " states_deriv = ['accelerations/qdot-rad_sec2'],\n", - " inputs=['fcs/elevator-cmd-norm'],\n", - " outputs=['ic/q-rad_sec'],\n", - " ic=op_hover,\n", - " dx=1e-3,\n", - " n_round=3\n", - "))\n", - "s = control.tf([1, 0], [1])\n", - "rad2deg = 180/np.pi\n", - "G_elev_to_pitch = rad2deg*clean_tf(control.minreal(control.ss2tf(sys), 1e-3))/s\n", - "G_elev_to_pitch" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "H_elev_to_pitch = 0.05*(s/0.5+1)\n", - "\n", - "plt.figure()\n", - "rootlocus(G_elev_to_pitch*H_elev_to_pitch)\n", - "plt.plot([0, -1], [0, 1], '--')\n", - "\n", - "Gc_elev_to_pitch = G_elev_to_pitch*H_elev_to_pitch/(1 + G_elev_to_pitch*H_elev_to_pitch)\n", - "\n", - "plt.figure()\n", - "step_size = 10\n", - "t, y = control.step_response(step_size*Gc_elev_to_pitch, T=np.linspace(0, 1, 1000));\n", - "plt.plot(t, y)\n", - "plt.ylabel('pitch, deg')\n", - "plt.xlabel('t, sec')\n", - "plt.title('output')\n", - "\n", - "plt.figure()\n", - "# actual error was computed in radians, so, converting back here\n", - "e = np.deg2rad(step_size-y)\n", - "t, u, _= control.forced_response(H_elev_to_pitch, T=t, U=e)\n", - "plt.plot(t, u)\n", - "plt.hlines([-1, 1], t[0], t[-1], linestyles='dashed')\n", - "plt.title('input')\n", - "plt.ylabel('elevator, norm')\n", - "plt.xlabel('t, sec')\n", - "\n", - "plt.figure(figsize=(15, 7))\n", - "control.gangof4(G_elev_to_pitch, H_elev_to_pitch, Hz=True, dB=True)\n", - "\n", - "plt.figure()\n", - "control.nyquist(Gc_elev_to_pitch, omega=np.logspace(-3, 3, 1000));\n", - "\n", - "control.margin(Gc_elev_to_pitch)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Roll" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "sys = control.ss(*linearize(\n", - " aircraft='F-35B-2',\n", - " states=['ic/p-rad_sec'],\n", - " states_deriv = ['accelerations/pdot-rad_sec2'],\n", - " inputs=['fcs/aileron-cmd-norm'],\n", - " outputs=['ic/p-rad_sec'],\n", - " ic=op_hover,\n", - " dx=1e-3,\n", - " n_round=3\n", - "))\n", - "rad2deg = 180/np.pi\n", - "s = control.tf([1, 0], [1])\n", - "G_aileron_to_roll = rad2deg*clean_tf(control.minreal(control.ss2tf(sys), 1e-3))/s\n", - "G_aileron_to_roll" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "H_aileron_to_roll = 0.1*(s/0.5 + 1)\n", - "\n", - "plt.figure()\n", - "rootlocus(G_aileron_to_roll*H_aileron_to_roll)\n", - "plt.plot([0, -1], [0, 1], '--')\n", - "\n", - "Gc_aileron_to_roll = G_aileron_to_roll*H_aileron_to_roll/(1 + G_aileron_to_roll*H_aileron_to_roll)\n", - "\n", - "\n", - "plt.figure()\n", - "step_size = 10\n", - "t, y = control.step_response(step_size*Gc_aileron_to_roll, T=np.linspace(0, 1, 1000));\n", - "plt.plot(t, y)\n", - "plt.xlabel('t, sec')\n", - "plt.ylabel('roll, deg')\n", - "plt.title('output')\n", - "\n", - "plt.figure()\n", - "# actual error was computed in radians, so, converting back here\n", - "e = np.deg2rad(step_size-y)\n", - "t, u, _= control.forced_response(H_aileron_to_roll, T=t, U=e)\n", - "plt.hlines([-0.1, 0.1], t[0], t[-1], linestyles='dashed')\n", - "plt.plot(t, u)\n", - "plt.xlabel('t, sec')\n", - "plt.ylabel('aileron %')\n", - "plt.title('input')\n", - "\n", - "plt.figure()\n", - "control.nyquist(Gc_aileron_to_roll, omega=np.logspace(-3, 3, 1000));\n", - "\n", - "plt.figure(figsize=(15, 7))\n", - "control.gangof4(G_aileron_to_roll, H_aileron_to_roll, Hz=True, dB=True)\n", - "\n", - "control.margin(Gc_aileron_to_roll)" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Yaw" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "sys = control.ss(*linearize(\n", - " aircraft='F-35B-2',\n", - " states=['ic/r-rad_sec'],\n", - " states_deriv = ['accelerations/rdot-rad_sec2'],\n", - " inputs=['propulsion/engine/yaw-angle-rad'],\n", - " outputs=['ic/r-rad_sec'],\n", - " ic=op_hover,\n", - " dx=1e-3,\n", - " n_round=3\n", - "))\n", - "s = control.tf([1, 0], [1])\n", - "G_rudder_to_yaw = -clean_tf(control.minreal(control.ss2tf(sys), 1e-3))/s\n", - "G_rudder_to_yaw" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "Yaw angle seems to have no impact on r moment, need to investigate. Can add another lift-fan to model this if necessary." - ], - "metadata": {} - }, - { - "cell_type": "markdown", - "source": [ - "## Altitude" - ], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "sys = control.ss(*linearize(\n", - " aircraft='F-35B-2',\n", - " states=['ic/w-fps'],\n", - " states_deriv = ['accelerations/wdot-ft_sec2'],\n", - " inputs=['fcs/throttle-cmd-norm'],\n", - " outputs=['ic/w-fps'],\n", - " ic=op_hover,\n", - " dx=1e-3,\n", - " n_round=3\n", - "))\n", - "G_throttle_to_alt = -clean_tf(control.minreal(control.ss2tf(sys), 1e-3))/s\n", - "G_throttle_to_alt" - ], - "outputs": [], - "metadata": {} - }, - { - "cell_type": "code", - "execution_count": null, - "source": [ - "H_throttle_to_alt = 0.01*(2*s + 1)\n", - "\n", - "\n", - "plt.figure()\n", - "rootlocus(G_throttle_to_alt*H_throttle_to_alt)\n", - "plt.plot([0, -1], [0, 1], '--')\n", - "\n", - "Gc_throttle_to_alt = G_throttle_to_alt*H_throttle_to_alt/(1 + G_throttle_to_alt*H_throttle_to_alt)\n", - "\n", - "plt.figure()\n", - "step_size = 10\n", - "t, y = control.step_response(step_size*Gc_throttle_to_alt, T=np.linspace(0, 40, 1000));\n", - "plt.plot(t, y)\n", - "plt.xlabel('t, sec')\n", - "plt.ylabel('altitude, ft')\n", - "plt.title('output')\n", - "\n", - "plt.figure()\n", - "# error computed in ft\n", - "e = step_size-y\n", - "t, u, _= control.forced_response(H_throttle_to_alt, T=t, U=e)\n", - "plt.hlines([-0.1, 0.1], t[0], t[-1], linestyles='dashed')\n", - "plt.plot(t, u)\n", - "plt.xlabel('t, sec')\n", - "plt.ylabel('throtle %')\n", - "plt.title('input')\n", - "\n", - "plt.figure()\n", - "control.nyquist(Gc_throttle_to_alt, omega=np.logspace(-3, 3, 1000));\n", - "\n", - "plt.figure(figsize=(15, 7))\n", - "control.gangof4(G_throttle_to_alt, H_throttle_to_alt, Hz=True, dB=True)\n", - "\n", - "control.margin(Gc_throttle_to_alt)" - ], - "outputs": [], - "metadata": {} - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.9.6", - "mimetype": "text/x-python", - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "pygments_lexer": "ipython3", - "nbconvert_exporter": "python", - "file_extension": ".py" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} \ No newline at end of file