First order Nomoto model equation
Understanding the Nomoto model equation
The first order Nomoto model can be written as: $$ K \cdot \delta=r+T_{1} \cdot \dot{r}+T_{2} \cdot \ddot{r} $$ where $r$ is yaw rate with its time derivatives and $\delta$ is the rudder angle. $K$, $T_{1}$ and $T_{1}$ are the coefficients describing the hydrodynamics of the ship.
For slow manoeuvres this equation can be further simplified by removing the $\ddot{r}$ term: $$ K \cdot \delta=r+T_{1} \cdot \dot{r}$$
More about this in this: post
#collapse
from scipy.integrate import solve_ivp
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, Latex, Math
from scipy.optimize import least_squares
import altair as alt
from ipywidgets import interactive
#collapse
def nomoto_zigzag(t, states, K, T_1, angle=np.deg2rad(10)):
"""
Simulation model for heading and yaw rate using Nomoto with only K and T_1
Also including an autopilot for ZigZag test:
"""
# states:
psi = states[0]
r = states[1]
#ZigZag autopilot:
sign=-1
psi_pluss = ((psi>=0) and (psi<angle))
psi_minus = ((psi>=-angle) and (psi<=0))
if (
(psi_pluss and (r>=0)) |
(psi<-angle) |
(psi_minus and (r>=0))
):
sign=1
delta_=sign*angle
#Nomoto equation:
r1d_ = (K*delta_ - r)/T_1
d_states_dt = np.array([r,r1d_])
return d_states_dt
def simulate_zigzag(K = 0.2, T_1=10):
## Simulation:
angle=np.deg2rad(10)
states_0 = np.array([0,0])
t = np.linspace(0,100,200)
sol = solve_ivp(fun = nomoto_zigzag,t_span=[t[0],t[-1]],t_eval=t, y0 = states_0, args=(K,T_1,angle))
psi = sol.y[0,:]
r = sol.y[1,:]
## Plotting:
fig,ax=plt.subplots()
ax.plot(t,np.rad2deg(psi));
ax.grid(True)
ax.set_title('Simulation ZigZag%0.0f/%0.0f with Nomoto model' % (np.rad2deg(angle),np.rad2deg(angle)))
ax.set_ylabel('$\psi$ [deg]')
ax.set_xlabel('time [s]');
ax.set_ylim(-30,30)
Here is an ipywidget expoling the influence of the $K$ and $T_1$ coefficients during a ZigZag10/10: (You can use the buttons launch binder or Open in Colab to get this running. It takes some time to load though...)
#collapse
interactive_plot = interactive(simulate_zigzag, K=(0.01, 2.0), T_1=(1, 10, 0.5))
output = interactive_plot.children[-1]
output.layout.height = '350px'
interactive_plot