一個用於模擬動態系統的 C++ 專案,聚焦於 Lorenz 吸子與 MCK(質彈阻)系統。此專案適合學術研究與工程應用,提供模組化、可擴充的數值積分與系統模擬架構。
- 物件導向設計:動態系統與積分器皆以 C++ 類別模組化設計。
- ODE4(RK4)積分法:內建經典四階 Runge-Kutta 積分器。
- 範例系統:內含 Lorenz 吸子與 MCK 系統模擬。
- MATLAB 驗證:提供 MATLAB 腳本進行結果比對。
- Eigen3 支援:採用 Eigen 函式庫進行高效線性代數運算。
- 下載專案
git clone https://github.com/yourusername/ode4solver.git cd ode4solver - 使用 CMake 編譯
mkdir build cd build cmake .. -G "Visual Studio 17 2022" -A x64 -T version=14.38.33130 cmake --build . --config Debug
- 執行範例
執行檔會在
bin/Debug/(或bin/Release/)下:example_Lorenz.exeexample_MCK.exe
matlab/ 資料夾內有驗證用腳本:
verify_lorenz_system.mverify_mck_system.m
模擬結果會以 CSV 檔儲存,可與 MATLAB 輸出比對。
bin/Debug/example_Lorenz.exebin/Debug/example_MCK.exeinclude/DynamicSystem.hpp:動態系統抽象基底類別LorenzAttractor.hpp:Lorenz 系統實作MCKSystem.hpp:質彈阻系統實作RK4Integrator.hpp:四階 Runge-Kutta 積分器SystemSimulator.hpp:模擬管理器
src/example_Lorenz.cpp:Lorenz 系統模擬範例example_MCK.cpp:MCK 系統模擬範例CMakeLists.txt:編譯設定
matlab/- MATLAB 腳本與 CSV 結果
本專案提供彈性架構,讓你可以輕鬆自定義自己的常微分方程(ODE)系統,並利用內建數值積分器進行模擬。以下以 Lorenz 吸子為例,說明如何擴充與使用:
請繼承 DynamicSystem 抽象類別,並實作 computeDerivatives、getStateDimension、getInputDimension 等必要方法。例如:
class LorenzAttractor : public DynamicSystem
{
public:
LorenzAttractor(double sigma, double beta, double rho);
Eigen::VectorXd computeDerivatives(const Eigen::VectorXd& state, const Eigen::VectorXd& input, double time) const override;
int getStateDimension() const override { return 3; }
int getInputDimension() const override { return 0; }
// ... 參數存取方法 ...
};computeDerivatives 需回傳一個與狀態維度相同的向量,描述系統的微分方程。
在主程式中,先建立系統物件,再用 SystemSimulator 包裝:
LorenzAttractor lorenz(10.0, 28.0, 8.0/3.0);
SystemSimulator simulator(lorenz);初始化狀態向量與時間步長:
Eigen::VectorXd initial_state(3);
initial_state << 1.0, 1.0, 1.0;
simulator.initial(initial_state, 0.01);以 for 迴圈進行多步積分,每步可傳入控制輸入(如無輸入可傳 0):
for (size_t i = 0; i < 100000; ++i)
{
Eigen::VectorXd u(1);
u(0) = 0.0;
simulator.step(u);
}模擬結束後,可將歷史資料存成 CSV 檔:
simulator.saveHistoryToCSV("result");只需仿照 LorenzAttractor,定義自己的系統類別,實作 computeDerivatives,即可模擬任意 ODE 問題。例如:
class MySystem : public DynamicSystem
{
public:
// ...建構子...
Eigen::VectorXd computeDerivatives(const Eigen::VectorXd& state, const Eigen::VectorXd& input, double time) const override
{
// 實作你的微分方程
}
// ...其餘必要方法...
};然後在主程式中建立 MySystem 物件並用 SystemSimulator 執行即可。
如需更進階功能(如多輸入、多輸出、參數調整等),可參考 LorenzAttractor.hpp 內的參數存取與設定方法。
- 確認狀態回饋控制功能
- Step()裡面Desire的去留,目前還是保留 (先嘗試用openloop打sin波進去)
- 多撈取誤差、誤差微分、誤差積分等資訊
- csv新增其他欄位(誤差、誤差微分、誤差積分,甚至控制命令)
- 讓其他系統問題也能使用相同的架構
- 透過MATLAB驗證回授控制的正確性
- 修改README,主要是說明如何使用這個專案中的自定義ODE問題 (紀錄只要有一點點的誤差出現,就會導致高度非線性的ODE誤差(渾沌系統)會快速累積,導致後面都不一樣)
- 進行RL的整合測試
若你在學術研究中使用本專案,請引用:
@misc{ode4solver2025,
title={ODE4Solver},
author={HeRong},
year={2025},
howpublished={\url{https://github.com/NCKU-He-Rong/ode4solver}}
}
本專案採用 MIT License 授權。詳見 LICENSE。
- Eigen3 線性代數函式庫
如有問題或想貢獻,歡迎於 GitHub 開 issue 或 pull request。
