【Nomoto 船舶模型】

【Nomoto 船舶模型】

  • 1. Nomoto 船舶模型簡介
  • 2. 來源及發展歷程
  • 3. 構建 一階模型Nomoto 船舶模型
    • 3.1 C++ 實現
    • 3.2 Python 實現
    • 3.3 說明
  • 5. 參數辨識方法
    • 5.1 基于最小二乘法的參數辨識
    • 5.2 數學推導
    • 5.3 Python 實現
    • 5.4 說明
  • 4. 結論
  • 參考文獻

1. Nomoto 船舶模型簡介

Nomoto 模型是由日本學者 T. Nomoto 于上世紀50年代提出的一種用于描述船舶操縱運動的數學模型。它最初是為了解決船舶在操舵時的動態響應問題,并且因其簡單性和實用性而被廣泛應用于航海工程和船舶自動控制領域。Nomoto 模型通過簡化實際的水動力特性來預測船舶在舵角輸入下的響應,適用于初步分析和控制系統設計。
參考學習:https://github.com/martinlarsalbert/blog/blob/master/_notebooks/2020-08-25-nomoto_model.ipynb

在這里插入圖片描述

2. 來源及發展歷程

Nomoto 模型的發展經歷了多個階段,從最初的一階模型擴展到二階甚至更高階模型,以更準確地描述船舶的動態行為。盡管存在更復雜的模型(如 Abkowitz 整體模型、MMG 分離型模型、Fossen 的矩陣向量形式模型),Nomoto 模型由于其簡潔性仍然在許多應用中具有重要地位。

3. 構建 一階模型Nomoto 船舶模型

Nomoto 模型通常用以下微分方程表示:

τ 1 d ψ d t + ψ = K δ \tau_1 \frac{d\psi}{dt} + \psi = K \delta τ1?dtdψ?+ψ=

其中:

  • ψ \psi ψ 是船舶的航向角(偏航角),單位為弧度。
  • δ \delta δ是舵角,單位為弧度。
  • K K K 是比例增益,表征舵角對航向角變化的影響程度。
  • τ 1 \tau_1 τ1? 是時間常數,代表系統的時間響應特性。

3.1 C++ 實現

下面是一個簡單的C++代碼示例,用于模擬Nomoto模型的行為:

#include <iostream>
#include <cmath>class NomotoModel {
public:NomotoModel(double tau, double K) : tau_(tau), K_(K), psi_(0.0), dpsi_dt_(0.0) {}// 更新狀態void update(double delta, double dt) {// 計算導數double d2psi_dt2 = (-1.0 / tau_) * dpsi_dt_ + (K_ / tau_) * delta;// 使用歐拉法更新狀態dpsi_dt_ += d2psi_dt2 * dt;psi_ += dpsi_dt_ * dt;// 確保航向角在 [-pi, pi] 范圍內while (psi_ > M_PI) psi_ -= 2 * M_PI;while (psi_ < -M_PI) psi_ += 2 * M_PI;}// 獲取當前航向角double getHeading() const { return psi_; }private:double tau_, K_;  // 模型參數double psi_;      // 當前航向角double dpsi_dt_;  // 當前航向角速度
};int main() {// 定義模型參數double tau = 5.0;  // 時間常數double K = 0.05;   // 比例增益// 創建 Nomoto 模型實例NomotoModel model(tau, K);// 模擬時間步長和總時間double dt = 0.1;  // 時間步長 (秒)double totalTime = 30.0;  // 總模擬時間 (秒)// 設置初始舵角double delta = M_PI / 6;  // 初始舵角為 30 度for (double t = 0; t <= totalTime; t += dt) {// 更新模型狀態model.update(delta, dt);// 輸出當前時間和航向角std::cout << "Time: " << t << "s, Heading: " << model.getHeading() * 180.0 / M_PI << " degrees" << std::endl;}return 0;
}

3.2 Python 實現

下面是等效的Python代碼實現:

import mathclass NomotoModel:def __init__(self, tau, K):self.tau_ = tauself.K_ = Kself.psi_ = 0.0self.dpsi_dt_ = 0.0# 更新狀態def update(self, delta, dt):# 計算導數d2psi_dt2 = (-1.0 / self.tau_) * self.dpsi_dt_ + (self.K_ / self.tau_) * delta# 使用歐拉法更新狀態self.dpsi_dt_ += d2psi_dt2 * dtself.psi_ += self.dpsi_dt_ * dt# 確保航向角在 [-pi, pi] 范圍內while self.psi_ > math.pi:self.psi_ -= 2 * math.piwhile self.psi_ < -math.pi:self.psi_ += 2 * math.pi# 獲取當前航向角def get_heading(self):return self.psi_if __name__ == "__main__":# 定義模型參數tau = 5.0  # 時間常數K = 0.05   # 比例增益# 創建 Nomoto 模型實例model = NomotoModel(tau, K)# 模擬時間步長和總時間dt = 0.1  # 時間步長 (秒)total_time = 30.0  # 總模擬時間 (秒)# 設置初始舵角delta = math.pi / 6  # 初始舵角為 30 度for t in range(int(total_time / dt)):current_time = t * dt# 更新模型狀態model.update(delta, dt)# 輸出當前時間和航向角print(f"Time: {current_time:.1f}s, Heading: {math.degrees(model.get_heading()):.2f} degrees")

3.3 說明

  • 參數解釋

    • tau:時間常數,反映了系統的慣性特性。
    • K:比例增益,決定了舵角對航向角變化的影響程度。
  • 數值積分方法

    • 在上述實現中,使用了簡單的歐拉法進行數值積分。對于更精確的仿真,可以考慮使用更高階的數值積分方法,如龍格-庫塔法(Runge-Kutta method)。
  • 角度范圍限制

    • 為了確保航向角保持在合理的范圍內,使用了 while 循環將角度限制在 ([-π, π]) 之間。
      Nomoto 模型參數辨識是指通過實驗數據或仿真結果來確定模型中的未知參數,如時間常數 (\tau) 和比例增益 (K)。對于 Nomoto 一階模型:

τ d ψ d t + ψ = K δ \tau \frac{d\psi}{dt} + \psi = K \delta τdtdψ?+ψ=

其中:

  • KaTeX parse error: Undefined control sequence: \ps at position 1: \?p?s?是船舶的航向角(偏航角)。
  • δ \delta δ是舵角。
  • KaTeX parse error: Undefined control sequence: \K at position 1: \?K?是比例增益,表征舵角對航向角變化的影響程度。
  • τ \tau τ 是時間常數,代表系統的時間響應特性。

5. 參數辨識方法

實現參數辨識通常需要以下步驟:

  1. 實驗設計:進行操舵實驗,記錄船舶在不同舵角下的航向角隨時間的變化情況。
  2. 數據預處理:清洗和整理實驗數據,確保其適用于后續分析。
  3. 選擇辨識方法:根據問題的具體情況選擇合適的參數辨識方法,常用的有最小二乘法、遞推最小二乘法、極大似然估計等。
  4. 參數優化:利用選定的方法估計模型參數,使模型預測值與實際觀測值之間的誤差最小化。

下面介紹一種基于最小二乘法的簡單參數辨識方法,并提供相應的 Python 實現示例。

5.1 基于最小二乘法的參數辨識

假設我們已經有一組實驗數據,包含時間序列 t、舵角序列 delta 和航向角序列 psi。我們的目標是找到最優的 (\tau) 和 (K),使得模型預測值與實際觀測值之間的誤差平方和最小。

5.2 數學推導

首先將 Nomoto 模型重寫為離散形式:

ψ k + 1 = ( 1 ? Δ t τ ) ψ k + Δ t τ K δ k \psi_{k+1} = (1 - \frac{\Delta t}{\tau}) \psi_k + \frac{\Delta t}{\tau} K \delta_k ψk+1?=(1?τΔt?)ψk?+τΔt?Kδk?

其中 Δ t \Delta t Δt 是采樣間隔, k k k 表示第 k k k 個采樣點。

定義誤差函數 E E E 為:

E ( τ , K ) = ∑ k = 1 N ( ψ k model ? ψ k data ) 2 E(\tau, K) = \sum_{k=1}^{N} (\psi_k^{\text{model}} - \psi_k^{\text{data}})^2 E(τ,K)=k=1N?(ψkmodel??ψkdata?)2

其中 ψ k model \psi_k^{\text{model}} ψkmodel?是模型預測的航向角, ψ k data \psi_k^{\text{data}} ψkdata? 是實驗數據中的航向角。

我們的目標是最小化 E ( τ , K ) E(\tau, K) E(τ,K)

5.3 Python 實現

以下是使用 Python 和 SciPy 庫進行參數辨識的示例代碼:

import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt# 定義模型函數
def nomoto_model(params, delta, dt):tau, K = paramspsi_model = [0]  # 初始航向角設為0for k in range(1, len(delta)):psi_next = (1 - dt / tau) * psi_model[-1] + (dt / tau) * K * delta[k]psi_model.append(psi_next)return np.array(psi_model)# 定義誤差函數
def error_function(params, delta, dt, psi_data):psi_model = nomoto_model(params, delta, dt)return np.sum((psi_model - psi_data) ** 2)# 生成模擬數據(用于測試)
np.random.seed(0)
time = np.linspace(0, 30, 300)
dt = time[1] - time[0]
delta = np.zeros_like(time)
delta[50:100] = np.radians(10)  # 設置舵角為10度
delta[150:200] = np.radians(-10)  # 設置舵角為-10度# 真實參數
true_tau = 5.0
true_K = 0.05# 使用真實參數生成模擬的航向角數據
psi_true = nomoto_model([true_tau, true_K], delta, dt)
psi_data = psi_true + np.random.normal(0, 0.01, size=psi_true.shape)  # 添加噪聲# 參數辨識
initial_guess = [1.0, 0.1]  # 初始猜測值
result = minimize(error_function, initial_guess, args=(delta, dt, psi_data), method='L-BFGS-B')estimated_tau, estimated_K = result.x
print(f"Estimated parameters: tau = {estimated_tau:.3f}, K = {estimated_K:.3f}")# 繪制結果
plt.figure(figsize=(10, 6))
plt.plot(time, np.degrees(psi_data), label="Noisy Data", linestyle='--')
plt.plot(time, np.degrees(nomoto_model([true_tau, true_K], delta, dt)), label="True Model")
plt.plot(time, np.degrees(nomoto_model(result.x, delta, dt)), label="Estimated Model")
plt.xlabel("Time (s)")
plt.ylabel("Heading Angle (degrees)")
plt.legend()
plt.show()

5.4 說明

  1. 數據生成:為了測試辨識算法的效果,我們首先生成了一組帶有噪聲的模擬數據。這里使用了真實的參數 (\tau) 和 (K) 來生成模擬的航向角數據,并添加了一些隨機噪聲以模擬實際情況。

  2. 誤差函數:定義了一個誤差函數 error_function,它計算模型預測值與實驗數據之間的誤差平方和。

  3. 參數辨識:使用 SciPy 的 minimize 函數來最小化誤差函數,從而估計出最佳的 (\tau) 和 (K) 值。這里選擇了 L-BFGS-B 方法作為優化算法,因為它適合處理有界的參數空間。

  4. 結果展示:最后,繪制了原始數據、真實模型輸出以及辨識得到的模型輸出,以便直觀地比較它們之間的差異。

上述方法是一個簡單的實現,適用于初步的參數辨識任務。在實際應用中,可能需要考慮以下幾個方面進行改進:

  • 更復雜的模型:如果需要更高的精度,可以考慮使用更高階的 Nomoto 模型或其他更為復雜的船舶操縱模型。
  • 魯棒性:針對不同的噪聲水平和數據質量,優化算法的選擇和參數初始化可能會有所不同。
  • 實時辨識:在某些應用場景下,可能需要在線實時地更新模型參數,這時可以考慮使用遞推最小二乘法等在線學習算法。

4. 結論

Nomoto 模型提供了一種簡便的方法來描述船舶的操縱行為,適用于初步分析和控制系統設計。盡管它有一定的局限性,但在很多情況下已經足夠有效。對于更精確的模擬和控制需求,可以考慮使用更復雜的模型,如 MMG 分離型模型或 Fossen 的矩陣向量形式模型。

通過【Nomoto 船舶模型C++與python實現】學習,您應該能夠用Nomoto 船舶模型描述船舶的操縱行為。從而實現對外部世界進行感知,充分認識這個有機與無機的環境,科學地合理地進行創作和發揮效益,然后為人類社會發展貢獻一點微薄之力。🤣🤣🤣

  1. 我會持續更新對應專欄博客,非常期待你的三連!!!🎉🎉🎉
  2. 如果鵬鵬有哪里說的不妥,還請大佬多多評論指教!!!👍👍👍
  3. 下面有我的🐧🐧🐧群推廣,歡迎志同道合的朋友們加入,期待與你的思維碰撞😘😘😘

參考文獻

  • Nomoto, K., Taguchi, K., Honda, K., & Hirano, S. (1957). On the Steering Qualities of Ships. International Shipbuilding Progress, 4(35), 354-370.
  • Fossen, T. I. (2011). Handbook of Marine Craft Hydrodynamics and Motion Control. John Wiley & Sons.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/66942.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/66942.shtml
英文地址,請注明出處:http://en.pswp.cn/web/66942.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

差分進化算法 (Differential Evolution) 算法詳解及案例分析

差分進化算法 (Differential Evolution) 算法詳解及案例分析 目錄 差分進化算法 (Differential Evolution) 算法詳解及案例分析1. 引言2. 差分進化算法 (DE) 算法原理2.1 基本概念2.2 算法步驟3. 差分進化算法的優勢與局限性3.1 優勢3.2 局限性4. 案例分析4.1 案例1: 單目標優化…

深入理解GPT底層原理--從n-gram到RNN到LSTM/GRU到Transformer/GPT的進化

從簡單的RNN到復雜的LSTM/GRU,再到引入注意力機制,研究者們一直在努力解決序列建模的核心問題。每一步的進展都為下一步的突破奠定了基礎,最終孕育出了革命性的Transformer架構和GPT大模型。 1. 從n-gram到循環神經網絡(RNN)的誕生 1.1 N-gram 模型 在深度學習興起之前,處理…

【JWT】jwt實現HS、RS、ES、ED簽名與驗簽

JWT 實現 HS、RS、ES 和 ED 簽名與驗簽 簽名方式算法密鑰類型簽名要點驗簽要點HSHMAC-SHA256對稱密鑰- 使用 crypto/hmac 和對稱密鑰生成 HMAC 簽名- 將 header.payload 作為數據輸入- 使用同一密鑰重新計算 HMAC 簽名- 比較計算結果與接收到的簽名是否一致RSRSA-SHA256公鑰 …

地址欄信息location

獲取信息 頁面跳轉 location.href當前地址欄信息 location.assign()設置跳轉新的頁面 location.replace() location.reload()刷新頁面

程序員轉型測試:解鎖漏洞挖掘新旅程

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 程序…

StarRocks常用命令

目錄 1、StarRocks 集群管理&配置命令 2、StarRocks 常用操作命令 3、StarRocks 數據導入和導出 1、StarRocks 集群管理&配置命令 查詢 FE 節點信息 SHOW frontends; SHOW PROC /frontends; mysql -h192.168.1.250 -P9030 -uroot -p -e "SHOW PROC /dbs;"…

08-ArcGIS For JavaScript-通過Mesh繪制幾何體(Cylinder,Circle,Box,Pyramid)

目錄 概述代碼實現1、Mesh.createBox2、createPyramid3、Mesh.createSphere4、Mesh.createCylinder 完整代碼 概述 對于三維場景而言&#xff0c;二位的點、線、面&#xff0c;三維的圓、立方體、圓柱等都是比較常見的三維對象&#xff0c;在ArcGIS For JavaScript中我們知道點…

Linux中page、buffer_head、bio的關系

在Linux中&#xff0c;page、buffer_head、bio這三個概念緊密相關&#xff0c;共同構成了塊設備I/O和內存管理的重要部分&#xff0c;它們的聯系主要體現在以下方面&#xff1a; page與buffer_head 基于page構建&#xff1a;buffer_head通常是基于page來構建的&#xff0c;一…

直線擬合例子 ,嶺回歸擬合直線

目錄 直線擬合,算出離群點 嶺回歸擬合直線&#xff1a; 直線擬合,算出離群點 import cv2 import numpy as np# 輸入的點 points np.array([[51, 149],[122, 374],[225, 376],[340, 382],[463, 391],[535, 298],[596, 400],[689, 406],[821, 407] ], dtypenp.float32)# 使用…

SpringCloud兩種注冊中心

SpringCloud 基本概念 系統架構 我們之前做的所有的項目都屬于單體架構&#xff0c;下面我們將要學習更適合大型項目的分布式架構 單體架構&#xff1a; 將業務的所有功能幾種在一個項目中開發&#xff0c;打成一個包部署。 優點&#xff1a;架構簡單、部署成本低 缺點&am…

SpringAI 搭建智能體(二):搭建客服系統智能體

在現代人工智能應用中&#xff0c;智能體&#xff08;Agent&#xff09; 是一個重要的概念&#xff0c;它的核心能力是自主性與靈活性。一個智能體不僅能夠理解用戶的需求&#xff0c;還能拆解任務、調用工具完成具體操作&#xff0c;并在復雜場景中高效運行。在本篇博客中&…

SVN客戶端使用手冊

目錄 一、簡介 二、SVN的安裝與卸載 1. 安裝&#xff08;公司內部一般會提供安裝包和漢化包&#xff0c;直接到公司內部網盤下載即可&#xff0c;如果找不到可以看下面的教程&#xff09; 2. 查看SVN版本 ?編輯 3. SVN卸載 三、SVN的基本操作 1. 檢出 2. 清除認證數據 3. 提交…

HTML 文本格式化詳解

在網頁開發中&#xff0c;文本內容的呈現方式直接影響用戶的閱讀體驗。HTML 提供了多種文本格式化元素&#xff0c;可以幫助我們更好地控制文本的顯示效果。本文將詳細介紹 HTML 中的文本格式化元素及其使用方法&#xff0c;幫助你輕松實現網頁文本的美化。 什么是 HTML 文本格…

衡量算法性能的量級標準:算法復雜度

今天開始數據結構的學習&#xff01;作為一大重點&#xff0c;拿出態度很重要&#xff0c;想要真實掌握&#xff0c;博客筆記自然少不了&#xff01;重點全部上色&#xff01;避免疏忽 下面我們從0基礎開始學習今天的第一節&#xff01;不用擔心看不懂&#xff0c;拒絕枯燥的理…

Spring Boot Starter介紹

前言 大概10來年以前&#xff0c;當時springboot剛剛出現并沒有流行&#xff0c;當時的Java開發者們開發Web應用主要是使用spring整合springmvc或者struts、iBatis、hibernate等開發框架來進行開發。項目里一般有許多xml文件配置&#xff0c;其中配置了很多項目中需要用到的Be…

Java面試題2025-Spring

講師&#xff1a;鄧澎波 Spring面試專題 1.Spring應該很熟悉吧&#xff1f;來介紹下你的Spring的理解 1.1 Spring的發展歷程 先介紹Spring是怎么來的&#xff0c;發展中有哪些核心的節點&#xff0c;當前的最新版本是什么等 通過上圖可以比較清晰的看到Spring的各個時間版本對…

Linux 切換到 Root 用戶的方式及差異詳解

在 Linux 系統中&#xff0c;切換到 root 用戶進行管理和操作是常見需求。不同的切換方法會影響環境變量、工作目錄以及加載的配置文件。本文將介紹幾種常用的切換方式及它們的特點。 切換到 Root 用戶的主要方式 1. sudo su 這是通過 sudo 提權后調用 su 切換到 root 用戶的…

虹科分享 | 汽車NVH小課堂之聽音辨故障

隨著車主開始關注汽車抖動異響問題&#xff0c;如何根據故障現象快速診斷異響來源&#xff0c;成了汽修人的必修課。 一個比較常用的方法就是靠“聽”——“聽音辨故障”。那今天&#xff0c;虹科Pico也整理了幾個不同類型的異響聲音&#xff0c;一起來聽聽看你能答對幾個吧 汽…

淺談Redis

2007 年&#xff0c;一位程序員和朋友一起創建了一個網站。為了解決這個網站的負載問題&#xff0c;他自己定制了一個數據庫。于2009 年開發&#xff0c;稱之為Redis。這位意大利程序員是薩爾瓦托勒桑菲利波(Salvatore Sanfilippo)&#xff0c;他被稱為Redis之父&#xff0c;更…

element tbas增加下拉框

使用Tabs 標簽頁的label插槽&#xff0c;嵌入Dropdown 下拉菜單&#xff0c;實現Tabs 標簽頁增加下拉切換功能 Tabs 標簽頁 tab-click"事件"&#xff08;這個事件當中到擁有下拉框的tab里時&#xff0c;可以存一下Dropdown 第一個菜單的id&#xff0c;實現點擊到擁有…