###### Content under Creative Commons Attribution license CC-BY 4.0, code under MIT license (c)2014 L.A. Barba, C. Cooper, G.F. Forsyth, A. Krishnan.

# Phugoid Motion

Welcome to [**"Practical Numerical Methods with Python!"**](http://openedx.seas.gwu.edu/courses/GW/MAE6286/2014_fall/about) This course is a collaborative, online, open education project, where we aim to give a foundation in scientific computing. The focus is on numerical solution of problems modeled by ordinary and partial differential equations.

This Jupyter Notebook introduces the problem we'll be studying in the **first module** of the course: the _phugoid model of glider flight_. We'll start with some background, explaining the physics, and working out the mathematical model.

First, we'll look at an idealized motion where there is no drag, resulting in a simple harmonic motion. We can plot some interesting trajectories that will pique your imagination. In the next notebook, you'll learn to numerically integrate the differential equation using Euler's method. But hang on ... first things first.

The term "phugoid" is used in aeronautics to refer to a motion pattern where an aircraft oscillates up and down —nose-up and climb, then nose-down and descend— around an equilibrium trajectory.  The aircraft oscillates in altitude, speed and pitch, with only small (neglected) variations in the angle of attack, as it repeatedly exchanges kinetic and potential energy.

A low-amplitude phugoid motion can be just a nuisance, as the aircraft does not exceed the stall angle of attack and nothing bad happens. But the mode can also be unstable leading to a stall or even a loop!

Look at this video showing a Cessna single-engine airplane in phugoid motion:

Hi there $\mathbf{\sigma}$

```python
from IPython.display import YouTubeVideo
YouTubeVideo('ysdU4mnRYdM')
```

That doesn't look too good! What's happening?

It can get a lot worse when an aircraft enters one of these modes that is unstable. For example, one of [NASA's Helios Solar Powered Aircraft](http://www.nasa.gov/centers/dryden/history/pastprojects/Helios/) prototype broke up in mid air due to extreme phugoid oscillations!

Helios was a proof-of-concept solar electric-powered flying wing that broke the world altitude record for a non-rocket-powered aircraft in August 2001. But in June 26, 2003, it broke something else. The aircraft entered phugoid motion after encountering turbulence near the Hawaiian Island of Kauai. The high speed in the oscillatory movement exceeded the design limits, and it ended up wrecked in the Pacific Ocean. Luckily, the Helios was remotely operated, and nobody got hurt.

## The physics of phugoids

The phugoid oscillation has the aircraft pitching up and down, as it decelerates and accelerates. The trajectory might look like a sinusoid, as in the figure below. The assumption is that the forward velocity of the aircraft, $v$, varies in such a way that the angle of attack remains (nearly) constant, which means that we can assume a constant lift coefficient.

#### Figure 1. Trajectory of an aircraft in phugoid motion.

In the descending portion of the trajectory, the aircraft's velocity increases as it proceeds from a peak to the minimum height—gaining kinetic energy at the expense of potential energy. The contrary happens in the upward segment, as its velocity decreases there.

We measure the pitch angle (between the aircraft's longitudinal axis and the horizontal) as positive when the aircraft's nose is pointing up. In the portion of the trajectory below the center-line, where it curves upwards, the pitch angle $\theta$ is increasing: $\dot{\theta}>0$. And where the trajectory curves down, the pitch angle is decreasing: $\dot{\theta}<0$, as shown in the figure.

Let's remind ourselves of the forces affecting an aircraft in a downward glide. Look at the figure below: we show the flight path, the forces on the glider (no thrust), and the _glide angle_ or flight path angle, $\gamma$, between the flight path and the horizontal.

#### Figure 2. Forces on a glider.

The force of lift, $L$ —created by the airflow around the wings— is perpendicular to the trajectory, and the force of drag, $D$, is parallel to the trajectory. Both forces are expressed in terms of coefficients of lift and drag, $C_L$ and $C_D$, respectively, that depend on the wing design and _angle of attack_—the angle between the wing chord and the flight path.

If you are not familiar with airplane aerodynamics, you might be getting confused with some terms here ... and all those angles! But be patient and look things up, if you need to. We're giving you a quick summary here.

Lift and drag are proportional to a surface area, $S$, and the dynamic pressure: $1/2 \rho v^2$, where $\rho$ is the density of air, and $v$ the forward velocity of the aircraft. The equations for lift and drag are:

$$
\begin{eqnarray}
L &=& C_L S \times \frac{1}{2} \rho v^2 \\
D &=& C_D S \times \frac{1}{2} \rho v^2
\end{eqnarray}
$$

If the glider were in equilibrium, the forces would balance each other. We can equate the forces in the directions perpendicular and parallel to the trajectory, as follows:

$$
\begin{equation}
L = W \cos \gamma \quad \text{and} \quad D = W \sin \gamma
\end{equation}
$$

where $W$ represents the weight of the glider.

In the figure, we've drawn the angle $\gamma$ as the _glide angle_, formed between the direction of motion and the horizontal. We are not bothered with the _sign_ of the angle, because we draw a free-body diagram and take the direction of the forces into account in writing our balance equations. But later on, we will need to be careful with the sign of the angles. It can cause you a real headache to keep this straight, so be patient!

It looks like we've set this up to do a little bit of mathematics. Are you ready?

But before, a short glimpse of the history.

## Lanchester's Aerodonetics

"Phugoid theory" was first described by the British engineer Frederick W. Lanchester in _"Aerodonetics"_ (1909). This book is so old that it is now in the public domain, so you can actually download [from Google Books](http://books.google.com/books?id=6hxDAAAAIAAJ&dq=%22phugoid%20theory%20deals%20with%20the%20longitudinal%20stability%22&pg=PA37#v=onepage&q=%22phugoid%20theory%20deals%20with%20the%20longitudinal%20stability%22&f=false) a PDF file of a scan, or read it online.

Lanchester defines phugoid theory as the study of longitudinal stability of a flying machine (aerodone). He first considered the simplification where drag and moment of inertia are neglected. Then he included these effects, obtaining an equation of stability. In addition to describing many experiments by himself and others, Lanchester also reports on _"numerical work ... done by the aid of an ordinary 25-cm slide rule."_ Go figure!

### Ideal case of zero drag

In this section, we follow the derivation given by Milne-Thompson (1966), which we find a little bit easier than that of the original in "Aerodonetics"!

An aircraft flying in a steady, straight horizontal flight has a lift equal to its weight. The velocity in this condition is sometimes called _trim velocity_ ("trim" is what pilots do to set the controls to just stay in a steady flight). Let's use $v_t$ for the trim velocity, and from $L=W$ deduce that:

$$
\begin{equation}
W = C_L S \times\frac{1}{2} \rho v_t^2
\end{equation}
$$

The weight $W$ is constant for the aircraft, but the lift at any other flight condition depends on the flight speed, $v$. We can use the expression for the weight in terms of $v_t$ to obtain the ratio $L/W$ at any other flight velocity, as follows:

$$
\begin{equation}
\frac{L}{W}= \frac{v^2}{v_t^2}
\end{equation}
$$

Imagine that the aircraft experienced a little upset, a wind gust, and it finds itself off the "trim" level, in a curved path with an instantaneous angle $\theta$. In the sketch below, we exaggerate the curved trajectory of flight to help you visualize what we'll do next. The angle $\theta$ (using the same name as Milne-Thompson) is between the _trajectory_ and the horizontal, positive up.

#### Figure 3. Curved trajectory of the aircraft going up.

We can form a free body diagram to determine the balance of forces.

#### Figure 4. Free body diagram of the aircraft trajectory

From the free body diagram, we can see that

$$
\begin{equation}
\vec{L} + \vec{W} = m\vec{a} = \frac{mv^2}{R}\hat{n} + m \frac{dv}{dt}\hat{t}
\end{equation}
$$

where $\frac{v^2}{R}$ is the centripetal acceleration and $R$ is the radius of curvature of the trajectory.
If we decompose the lift and weight into their normal and tangential components we get

$$
\begin{equation}
L\hat{n} + W_n\hat{n} + W_t\hat{t} = \frac{mv^2}{R}\hat{n} + m \frac{dv}{dt}\hat{t}
\end{equation}
$$

The component of the weight in the normal direction ($W_n$) is

$$
\begin{equation}
W_n = -W \cos \theta
\end{equation}
$$

If we then consider that all of the components in $\hat{n}$ must balance out, we arrive at

$$
\begin{equation}
L - W \cos \theta = \frac{mv^2}{R}
\end{equation}
$$

We can rewrite this as

$$
\begin{equation}
L- W \cos \theta = \frac{W}{g} \frac{v^2}{R}
\end{equation}
$$

where $g$ is the acceleration due to gravity. Rearrange this by dividing the equation by the weight, and use the expression we found for $L/W$, above. The following equation results:

$$
\begin{equation}
\frac{v^2}{v_t^2}-\cos \theta = \frac{v^2}{g R}
\end{equation}
$$

Recall that we simplified the problem assuming that there is no friction, which means that the total energy is constant (the lift does no work). If $z$ represents the depth below a reference horizontal line, the energy per unit mass is (kinetic plus potential energy):

$$
\begin{equation}
\frac{1}{2}v^2-g z = \text{constant}
\end{equation}
$$

To get rid of that pesky constant, we can choose the reference horizontal line at the level that makes the constant energy equal to zero, so $v^2 = 2 g z$. That helps us re-write the phugoid equation in terms of $z$ as follows:

$$
\begin{equation}
\frac{z}{z_t}-\cos \theta = \frac{2z}{R}
\end{equation}
$$

Let $ds$ represent a small arc-length of the trajectory. We can write

$$
\begin{equation}
\frac{1}{R} = \frac{d\theta}{ds} \quad \text{and}\quad  \sin\theta = -\frac{dz}{ds}
\end{equation}
$$

Employing the chain rule of calculus,

$$
\begin{equation}
\frac{1}{R} = \frac{d\theta}{ds} = \frac{dz}{ds}\frac{d\theta}{dz} = -\sin \theta\frac{d\theta}{dz}
\end{equation}
$$

Multiply the phugoid equation by $\frac{1}{2\sqrt{z}}$ to get:

$$
\begin{equation}
\frac{\sqrt{z}}{2z_t} - \frac{\cos\theta}{2\sqrt{z}} = \frac{\sqrt{z}}{R}
\end{equation}
$$

Substituting for $1/R$ on the right hand side and bringing the cosine term over to the right, we get:

$$
\begin{equation}
\frac{\sqrt{z}}{2z_t} = \frac{\cos \theta}{2 \sqrt{z}} - \sqrt{z} \sin \theta \frac{d\theta}{dz}
\end{equation}
$$

The right-hand-side is an exact derivative! We can rewrite it as:

$$
\begin{equation}
\frac{d}{dz} \left(\sqrt{z}\cos\theta \right) = \frac{\sqrt{z}}{2z_t}
\end{equation}
$$

Integrating this equation, we add an arbitrary constant, chosen as $C\sqrt{z_t}$ which (after dividing through by $\sqrt{z}$) gives:

$$
\begin{equation}
\cos \theta = \frac{1}{3}\frac{z}{z_t} + C\sqrt{\frac{z_t}{z}}
\end{equation}
$$

Taking the derivative of both sides of equation (19) and applying the relations from equation (15) yields:

$$
\begin{equation}
\frac{z_t}{R} = \frac{1}{3} - \frac{C}{2}\sqrt{\frac{z_t^3}{z^3}}
\end{equation}
$$

Make sure you have followed the derivation, and perhaps write it out on paper!

## Phugoid Curves

Equation (15) is non-linear, which usually means we are hard-pressed to write a clean expression for the variable of interest, $z$.  In fact, Lanchester himself said that he was unable to _"reduce this expression to a form suitable for co-ordinate plotting."_ If the great polymath couldn't do it, we can't either!

But Lanchester _was_ able to plot a suitable approximation of the phugoid flight path using what he called the "trammel" method.  If you're interested in seeing how he did it, his explanation begins on page [48 of Aerodonetics](http://books.google.com/books?id=6hxDAAAAIAAJ&pg=PA49&lpg=PA48&dq=aerodonetics+the+use+of+the+trammel&source=bl&ots=lB6EVKYQuT&sig=aVE2kiDWZoWftaWczMIrcYftMOs&hl=en&sa=X&ei=gTD_U82fGYjzgwT3moGwCQ&ved=0CCAQ6AEwAA#v=onepage&q=aerodonetics%20the%20use%20of%20the%20trammel&f=false).  It's a trip.

Lanchester used Equations (15) and (16) to solve for the constant $C$ and the radius of curvature $R$ and then iteratively plotted small arcs of the phugoid path. By hand.

We wrote a neat little code that duplicates the manual trammel method, but it might be a bit much for you to absorb in the first lesson.  If you want to look it over, you are more than welcome to.  If you are just starting with Python, skip it for the moment and we'll return to it at the end of this module.

### Plotting the flight path

As we mentioned, we wrote a Python code to reproduce programmatically what Lanchester did graphically. Here's a neat feature of Jupyter Notebooks: you can run external programs with the magical keyword ... wait for it ... `run`. And the jargon of Jupyter _is_ to call this "magic." In fact, there are a bunch of [magic functions](https://ipython.readthedocs.io/en/stable/interactive/index.html) that you will learn about. They will make you a happy camper.
The line `%matplotlib inline` tells Jupyter Notebook to show the plots inline.

Let's do it:

```python
%run phugoid.py
%matplotlib inline
```

This code cell loaded our simulated-trammel code, `phugoid.py`. The code defined a function for you in the background, called `plot_flight_path`, taking three positional inputs: $z_t$, $z$ and $\theta$.

Look again at Equation (15), where we take the positive square root. There are several possibilities, depending on the value that the constant $C$ takes.

* There are no physical solutions for $C>2/3$, because it would result in $\cos\theta>1$.

* If $C=2/3$, then the solution is a horizontal straight line, because $\cos\theta=1$, $\theta=0$ and $R=\infty$.

* Any value of $C$ for which $0 < C < \frac{2}{3}$ will produce "trochoidal"-like paths.  What does this look like? Let's use our custom function `plot_flight_path` to find out!

```python
# Initial conditions: zt = 64.0, z0 = 16.0, theta0 = 0.0.
plot_flight_path(64.0, 16.0, 0.0)
```

Cool!  Note that the plot title tells us what the calculated value of $C$ was for our input conditions.  We have a value of $C$ between $0$ and $\frac{2}{3}$ and our path is trochoidal, like we announced it would be.

* For negative values of $C$, the resultant flight path consists of a series of loops.  Let's try it out!

```python
# Initial conditions: zt = 64.0, z0 = 16.0, theta0 = 180.0.
plot_flight_path(64.0, 16.0, 180.0)
```

You can play around with the input values and see what kind of behavior results.  Just note that any value of $C > \frac{2}{3}$ will result in $\cos \theta > 1$, which doesn't exist.  Python will probably throw a few errors if you hit that condition, but just try again!

* The last case is $C = 0$.  Take another look at Equation (16) and plug in $C = 0$, what should happen? It looks like it will just reduce to

$$R = 3z_t$$

It's a constant radius of curvature!  In fact, this solution is a series of semi-circles, with a cusp between them. One way to force $C = 0$ that we can figure out from Equation (15), is to make:

$$z = 3z_t, \quad \theta = 0$$

```python
# Initial conditions: zt = 16.0, z0 = 48.0, theta0 = 0.0.
plot_flight_path(16.0, 48.0, 0.0)
```

That looks an awful lot like a quarter circle.  And what's the radius of the arc?  It's $r = 48 = 3z_t$.

We can also get a semi-circle out of our simulated trammel by changing to another configuration where $C$ is (near) zero. Here's one example:

```python
# Initial conditions: zt = 64.0, z0 = 16.0, theta0 = -90.0.
plot_flight_path(64.0, 16.0, -90.0)
```

That is so nice. We have reproduced the trajectories that Lanchester found more than a hundred years ago, painstakingly drawing them by hand with a contraption called a "trammel." It must have taken him days!

Here is how the different phugoid curves are drawn in von Kármán's book, _Aerodynamics_ (1957). He never says _how_ he drew them, but we're guessing by hand, also. We did pretty good!

#### Figure 4. Phugoid curves in von Kármán (1957).

In the [next notebook](https://nbviewer.jupyter.org/github/numerical-mooc/numerical-mooc/blob/master/lessons/01_phugoid/01_02_Phugoid_Oscillation.ipynb) of this series, we'll look at the differential equation that arises when you consider small perturbations on the horizontal phugoid, and we'll learn to numerically integrate that to get the flight paths.

## References

1. Lanchester, F. W. _Aerodonetics_, D. van Nostrand Company: New York, 1909. On the public domain. [Get it from Google Books](http://books.google.com/books?id=6hxDAAAAIAAJ&pg=PP1#v=onepage&q&f=false).

2. Milne-Thompson, L. M. _Theoretical Aerodynamics_, Dover 2012 reprint of the revised 1966 edition. [Read on Google Books](http://books.google.com/books?id=EMfCAgAAQBAJ&lpg=PP1&pg=PP1#v=onepage&q&f=false) (see section 18.5)

3. Sinha, N. K. and Ananthkrishnan, N. _Elementary Flight Dynamics with an introduction to Bifurcation and Continuation Methods_, CRC Press, 2013. [Read on Google Books](http://books.google.com/books?id=yXL6AQAAQBAJ&lpg=PP1&pg=PP1#v=onepage&q&f=false) (see chapter 5)

4. von Kármán, T. _Aerodynamics_, Dover 2004 reprint of the 1957 2nd edition. (see pages 149–151)

---

###### The cell below loads the style of this notebook.

```python
# Execute this cell to load the notebook's style sheet, then ignore it.
from IPython.core.display import HTML
css_file = '../../styles/numericalmoocstyle.css'
HTML(open(css_file, 'r').read())
```

<link href='http://fonts.googleapis.com/css?family=Alegreya+Sans:100,300,400,500,700,800,900,100italic,300italic,400italic,500italic,700italic,800italic,900italic' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Arvo:400,700,400italic' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=PT+Mono' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Shadows+Into+Light' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Nixie+One' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Source+Code+Pro' rel='stylesheet' type='text/css'>
<style>

@font-face {
    font-family: "Computer Modern";
    src: url('http://mirrors.ctan.org/fonts/cm-unicode/fonts/otf/cmunss.otf');
}

#notebook_panel { /* main background */
    background: rgb(245,245,245);
}

div.cell { /* set cell width */
    width: 750px;
}

div #notebook { /* centre the content */
    background: #fff; /* white background for content */
    width: 1000px;
    margin: auto;
    padding-left: 0em;
}

#notebook li { /* More space between bullet points */
    margin-top:0.8em;
}

/* draw border around running cells */
div.cell.border-box-sizing.code_cell.running {
    border: 1px solid #111;
}

/* Put a solid color box around each cell and its output, visually linking them*/
div.cell.code_cell {
    background-color: rgb(256,256,256);
    border-radius: 0px;
    padding: 0.5em;
    margin-left:1em;
    margin-top: 1em;
}

div.text_cell_render{
    font-family: 'Alegreya Sans' sans-serif;
    line-height: 140%;
    font-size: 125%;
    font-weight: 400;
    width:600px;
    margin-left:auto;
    margin-right:auto;
}

/* Formatting for header cells */
.text_cell_render h1 {
    font-family: 'Nixie One', serif;
    font-style:regular;
    font-weight: 400;
    font-size: 45pt;
    line-height: 100%;
    color: rgb(0,51,102);
    margin-bottom: 0.5em;
    margin-top: 0.5em;
    display: block;
}

.text_cell_render h2 {
    font-family: 'Nixie One', serif;
    font-weight: 400;
    font-size: 30pt;
    line-height: 100%;
    color: rgb(0,51,102);
    margin-bottom: 0.1em;
    margin-top: 0.3em;
    display: block;
}

.text_cell_render h3 {
    font-family: 'Nixie One', serif;
    margin-top:16px;
    font-size: 22pt;
    font-weight: 600;
    margin-bottom: 3px;
    font-style: regular;
    color: rgb(102,102,0);
}

.text_cell_render h4 {    /*Use this for captions*/
    font-family: 'Nixie One', serif;
    font-size: 14pt;
    text-align: center;
    margin-top: 0em;
    margin-bottom: 2em;
    font-style: regular;
}

.text_cell_render h5 {  /*Use this for small titles*/
    font-family: 'Nixie One', sans-serif;
    font-weight: 400;
    font-size: 16pt;
    color: rgb(163,0,0);
    font-style: italic;
    margin-bottom: .1em;
    margin-top: 0.8em;
    display: block;
}

.text_cell_render h6 { /*use this for copyright note*/
    font-family: 'PT Mono', sans-serif;
    font-weight: 300;
    font-size: 9pt;
    line-height: 100%;
    color: grey;
    margin-bottom: 1px;
    margin-top: 1px;
}

.CodeMirror{
    font-family: "Source Code Pro";
    font-size: 90%;
}

.alert-box {
    padding:10px 10px 10px 36px;
    margin:5px;
}

.success {
    color:#666600;
    background:rgb(240,242,229);
}
</style>


# Lagrangian mechanics

> Marcos Duarte
> Laboratory of Biomechanics and Motor Control ([http://demotu.org/](http://demotu.org/))
> Federal University of ABC, Brazil

## The development of the laws of motion of bodies

> *"The theoretical development of the laws of motion of bodies is a problem of such interest and importance that it has engaged the attention of all the most eminent mathematicians since the invention of dynamics as a mathematical science by Galileo, and especially since the wonderful extension which was given to that science by Newton.
> Among the successors of those illustrious men, Lagrange has perhaps done more than any other analyst to give extent and harmony to such deductive researches, by showing that the most varied consequences respecting the motions of systems of bodies may be derived from one radical formula; the beauty of the methods so suiting the dignity of the results as to make of his great work a kind of scientific poem."*
— Hamilton, 1834 (apud Taylor, 2005).

The [Lagrangian mechanics](https://en.wikipedia.org/wiki/Lagrangian_mechanics) is a formulation of [classical mechanics](https://en.wikipedia.org/wiki/Classical_mechanics) where the [equations of motion](https://en.wikipedia.org/wiki/Equations_of_motion) are obtained from the [kinetic](https://en.wikipedia.org/wiki/Kinetic_energy) and [potential](https://en.wikipedia.org/wiki/Potential_energy) energy of the system (scalar quantities) represented in [generalized coordinates](https://en.wikipedia.org/wiki/Generalized_coordinates) instead of using [Newton's laws of motion](https://en.wikipedia.org/wiki/Newton's_laws_of_motion) to deduce the equations of motion from the [forces](https://en.wikipedia.org/wiki/Force) on the system ([vector](https://en.wikipedia.org/wiki/Euclidean_vector) quantities) represented in [Cartesian coordinates](https://en.wikipedia.org/wiki/Cartesian_coordinate_system). Lagrangian mechanics was introduced by [Joseph-Louis Lagrange](https://en.wikipedia.org/wiki/Joseph-Louis_Lagrange) in the late 18th century.

Let's deduce the Lagrange equations, but first let's review the basics of the Newtonian approach.

## Description of motion

One can describe the motion of a particle by specifying its position with respect to a frame of reference in the three-dimensional space as a function of time:

\begin{equation}
x(t),\, y(t),\, z(t) \quad \equiv \quad x_i(t) \quad i=1,\dotsc,3
\label{eq1}
\end{equation}

A system of $N$ particles will require $3N$ equations to describe their motion.

The basic problem in classical mechanics is to find ways to determine functions such as these, also known as equations of motion, capable of specifying the position of objects over time, for any mechanical situation. Assuming as known the meaning of $x_i(t)$, one can define the components of velocity, $v_i$, and acceleration, $a_i$, at time $t$, as:

\begin{equation} \begin{array}{rcl}
v_i(t) = \dfrac{\mathrm d x_i(t)}{\mathrm d t} = \dot{x}_i(t) \\
a_i(t) = \dfrac{\mathrm d^2 x_i(t)}{\mathrm d t^2} = \dot{v}_i(t)
\label{eq3}
\end{array} \end{equation}

Where we used the Newton's notation for differentiation (also called the dot notation), a dot over the dependent variable. Of note, [Joseph Louis Lagrange](https://pt.wikipedia.org/wiki/Joseph-Louis_Lagrange) introduced the prime mark to denote a derivative: $x'(t)$. Read more about the different notations for differentiation at [Wikipedia](https://en.wikipedia.org/wiki/Notation_for_differentiation).

### Laws of motion

The [Newton's laws of motion](https://en.wikipedia.org/wiki/Newton's_laws_of_motion) laid the foundation for classical mechanics. They describe the relationship between the motion of a body and the possible forces acting upon it.

In Newtonian mechanics, the body's linear momentum is defined as:

\begin{equation}
\mathbf{p} = m\mathbf{v}
\label{eq5}
\end{equation}

If the mass of the body is constant, remember that Newton's second law can be expressed by:

\begin{equation}
\mathbf{F} = \frac{\mathrm d \mathbf{p}}{\mathrm d t}=\frac{\mathrm d \big(m\mathbf{v}\big)}{\mathrm d t} = m\mathbf{a}
\label{eq6}
\end{equation}

Using Newton's second law, to determine the position of the body we will have to solve the following second order ordinary differential equation:

\begin{equation}
\frac{\mathrm d^2 x_i(t)}{\mathrm d t^2} = \frac{\mathbf{F}}{m}
\label{eqa7}
\end{equation}

Which has the general solution:

\begin{equation}
\mathbf{x}(t) = \int\!\bigg(\int\frac{\mathbf{F}}{m} \mathrm{d}t\bigg)\mathrm{d}t
\label{eq8}
\end{equation}

### Mechanical energy

A related physical quantity is the mechanical energy, which is the sum of kinetic and potential energies.
The kinetic energy, $T$ of a particle is given by:

\begin{equation}
T = \frac{1}{2}mv^2
\label{eq9}
\end{equation}

The kinetic energy of a particle can be expressed in terms of its linear momentum:

\begin{equation}
T = \frac{p^2}{2m}
\label{eq10}
\end{equation}

And for a given coordinate of the particle's motion, its linear momentum can be obtained from its kinetic energy by:

\begin{equation}
p_i = \frac{\partial T}{\partial v_i}
\label{eq11}
\end{equation}

The potential energy, $V$ is the stored energy of a particle and its formulation is dependent on the force acting on the particle. For example, for a conservative force dependent solely on the particle position, such as due to the gravitational field near the Earth  surface or due to a linear spring, force and potential energy are related by:

\begin{equation}
\mathbf{F} = - \frac{\partial \mathbf{V}}{\partial x}
\label{eq12}
\end{equation}

## Lagrange's equation in Cartesian Coordinates

The Lagrangian mechanics can be formulated independent of the Newtonian mechanics and Cartesian coordinates; in fact  Joseph-Louis Lagrange this new formalism from the [principle of least action](http://nbviewer.jupyter.org/github/BMClab/bmc/blob/master/notebooks/principle_of_least_action.ipynb).

For simplicity, let's first deduce the Lagrange's equation for a particle in Cartesian Coordinates and from Newton's second law.

Because we want to deduce the laws of motion based on the mechanical energy of the particle, one can see that the time derivative of the expression for the linear momentum as a function of the kinetic energy, cf. Eq. (\ref{eq11}), is equal to the force acting on the particle and we can substitute the force in Newton's second law by this term:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\bigg(\frac{\partial T}{\partial \dot x}\bigg) = m\ddot x
\label{eq13}
\end{equation}

We saw that a conservative force can also be expressed in terms of the potential energy of the particle, cf. Eq. (\ref{eq12}); substituting the right side of the equation above by this expression, we have:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\bigg(\frac{\partial T}{\partial \dot x}\bigg) = -\frac{\partial V}{\partial x}
\label{eq14}
\end{equation}

Using the fact that:

\begin{equation}
\frac{\partial T}{\partial x} = 0 \quad and \quad \frac{\partial V}{\partial \dot x} = 0
\label{eq15}
\end{equation}

We can write:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\bigg(\frac{\partial (T-V)}{\partial \dot x}\bigg) - \frac{\partial (T-V)}{\partial x} = 0
\label{eq16}
\end{equation}

Defining the Lagrange or Lagrangian function, $\mathcal{L}$, as the difference between the kinetic and potential energy in the system:

\begin{equation}
\mathcal{L} = T - V
\label{eq17}
\end{equation}

We have the Lagrange's equation in Cartesian Coordinates for a conservative force acting on a particle:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\bigg(\frac{\partial \mathcal{L}}{\partial \dot x}\bigg) - \frac{\partial \mathcal{L}}{\partial x} = 0
\label{eq18}
\end{equation}

Once all derivatives of the Lagrangian function are calculated, this equation will be the equation of motion for the particle. If there are $N$ independent particles in a three-dimensional space, there will be $3N$ equations for the system.
The set of equations above for a system are known as Euler–Lagrange equations, or Lagrange's equations of the second kind.

Let's see some simple examples of the Lagrange's equation in Cartesian Coordinates just to consolidate what was deduced above. The real application of Lagrangian mechanics is in generalized coordinates, what will see after these examples.

### Example 1: Particle moving under the influence of a conservative force

Let's deduce the equation of motion using the Lagrangian mechanics for a particle with mass $m$ moving in the 3D space under the influence of a [conservative force](https://en.wikipedia.org/wiki/Conservative_force).
The Lagrangian $(\mathcal{L} = T - V)$ of the particle is:

\begin{equation}
\mathcal{L}(x,y,z,\dot x,\dot y,\dot z) = \frac{1}{2}m(\dot x^2 + \dot y^2 + \dot z^2) - V(x,y,z)
\end{equation}

The equations of motion for the particle are found by applying the Lagrange's equation for each coordinate.

For the x coordinate:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\left( {\frac{\partial \mathcal{L}}{\partial \dot{x}}}
\right) = \frac{\partial \mathcal{L}}{\partial x }
\end{equation}

And the derivatives of $\mathcal{L}$ are given by:

\begin{equation} \begin{array}{rcl}
&\dfrac{\partial \mathcal{L}}{\partial x} &=& -\dfrac{\partial \mathbf{V}}{\partial x} \\
&\dfrac{\partial \mathcal{L}}{\partial \dot{x}} &=& m\dot{x} \\
&\dfrac{\mathrm d }{\mathrm d t}\left( {\dfrac{\partial \mathcal{L}}{\partial \dot{x}}} \right) &=& m\ddot{x}
\end{array} \end{equation}

hence:

\begin{equation}
m\ddot{x} = -\frac{\partial \mathbf{V}}{\partial x}
\end{equation}

and similarly for the $y$ and $z$ coordinates.

For instance, if the conservative force is due to the gravitational field near Earth's surface $(\mathbf{V}=[0, mgy, 0])$, the Lagrange's equations (the equations of motion) are:

\begin{equation} \begin{array}{rcl}
m\ddot{x} &=& -\dfrac{\partial (0)}{\partial x} = 0 \\
m\ddot{y} &=& -\dfrac{\partial (mgy)}{\partial y} = -mg \\
m\ddot{z} &=& -\dfrac{\partial (0)}{\partial z} = 0
\end{array} \end{equation}

### Example 2: Ideal mass-spring system

Consider a system with a mass $m$ attached to an ideal spring (massless) with spring constant $k$ at the horizontal direction $x$. If the system is perturbed (a force is momentarily applied to the mass), we know the mass will oscillate around the rest position of the spring. Let's deduce the equation of motion for this system using the Lagrangian mechanics.
The Lagrangian $(\mathcal{L} = T - V)$ of the system is:

\begin{equation}
\mathcal{L}(x,\dot x) = \frac{1}{2}m\dot x^2 - \frac{1}{2}kx^2
\end{equation}

The derivatives of $L$ are given by:

\begin{equation} \begin{array}{rcl}
&\dfrac{\partial \mathcal{L}}{\partial x} &=& -kx \\
&\dfrac{\partial \mathcal{L}}{\partial \dot{x}} &=& m\dot{x} \\
&\dfrac{\mathrm d }{\mathrm d t}\left( {\dfrac{\partial \mathcal{L}}{\partial \dot{x}}} \right) &=& m\ddot{x}
\end{array} \end{equation}

And the Lagrange's equation (the equation of motion) is:

\begin{equation}
m\ddot{x} + kx = 0
\end{equation}

## Generalized coordinates

The direct application of Newton's laws to mechanical systems results in a set of equations of motion in terms of Cartesian coordinates of each of the particles that make up the system. In many cases, this is not the most convenient coordinate system to solve the problem or describe the movement of the system. For example, in problems involving many particles, it may be convenient to choose a system that includes the coordinate of the center of mass. Another example is a serial chain of rigid links, such as a member of the human body or from a robot manipulator, it may be simpler to describe the positions of each link by the angles between links.

Coordinate systems such as these are referred as [generalized coordinates](https://en.wikipedia.org/wiki/Generalized_coordinates). Generalized coordinates uniquely specify the positions of the particles in a system. Although there may be several generalized coordinates to describe a system, usually a judicious choice of generalized coordinates provides the minimum number of independent coordinates that define the configuration of a system (which is the number of degrees of freedom of the system), turning the problem simpler to solve.

Being a little more technical, according to [Wikipedia](https://en.wikipedia.org/wiki/Configuration_space_(physics)):
"In classical mechanics, the parameters that define the configuration of a system are called generalized coordinates, and the vector space defined by these coordinates is called the configuration space of the physical system. It is often the case that these parameters satisfy mathematical constraints, such that the set of actual configurations of the system is a manifold in the space of generalized coordinates. This manifold is called the configuration manifold of the system."

In problems where it is desired to use generalized coordinates, one can write Newton's equations of motion in terms of Cartesian coordinates and then transform them into generalized coordinates. However, it would be desirable and convenient to have a general method that would directly establish the equations of motion in terms of a set of convenient generalized coordinates. In addition, general methods for writing, and perhaps solving, the equations of motion in terms of any coordinate system would also be desirable. The [Lagrangian mechanics](https://en.wikipedia.org/wiki/Lagrangian_mechanics) is such a method.

### Lagrange's equation in generalized coordinates

We have deduced the Lagrange's equation in Cartesian Coordinates from the Newton's law just because it was a simple form of getting to the final equations. But, by no means the Lagrangian Mechanics should be viewed as a consequence of Newton's laws and specific to Cartesian Coordinates. The Lagrangian Mechanics could be deduced completely independent of Newton's law.

The Lagrange's equation can be expressed in terms of generalized coordinates what makes the Lagrangian formalism even more powerful. In fact, we will have the same equation as we deduced before (the only explicit difference will be that we will use $q_i$ instead of the Cartesian coordinate).
See [this notebook](http://nbviewer.jupyter.org/github/BMClab/bmc/blob/master/notebooks/lagrangian_mechanics_generalized.ipynb) for a deduction of the Lagrange's equation in generalized coordinates.

Defining the Lagrange or Lagrangian function of a system with $N$ generalized coordinates:

\begin{equation}
\mathcal{L} \equiv \mathcal{L}(q_1,\dotsc,q_{N} ,\dot{q}_1,\dotsc,\dot{q}_{N} ) = T - V
\label{eq46}
\end{equation}

We have the Lagrange's equation:

\begin{equation}
\frac{\mathrm d }{\mathrm d t}\left( {\frac{\partial \mathcal{L}}{\partial \dot{q}_i }}
\right)-\frac{\partial \mathcal{L}}{\partial q_i } = Q_{NCi} \quad i=1,\dotsc,N
\label{eq47}
\end{equation}

Where $Q_{NC}$ is a term representing a non-conservative force, such as a frictional force.

Once all derivatives of the Lagrangian function are calculated, this equation will be the equation of motion for each particle. If there are $N$ generalized coordinates to define the configuration of a system, there will be $N$ equations for the system.

The set of equations above for a system are known as Euler–Lagrange equations, or Lagrange's equations of the second kind.

### Example 3: Simple pendulum under the influence of gravity

Consider a pendulum with a massless rod of length $d$ and a mass $m$ at the extremity swinging in a plane forming the angle $\theta$ with vertical.
Although the pendulum moves at the plane, it only has one degree of freedom, which can be described by the angle $\theta$, the generalized coordinate. It is not difficult to find the equation of motion using Newton's law, but let's find it using the Lagrangian mechanics.

The kinetic energy is:

\begin{equation} T = \frac{1}{2}md^2\dot\theta^2 \end{equation}

And the potential energy is:

\begin{equation} V = -mgd\cos\theta \end{equation}

The Lagrangian function is:

\begin{equation} \mathcal{L} = \frac{1}{2}md^2\dot\theta^2 + mgd\cos\theta \end{equation}

And the derivatives are given by:

\begin{equation} \begin{array}{rcl}
&\dfrac{\partial \mathcal{L}}{\partial \theta} &=& -mgd\sin\theta \\
&\dfrac{\partial \mathcal{L}}{\partial \dot{\theta}} &=& md^2\dot{\theta} \\
&\dfrac{\mathrm d }{\mathrm d t}\left( {\dfrac{\partial \mathcal{L}}{\partial \dot{\theta}}} \right) &=& md^2\ddot{\theta}
\end{array} \end{equation}

Finally, the Lagrange's equation (the equation of motion) is:

\begin{equation} md^2\ddot\theta + mgd\sin\theta = 0 \end{equation}

### Example 4: Double pendulum under the influence of gravity

Consider a double pendulum (one pendulum attached to another) with massless rods of length $d_1$ and $d_2$ and masses $m_1$ and $m_2$ at the extremities of each rod swinging in a plane forming the angles $\theta_1$ and $\theta_2$ with vertical.
This case could be solved using Newtonian mechanics, but it's not simple (e.g., see [this link](http://www.myphysicslab.com/pendulum/double-pendulum/double-pendulum-en.html)). Instead, let's use the Lagrangian mechanics to derive the equations of motion for each pendulum.

The position of masses $m_1$ and $m_2$ are:

$x_1 = d_1\sin\theta_1$
$y_1 = -d_1\cos\theta_1$

$x_2 = d_1\sin\theta_1 + d_2\sin\theta_2$
$y_2 = -d_1\cos\theta_1 - d_2\cos\theta_2$

The kinetic and potential energies of the system are:

$ T = \frac{1}{2}m_1(\dot x_1^2 + \dot y_1^2) + \frac{1}{2}m_2(\dot x_2^2 + \dot y_2^2) $

$ V = m_1gy_1 + m_2gy_2 $

Let's use Sympy to help us; in fact we could solve this problem entirely in Sympy, see [Lagrange’s method in Sympy](http://docs.sympy.org/latest/modules/physics/mechanics/lagrange.html), but for now let's do just the derivatives.

Let's import Sympy libraries and define some variables:

```python
from sympy import Symbol, symbols, cos, sin, Matrix, simplify, Eq, latex
from sympy.physics.mechanics import dynamicsymbols, mlatex, init_vprinting
init_vprinting()
from IPython.display import display, Math

t = Symbol('t')
d1, d2, m1, m2, g = symbols('d1 d2 m1 m2 g', positive=True)
a1, a2 = dynamicsymbols('theta1 theta2')
```

The positions and velocities of masses $m_1$ and $m_2$ are:

```python
x1, y1 = d1*sin(a1), -d1*cos(a1)
x2, y2 = d1*sin(a1) + d2*sin(a2), -d1*cos(a1) - d2*cos(a2)
x1d, y1d = x1.diff(t), y1.diff(t)
x2d, y2d = x2.diff(t), y2.diff(t)

display(Math(r'x_1=' + mlatex(x1) + r'\quad \text{and} \quad \dot{x}_1=' + mlatex(x1d)))
display(Math(r'y_1=' + mlatex(y1) + r'\quad \text{and} \quad \dot{y}_1=' + mlatex(y1d)))
display(Math(r'x_2=' + mlatex(x2) + r'\quad \text{and} \quad \dot{x}_2=' + mlatex(x2d)))
display(Math(r'y_2=' + mlatex(y2) + r'\quad \text{and} \quad \dot{y}_2=' + mlatex(y2d)))
```

$$x_1=d_{1} \operatorname{sin}\left(\theta_{1}\right)\quad \text{and} \quad \dot{x}_1=d_{1} \operatorname{cos}\left(\theta_{1}\right) \dot{\theta}_{1}$$

$$y_1=- d_{1} \operatorname{cos}\left(\theta_{1}\right)\quad \text{and} \quad \dot{y}_1=d_{1} \operatorname{sin}\left(\theta_{1}\right) \dot{\theta}_{1}$$

$$x_2=d_{1} \operatorname{sin}\left(\theta_{1}\right) + d_{2} \operatorname{sin}\left(\theta_{2}\right)\quad \text{and} \quad \dot{x}_2=d_{1} \operatorname{cos}\left(\theta_{1}\right) \dot{\theta}_{1} + d_{2} \operatorname{cos}\left(\theta_{2}\right) \dot{\theta}_{2}$$

$$y_2=- d_{1} \operatorname{cos}\left(\theta_{1}\right) - d_{2} \operatorname{cos}\left(\theta_{2}\right)\quad \text{and} \quad \dot{y}_2=d_{1} \operatorname{sin}\left(\theta_{1}\right) \dot{\theta}_{1} + d_{2} \operatorname{sin}\left(\theta_{2}\right) \dot{\theta}_{2}$$

The kinetic and potential energies of the system are:

```python
T = m1*(x1d**2 + y1d**2)/2 + m2*(x2d**2 + y2d**2)/2
V = m1*g*y1 + m2*g*y2

display(Math(r'T=' + mlatex(simplify(T))))
display(Math(r'V=' + mlatex(simplify(V))))
```

$$T=\frac{d_{1}^{2} m_{1}}{2} \dot{\theta}_{1}^{2} + \frac{m_{2}}{2} \left(d_{1}^{2} \dot{\theta}_{1}^{2} + 2 d_{1} d_{2} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + d_{2}^{2} \dot{\theta}_{2}^{2}\right)$$

$$V=- g \left(d_{1} m_{1} \operatorname{cos}\left(\theta_{1}\right) + d_{1} m_{2} \operatorname{cos}\left(\theta_{1}\right) + d_{2} m_{2} \operatorname{cos}\left(\theta_{2}\right)\right)$$

The Lagrangian function is:

```python
L = T - V

display(Math(r'\mathcal{L}=' + mlatex(simplify(L))))
```

$$\mathcal{L}=\frac{d_{1}^{2} m_{1}}{2} \dot{\theta}_{1}^{2} + d_{1} g m_{1} \operatorname{cos}\left(\theta_{1}\right) + g m_{2} \left(d_{1} \operatorname{cos}\left(\theta_{1}\right) + d_{2} \operatorname{cos}\left(\theta_{2}\right)\right) + \frac{m_{2}}{2} \left(d_{1}^{2} \dot{\theta}_{1}^{2} + 2 d_{1} d_{2} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + d_{2}^{2} \dot{\theta}_{2}^{2}\right)$$

And the derivatives are (let's write a function to automate this process):

```python
def lagrange_terms(L, *q, show=True):
    """Calculate terms of Lagrange equations given the Lagrangian and q's.
    """
    Lterms = []
    for qi in q:
        dLdqi = simplify(L.diff(qi))
        Lterms.append(dLdqi)
        dLdqdi = simplify(L.diff(qi.diff(t)))
        Lterms.append(dLdqdi)
        dtdLdqdi = simplify(dLdqdi.diff(t))
        Lterms.append(dtdLdqdi)
        if show:
            display(Math(r'w.r.t.\;%s:'%latex(qi.func)))
            display(Math(r'\dfrac{\partial\mathcal{L}}{\partial %s}='
                         %latex(qi.func) + mlatex(dLdqi)))
            display(Math(r'\dfrac{\partial\mathcal{L}}{\partial\dot{%s}}='
                         %latex(qi.func) + mlatex(dLdqdi)))
            display(Math(r'\dfrac{\mathrm d}{\mathrm{dt}}\left({\dfrac{'+
                         r'\partial\mathcal{L}}{\partial\dot{%s}}}\right)='
                         %latex(qi.func) + mlatex(dtdLdqdi)))
    return Lterms

Lterms = lagrange_terms(L, a1, a2)
```

$$w.r.t.\;\theta_{1}:$$

$$\dfrac{\partial\mathcal{L}}{\partial \theta_{1}}=- d_{1} \left(d_{2} m_{2} \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + g m_{1} \operatorname{sin}\left(\theta_{1}\right) + g m_{2} \operatorname{sin}\left(\theta_{1}\right)\right)$$

$$\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{1}}}=d_{1} \left(d_{1} m_{1} \dot{\theta}_{1} + m_{2} \left(d_{1} \dot{\theta}_{1} + d_{2} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{2}\right)\right)$$

$$\dfrac{\mathrm d}{\mathrm{dt}}\left({\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{1}}}}\right)=d_{1} \left(d_{1} m_{1} \ddot{\theta}_{1} + m_{2} \left(d_{1} \ddot{\theta}_{1} - d_{2} \left(\dot{\theta}_{1} - \dot{\theta}_{2}\right) \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{2} + d_{2} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \ddot{\theta}_{2}\right)\right)$$

$$w.r.t.\;\theta_{2}:$$

$$\dfrac{\partial\mathcal{L}}{\partial \theta_{2}}=d_{2} m_{2} \left(d_{1} \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} - g \operatorname{sin}\left(\theta_{2}\right)\right)$$

$$\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{2}}}=d_{2} m_{2} \left(d_{1} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} + d_{2} \dot{\theta}_{2}\right)$$

$$\dfrac{\mathrm d}{\mathrm{dt}}\left({\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{2}}}}\right)=d_{2} m_{2} \left(- d_{1} \left(\dot{\theta}_{1} - \dot{\theta}_{2}\right) \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} + d_{1} \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \ddot{\theta}_{1} + d_{2} \ddot{\theta}_{2}\right)$$

Finally, the Lagrange's equations (the equations of motion) are:

```python
for i in range(int(len(Lterms)/3)):
    display(Eq(simplify(Lterms[3*i+2]-Lterms[3*i]), 0))
```

The motion of a double pendulum is very interesting; most of times it presents a chaotic behavior, see for example [https://www.myphysicslab.com/pendulum/double-pendulum-en.html](https://www.myphysicslab.com/pendulum/double-pendulum-en.html).

### Example 5: Double compound pendulum under the influence of gravity

Consider the double compound pendulum shown on the the right with length $d$ and mass $m$ of each rod swinging in a plane forming the angles $\theta_1$ and $\theta_2$ with vertical.
Let's use the Lagrangian mechanics to derive the equations of motion for each pendulum.

To calculate the potential and kinetic energy of the system, we will need to calculate the position and velocity of each pendulum. Now each pendulum is a rod with distributed mass and we will have to calculate the moment of rotational inertia of the rod. In this case, the kinetic energy of each pendulum will be given as the kinetic energy due to rotation of the pendulum plus the kinetic energy due to the speed of the center of mass of the pendulum, such that the total kinetic energy of the system is:

$ T = \overbrace{\underbrace{\frac{1}{2}I_{cm}\dot\theta_1^2}_{\text{rotation}} + \underbrace{\frac{1}{2}m(\dot x_{1,cm}^2 + \dot y_{1,cm}^2)}_{\text{translation}}}^{\text{pendulum 1}} + \overbrace{\underbrace{\frac{1}{2}I_{cm}\dot\theta_2^2}_{\text{rotation}} + \underbrace{\frac{1}{2}m(\dot x_{2,cm}^2 + \dot y_{2,cm}^2)}_{\text{translation}}}^{\text{pendulum 2}} $

And the potential energy of the system is:

$ V = mg\big(y_{1,cm} + y_{2,cm}\big) $

Once again, Sympy is on our side.

The position and velocity of the center of mass of the rods $1$ and $2$ are:

```python
d, m, g = symbols('d m g', positive=True)
a1, a2 = dynamicsymbols('theta1 theta2')
I = m*d*d/12

x1, y1 = d*sin(a1)/2, -d*cos(a1)/2
x2, y2 = d*sin(a1) + d*sin(a2)/2, -d*cos(a1) - d*cos(a2)/2
x1d, y1d = x1.diff(t), y1.diff(t)
x2d, y2d = x2.diff(t), y2.diff(t)

display(Math(r'x_1=' + mlatex(x1) + r'\quad \text{and} \quad \dot{x}_1=' + mlatex(x1d)))
display(Math(r'y_1=' + mlatex(y1) + r'\quad \text{and} \quad \dot{y}_1=' + mlatex(y1d)))
display(Math(r'x_2=' + mlatex(x2) + r'\quad \text{and} \quad \dot{x}_2=' + mlatex(x2d)))
display(Math(r'y_2=' + mlatex(y2) + r'\quad \text{and} \quad \dot{y}_2=' + mlatex(y2d)))
```

$$x_1=\frac{d \operatorname{sin}\left(\theta_{1}\right)}{2}\quad \text{and} \quad \dot{x}_1=\frac{d \dot{\theta}_{1}}{2} \operatorname{cos}\left(\theta_{1}\right)$$

$$y_1=- \frac{d \operatorname{cos}\left(\theta_{1}\right)}{2}\quad \text{and} \quad \dot{y}_1=\frac{d \dot{\theta}_{1}}{2} \operatorname{sin}\left(\theta_{1}\right)$$

$$x_2=d \operatorname{sin}\left(\theta_{1}\right) + \frac{d \operatorname{sin}\left(\theta_{2}\right)}{2}\quad \text{and} \quad \dot{x}_2=d \operatorname{cos}\left(\theta_{1}\right) \dot{\theta}_{1} + \frac{d \dot{\theta}_{2}}{2} \operatorname{cos}\left(\theta_{2}\right)$$

$$y_2=- d \operatorname{cos}\left(\theta_{1}\right) - \frac{d \operatorname{cos}\left(\theta_{2}\right)}{2}\quad \text{and} \quad \dot{y}_2=d \operatorname{sin}\left(\theta_{1}\right) \dot{\theta}_{1} + \frac{d \dot{\theta}_{2}}{2} \operatorname{sin}\left(\theta_{2}\right)$$

The kinetic and potential energies of the system are:

```python
T = I/2*(a1.diff(t))**2 + m*(x1d**2+y1d**2)/2 + I/2*(a2.diff(t))**2 + m*(x2d**2+y2d**2)/2
V = m*g*y1 + m*g*y2

display(Math(r'T=' + mlatex(simplify(T))))
display(Math(r'V=' + mlatex(simplify(V))))
```

$$T=\frac{d^{2} m}{6} \left(3 \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + 4 \dot{\theta}_{1}^{2} + \dot{\theta}_{2}^{2}\right)$$

$$V=- \frac{d g}{2} m \left(3 \operatorname{cos}\left(\theta_{1}\right) + \operatorname{cos}\left(\theta_{2}\right)\right)$$

The Lagrangian function is:

```python
L = T - V

display(Math(r'\mathcal{L}=' + mlatex(simplify(L))))
```

$$\mathcal{L}=\frac{d m}{6} \left(3 d \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + 4 d \dot{\theta}_{1}^{2} + d \dot{\theta}_{2}^{2} + 9 g \operatorname{cos}\left(\theta_{1}\right) + 3 g \operatorname{cos}\left(\theta_{2}\right)\right)$$

And the derivatives are (let's write a function to automate this process):

```python
Lterms = lagrange_terms(L, a1, a2)
```

$$w.r.t.\;\theta_{1}:$$

$$\dfrac{\partial\mathcal{L}}{\partial \theta_{1}}=- \frac{d m}{2} \left(d \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} + 3 g \operatorname{sin}\left(\theta_{1}\right)\right)$$

$$\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{1}}}=\frac{d^{2} m}{12} \left(6 \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{2} + 16 \dot{\theta}_{1}\right)$$

$$\dfrac{\mathrm d}{\mathrm{dt}}\left({\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{1}}}}\right)=\frac{d^{2} m}{6} \left(- 3 \left(\dot{\theta}_{1} - \dot{\theta}_{2}\right) \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{2} + 3 \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \ddot{\theta}_{2} + 8 \ddot{\theta}_{1}\right)$$

$$w.r.t.\;\theta_{2}:$$

$$\dfrac{\partial\mathcal{L}}{\partial \theta_{2}}=\frac{d m}{2} \left(d \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} \dot{\theta}_{2} - g \operatorname{sin}\left(\theta_{2}\right)\right)$$

$$\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{2}}}=\frac{d^{2} m}{12} \left(6 \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} + 4 \dot{\theta}_{2}\right)$$

$$\dfrac{\mathrm d}{\mathrm{dt}}\left({\dfrac{\partial\mathcal{L}}{\partial\dot{\theta_{2}}}}\right)=\frac{d^{2} m}{6} \left(- 3 \left(\dot{\theta}_{1} - \dot{\theta}_{2}\right) \operatorname{sin}\left(\theta_{1} - \theta_{2}\right) \dot{\theta}_{1} + 3 \operatorname{cos}\left(\theta_{1} - \theta_{2}\right) \ddot{\theta}_{1} + 2 \ddot{\theta}_{2}\right)$$

Finally, the Lagrange's equations (the equations of motion) are:

```python
for i in range(int(len(Lterms)/3)):
    display(Eq(simplify(Lterms[3*i+2]-Lterms[3*i]), 0))
```

### Example 6: Simple pendulum on moving cart

Consider a simple pendulum with massless rod of length $d$ and mass $m$ at the extremity of the rod forming an angle $\theta$ with the vertical direction under the action of gravity. The pendulum swings freely from a cart with mass $M$ that moves at the horizontal direction pushed by a force $F_x$.
Let's use the Lagrangian mechanics to derive the equations of motion for the system

From the figure on the right, because of the constraints introduced by the constant length of the rod and the motion the cart can perform, good generalized coordinates to describe the configuration of the system are $x$ and $\theta$. Let's use these coordinates.

The positions of the cart (c) and of the pendulum tip (p) are:

$ x_c = x $
$ y_c = 0 $

$ x_p = x + d \sin \theta $
$ y_p = -d \cos \theta $

The velocities of the cart and of the pendulum are:

$ \dot{x}_c = \dot{x} $
$ \dot{y}_c = 0 $

$ \dot{x}_p = \dot{x} + d \dot{\theta} \cos \theta $
$ \dot{y}_p = d \dot{\theta} \sin \theta $

The kinetic energy of the system is:

\begin{equation}
T = \frac{1}{2} M \big(\dot x_c^2 + \dot y_c^2 \big) + \frac{1}{2}m\,\big( \dot x_p^2 + \dot y_p^2 \big)
\end{equation}

And the potential energy of the system is:

\begin{equation}
V = M g y_c + m g y_p
\end{equation}

The Lagrangian function is:

\begin{equation}\begin{array}{rcl}
\mathcal{L} &=& \frac{1}{2} M \dot x^2 + \frac{1}{2}m\,\bigg[ \big(\dot{x} + d \dot{\theta} \cos\theta \big)^2 + \big(d \dot{\theta} \sin \theta \big)^2 \bigg] + m g d \cos \theta \\
&=& \frac{1}{2} (M+m) \dot x^2 + m\dot{x}d\dot{\theta}\cos\theta + \frac{1}{2}md^2\dot{\theta}^2 + m g d \cos \theta
\end{array}\end{equation}

The derivatives w.r.t. $x$ are:

\begin{equation}\begin{array}{rcl}
\dfrac{\partial \mathcal{L}}{\partial x} &=& 0 \\
\dfrac{\partial \mathcal{L}}{\partial \dot{x}} &=& (M+m) \dot{x} + m d \dot{\theta} \cos \theta \\
\dfrac{\mathrm d }{\mathrm d t}\left( {\dfrac{\partial \mathcal{L}}{\partial \dot{x}}} \right) &=& (M+m)\ddot{x} + m d \ddot{\theta} \cos \theta - m d \dot{\theta}^2 \sin \theta
\end{array}\end{equation}

The derivatives w.r.t. $\theta$ are:

\begin{equation}\begin{array}{rcl}
\dfrac{\partial \mathcal{L}}{\partial \theta} &=& -m\dot{x}d\dot{\theta}\sin\theta - mgd\sin\theta \\
\dfrac{\partial \mathcal{L}}{\partial \dot{\theta}} &=& m\dot{x}d\cos\theta + md^2\dot{\theta} \\
\dfrac{\mathrm d }{\mathrm d t}\left( {\dfrac{\partial \mathcal{L}}{\partial \dot{\theta}}} \right) &=& m\ddot{x}d\cos\theta - m\dot{x}d\dot{\theta}\sin\theta + md^2\ddot{\theta}
\end{array}\end{equation}

Finally, the Lagrange's equations (the equations of motion) are:

\begin{equation}\begin{array}{rcl}
(M+m)\ddot{x} + md\big(\ddot{\theta} \cos\theta - \dot{\theta}^2 \sin\theta\big) = F_x \\
\ddot{\theta} + \dfrac{\ddot{x}}{d}\cos\theta + \dfrac{g}{d}\sin\theta = 0
\end{array}\end{equation}

## Considerations on the Lagrangian mechanics

The Lagrangian mechanics does not constitute a new theory in classical mechanics; the results of a Lagrangian or Newtonian analysis must be the same for any mechanical system, only the method used to obtain the results is different.

We are accustomed to think of mechanical systems in terms of vector quantities such as force, velocity, angular momentum, torque, etc., but in the Lagrangian formalism the equations of motion are obtained entirely in terms of the kinetic and potential energies (scalar operations) in the configuration space. Another important aspect of the force vs. energy analogy is that in situations where it is not possible to make explicit all the forces acting on the body, it is still possible to obtain expressions for the kinetic and potential energies.

In fact, the concept of force does not enter into Lagrangian mechanics. This is an important property of the method. Since energy is a scalar quantity, the Lagrangian function for a system is invariant for coordinate transformations. Therefore, it is possible to move from a certain configuration space (in which the equations of motion can be somewhat complicated) to a space that can be chosen to allow maximum simplification of the problem.

## Problems

1. Derive the Lagrange's equation for a mass-spring system where the spring is attached to the ceiling and the mass in hanging in the vertical.
2. Derive the Lagrange's equation for an inverted pendulum in the vertical.
3. Derive the Lagrange's equation for the following system:

4. Derive the Lagrange's equation for a spring pendulum, a simple pendulum where a mass $m$ is attached to a massless spring with spring constant $k$ and length at rest $d_0$.

## References

- Marion JB (1970) [Classical Dynamics of particles and systems](https://books.google.com.br/books?id=Ss43BQAAQBAJ), 2nd ed., Academic Press.
- Synge JL (1949) [Principles of Mechanics](https://books.google.com.br/books?id=qsYfENCRG5QC), 2nd ed., McGraw-hill.
- Taylor J (2005) [Classical Mechanics](https://archive.org/details/JohnTaylorClassicalMechanics). University Science Books.


# Experiment 2: Airtrack I---Kinematics
### Objectives
- To learn good lab practice
- To learn how to estimate and propagate uncertainties
- To learn how position, velocity, and acceleration are related
- To learn how to use the Airtrack
- To learn how to use PASCO Capstone Data Acquisition and Analysis software

### Equipment
- One Airtrack, Blower, Cart, and Acoustic Sensor
- One wooden reflector
- One 2x4 “shim”
- One 30 cm plastic ruler
- One two-meter stick

### Safety
- **Do not attempt to push the carts faster than 1 m/s.**
- **Be careful placing the carts on the track.**
- **Do not damage the track.** Please place paper underneath the carts when they are resting on the track without the air turned on.
- **Do not slide the carts on the track without the air turned on.**

# Introduction

Before one can study the action of forces on objects, one must be able to describe motion. This description of motion is called $kinematics$. We will be learning how to use two tools to investigate the meanings of the three kinematic equations for motion in one dimension:
The definition of average velocity:

\begin{equation}
v_{avg} \equiv \frac{\Delta x}{\Delta t}
\tag{1}
\end{equation}

The definition of average acceleration:

\begin{equation}
a_{avg} \equiv \frac{\Delta v}{\Delta t}
\tag{2}
\end{equation}
And the position of an object undergoing constant acceleration:

\begin{equation}
x(t) = \frac{1}{2} a t^2 + v_o t + x_o
\tag{3}
\end{equation}
In this lab, your job will be to compare different measurements of velocity and acceleration for an air-cart experiencing both no acceleration and constant acceleration.

# Theory

### Measurement of Velocity and Acceleration
An acoustic sensor will measure the position of a cart on the airtrack at specific intervals of time. By use of the definition of velocity (Equation ([1](#mjx-eqn))), we can compute the average velocity between two measurements. Notice that if we plot the position versus time, the fraction is the same as the rise divided by the run-- or the slope of the graph. By plotting *x* vs. *t*, we then find the slope of the graph and determine the velocity.

This same technique works for determining acceleration. However, notice that the variables to plot are now *velocity* versus time.

### Analysis of Uncertainties
It will be important to know what the uncertainties are in our computed velocities and accelerations.

First, recall that a difference in position or time is a subtraction of two quantities:
$$ \Delta x = x_2 - x_1 \nonumber $$

Therefore, we can use (R1) to compute the uncertainty in the difference:
$$ (\delta(\Delta x))^2 = (\delta x_2)^2 - (\delta x_1)^2 \nonumber $$

However, in this case, the uncertainties $\delta x_1$ and $\delta x_2$ should be the same, so we can say that the uncertainty in our computed difference is:
\begin{equation}
\delta(\Delta x) = \sqrt{2} (\delta x)
\tag{4}
\end{equation}

where $\delta x$ is the uncertainty in a single position measurement. We can say the same for time differences:
\begin{equation}
\delta(\Delta t) = \sqrt{2} (\delta t)
\tag{5}
\end{equation}

where $\delta t$ is the uncertainty in a single time measurement. Notice that the uncertainty in the difference is larger than the uncertainty in each individual measurement.

Computing the uncertainty in velocity, $\delta v$, is a straightforward application of (R2). Looking at Equation ([1](#mjx-eqn)) we have:
$$ \left(\frac{\delta v}{v}\right)^2 = \left(\frac{\delta (\Delta x)}{\Delta x}\right)^2 + \left(\frac{\delta (\Delta t)}{\Delta t}\right)^2 \nonumber $$

This equation needs some work to become useful. Capstone will take data points at constant $\Delta t$. But because $\Delta x$ may be different for each measurement, we should try to remove it from our equation. We do this by using the definition of velocity to replace $\Delta x$ with $v \Delta t$:
$$ \left(\frac{\delta v}{v}\right)^2 = \left(\frac{\delta (\Delta x)}{v \Delta t}\right)^2 + \left(\frac{\delta (\Delta t)}{\Delta t}\right)^2 \nonumber $$

Factoring out $\Delta t$ so that we need only use it once:
$$ \left(\frac{\delta v}{v}\right)^2 = \frac{1}{(\Delta t)^2} \left(\left(\frac{\delta (\Delta x)}{v}\right)^2 + \left(\delta (\Delta t)\right)^2 \right) \nonumber $$

We may also multiply through by $v^2$:
\begin{equation}
\left(\delta v\right)^2 = \frac{1}{(\Delta t)^2} \left(\left(\delta (\Delta x)\right)^2 + v^2 \left(\delta (\Delta t)\right)^2 \right)
\tag{6}
\end{equation}

Now we have an equation to find our uncertainty in velocity based on things we know. Notice that the uncertainty in the velocity increases with the velocity. Also notice that the uncertainty is not zero when the velocity is zero. Does this make sense?

# Experimental Procedure

### Leveling the Airtrack
In order to study unaccelerated motion, we must ensure that gravity does not interfere. To do this, we must level the airtrack. The best method for leveling the airtrack is to use the cart itself to verify that it is not pulled one way or the other by gravity.

1. Turn on the blower (you should be able to feel the air coming out of the drilled holes) and place a cart at the 100 cm mark.
2. Place your fingers at the front and rear of the cart so that it remains at rest.
3. Release the cart without pushing it.

If the cart tends to move to one side, you will need to raise that side (or lower the other side). This can be accomplished by rotating the feet on the two-foot support. If this is still not sufficient, you may need to place a folded sheet of paper under one of the two supports until the cart favors neither side. It’s OK if the cart slowly oscillates.

### Configuring the Acoustic Sensor
Place a wooden reflector into the center top hole in the cart. You will now need to place the sensor so that it properly reads the position of the reflector.

1. Place the sensor at the opposite end from where the air hose is placed.
2. Place a cart at that end of the airtrack and set the sensor at the same height as the center of the wooden reflector.
3. Ensure that the sensor is centered over the track and pointed straight down the track.
4. Ensure that the top switch is in “cart” mode (*not* “stick figure” mode).

There are two plugs which must be inserted into the PASCO 850 interface. The yellow plug goes into Digital Input 1 and the black plug goes into Digital Input 2.

### Using PASCO Capstone DAA
Capstone will be used throughout the physics laboratories to collect data, so you should spend some time now learning how to use it. To set it up for the first time, the PASCO 850 interface must be turned on (press and hold the power button until it beeps and the green light is lit) and connected to the computer.

1. Start Capstone.
2. Click “Hardware Setup” on the left-side “Tools” palette. A picture of the PASCO 850 interface will appear.
3. Click on the Digital Input 1 port and
4. Click on the Settings Gear Icon in the lower left. You will need to enter the proper speed of sound. The speed of sound is (331+0.6T) m/s where T is the air temperature in Celcius. Click “OK.”
5. Click on “Hardware Setup” to close the window.
6. In the right-side palette, drag “Graph” to the main window. A large graph will appear.

At the very bottom of the window, notice the sample rate (in Hz). This number tells you how many data points are taken every second. You will need this number later.

When you click “Record,” Capstone will start taking data on all the sensors attached to the 850 interface. When you click “Stop,” Capstone will stop taking data. Every Record/Stop sequence is considered a “run.” All of the data runs you gather are listed in the “Data Summary” tab on the left-side palette. Clicking “Data Summary” a second time will close that window.

### Testing the Acoustic Sensor using Capstone
A very quick test of the sensor would be to click “Record” and move your hand towards and away from the sensor a few times and then click “Stop.” By clicking `<Select Measurement>` on the y-axis and selecting “Position (m),” Capstone will plot a graph of that data. If this works, then your sensor works and it’s time to test the alignment with your cart.

Turn on the air for your airtrack and place a cart on the track. Push the cart towards the sensor and click “Record.” Let the cart bounce back and forth between the bumpers a few times before clicking “Stop.” The new data should have replaced the old data on the graph. (If not, then there are two ways to have the new data plotted: (1) In the “Data Summary” tab, drag the desired run icon from under “Position” and drop it onto the graph. (2) The toolbar on the menu itself has a rainbow-colored triangle on it. Click the arrow next to that icon and select the data run you would like to plot.)

The data should look something like this:
<div align="center">

</div>

***
***FIX TROUBLESHOOTING INSTRUCTIONS REGARDING PRINTING TO HOW TO SAVE AND EXPORT AS A CSV FILE AND PUT IT INTO JUPYTERLAB***
***

### Troubleshooting
If your data does not look like this, you will need to work on the alignment of your sensor with the reflector. Check the following things:

1. The sensor should be at the same height as the center of the reflector.
2. The sensor should be pointed directly at the reflector.
3. The reflector should be fully facing the sensor.
4. The sensor must be centered on the track (look down over the sensor and make sure the center of the gold circle is over the ridge-line of the airtrack).
5. The sensor must be pointed directly down the track.
6. The switch on the sensor must be set to “Cart.”
7. The green light should blink while data is being taken.

We will be using the PASCO Capstone software frequently in all the laboratory courses, so it is important that you become familiar with this software now. Once your data looks pretty good, perform the following functions:

1. In the “Data Summary” tab, double-click on the data tag and rename it to “Calibration Run #1.”
2. Print your graph in landscape mode (File -> Print, then click the “Preferences” button).
3. Have your instructor sign off on your graph.
4. Grab the right side of your graph and make some space for another display.
5. Drag “Meter” or “Digits” or “Table” display into the open area, click on that display’s `<Select Measurement>` button and select a data source, then click Record/Stop.
6. Click each button on the graph to see what it does.
7. Learn how to pan and zoom your graph.
8. Drag the legend around the graph.
9. Delete all your graphs/tables (select the display by clicking on it, then click on the “Delete Selected Display” icon in the upper Capstone toolbar).
10. Delete every data run and start over by clicking the arrow next to “Delete Last Run” in the bottom tool palette and selecting “Delete All Runs.”

```python
# Sensor test (Sawtooth plot)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from P201_Functions import *

# Reads the name of the csv file and gets the data
df = pd.read_csv("./Lab2_Trace1.csv")

# Prints information about the file
df.info()

print("")

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
position = df.filter(['Position (m) Run #1'], axis=1).dropna()

# Create a figure of reasonable size and resolution, white background, black edge color
fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = position.values.reshape(-1, 1)

# Creates the base plot with titles
plt.plot(x_data,y_data,'b.')
plt.ylabel('Position (m)')
plt.xlabel('Time (s)')
plt.title('Troubleshooting the Capstone Software')

# Add a dotted line through the data points
plt.plot(x_data,y_data,'b--')

# Displays the plot
plt.show()

print("")
```

### Acoustic Sensor Uncertainty
The acoustic sensor can only measure distance so well. How well? You’ll need to determine that. The best way to do this is to take many distance measurements at a fixed location and find the standard deviation of those measurements. Here is one method of doing this:

Turn the air off so that the cart doesn’t move. At three locations on your airtrack (near the sensor, at the 100 cm mark, and at the far end from the sensor):
1. $Carefully$ place the cart at its location on a sheet of paper and press “Record.”
2. After 30 seconds, press “Stop.”
3. Drag a “Table” from the right tool palette onto the main window.
4. In one column, click the `<Select Measurement>` button and select “Time (s).”
5. In the other column, click the `<Select Measurement>` button and select “Position (m).”
6. The cell above should show your last data run. If not, click it and select your last data run.
7. On the table, click the arrow next to the summation sign ($\Sigma$) and make sure “Mean” and “Standard Deviation” are selected. Then click the summation sign ($\Sigma$) itself.
8. Read the standard deviation off the table at the bottom. This is your $\delta x$.

If your standard deviation is greater than 0.001 m (1.0 mm) then you should try to fine-tune the alignment of your sensor. It is very possible to get less than one millimeter uncertainty at the far end of the track. By looking at the
displayed significant digits, your table also tells you what the uncertainty is for a single time measurement. Once you are done aligning your set-up, record your new worst (highest) position uncertainty (this will probably be at
your far position) as well as your uncertainty in time, and the uncertainties for any differences the computer would calculate between two adjacent points.

```python
# Raw Data 1

#### Enter Raw Data Here!!!!!!!!!!!!!####

# Enter Δx (m)
Delta_x = 7.223E-5

###########################################

# Calculates the uncertainty in 𝛿(Δx) using Equation 4
delta_Delta_x = np.sqrt(2)*Delta_x

print("Δx =", Delta_x, "m")
print("𝛿(Δx) = %0.5f" % (delta_Delta_x))
```

    Δx = 7.223e-05 m
    𝛿(Δx) = 0.00010

What is the difference in time between two $successive$ data points? (You can either look at your table or recall the Sample Rate from above). The uncertainty in time, $\delta t$, will be $half$ of this number.

```python
# Raw Data 2

#### Enter Raw Data Here!!!!!!!!!!!!!! ####

# Enter Δt (s)
Delta_t = 0.025

###########################################

# Calculates the uncertainty in 𝛿(Δt) using Equation 5
delta_Delta_t = np.sqrt(2)*Delta_t

print("Δt =", Delta_t, "s")
print("𝛿(Δt) = %0.5f" % (delta_Delta_t))
```

    Δt = 0.025 s
    𝛿(Δt) = 0.03536

### Unaccelerated Motion
This first part of the experiment is to compare the position of the cart as a function of time with its velocity and verify equation ([1](#mjx-eqn)):

1. Start fresh: delete ALL data sets and close all data windows.
2. Drag a “Graph” from the right tool palette to your data area. Select “Position (m)” for your y-axis.
3. Turn on the air and remove the paper from under the cart.
4. With your cart at the far end of the track, give it a good push towards the sensor.
5. Immediately after the cart bounces off the near bumper, press “Record.”
6. Immediately BEFORE the cart strikes the far bumper, press “Stop.”
7. Turn off the air.
8. Rename this run “Level Airtrack”, and export the data as Lab2_Level_Airtrack.csv

```python
# Position vs. Time Graph

# Reads the name of the csv file and gets the data
df = pd.read_csv("./Lab2_Level_Airtrack.csv")

# Prints information about the file
df.info()

print("")

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
position = df.filter(['Position (m) Run #1'], axis=1).dropna()

# Create a figure of reasonable size and resolution, white background, black edge color
fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = position.values.reshape(-1, 1)

xi = df['Time (s) Run #1'].to_numpy()
yi = df['Position (m) Run #1'].to_numpy()

# Creates the base plot with titles
plt.errorbar(x_data,y_data,Delta_x,Delta_t,'b.',label='Raw Data')
plt.ylabel('Position (m)')
plt.xlabel('Time (s)')
plt.title('Position vs. Time')

# Takes the x and y values to make a trendline
intercept, slope, dintercept, dslope = linear_fit_plot_errors(xi,yi,0.5,2.5)

# Adds the legend to the plot
plt.legend()

# Displays the plot
plt.show()

print("")
```

```python
# Velocity vs. Time Graph (unaccelerated)

# Remove NaN entries from dataframe
df = df.dropna()

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
position = df.filter(['Velocity (m/s) Run #1'], axis=1).dropna()

fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = position.values.reshape(-1, 1)
xi = df['Time (s) Run #1'].to_numpy()
yi = df['Velocity (m/s) Run #1'].to_numpy()

Delta_v = delta_Delta_x/Delta_t

# Creates the base plot with titles
plt.errorbar(x_data,y_data,Delta_v,Delta_t,'b.',label='Raw Data')
plt.ylabel('Velocity (m/s)')
plt.xlabel('Time (s)')
plt.title('Velocity vs. Time')

# Takes the x and y values to make a trendline
intercept2, slope2, dintercept2, dslope2 = linear_fit_plot_errors(xi,yi,0.5,2.0)

# Adds the legend to the plot
plt.legend()

# Displays the plot
plt.show()

print("")
```

# Results and Conclusions¶
- Why does the time between peaks in the saw-tooth pattern increase? Will this affect your results?
- Compare the slope of the Position vs. Time graph to the average value of the velocities in the velocity vs. time graph. Do the two numbers overlap if you include your uncertainties?

```python
# Comparision of Measured Velocities - Unacclerated Motion

print()
print ("Velocity, from x vs. t graph = ",slope," +/- ",dslope,"m/s")

print()
print ("Velocity, from v vs. t graph = ",intercept2," +/- ",dintercept2,"m/s")

print()
print()

x = ['x vs. t','v vs. t']
dx = ['','','','']
y = np.array([slope,intercept2])
dy = np.array([dslope,dintercept2])

fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

plt.errorbar(x,y,dy,fmt='o')
plt.ylabel('Velocity (m/s)')
plt.title('Comparision of Measured Velocities - Unacclerated Motion')
```

***

## Accelerated Motion
Now that you’ve gotten some data to investigate unaccelerated motion, you need to collect data on accelerated motion. To do this, you will need to allow gravity to provide the acceleration by tilting the track.

1. Measure the distance between the supports on the airtrack. This will be your base length.
2. Measure the thickness of a 2x4 “shim.” This will be your height change.
3. Place the 2x4 “shim” under the foot nearest the acoustic sensor.
4. You will need to re-align the acoustic sensor using the methods described earlier.
5. Re-measure the uncertainty in position at the end of the track furthest from the sensor and try to reduce that uncertainty below 1 mm. Record this uncertainty in your Data Sheet.

When you are ready to take data:

1. Remove everything except one graph from the data area and make sure the y-axis is set to “Acceleration ($m / s^2$).”
2. Turn on the air, remove the paper, and allow the cart to slide down the airtrack and bounce off the far bumper.
3. **START** taking data ***immediately after*** the cart strikes the bumper.
4. **STOP** taking data ***just before*** the cart strikes the bumper again.
5. Turn off the air.
6. Rename this data set as “Tilted Airtrack”, and export the data as Lab2_Inclined_Airtrack.csv

***
***FIX INSTRUCTIONS REGARDING PRINTING TO HOW TO SAVE AND EXPORT AS A CSV FILE AND PUT IT INTO JUPYTERLAB***
***

This time, let’s allow the Capstone software to analyze our data:

1. Click the arrow beside the summation symbol ($\Sigma$) and make sure that “Mean” and “Standard Deviation” are selected. Then click the summation symbol ($\Sigma$).
2. Move the legend so that it does not obscure the data points.
3. Type in an appropriate title and print this graph in Landscape Mode.
4. Click the summation symbol ($\Sigma$) again to remove the fit.
5. Click the axis button labeled “Acceleration ($m / s^2$)” and select “Velocity (m/s)”
6. Click the arrow next to to the “Fit” button and select “Linear.” Then click the “Fit” button.
7. Move the legend and linear fit windows so that they do not obscure the data points.
8. Type in an appropriate title and print this graph in Landscape Mode.
9. Click the “Fit” button to remove the fit.
10. Click the axis button labeled “Velocity (m/s)” and select “Position (m).”
11. Click the arrow next to to the “Fit” button, unselect “Linear” and select “Quadratic.” Then click the “Fit” button.
12. Move the legend and quadratic fit windows so that they do not obscure the data points.
13. Type in an appropriate title and print this graph in Landscape Mode.

```python
# Acceleration vs Time Graph (Tilted Airtrack)

# Reads the name of the csv file and gets the data
df = pd.read_csv("./Lab2_Inclined_Airtrack.csv")

# Prints information about the file
df.info()
df = df.dropna()

Delta_a = delta_Delta_x/(Delta_t**2)

print("")

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
position = df.filter(['Acceleration (m/s²) Run #1'], axis=1).dropna()

fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = position.values.reshape(-1, 1)
xi = df['Time (s) Run #1'].to_numpy()
yi = df['Acceleration (m/s²) Run #1'].to_numpy()

# Creates the base plot with titles
plt.errorbar(x_data,y_data,Delta_a,Delta_t,'b.',label='Raw Data')
plt.ylabel('Acceleration (m/s²)')
plt.xlabel('Time (s)')
plt.title('Acceleration vs. Time')

# Takes the x and y values to make a trendline
intercept1, slope1, dintercept1, dslope1 = linear_fit_plot_errors(xi,yi,
                                                                  0.8,3.6)
# Adds the legend to the plot
plt.legend()

# Displays the plot
plt.show()

print("")
```

```python
# Position vs. Time Graph (accelerated)

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
position = df.filter(['Position (m) Run #1'], axis=1).dropna()

# Create a figure of reasonable size and resolution, white background, black edge color
fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = position.values.reshape(-1, 1)
xi = df['Time (s) Run #1'].to_numpy()
yi = df['Position (m) Run #1'].to_numpy()

# Creates the base plot with titles
plt.errorbar(x_data,y_data,Delta_x,Delta_t,'b.',label='Raw Data')
plt.ylabel('Position (m)')
plt.xlabel('Time (s)')
plt.title('Position vs. Time')

# Takes the x and y values to make a trendline
a,b,c,da,db,dc = quadratic_fit_plot_errors(xi,yi,linestring='g-')

# Adds the legend to the plot
plt.legend()

# Displays the plot
plt.show()

print("")
```

```python
# Velocity vs. Time Graph (Accelerated Motion)

# Defines the x and y values
time = df.filter(['Time (s) Run #1'], axis=1).dropna()
velocity = df.filter(['Velocity (m/s) Run #1'], axis=1).dropna()

fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

# Gets the data values for x and y
x_data = time.values.reshape(-1, 1)
y_data = velocity.values.reshape(-1, 1)
xi = df['Time (s) Run #1'].to_numpy()
yi = df['Velocity (m/s) Run #1'].to_numpy()

# Creates the base plot with titles
plt.errorbar(x_data,y_data,Delta_v,Delta_t,'b.',label='Raw Data')
plt.ylabel('Velocity (m/s)')
plt.xlabel('Time (s)')
plt.title('Velocity vs. Time')

# Takes the x and y values to make a trendline
intercept2, slope2, dintercept2, dslope2 = linear_fit_plot_errors(xi,yi,
                                                                  0.8,3.6,"Linear Fit",'r-')

#Adds the legend to the plot
plt.legend()

# Displays the plot
plt.show()

print("")
```

## Results and Conclusions
Report the following data (with units and uncertainties):

- Velocity of cart without acceleration
- Angle that you tilted the airtrack
- Average Acceleration from the Acceleration vs. Time graph
- Average Acceleration calculated form the slope of the Velocity vs. Time graph
- Average Acceleration computed from the parabolic fit to your Position vs. Time graph

To compare the “A” value to the acceleration, you will need to know that the A, B, and C values are the constants for the following fit to the data:

$$ x(t) = At^2 + Bt + C \nonumber $$
Compare this equation to equation ([3](#mjx-eqn)) to determine the acceleration, *a*.

```python
# Raw Data 3

#### Enter Raw Data Here!!!!!!!!!!!!!! ####

# The distance between the two supports and the uncertainty in that distance (m)
d = 1.000
uncertainty_d = 0.001

# The thickness of the 2x4 and the uncertainty in that thickness (m)
h = 0.029
uncertainty_h = 0.001

# Your new uncertainty in cart position
uncertainty_x = 0.002

###########################################

# The angle your track was tilted
theta_min = np.arctan((h-uncertainty_h)/(d+uncertainty_d))
theta_max = np.arctan((h+uncertainty_h)/(d-uncertainty_d))
theta = (theta_max+theta_min)/2.0
dtheta = (theta_max-theta_min)/2.0

print("d =", d, "m, 𝛿d =", uncertainty_d,"m")
print("")
print("h =", h, "m, 𝛿h =", uncertainty_h,"m")
print("")
print("𝛿x =", uncertainty_x,"m")
print("")
print("θ =", theta," +/- ",dtheta,"radians")

gravity = 9.80

a_max = gravity*np.sin(theta_max)
a_min = gravity*np.sin(theta_min)

a_theory = (a_max+a_min)/2.0
da_theory = (a_max-a_min)/2.0

print()
print ("Expected Acceleration = ",a_theory," +/- ",da_theory,"m/s^2")

a_experiment_1 = intercept1
da_experiment_1 = dintercept1

print()
print ("Average Acceleration from a vs. t graph = ",a_experiment_1," +/- ",da_experiment_1,"m/s^2")

a_experiment_2 = 2.0*a
da_experiment_2 = 2.0*da

print()
print ("Average Acceleration from x vs. t graph = ",a_experiment_2," +/- ",da_experiment_2,"m/s^2")

a_experiment_3 = slope2
da_experiment_3 = dslope2

print()
print ("Average Acceleration from v vs. t graph = ",a_experiment_3," +/- ",da_experiment_3,"m/s^2")

print()
print()

x = ['Theory','a vs. t','x vs. t','v vs. t']
dx = ['','','','']
y = np.array([a_theory,a_experiment_1,a_experiment_2,a_experiment_3])
dy = np.array([da_theory,da_experiment_1,da_experiment_2,da_experiment_3])

fig=plt.figure(figsize=(7,5), dpi= 100, facecolor='w', edgecolor='k')

plt.errorbar(x,y,dy,fmt='o')
plt.ylabel('Acceleration (m/s^2)')
plt.title('Comparision of Measured Accelerations to Theoretical Prediction')
```

# Your Lab Report

## EXPERIMENTAL PROCEDURE Section
You will need to write a few paragraphs to carefully describe how you set up your experiment. Include the following specific items:
- What did you do to ensure that your zero-acceleration and constant-acceleration experiments were free from unwanted sources of acceleration?
- How did you configure your measurement equipment so that you got the most accuracy?
- How did you set the track and determine the angle for the constant-acceleration experiment?
- How did you re-calibrate your measurement equipment after changing experiments?

**Remember:** This section is a description of what <u>you</u> did---not a set of instructions. Include a description of any problems you encountered and how you solved them.

Did you have any systematic errors (i.e. were there sources of acceleration in either experiment that you could not remove)?

How could you reduce your errors/uncertainties?

## Appendix
- Include your signed raw data sheet


# Ikeda for S175
Scope:
* S175 will be calculated in ScoresII:
   * S175 geometry in a *Seaway input file* will be parsed
   * *Seaway input file* will be converted to ScoresII
   * Draught need to be adjusted to 9.5 m

```python
# %load ../../imports.py
"""
These is the standard setup for the notebooks.
"""

%matplotlib inline
%load_ext autoreload
%autoreload 2

from jupyterthemes import jtplot
jtplot.style(theme='onedork', context='notebook', ticks=True, grid=False)

import pandas as pd
pd.options.display.max_rows = 999
pd.options.display.max_columns = 999
pd.set_option("display.max_columns", None)
import numpy as np
import os
import matplotlib.pyplot as plt
#plt.style.use('paper')

#import data
import copy
from rolldecay.bis_system import BisSystem
from rolldecay import database
from mdldb.run import Run

from sklearn.pipeline import Pipeline
from rolldecayestimators.transformers import CutTransformer, LowpassFilterDerivatorTransformer, ScaleFactorTransformer, OffsetTransformer
from rolldecayestimators.direct_estimator_cubic import EstimatorQuadraticB, EstimatorCubic
from rolldecayestimators.ikeda_estimator import IkedaQuadraticEstimator
import rolldecayestimators.equations as equations
import rolldecayestimators.lambdas as lambdas
from rolldecayestimators.substitute_dynamic_symbols import lambdify
import rolldecayestimators.symbols as symbols
import sympy as sp

from sklearn.metrics import r2_score

```

```python
import re
```

## S175 geometry in a Seaway input file will be parsed

```python
with open('S175.seaway', mode='r') as file:
    lines = file.readlines()
```

```python
lines[0:3]
```

```python
regexp_line=re.compile('.*')
def read_line(line):
    result = regexp_line.search(line)
    if not result:
        raise ValueError('Cannot read line:%s'%lins)
    return result.group(0)

def read_line_values(line):
    s = read_line(line)
    regexp_parts = re.compile('(\S+)')
    return regexp_parts.findall(s)

```

```python
read_line(line=lines[0])
```

```python
seaway={}
seaway['version'] = read_line(lines[0])
seaway['text'] = read_line(lines[1])
```

```python
## Definition of Longitudinal Values:
values = read_line_values(lines[2])
keys=['DR','TR','RLPP','RLA']
for key,value in zip(keys,values):
    seaway[key]=float(value)
seaway
```

```python
seaway['NS']=int(read_line(lines[3]))
seaway['NS']
```

```python
seaway['DX']=np.array(read_line_values(lines[4]) +
                      read_line_values(lines[5]) +
                      read_line_values(lines[6]), dtype=float)
seaway['DX']
```

```python
seaway['X']=np.concatenate([[0],np.cumsum(seaway['DX'])])
seaway['X']
```

```python
seaway['KCON']=int(read_line(lines[7]))
seaway['KCON']  # KCON = 2: input-sequence is [Z(J,I),Y(J,I)],
```

```python
NS=seaway['NS']+1  # one extra?
empty=np.empty(shape=NS)*np.NaN
keys = ['SNR','NWL','SDIST']
for key in keys:
    seaway[key] = empty.copy()

index=8
seaway['Y']=[]
seaway['Z']=[]

for J in range(NS):
    values = read_line_values(lines[index])
    seaway['SNR'][J]=float(values[0])
    seaway['NWL'][J]=NWL=int(float(values[1]))
    seaway['SDIST'][J]=SNR=float(values[2])
    section_values=[]
    while(len(section_values)<(2*(NWL+1))):
        index+=1
        section_values+=read_line_values(lines[index])

    Y=np.empty(shape=NWL)*np.NaN
    Z=np.empty(shape=NWL)*np.NaN

    for I in range(NWL):
        i=2*I
        Z[I]=section_values[i]
        Y[I]=section_values[i+1]

    seaway['Y'].append(np.array(Y, dtype=float))
    seaway['Z'].append(np.array(Z, dtype=float))

    index+=1
```

```python
def body_plan(Y,Z):
    fig,ax=plt.subplots()
    frames,points = Y.shape
    N=int(np.floor(frames/2))

    for y,z in zip(Y[0:N,:], Z[0:N,:]):
        ax.plot(-y,z)

    for y,z in zip(Y[N:,:], Z[N:,:]):
        ax.plot(y,z)

```

```python
N=int(seaway['NWL'].max())*5
X=np.empty(shape=(NS,N))*np.NaN
Y=np.empty(shape=(NS,N))*np.NaN
Z=np.empty(shape=(NS,N))*np.NaN
for i,(y,z) in enumerate(zip(seaway['Y'], seaway['Z'])):

    x=np.arange(N)
    xp=np.arange(len(y))
    y_interp=np.interp(x=x, xp=xp, fp=y)
    z_interp=np.interp(x=x, xp=xp, fp=z)

    Y[i,:]=y_interp
    Z[i,:]=z_interp
    X[i,:]=np.ones(shape=N)*seaway['X'][i]
```

```python
body_plan(Y,Z)
```

```python
from mpl_toolkits.mplot3d import Axes3D  # noqa: F401 unused import
from matplotlib import cm

fig = plt.figure()
#fig.set_size_inches(10,10)
ax = fig.gca(projection='3d',)
ax.view_init(45, 20)

# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
                       linewidth=0, antialiased=True)

ax.set_xlim3d([X.min(), X.max()])
ax.set_ylim3d([Y.min(), Y.max()])
ax.set_zlim3d([Z.min(), Z.max()])

#ax.set_aspect('equal')
#fig.set_size_inches(15,20)

```

## Draught need to be adjusted to 9.5 m

```python
T=9.5
N=40
Xs=[]
Ys=[]
Zs=[]

for i,(y,z) in enumerate(zip(seaway['Y'], seaway['Z'])):

    mask=y > 0
    zp=z[mask]
    yp=y[mask]

    if zp[0] > T:
        continue

    z_interp=np.linspace(zp[0],T,N)
    y_interp=np.interp(x=z_interp, xp=zp, fp=yp)

    Ys.append(y_interp)
    Zs.append(z_interp)
    Xs.append(np.ones(shape=N)*seaway['X'][i])

Y=np.array(Ys)
Z=np.array(Zs)
X=np.array(Xs)
```

```python
body_plan(Y,Z)
```

## Seaway input file will be converted to ScoresII

```python
areas=[]
SECOEs=[]
DRAFTs=[]
BSTARs=[]
ZBARs=[]

for y,z in zip(Y, Z):
    area=np.trapz(y=y,x=z)
    areas.append(area)

    BSTAR=2*y[-1]
    BSTARs.append(BSTAR)

    DRAFT_=z[-1]-z[0]
    DRAFTs.append(DRAFT_)

    c=area/(y.max()*DRAFT_)
    SECOEs.append(c)

    lever=np.flipud(T-z)
    y_=np.flipud(y)*lever

    ZBAR=np.trapz(y=y_,x=lever)/area
    ZBARs.append(ZBAR)
```

```python
x=X[:,0]
#x-=x[0]
#x
```

```python
from scipy.integrate import simps
2*simps(y=areas,x=x)
```

```python
def reduce_sections(xp,fp,lpp, N=21):
    x=np.linspace(0,lpp,N)
    y=np.interp(x=x, xp=xp, fp=fp)
    return x,y
```

```python
from rolldecayestimators.tests import test_ikeda_speed_S175 as ti
lpp=ti.L
x_21, areas_21=reduce_sections(x, areas, lpp)
x_21, SECOEs_21=reduce_sections(x,SECOEs, lpp)
x_21, DRAFTs_21=reduce_sections(x,DRAFTs, lpp)
x_21, BSTARs_21=reduce_sections(x,BSTARs, lpp)
x_21, ZBARs_21=reduce_sections(x,ZBARs, lpp)
```

```python
lcb=np.trapz(y=areas_21*x_21,x=x_21)/np.trapz(y=areas_21,x=x_21)
displacement=2*np.trapz(y=areas_21,x=x_21)
```

```python
lcb
```

```python
x_21
```

```python
fig,ax=plt.subplots()
ax.plot(x,areas);
ax.set_title('Area curve')
ax.set_xlabel('X [m]')
ax.set_ylabel('Section area $[m^2]$')

fig,ax=plt.subplots()
ax.plot(x,SECOEs);
ax.plot(x_21,SECOEs_21,'--');
ax.set_title('Area coefficients')
ax.set_xlabel('X [m]')
ax.set_ylabel(r'Section coefficient: $\frac{A}{B_s \cdot T_s}$')

fig,ax=plt.subplots()
ax.plot(x,BSTARs);
ax.plot(x_21,BSTARs_21,'--');
ax.set_title('Section water line beam')
ax.set_xlabel('X [m]')
ax.set_ylabel(r'Section water line beam [m]')

fig,ax=plt.subplots()
ax.plot(x,DRAFTs);
ax.plot(x_21,DRAFTs_21,'--');
ax.set_title('Section water draft')
ax.set_xlabel('X [m]')
ax.set_ylabel(r'Section water draft [m]')

fig,ax=plt.subplots()
ax.plot(x,ZBARs);
ax.plot(x_21,ZBARs_21,'--');
ax.set_title('Sectional centeroid')
ax.set_xlabel('X [m]')
ax.set_ylabel(r'Sectional centeroid [m]')
ax.plot([x.min(),x.max()],[T/2,T/2],'r-');
```

## Save to scoresII indata

```python
from pyscores2.indata import Indata
from pyscores2.runScores2 import Calculation
from pyscores2.output import OutputFile
```

```python
indata = Indata()
```

```python
T = 20
wE = 2 * np.pi * 1 / T  # circular frequency
wE

indata.cScores=SECOEs_21
indata.ts=DRAFTs_21
indata.bs=BSTARs_21
indata.zbars=ZBARs_21

kxx=seaway
beam=2*BSTARs_21.max()
indata.lpp=lpp
#indata.displacement=ti.disp
indata.displacement=ti.disp
draught=ti.d
indata.draught=draught
indata.g=ti.g
indata.kxx=0.19*beam  # Guessing to get correct omega0
indata.kyy=0.4*lpp
indata.lcb=lcb-lpp/2
indata.lpp=lpp
indata.projectName='S175'
indata.rho=ti.ra
indata.zcg=ti.vcg-draught
#indata.waveFrequenciesMin=0.2
#indata.waveFrequenciesMax=0.5
#indata.waveFrequenciesIncrement=0.006

indata.waveFrequenciesMin=wE*0.5
indata.waveFrequenciesMax=wE*2.0
N=50
indata.waveFrequenciesIncrement=(indata.waveFrequenciesMax-indata.waveFrequenciesMin)/N

indata.runOptions["IE"].set_value(1)
```

```python
indata.lcb
```

```python
indata.zcg
```

```python
indata.kyy
```

```python
#indata.runOptions["IJ"].set_value(1)
```

```python
indata.waveFrequenciesMax
```

```python
calculation = Calculation(outDataDirectory='scores2/result')
calculation.run(indata=indata)
```

```python
output_file = OutputFile(filePath=calculation.outDataPath)
df = output_file.get_result()

fig,ax=plt.subplots()
for index, group in df.groupby(by=['speed','wave direction'], sort=False):
    group.plot(x='frequencies', y='rollAmplitude', style='o-', label=index, ax=ax)

ax.grid(True)
ax.legend();
ax.set_ylabel('Roll');
```

```python
df_roll_damping = output_file.get_roll_damping()
df_roll_damping
```

## Damping from Carl-Johan

```python
import rolldecayestimators
csv_damping_path = os.path.join(rolldecayestimators.path,'Bw0_S175.csv')
df_Bw0_cj = pd.read_csv(csv_damping_path, sep=';', index_col=0)
df_Bw0_cj.head()

fig,ax=plt.subplots()
df_Bw0_cj.plot(y='b44_vec', ax=ax, label='Carl-Johan')
ax.set_ylabel('$B44_W [Nm*s/rad]$')
ax.set_xlabel('$\omega [rad/s]$');
```

```python
coefficient_path='scores2/result/S175-COEFF.out'
with open(coefficient_path, mode='r') as file:
    lines = file.readlines()
```

```python
line=lines[0]
line
```

```python
cols=[1,11,20,30,40,50,60]
def split_line(line):
    parts=[]
    for i in range(len(cols)-1):
        start=cols[i]-1
        stop=cols[i+1]-1
        part=line[start:stop]
        parts.append(part)

    return parts
```

```python
np.array(split_line(line),dtype=float)
```

```python
def read_coefficients(file):
    lines = file.readlines()

    data = np.ones(shape=(len(lines),6))

    for i,line in enumerate(lines):
        row = np.array(split_line(line),dtype=float)
        data[i,:]=row

    return data

```

```python
with open(coefficient_path, mode='r') as file:
    data = read_coefficients(file=file)
```

```python
mask=data[:,0]==0
data=data[mask,:]
```

```python
for i in [1,2,3,4,5]:
    fig,ax=plt.subplots()
    ax.plot(data[:,i])
```

```python
df_stations = output_file.get_section_coefficients()
```

```python
df_stations.head()
```

```python
df_station=df_stations.groupby(by='station').get_group(10)
df_station.set_index('FREQ.', inplace=True)
```

```python
for key in df_station:
    fig,ax=plt.subplots()
    df_station.plot(y=key, ax=ax)
```

```python
df_station.plot(y='N-SUB(R)');
```

```python
(n_rows,_)=df_stations.groupby(by='station').get_group(0).shape
N_rs=np.zeros(shape=(n_rows, 21))
N_s_phis=np.zeros(shape=(n_rows, 21))
N_RSs=np.zeros(shape=(n_rows, 21))
N_Ss=np.zeros(shape=(n_rows, 21))

for station,df_station in df_stations.groupby(by='station'):
    N_rs[:,station] = df_station['N-SUB(R)']
    N_s_phis[:,station] = df_station['N(S.PHI)']
    N_RSs[:,station] = df_station['N-SUB(R.S)']
    N_Ss[:,station] = df_station['N-SUB(S)']

```

```python
N_r=np.zeros(n_rows)
N_s_phi=np.zeros(n_rows)
N_RS=np.zeros(n_rows)
N_S=np.zeros(n_rows)

for i in range(n_rows):
    N_r[i]=simps(y=N_rs[i,:],x=x_21)
    N_s_phi[i]=simps(y=N_s_phis[i,:],x=x_21)
    N_RS[i]=simps(y=N_RSs[i,:],x=x_21)
    N_S[i]=simps(y=N_Ss[i,:],x=x_21)
```

```python
w,B_W0=output_file.calculate_B_W0()
g=ti.g
ra=ti.ra
```

```python
w=df_station['FREQ.']

fig,ax=plt.subplots()
ax.plot(w,N_r, label='N_r');
ax.set_xlim(0,2.5)

ax.plot(w,N_s_phi, label='N_s_phi');
ax.set_xlim(0,2.5)

ax.plot(w,N_RS, label='N_RS');
ax.set_xlim(0,2.5)

ax.plot(w,N_S, label='N_S');
ax.set_xlim(0,2.5)

ax.plot(w,B_W0,'--',label='B_W0');
ax.set_xlim(0,2.5)
ax.set_title('B_W0')
ax.legend()
```

```python
fig,ax=plt.subplots()
df_Bw0_cj.plot(y='b44_vec', ax=ax, label='Carl-Johan')
ax.set_ylabel('$B44_W [Nm*s/rad]$')
ax.set_xlabel('$\omega [rad/s]$');
ax.plot(w,B_W0,'--',label='B_W');
```

```python
from rolldecayestimators import ikeda_speed_S175 as ikeda  # Note that this one is slightly different (I'm not 100% sure wish one is correct)

V = np.arange(1,17+1)

T = 20
wE = 2 * np.pi * 1 / T  # circular frequency
fi_a = 5 * np.pi / 180;  # roll amplitude !!rad??

inputs = pd.DataFrame(index=V)
inputs['V']=V
inputs['w']=wE
inputs['fi_a']=fi_a
inputs['Bw0']=ikeda.Bw0_S175(w=wE)
inputs['d']=draught
inputs['B']=beam
inputs['A']=SECOEs_21[10]*beam*draught
inputs['BKB']=ti.bBK
inputs['R_b']=ti.R
OG=ti.vcg-draught
inputs['OG']=OG
inputs['Ho']=ti.Ho

inputs['ra']=ra
inputs['Cb']=displacement/(lpp*draught*beam)
inputs['L']=lpp
inputs['LBK']=ti.LBK
inputs['visc']=ti.visc
inputs['rho']=ra

inputs['g']=g
ND_factor = np.sqrt(beam/(2*g))/(ra*displacement*(beam**2))   # Nondimensiolizing factor of B44

results = inputs.apply(func=ikeda.calculate_B44_series, axis=1)
```

```python
fig,ax=plt.subplots()
result_nondim = results*ND_factor
result_nondim.plot.area(y = ['B_BK','B_L','B_W','B_F'], ax=ax);
```

```python
inputs['Bw0']=np.interp(wE,w,B_W0)
results = inputs.apply(func=ikeda.calculate_B44_series, axis=1)

fig,ax=plt.subplots()
result_nondim = results*ND_factor
result_nondim.plot.area(y = ['B_BK','B_L','B_W','B_F'], ax=ax);
```

```python
from rolldecayestimators.ikeda_speed import calculate_sectional_lewis, eddy
```

```python
a, a_1, a_3, sigma_s, H = calculate_sectional_lewis(B_s=indata.bs, T_s=indata.ts, S_s=areas_21)

R=2
d=draught
B_E = eddy(bwl=indata.bs, a_1=a_1, a_3=a_3, sigma=sigma_s, xs=x_21, H0=H, Ts=indata.ts,
                 OG=OG, R=R, wE=wE, fi_a=fi_a)
B_E_hat = B_E*ND_factor
```

```python
equations.omega_hat_equation
```

```python
sp.solve(equations.omega_hat_equation, symbols.omega)[0]
```

```python
omega_from_hat = lambdify(sp.solve(equations.omega_hat_equation, symbols.omega)[0])
```

```python
w_hats = np.linspace(0,1,10)
B_E_hats = []
for w_hat in w_hats:

    w = omega_from_hat(beam=beam, g=g, omega_hat=w_hat)
    B_E = eddy(bwl=indata.bs, a_1=a_1, a_3=a_3, sigma=sigma_s, xs=x_21, H0=H, Ts=indata.ts,
                 OG=OG, R=R, wE=w, fi_a=fi_a)
    B_E_hat = B_E*ND_factor
    B_E_hats.append(B_E_hat)

fig,ax=plt.subplots()
ax.plot(w_hats, B_E_hats)
ax.ticklabel_format(style='sci', axis='y', scilimits=(0,0))
```

```python
OG
```

```python
from pandas import util
X=np.random.rand(2,3)
X
```

```python
simps(X, axis=0, x=[1,2])
```

```python

```

```python

```