{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Longitudinal Stability\n", "\n", "Through the remainder of the course, means will be developed to analyse the full stability characteristics of aircraft, including the dynamic behaviour. For this, we will separate the aircraft into *longitudinal* motion (pitching), and combined *lateral/directional* (rolling/yawing).\n", "\n", "For the purposes of static stability, aircraft motion can be isolated to looking at moments about each of the three axes independently.\n", "\n", "Longitudinal stability is *more interesting* and *more complicated* than than both lateral and directional stability, so it will be analysed first and the same techniques used to explore the other two axes.\n", "\n", "For longitudinal stability, the static response is concerned with the aircraft pitching motion - so the parameter of interest is the pitching moment. A model needs to be formulated than can account for the combined effect of the wing, horizontal stabiliser, the elevator, and the aircraft weight therereupon. The pitching moment coefficient is defined\n", "\n", "$$C_m\\triangleq\\frac{M}{\\tfrac{1}{2}\\rho V^2 S\\bar{c}}$$\n", "\n", "Before building a model, consider what stability would look like for aircraft pitching motion. The desired behaviour for stability would be that if the aircraft were perturbed in pitch, it would return to the equilibrium position. That is, pitch stability means that a nose-up perturbation is accompanied by a nose-down pitching moment.\n", "\n", "## Stability Derivatives\n", "\n", "The assumption is made that the aircraft pitching moment can be represented as the product of terms comprising the product of **stability derivatives** and variables, and constants.\n", "\n", "The **stability derivatives** are written in non-dimensional form as:\n", "\n", "$$C_{A_B}=\\frac{\\partial C_A}{B}$$\n", "\n", "The pitching moment coefficient is assumed to be of the form:\n", "\n", "$$C_m = C_{m_0} + C_{m_\\alpha}\\cdot\\alpha + C_{m_Q}\\cdot{Q}$$\n", "\n", "where $C_{m_0}$ is a *constant* term and hence does not affect stability in any way.\n", "\n", "### Condition for $C_{m_\\alpha}$\n", "\n", "Since $\\alpha$ is defined as a nose-up motion, and $M$ is defined positive nose-up, it follows that **for stability, $C_{m_\\alpha}$ must be negative**\n", "\n", "$$\\begin{align}\n", " C_{m_\\alpha} &< 0 \\rightarrow\\text{stable}\\\\\n", " C_{m_\\alpha} &>0 \\rightarrow\\text{unstable}\\\\\n", "\\end{align}$$\n", "\n", "What aircraft design parameters lead to $C_{m_\\alpha}$ being negative? A full model will be formulated that will lead to design parameters, but some simple observations can be made from first principles. Consider the respective longitudinal locations of the aircraft centre of gravity (CG), and the aircaft aerodynamic centre (AC).\n", "\n", "```{margin} Aircraft AC\n", "You will be familiar with centre of pressure and aerodynamic centre from 2D aerofoil theory - the point at which the lift can be assumed to act as a resultant force, and the point at which the moment is independent of AoA, respectively.\n", "\n", "The CP moves with angle of attack for a cambered aerofoil, whilst the AC is a fixed position.\n", "```\n", "\n", "There are two possibilties; the AC can be ahead of the CG, or the AC can be behind the CG.\n", "\n", "#### AC Ahead of CG\n", "\n", "```{figure} ../Images/CPCG1.png\n", "---\n", "height: 300px\n", "name: CPCG1\n", "---\n", "AC ahead of CG\n", "```\n", "\n", "Consider the case with the AC ahead of the CG. The lift is directly proportional to the angle of attack, and the nose-up moment is directly proportional to the lift. In the following, $M_0$ represents the lift independent pitching moment *and* the pitching moment at $\\alpha=0$ for the sake of mathematical simplicity.\n", "\n", "$$M(\\alpha) = M_0 + a\\cdot\\alpha\\cdot l$$\n", "$$\\frac{\\text{d}M}{\\text{d}\\alpha}= a\\cdot l > 0$$\n", "\n", "So with the AC ahead of the CG, the aircraft is statically unstable in pitch.\n", "\n", "#### AC Aft of CG\n", "\n", "```{figure} ../Images/CPCG2.png\n", "---\n", "height: 300px\n", "name: CPCG2\n", "---\n", "AC aft of CG\n", "```\n", "\n", "Consider the case with the AC aft of the CG. \n", "\n", "$$M(\\alpha) = M_0 - a\\cdot\\alpha\\cdot l$$\n", "$$\\frac{\\text{d}M}{\\text{d}\\alpha}= -a\\cdot l < 0$$\n", "\n", "So with the AC aft of the CG, the aircraft is statically stable in pitch.\n", "\n", "This shows why most aircraft *except* fighter aircraft have aft horizontal tails - the horizontal tail *pulls* the aerodynamic centre aft, and allows the CG to be moved further aft.\n", "\n", "A model will be formulated to show the numerical relationship between the tail and the aerodynamic centre, but the result above has been shown from first principles, and is instructive and intuitive. If you're still not wholly satisfied in this result - try throwing a dart/nerf vortex/arrow \"tail first\". It will immediately flip over. \n", "\n", "So the stability condition for $C_{m_\\alpha}$ has been established, and a model will be developed to relate design parameters to the numerical value thereof. Before this, though, the stability of $C_{M_Q}$ will be explored.\n", "\n", "### Condition for $C_{m_Q}$\n", "\n", "Using similar reasoning, both conditions for AC/CG location can be overlaid in a single diagram:\n", "\n", "```{figure} ../Images/CMQ.png\n", "---\n", "height: 500px\n", "name: CMQ\n", "---\n", "CP and CG with a pitch rate\n", "```\n", "\n", "Looking at Figure {ref}`CMQ` it can be readily seen that a positive pitch rate will cause an downwash for AC ahead of CG, and a upwash for AC aft of CG. This causes a respective decrease and increase in angle of attack, and lift. So **for any AC/CG location, the derivative $C_{M_Q}$ will always be negative and hence restorative**.\n", "\n", "### Second order system representation\n", "\n", "The aircraft pitching motion can be modeled as a second order system\n", "\n", "```{figure} ../Images/Victor2ndOrder.png\n", "---\n", "height: 300px\n", "name: SecondOrder\n", "---\n", "Second order system for pitching motion\n", "```\n", "\n", "This representation should be familiar for you from previous courses, and will be used more in later modules - but for now it serves to help understand the concepts of $C_{m_\\alpha}$ and $C_{m_Q}$. The former represents the *pitch stiffness*, whilst the latter represents the *pitch damping*.\n", "\n", "#### Too much stability?\n", "\n", "Whilst it can be readily observed that for stability $C_{m_\\alpha}<0$, with this term now being described as *pitch stiffness*, you will be able to further observe that it gives an indication of *how difficult* it is to get an aircraft to move manoeuvred from steady flight. As such, if an aircraft is **too stable**, its handling is sluggish. Fundamentally, this explains the planform differences between fighter aircraft and commuter aircraft. \n", "\n", "### A model for pitch stability\n", "\n", "A simplified aircraft representation will be used that comprises the aircraft wing, HT, elevator, and centre of gravity:\n", "\n", "```{figure} ../Images/Wing_HT_Layout.png\n", "---\n", "height: 300px\n", "name: Wing_HT_Layout\n", "---\n", "Model for wing/HT contribution to pitching moment\n", "```\n", "where\n", "\n", "$$\\begin{align}\n", "\\bar{c} &= \\text{Mean aerodynamic chord}\\\\\n", "L_w &= \\text{Wing lift}\\\\\n", "L_t &= \\text{Tail lift}\\\\\n", "M_0 &= \\text{Zero lift pitching moment (taken to represent wing/tail combination)}\\\\\n", "\\alpha &= \\text{AoA at the main wing}\\\\\n", "i_t &= \\text{Tail incidence}\\\\\n", "\\delta_e &= \\text{Elevator deflection angle}\\\\\n", "w_i &= \\text{Downwash due to wing}\\\\\n", "\\epsilon &= \\text{Resultant change to incidence at tail due to downwash}\\\\\n", "V^\\prime &= \\text{Resultant velocity vector at tail}\\\\\n", "h_0\\bar{c} &= \\text{Distance between forward moment ref. point and wing AC}\\\\\n", "h\\bar{c} &= \\text{Distance between forward moment ref. point and a/c CG}\\\\\n", "l_t &= \\text{Distance between CG and AC of tail}\\\\\n", "\\bar{l}_t &= \\text{Distance between wing AC and tail AC}\n", "\\end{align}$$\n", "```{margin} Control surface deflections\n", "Some texts use $\\xi$, $\\eta$, and $\\zeta$ for aileron, elevator, and rudder deflections - but who, aside from actual Greeks, can write $\\xi$ and $\\zeta$ consistently distinguishable? Certainly not me.\n", "\n", "We'll use the slightly-more accessible nomenclature of $\\delta_a$, $\\delta_e$, and $\\delta_r$. This is more commonplace in US texts anyway.\n", "```\n", "\n", "Note that the forward moment reference point has been written as the leading edge of the wing, but this is an arbitrary point about which moments are evaluated. It could be the nose, for example.\n", "\n", "```{margin} CP or AC?\n", "To resolve lift as a constant force, it should be applied at the centre of pressure. To decouple the moment from incidence, the lift force should be applied at the aerodynamic centre. \n", "\n", "In the analysis herein, the aerofoils are approximated as thin and symmetric which means both the AC and CP can be treated as the quarter chord position.\n", "\n", "For a real cambered aerofoil, the CP moves with angle of attack and is at a location infinitely far behind the aerofoil. This obviously makes the analysis difficult, so we use the AC as the point of force application.\n", "```\n", "\n", "### Collecting moments\n", "\n", "One can evaluate the moments anywhere using this model and they should equal zero for trim. They will be evaluated at the wing AC and the aircraft CG.\n", "\n", "First, at the AC:\n", "\n", "$$\\Sigma M_{ac} = M_0 + W\\left(h-h_0\\right)\\bar{c} - L_t\\cdot\\bar{l}_t$$\n", "\n", "with the equilibrium steady flight condition this becomes\n", "\n", "$$\\Sigma M_{ac} = M_0 + L\\left(h-h_0\\right)\\bar{c} - L_t\\cdot\\bar{l}_t$$\n", "\n", "since \n", "\n", "$$C_m=\\frac{M}{\\frac{1}{2}\\rho V^2S\\bar{c}}$$\n", "\n", "then\n", "\n", "$$C_{m_{ac}} = C_{m_0} + C_{L}\\left(h-h_0\\right)-C_{L_t}\\eta_t\\frac{S_t\\,\\bar{l}_t}{S_W\\,\\bar{c}}$$\n", "\n", "where $\\eta_t=\\frac{q_t}{q}$ and represents the loss in total head from the freestream to the tail.\n", "\n", "Similarly the moments can be evaluated at the centre of gravity:\n", "\n", "$$\\Sigma M_{cg} = M_0 + L_w\\left(h-h_0\\right)\\bar{c} - L_t\\cdot l_t$$\n", "\n", "and in coefficient form\n", "\n", "$$C_{m_{cg}} = C_{m_0} + C_{L_w}\\left(h-h_0\\right)-C_{L_t}\\eta_t\\frac{S_t\\,l_t}{S_W\\,\\bar{c}}$$\n", "\n", "Two dimensionless parameters appear in the above expressions as the *modified tail volume coefficient* and *tail volume coefficient*, respectively:\n", "\n", "$$\\bar{V_H} = \\frac{S_t}{S_W}\\cdot\\frac{\\bar{l}_t}{\\bar{c}}$$\n", "$$V_H = \\frac{S_t}{S_W}\\cdot\\frac{l_t}{\\bar{c}}$$\n", "\n", "giving\n", "\n", "$$C_{m_{ac}} = C_{m_0} + C_{L}\\left(h-h_0\\right)-C_{L_t}\\eta_t\\,\\bar{V_H}$$\n", "$$C_{m_{cg}} = C_{m_0} + C_{L_w}\\left(h-h_0\\right)-C_{L_t}\\eta_t\\,V_H$$\n", "\n", "For the aircraft to be in trim, the total moment must be zero - so these can be rearranged to yield an expression for the lift that the tail must produce to give trim\n", "\n", "$$\tC_{L_T} = \\frac{C_{m0} + C_L\\left(h-h_0\\right)}{\t\\eta_T\\,\\bar{V}_H} = \\frac{C_{m0} + C_{L_W}\\left(h-h_0\\right)}{\\eta_T\\,{V}_H}$$\n", "\n", "The quanity $(h-h_0)$ is *how far the CG is aft of the AC*, so the tail lift is clearly directly proportional to this quantity. In reality, this relationship is more useful the other way around - that is, the amount of lift that the tail can produce dictates the CG limits.\n", "\n", "### A model for tail lift\n", "\n", "The tail lift is assumed to be a function of the angle of attack and the elevator deflection angle\n", "\n", "$$C_{L_T} = a_{t}\\alpha_t + a_{e}\\delta_e$$\n", "\n", "where $a_t$ is the tail lift curve slope, and $a_e$ is the rate of change of tail lift with elevator deflection angle.\n", "\n", "The angle of attack at the tail will be different to that of the wing due to the tailplane incidence, and the fact that the wing sits in the downwash of the wing.\n", "\n", "$$\\alpha_t = \\alpha + i_t- \\epsilon$$\n", "\n", "hence\n", "\n", "$$C_{L_T} = a_{t}\\left(\\alpha + i_t- \\epsilon\\right) + a_{e}\\delta_e$$\n", "\n", "the downwash at the tail is a function of the main wing bound vortex strength, and hence of the angle of attack\n", "\n", "$$C_{L_T} = a_{t}\\left(i_t + \\alpha\\left\\{1-\\frac{\\partial\\epsilon}{\\partial\\alpha}\\right\\}\\right) + a_{e}\\delta_e$$\n", "$$C_{L_T} = a_{t}\\left(i_t + \\alpha\\left\\{1-\\epsilon_\\alpha\\right\\}\\right) + a_{e}\\delta_e$$\n", "\n", "The expression above can be substituted into the two expressions for the pitching moment coefficient\n", "\n", "$$C_{m_{ac}} = C_{m_0} + C_{L}\\left(h-h_0\\right)-\\left[a_{t}\\left(i_t + \\alpha\\left\\{1-\\epsilon_\\alpha\\right\\}\\right) + a_{e}\\delta_e\\right]\\eta_t\\,\\bar{V_H}$$\n", "$$C_{m_{cg}} = C_{m_0} + C_{L_w}\\left(h-h_0\\right)-\\left[a_{t}\\left(i_t + \\alpha\\left\\{1-\\epsilon_\\alpha\\right\\}\\right) + a_{e}\\delta_e\\right]\\eta_t\\,V_H$$\n", "\n", "#### Downwash angle?\n", "\n", "The derivative $\\epsilon_\\alpha=\\frac{\\partial\\epsilon}{\\partial\\alpha}$ is the rate of change of downwash angle with wing angle of attack. A detailed consideration of this effect is beyond the scope of this course, but you should be able to intuit the qualitative relatioship:\n", "- The downwash will be larger with more lift, so $\\epsilon_\\alpha$ must be positive for an aft tail\n", "- $\\epsilon_\\alpha$ should be inversely proportional to the vertical and horizontal separation of the wing and tail\n", "- $\\epsilon_\\alpha$ will increase with sweepback\n", "- $\\epsilon_\\alpha$ will decrease with aspect ratio\n", "\n", "A detailed discussion of a potential solution to $\\epsilon_\\alpha$ is provided in MacCormick{cite}`MacCormick:1995wq`, pg 486. I *may* include the potential model in this section as an interactive script at a future date...remind me if I haven't.\n", "\n", "For our purposes, an approximation will suffice. For an aircraft with an elliptical lift distribution, if it is assumed that the tail is 'far' downstream of the wing, then the induced angle of attack at the tail is reduced by twice the induced angle of attack at the wing. That is\n", "\n", "$$\\epsilon=-\\delta\\alpha_t=2\\alpha_w$$\n", "\n", "which, from lifting line theory is\n", "\n", "$$\\epsilon=\\frac{2\\cdot C_L}{\\pi\\cdot AR}$$\n", "\n", "\n", "$$\\epsilon_\\alpha= \\frac{4}{AR}$$\n", "\n", "\n", "\n", "\n", "### Elevator angle to trim\n", "\n", "The equations derived are useful in that they can be set to zero and rearranged for the elevator deflection or the lift coefficient. This gives either the elevator deflection as a function of $C_L$ or vice versa. This then enables determintion of the elevator angle required to reach certain speeds, or the speeds achievable with given elevator deflection angles.\n", "\n", "Seeting $C_{m_{ac}}=0$ and rearranging for $\\delta_e$ yields\n", "\n", "\n", "$$\\delta_e=\\frac{1}{a_e\\,\\eta_T\\,\\bar{V}_T}\\left[C_{m_0} - C_L\\left\\{\\frac{a_t}{a}\\left[1-\\epsilon_\\alpha\\right]\\,\\eta_t\\,\\bar{V}_t -(h-h_0)\\right\\}-a_t\\,\\eta_t\\,\\bar{V}_T\\left\\{i_t-\\frac{C_{L_0}}{a}\\left[1-\\epsilon_\\alpha\\right]\\right\\} \\right]$$(elevatorangletotrim)\n", "\n", "The expression above can be sense checked to prove that it shows sensible relationships based on what we know about aircraft:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{margin} Sign convention\n", "The sign convention is not consistent for control surface deflectons from book to book, and often depends on different airframers. In my previous life doing stability and control transonic wind tunnel testing for different manufacturers, this could lead to confusing moments.\n", "\n", "C'mon, that's an amazing pun.\n", "```\n", "1. From the model developed, the sign convention is that elevator deflection is positive trailing edge down.\n", "2. The equation above shows that the elevator angle is a linear, inverse function of $C_L$. This is actually just due to the way that I've written it since the sign of $\\left\\{\\frac{a_t}{a}\\left[1-\\epsilon_\\alpha\\right]\\,\\eta_t\\,\\bar{V}_t -(h-h_0)\\right\\}$ is ambiguous at first glance. Generally, though, the left hand side terms will be greater than the right hand ones. So, $\\delta_e\\propto-C_L$\n", "\n", " This makes sense as we'd expect the elevator angle to become more negative with an increase in $C_L$. If this doesn't make sense to you, then consider that an increase on $C_L$ is caused by an increase in $\\alpha$ hence requiring a nose up moment - hence, a reduction in lift on the tail.\n", "3. It further shows that the elevator angle is a linear and positive function of the quantity $(h-h_0)$. Recall that this represents the CG position aft of the wing AC. Hence, with an aft CG, more elevator deflection is required.\n", "\n", "```{admonition} Try and do this rearrangement yourself\n", ":class: dropdown\n", "It's a bit of a bastard of algebra - and you'll ned $C_L=C_{L_0}+\\alpha\\cdot a$ to make it work.\n", "```\n", "\n", "It is also common to wish to have zero elevator deflection at the cruise condition.\n", "\n", "```{admonition} Why do we wish to have $\\delta_e=0$ at cruise?\n", ":class: dropdown\n", "Elevator deflection increases the drag.\n", "```\n", "\n", "Setting the elevator deflection to zero allows for solution of either $\\bar{V}_H$ for a given $i_t$ OR solution of $i_t$ for a given $\\bar{V}_H$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Relationship between lift coefficients, lift curve slopes\n", "\n", "Quantities with a subscript $()_w$ denote wing quantities, and $()_t$ denote tail quantities. The dimensional lift is the sum of wing and lift\n", "\n", "$$L=L_w + L_t$$\n", "\n", "but\n", "\n", "$$C_L\\neq C_{L_w} + C_{L_t}$$\n", "\n", "because of the different denominators in the two coefficients. Rather,\n", "\n", "$$C_L= C_{L_w} + \\eta_t\\frac{S_t}{S}C_{L_t}$$\n", "\n", "using the tail lift model:\n", "\n", "$$C_L= C_{L_w} + \\eta_t\\frac{S_t}{S}\\left[a_{t}\\left(i_t + \\alpha\\left(1-\\epsilon_\\alpha\\right)\\right) + a_{e}\\delta_e\\right]$$\n", "\n", "hence the total aircraft lift curve slope can now be denoted - for the *stick-fixed* case.\n", "```{margin} \n", "Stick Fixed meaning no input, since for steady flight, $\\delta_e$ is a function of $\\alpha$ and that'd be a much more complicated derivative to solve. Furthermore, we're after the response of the aircraft withut any changes to controls.\n", "```\n", "\n", "$$a=\\frac{\\partial C_L}{\\partial\\alpha} = a_w + \\eta_t\\frac{S_t}{S}a_t\\left(1-\\epsilon_\\alpha\\right) $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Stick Fixed Static Stability\n", "\n", "With no control input, we will use the expression for $C_{m_{ac}}$ and differentiate wrt $\\alpha$ to get $C_{m_\\alpha}$ thus yielding the stability criteria - since we know that $C_{m_\\alpha}<0$ for stability.\n", "\n", "$$\\frac{\\partial C_{m_{ac}}}{\\partial\\alpha} = a\\left(h-h_0\\right) - \\bar{V}_H\\cdot\\eta_t\\cdot a_t\\left(1-\\epsilon_\\alpha\\right)$$\n", "\n", "It is more common to work in terms of $C_L$ rather than $\\alpha$ so\n", "\n", "$$\\frac{\\partial C_m}{\\partial C_L}=\\frac{\\partial C_m}{\\partial \\alpha}\\frac{\\partial \\alpha}{\\partial C_L}=\\frac{\\partial C_m}{\\partial \\alpha}\\frac{1}{a}$$\n", "\n", "$$\\frac{\\partial C_m}{\\partial C_L}=\\underbrace{\\left(h-h_0\\right)}_{\\substack{\\text{Distance between CG}\\\\ \\text{and wing AC}}} - \\underbrace{\\bar{V}_H\\cdot\\eta_t\\cdot\\frac{a_t}{a}\\left(1-\\epsilon_\\alpha\\right)}_{\\substack{\\text{Horizontal Tail}\\\\ \\text{Parameters}}}$$\n", "\n", "Since $\\frac{\\partial C_m}{\\partial C_L}$ will have the same sign as $\\frac{\\partial C_m}{\\partial\\alpha}$, the stability criteria are the same. The boundary between positive and negative stability is governed by the above equation equallying zero.\n", "\n", "### Neutral Point\n", "\n", "This defines the **neutral point**, which is the centre of gravity position that provides neutral stability. This is the most *aft* the CG can be before instability occurs (although flight with $h=h_0$ is clearly not safe, either).\n", "\n", "The neutral point has the symbol $h_n$ and it can be shown:\n", "\n", "$$h_n = \\underbrace{h_0}_{\\substack{\\text{Wing AC}}} + \\underbrace{\\bar{V}_H\\cdot\\eta_t\\cdot\\frac{a_t}{a}\\left(1-\\epsilon_\\alpha\\right)}_{\\substack{\\text{Horizontal Tail}\\\\ \\text{Parameters}}}$$\n", "\n", "Therefore, without the tail, the neutral point is the wing AC. The horizontal tail \"pulls\" the neutral point aft of this position\n", "\n", "### Static Margin\n", "\n", "It follows from the above that the distance between the centre of gravity position and the neutral point dictates the degree of stability. This non-dimensional quantity is termed the **static margin**, $H_n$\n", "\n", "```{margin} Nondimensional?\n", "Recall that $h$ is the longitudinal CG location, nondimensionalised by MAC\n", "```\n", "$$H_n = h_n - h$$\n", "\n", "Substituting $h_n$ into the above yields\n", "\n", "$$\\begin{align}\n", "H_n &= h_0 - h + \\eta_t\\bar{V}_H\\frac{a_t}{a}\\left(1-\\epsilon_\\alpha\\right)\\\\\n", "&= -\\frac{\\partial C_m}{\\partial C_L}\\end{align}$$\n", "\n", "Since we need $\\frac{\\partial C_m}{\\partial\\alpha}<0$ and hence $\\frac{\\partial C_m}{\\partial C_L}<0$, it can be observed that **the static margin IS the pitch stiffness** (well, it's *proportional* to the pitch stiffness since $C_{m_\\alpha}$ is the actual stiffness) of the aircraft, and hence dictates the stability and how difficult it is to pitch the aircraft.\n", "\n", "The aircraft becomes more difficult to pitch with an increase in static margin, and this can be shown.\n", "\n", "### Elevator lift coefficient gradient\n", "\n", "Taking the elevator angle to trim, {eq}`elevatorangletotrim`, and differentiating with respect to lift coefficient yields\n", "\n", "$$\\begin{align}\n", "\\frac{\\partial\\delta_e}{\\partial C_L} &= -\\frac{1}{a_e\\,\\eta_t\\,\\bar{V}_H}\\left[\\frac{a_t}{a}\\left(1-\\epsilon_\\alpha\\right)\\eta_t\\bar{V}_H-\\left(h-h_0\\right)\\right]\\\\\n", "&= -\\frac{1}{a_e\\,\\eta_t\\,\\bar{V}_H}H_n\\end{align}$$\n", "\n", "again showing that a **more stable aircraft is harder to change cruise speed**.\n", "\n", "### Determination of NP by flight test\n", "\n", "To determine/confirm the Neutral Point of an aircraft using flight test, a series of flights are performed with the longitudinal CG position varied (but still with the CG ahead of the predicted neutral point - else flight would occur with neutral stability, which is dangerous. During these flights, cruise trim is reached at a range of different lift coefficients to provide data such as the following, whereby the slope of $\\frac{\\partial\\delta_e}{\\partial C_L}$ may be determined.\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "tags": [ "remove-input" ] }, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "line": { "color": "red", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Aft - FT Data", "type": "scatter", "x": [ 0.3, 0.4, 0.5, 0.6000000000000001, 0.7000000000000002, 0.8000000000000003, 0.9000000000000001, 1.0000000000000002, 1.1000000000000003, 1.2000000000000004, 1.3000000000000005 ], "y": [ 3.4710681293817256, 1.4459804227799982, -0.6247998165569602, -2.963277705887389, -4.963320922016603, -7.252822902639743, -9.546965508698356, -11.847456972079385, -13.927272175137915, -16.293001066753657, -18.002931028436432 ] }, { "line": { "color": "red", "dash": "solid", "width": 1 }, "mode": "lines", "name": "dE/dCL=-21.9", "type": "scatter", "x": [ 0.3, 1.3000000000000005 ], "y": [ 3.617079220452017, -18.254315501551083 ] }, { "line": { "color": "green", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Med - FT Data", "type": "scatter", "x": [ 0.3, 0.4, 0.5, 0.6000000000000001, 0.7000000000000002, 0.8000000000000003, 0.9000000000000001, 1.0000000000000002, 1.1000000000000003, 1.2000000000000004, 1.3000000000000005 ], "y": [ 0.40227011581484895, -3.0477157008847957, -6.023707316944002, -9.243264892807517, -12.78634691130799, -16.009549372846383, -19.453757595197917, -22.327521547724565, -25.734468167834343, -29.39100232132074, -32.29683018246442 ] }, { "line": { "color": "green", "dash": "solid", "width": 1 }, "mode": "lines", "name": "dE/dCL=-32.8", "type": "scatter", "x": [ 0.3, 1.3000000000000005 ], "y": [ 0.4096848514772411, -32.393665559389596 ] }, { "line": { "color": "blue", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Fwd - FT Data", "type": "scatter", "x": [ 0.3, 0.4, 0.5, 0.6000000000000001, 0.7000000000000002, 0.8000000000000003, 0.9000000000000001, 1.0000000000000002, 1.1000000000000003, 1.2000000000000004, 1.3000000000000005 ], "y": [ -2.7446988264387286, -7.524714436612616, -11.906783141720037, -16.09574852048676, -20.606623374481558, -24.53819241710292, -29.172876533491063, -33.647094243019296, -37.701465362362704, -42.281315674167175, -46.76008219838053 ] }, { "line": { "color": "blue", "dash": "solid", "width": 1 }, "mode": "lines", "name": "dE/dCL=-43.7", "type": "scatter", "x": [ 0.3, 1.3000000000000005 ], "y": [ -2.9910398354817076, -46.64161375147533 ] } ], "layout": { "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "Three different CG positions, elevator angle to trim - FT data and linear fit", "x": 0.5 }, "xaxis": { "title": { "text": "$C_L$" } }, "yaxis": { "title": { "text": "$\\text{Elevator angle to trim - }\\delta_E|_\\text{trim}$" } } } }, "text/html": [ "
\n", " \n", " \n", "
\n", " \n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import meshio\n", "import plotly.graph_objects as go\n", "from myst_nb import glue\n", "\n", "## Make some fake data\n", "import numpy as np\n", "ae = 1.1\n", "eta_t = 0.95\n", "V_H = 0.5\n", "Hns = [.2, .3, .4]\n", "\n", "CLs = np.arange(0.3, 1.4, .1)\n", "\n", "fig = go.Figure()\n", "\n", "from scipy.interpolate import interp1d\n", "\n", "## Add some axes\n", "# fig.add_trace(go.Scatter3d(x=[0, tiprange], y=[0, 0], z=[0, 0],\n", "# mode='lines',\n", "# showlegend=False, line=dict(color='royalblue', width=4)))\n", "\n", "names = [\"CG Aft - FT Data\", \"CG Med - FT Data\", \"CG Fwd - FT Data\"]\n", "dE0 = 10\n", "\n", "colours = ['red', 'green', 'blue']\n", "gradients = np.array([0, 0, 0])\n", "\n", "for i, Hn in enumerate(Hns):\n", " dEdCL = -1/(ae*eta_t*V_H) * Hn\n", " dE = dE0 + np.degrees(dEdCL * CLs + np.random.rand(CLs.size)*.01)\n", "\n", " fig.add_trace(go.Scatter(x=CLs, y=dE,\n", " mode='markers', name=names[i], line=dict(color=colours[i], width=1, dash='solid')))\n", "\n", " polyline = np.polyfit(CLs, dE, 1)\n", " CLS = np.array([min(CLs), max(CLs)])\n", " dEs = CLS * polyline[0] + polyline[1]\n", " \n", " fig.add_trace(go.Scatter(x=CLS, y=dEs,\n", " mode='lines', name=f\"dE/dCL={polyline[0]:1.1f}\", line=dict(color=colours[i], width=1, dash='solid')))\n", " \n", " gradients[i] = polyline[0]\n", " \n", "\n", "\n", "fig.update_layout(\n", " title='Three different CG positions, elevator angle to trim - FT data and linear fit', title_x=0.5,\n", " xaxis_title=\"$C_L$\",\n", " yaxis_title=\"$\\\\text{Elevator angle to trim - }\\delta_E|_\\\\text{trim}$\",\n", ")\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{figure} FTdata\n", "Flight test data (obviously simulated) for elevator deflection angle for three CG locations\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The gradient of a straight line through the data is proportional to $C_{M_\\alpha}$, so the stability boundary is the case with $h=h_n$. The gradient can be plotted against the CG location, and a line fitted through these data:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "tags": [ "remove-input" ] }, "outputs": [ { "data": { "application/vnd.plotly.v1+json": { "config": { "plotlyServerURL": "https://plot.ly" }, "data": [ { "line": { "color": "red", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Aft - FT Data", "type": "scatter", "x": [ 0.6 ], "y": [ -21 ] }, { "line": { "color": "green", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Med - FT Data", "type": "scatter", "x": [ 0.4 ], "y": [ -32 ] }, { "line": { "color": "blue", "dash": "solid", "width": 1 }, "mode": "markers", "name": "CG Fwd - FT Data", "type": "scatter", "x": [ 0.19999999999999996 ], "y": [ -43 ] }, { "line": { "color": "blue", "dash": "solid", "width": 1 }, "mode": "lines", "name": "Linear Fit", "type": "scatter", "x": [ 0.19999999999999996, 1 ], "y": [ -42.99999999999998, 1.0000000000000568 ] }, { "mode": "markers", "name": "NP Location", "type": "scatter", "x": [ 0.9818181818181808 ], "y": [ 0 ] } ], "layout": { "template": { "data": { "bar": [ { "error_x": { "color": "#2a3f5f" }, "error_y": { "color": "#2a3f5f" }, "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "bar" } ], "barpolar": [ { "marker": { "line": { "color": "#E5ECF6", "width": 0.5 } }, "type": "barpolar" } ], "carpet": [ { "aaxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "baxis": { "endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f" }, "type": "carpet" } ], "choropleth": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "choropleth" } ], "contour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "contour" } ], "contourcarpet": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "contourcarpet" } ], "heatmap": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmap" } ], "heatmapgl": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "heatmapgl" } ], "histogram": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "histogram" } ], "histogram2d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2d" } ], "histogram2dcontour": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "histogram2dcontour" } ], "mesh3d": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "type": "mesh3d" } ], "parcoords": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "parcoords" } ], "pie": [ { "automargin": true, "type": "pie" } ], "scatter": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter" } ], "scatter3d": [ { "line": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatter3d" } ], "scattercarpet": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattercarpet" } ], "scattergeo": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergeo" } ], "scattergl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattergl" } ], "scattermapbox": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scattermapbox" } ], "scatterpolar": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolar" } ], "scatterpolargl": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterpolargl" } ], "scatterternary": [ { "marker": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "type": "scatterternary" } ], "surface": [ { "colorbar": { "outlinewidth": 0, "ticks": "" }, "colorscale": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "type": "surface" } ], "table": [ { "cells": { "fill": { "color": "#EBF0F8" }, "line": { "color": "white" } }, "header": { "fill": { "color": "#C8D4E3" }, "line": { "color": "white" } }, "type": "table" } ] }, "layout": { "annotationdefaults": { "arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1 }, "coloraxis": { "colorbar": { "outlinewidth": 0, "ticks": "" } }, "colorscale": { "diverging": [ [ 0, "#8e0152" ], [ 0.1, "#c51b7d" ], [ 0.2, "#de77ae" ], [ 0.3, "#f1b6da" ], [ 0.4, "#fde0ef" ], [ 0.5, "#f7f7f7" ], [ 0.6, "#e6f5d0" ], [ 0.7, "#b8e186" ], [ 0.8, "#7fbc41" ], [ 0.9, "#4d9221" ], [ 1, "#276419" ] ], "sequential": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ], "sequentialminus": [ [ 0, "#0d0887" ], [ 0.1111111111111111, "#46039f" ], [ 0.2222222222222222, "#7201a8" ], [ 0.3333333333333333, "#9c179e" ], [ 0.4444444444444444, "#bd3786" ], [ 0.5555555555555556, "#d8576b" ], [ 0.6666666666666666, "#ed7953" ], [ 0.7777777777777778, "#fb9f3a" ], [ 0.8888888888888888, "#fdca26" ], [ 1, "#f0f921" ] ] }, "colorway": [ "#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52" ], "font": { "color": "#2a3f5f" }, "geo": { "bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white" }, "hoverlabel": { "align": "left" }, "hovermode": "closest", "mapbox": { "style": "light" }, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": { "angularaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "radialaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "scene": { "xaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "yaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" }, "zaxis": { "backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white" } }, "shapedefaults": { "line": { "color": "#2a3f5f" } }, "ternary": { "aaxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "baxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" }, "bgcolor": "#E5ECF6", "caxis": { "gridcolor": "white", "linecolor": "white", "ticks": "" } }, "title": { "x": 0.05 }, "xaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 }, "yaxis": { "automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": { "standoff": 15 }, "zerolinecolor": "white", "zerolinewidth": 2 } } }, "title": { "text": "Three different CG positions, elevator trim/CL gradient - FT data and linear fit", "x": 0.5 }, "xaxis": { "title": { "text": "$h-h_0$" }, "zeroline": true, "zerolinecolor": "black", "zerolinewidth": 2 }, "yaxis": { "title": { "text": "$\\text{Elevator trim gradient - }\\frac{\\partial\\delta_E|_\\text{trim}}{\\partial C_L}$" }, "zeroline": true, "zerolinecolor": "black", "zerolinewidth": 2 } } }, "text/html": [ "
\n", " \n", " \n", "
\n", " \n", "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = go.Figure()\n", "fig_X = np.array([-i*2 for i in Hns]) + 1\n", "\n", "for i in range(len(fig_X)):\n", " fig.add_trace(go.Scatter(x=[fig_X[i]], y=[gradients[i]],\n", " mode='markers', line=dict(color=colours[i], width=1, dash='solid'),\n", " name=names[i]))\n", "\n", "polyline = np.polyfit(fig_X, gradients, 1)\n", "grad_X = np.array([min(fig_X), 1])\n", "grads = grad_X * polyline[0] + polyline[1]\n", "intercept_X = -polyline[1]/polyline[0]\n", "\n", "intercept_Y = 0\n", "\n", "fig.add_trace(go.Scatter(x=grad_X, y=grads,\n", " mode='lines', name = 'Linear Fit', line=dict(color=colours[i], width=1, dash='solid')))\n", "\n", "fig.add_trace(go.Scatter(x=[intercept_X], y=[intercept_Y], mode='markers', name='NP Location'))\n", "\n", "fig.update_xaxes(zeroline=True, zerolinewidth=2, zerolinecolor='black')\n", "fig.update_yaxes(zeroline=True, zerolinewidth=2, zerolinecolor='black')\n", "\n", "fig.update_layout(\n", " title='Three different CG positions, elevator trim/CL gradient - FT data and linear fit', title_x=0.5,\n", " xaxis_title=\"$h-h_0$\",\n", " yaxis_title=\"$\\\\text{Elevator trim gradient - }\\\\frac{\\partial\\delta_E|_\\\\text{trim}}{\\partial C_L}$\",\n", ")\n", "\n", "fig.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "celltoolbar": "Tags", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }