MATLAB - 仿真单摆的周期性摆动

系列文章目录

 


前言

本例演示如何使用 Symbolic Math Toolbox™ 模拟单摆的运动。推导摆的运动方程,然后对小角度进行分析求解,对任意角度进行数值求解。

a63818f5d19e454581544d5694154996.png


 

一、步骤 1:推导运动方程

摆是一个遵循微分方程的简单机械系统。摆最初静止在垂直位置。当摆移动一个角度 θ 并释放时,重力将其拉回静止位置。它的动量会使它过冲并到达 -θ 角(如果没有摩擦力),以此类推。由于重力的作用,钟摆运动的恢复力为 -mgsinθ。因此,根据牛顿第二定律,质量乘以加速度必须等于 -mgsinθ。

syms m a g theta(t)
eqn = m*a == -m*g*sin(theta)
eqn(t) = a m=−g m sin(θ(t))

对于长度为 r 的摆锤,摆锤的加速度等于角加速度乘以 r。

eq?a%3Dr%5Cfrac%7Bd%5E2%5Ctheta%7D%7Bdt%5E2%7D.

用子项代替 a。 

syms r
eqn = subs(eqn,a,r*diff(theta,2))

 eq?%5Cbegin%7Baligned%7Deqn%28t%29%26%3D%5C%5Cmr%5Cfrac%7B%5Cpartial%5E2%7D%7B%5Cpartial%20t%5E2%7D%26%5Ctheta%28t%29%3D-gm%5Csin%28%5Ctheta%28t%29%29%5Cend%7Baligned%7D

使用 isolate 隔离公式中的角加速度。

eqn = isolate(eqn,diff(theta,2))

eq?%5Cbegin%7Baligned%7D%5Ctext%7Beqn%20%3D%7D%20%5Cfrac%7B%5Cpartial%5E2%7D%7B%5Cpartial%20t%5E2%7D%5Cleft.%5Ctheta%28t%29%3D-%5Cfrac%7Bg%5Csin%28%5Ctheta%28t%29%29%7Dr%5Cright.%5Cend%7Baligned%7D

将常数 g 和 r 合并为一个参数,也称为固有频率。

eq?%5Comega_0%3D%5Csqrt%7B%5Cdfrac%7Bg%7D%7Br%7D%7D.

syms omega_0
eqn = subs(eqn,g/r,omega_0^2)

eq?%5Cbegin%7Baligned%7D%5Ctext%7Beqn%20%3D%7D%5Cfrac%7B%5Cpartial%5E2%7D%7B%5Cpartial%20t%5E2%7D%5Ctheta%28t%29%3D-%5Comega_0%5E2%5Csin%28%5Ctheta%28t%29%29%5Cend%7Baligned%7D

二、步骤 2:运动方程线性化

运动方程是非线性的,因此难以用解析法求解。假设角度很小,利用 sinθ 的泰勒展开式将方程线性化。 

syms x
approx = taylor(sin(x),x,'Order',2);
approx = subs(approx,x,theta(t))

eq?approx%20%3D%20%5Ctheta%28t%29

运动方程变成了线性方程。

eqnLinear = subs(eqn,sin(theta(t)),approx)

eq?%5Cbegin%7Baligned%7D%5Ctext%7BeqnLinear%7D%26%3D%5C%5C%5Cfrac%7B%5Cpartial%5E2%7D%7B%5Cpartial%20t%5E2%7D%5Ctheta%28t%29%26%3D-%5Comega_0%5E2%5Ctheta%28t%29%5Cend%7Baligned%7D

三、步骤 3:分析求解运动方程

使用 dsolve 求解方程 eqnLinear。将初始条件指定为第二个参数。使用 assume 假设 ω0 为实数,简化解法。

syms theta_0 theta_t0
theta_t = diff(theta);
cond = [theta(0) == theta_0, theta_t(0) == theta_t0];
assume(omega_0,'real')
thetaSol(t) = dsolve(eqnLinear,cond)

eq?%5Cbegin%7Baligned%7D%5Ctext%7Bthetasol%28t%29%7D%26%3D%5Ctheta_0%5Ccos%28%5Comega_0t%29+%5Cfrac%7B%5Ctheta_%7Bt0%7D%5Csin%28%5Comega_0t%29%7D%7B%5Comega_0%7D%5Cend%7Baligned%7D

四、步骤 4:ω0 的物理意义

项 ω 0 t 称为相位。余弦函数和正弦函数每 2π 重复一次。改变 ω 0 t 变化 2π 所需的时间称为时间周期。

eq?T%3D%5Cdfrac%7B2%5Cpi%7D%7B%5Comega0%7D%3D2%5Cpi%5Csqrt%7B%5Cdfrac%7Br%7D%7Bg%7D%7D.

时间周期 T 与摆长的平方根成正比,与质量无关。对于线性运动方程,时间周期与初始条件无关。

五、步骤 5:绘制摆的运动图

绘制小角度近似的摆运动图。

定义物理参数:

  • 重力加速度 s%7D%5E%7B2%7D
  • 摆长 eq?%5Ctext%7Br%3D1%20m%7D

 

gValue = 9.81;
rValue = 1;
omega_0Value = sqrt(gValue/rValue);
T = 2*pi/omega_0Value;

设置初始条件。

theta_0Value  = 0.1*pi; % Solution only valid for small angles.
theta_t0Value = 0;      % Initially at rest.

 将物理参数和初始条件代入一般解法。

vars   = [omega_0      theta_0      theta_t0];
values = [omega_0Value theta_0Value theta_t0Value];
thetaSolPlot = subs(thetaSol,vars,values);

 绘制谐摆运动图。

fplot(thetaSolPlot(t*T)/pi, [0 5]);
grid on;
title('Harmonic Pendulum Motion');
xlabel('t/T');
ylabel('\theta/\pi');

8eb90a748ded400aa701f5e81c3b2531.png

求出 θ(t) 的解后,想象一下摆的运动。 

x_pos = sin(thetaSolPlot);
y_pos = -cos(thetaSolPlot);
fanimator(@fplot,x_pos,y_pos,'ko','MarkerFaceColor','k','AnimationRange',[0 5*T]);
hold on;
fanimator(@(t) plot([0 x_pos(t)],[0 y_pos(t)],'k-'),'AnimationRange',[0 5*T]);
fanimator(@(t) text(-0.3,0.3,"Timer: "+num2str(t,2)+" s"),'AnimationRange',[0 5*T]);

f7032f03593c4a37b21f75d0d7abdedd.png

输入 playAnimation 命令播放钟摆运动的动画。 

6c850fe8dde34909aa426df85a494e71.gif

六、步骤 6:使用恒定能量路径确定非线性摆运动

为了理解摆的非线性运动,请使用总能量方程来直观显示摆的运动轨迹。总能量是守恒的。

eq?E%3D%5Cdfrac12mr%5E2%7B%5Cleft%28%5Cdfrac%7Bd%5Ctheta%7D%7Bdt%7D%5Cright%29%7D%5E2+mgr%281-%5Ccos%5Ctheta%29 

使用三角函数特性 2%29 和关系式 r%7D 重写比例能量。

eq?%5Cdfrac%20E%7Bmr%5E2%7D%3D%5Cdfrac12%5Cleft%5B%5Cleft%28%5Cdfrac%7Bd%5Ctheta%7D%7Bdt%7D%5Cright%29%5E2+%5Cleft%282%5Comega_0%5Csin%5Cdfrac%5Ctheta2%5Cright%29%5E2%5Cright%5D 

由于能量守恒,摆的运动可以用相空间中的恒定能量路径来描述。相空间是一个抽象空间,坐标为 θ 和 dθ/dt。使用 fcontour 将这些路径可视化。

syms theta theta_t omega_0
E(theta, theta_t, omega_0) = (1/2)*(theta_t^2+(2*omega_0*sin(theta/2))^2);
Eplot(theta, theta_t) = subs(E,omega_0,omega_0Value);figure;
fc = fcontour(Eplot(pi*theta, 2*omega_0Value*theta_t), 2*[-1 1 -1 1], ...'LineWidth', 2, 'LevelList', 0:5:50, 'MeshDensity', 1+2^8);
grid on;
title('Constant Energy Contours in Phase Space ( \theta vs. \theta_t )');
xlabel('\theta/\pi');
ylabel('\theta_t/2\omega_0');

1ca04c2158374f96a101b5ad1e0aed66.png

恒定能量等值线围绕 θ 轴和 dθ/dt 轴对称,沿 θ 轴呈周期性分布。图中显示了两个行为截然不同的区域。

等值线图的较低能量相互靠近。摆锤在两个最大角度和速度之间来回摆动。摆锤的动能不足以克服重力能,使摆锤绕一圈。

afd1ca0e5c744a12bc95dbc61e07a2fe.gif

等值线图中的高能量不会自行闭合。摆锤始终沿着一个角度方向运动。钟摆的动能足以克服重力能,使钟摆能够绕一圈。 

78b67ff177b24fb4a1a4ecf0e2c34c86.gif

七、步骤 7:求解非线性运动方程

非线性运动方程是二阶微分方程。使用 ode45 求解器对这些方程进行数值求解。由于 ode45 只接受一阶系统,因此请将系统简化为一阶系统。然后生成函数句柄,作为 ode45 的输入。

将二阶 ODE 重写为一阶 ODE 系统。

syms theta(t) theta_t(t) omega_0
eqs = [diff(theta)   == theta_t;diff(theta_t) == -omega_0^2*sin(theta)]

 eq?%5Cleft.%5Ctext%7Beqs%7D%28t%29%3D%5C%5C%5Cleft%28%5Cbegin%7Baligned%7D%5Cfrac%7B%5Cpartial%7D%7B%5Cpartial%20t%7D%26%5Ctheta%28t%29%3D%5Ctheta_t%28t%29%5C%5C%5C%5C%5Cfrac%7B%5Cpartial%7D%7B%5Cpartial%20t%7D%26%5Ctheta_t%28t%29%3D-%5Comega_0%5E2%5Csin%28%5Ctheta%28t%29%29%5Cend%7Baligned%7D%5Cright.%5Cright%29

eqs  = subs(eqs,omega_0,omega_0Value);
vars = [theta, theta_t];

 求出系统的质量矩阵 M 和方程 F 的右边。

[M,F] = massMatrixForm(eqs,vars)

 eq?%5Cbegin%7Barray%7D%7Brcl%7D%5Ctext%7BM%7D%26%3D%26%5C%5C%26%26%5Cbegin%7Bbmatrix%7D1%260%5C%5C0%261%5Cend%7Bbmatrix%7D%5Cend%7Barray%7D

eq?%5Cbegin%7Baligned%7D%7BF%7D%26%3D%5C%5C%26%5Cbegin%7Bbmatrix%7D%5Ctheta_t%28t%29%5C%5C-%5Cdfrac%7B981%5Csin%28%5Ctheta%28t%29%29%7D%7B100%7D%5Cend%7Bbmatrix%7D%5Cend%7Baligned%7D

M 和 F 指的就是这种形式。

eq?M%28t%2Cx%28t%29%29%5Cdfrac%7Bdx%7D%7Bdt%7D%3DF%28t%2Cx%28t%29%29. 

为简化进一步计算,可将系统改写为 dt%3Df%28t%2Cx%28t%29%29. 的形式。

f = M\F

 eq?%5Cbegin%7Baligned%7D%5Ctext%7Bf%7D%26%3D%5C%5C%26%5Cbegin%7Bbmatrix%7D%5Ctheta_t%28t%29%5C%5C-%5Cdfrac%7B981%5Csin%28%5Ctheta%28t%29%29%7D%7B100%7D%5Cend%7Bbmatrix%7D%5Cend%7Baligned%7D

使用 odeFunction 将 f 转换为 MATLAB 函数句柄。生成的函数句柄是 MATLAB ODE 求解器 ode45 的输入。 

f = odeFunction(f, vars)
f = function_handle with value:@(t,in2)[in2(2,:);sin(in2(1,:)).*(-9.81e+2./1.0e+2)]

八、步骤 8:求解封闭能量等值线的运动方程

使用 ode45 求解封闭能量等值线的 ODE。

从能量等值线图来看,封闭等值线满足条件 2%5Comega_0%5Cleq1. 将 θ 和 dθ/dt 的初始条件存储在变量 x0 中。

x0 = [0; 1.99*omega_0Value];

指定一个从 0 秒到 10 秒的时间间隔,用于求解。这个时间间隔允许摆锤经历两个完整的周期。

tInit  = 0;
tFinal = 10;

求解 ODE。

sols = ode45(f,[tInit tFinal],x0)
sols = struct with fields:solver: 'ode45'extdata: [1x1 struct]x: [0 3.2241e-05 1.9344e-04 9.9946e-04 0.0050 0.0252 0.1259 0.3449 0.6020 0.8591 1.1161 1.3597 1.5996 1.8995 2.2274 2.4651 2.7028 2.9567 3.2138 3.4709 3.7150 3.9511 4.2483 4.5759 4.8239 5.0719 5.3182 5.5764 5.8346 6.0803 ... ] (1x45 double)y: [2x45 double]stats: [1x1 struct]idata: [1x1 struct]

sols.y(1,:) 表示角位移 θ,sols.y(2,:) 表示角速度 dθ/dt。

绘制闭合路径解。

figure;yyaxis left;
plot(sols.x, sols.y(1,:), '-o');
ylabel('\theta (rad)');yyaxis right;
plot(sols.x, sols.y(2,:), '-o');
ylabel('\theta_t (rad/s)');grid on;
title('Closed Path in Phase Space');
xlabel('t (s)');

80eb2447004a483aa049ee40b70c5470.png

可视化钟摆的运动。 

x_pos = @(t) sin(deval(sols,t,1));
y_pos = @(t) -cos(deval(sols,t,1));
figure;
fanimator(@(t) plot(x_pos(t),y_pos(t),'ko','MarkerFaceColor','k'));
hold on;
fanimator(@(t) plot([0 x_pos(t)],[0 y_pos(t)],'k-'));
fanimator(@(t) text(-0.3,1.5,"Timer: "+num2str(t,2)+" s"));

8a541ad36396414ea0d689cffcdbaaf0.png

输入 playAnimation 命令播放钟摆运动的动画。 

e77f57e87f15422cba0dc4c074f3bf33.gif

九、步骤 9:开放式能量等值线的求解

使用 ode45 求解开放式能量等值线的 ODE。从能量等值线图来看,开放式等值线满足条件 2%5Comega_0%3E1.

x0 = [0; 2.01*omega_0Value];
sols = ode45(f, [tInit, tFinal], x0);

绘制开放式能量等值线的解。

figure;yyaxis left;
plot(sols.x, sols.y(1,:), '-o');
ylabel('\theta (rad)');yyaxis right;
plot(sols.x, sols.y(2,:), '-o');
ylabel('\theta_t (rad/s)');grid on;
title('Open Path in Phase Space');
xlabel('t (s)');

a44827106aa74d0895ff9f7a600515cf.png

可视化钟摆的运动。 

x_pos = @(t) sin(deval(sols,t,1));
y_pos = @(t) -cos(deval(sols,t,1));
figure;
fanimator(@(t) plot(x_pos(t),y_pos(t),'ko','MarkerFaceColor','k'));
hold on;
fanimator(@(t) plot([0 x_pos(t)],[0 y_pos(t)],'k-'));
fanimator(@(t) text(-0.3,1.5,"Timer: "+num2str(t,2)+" s"));

371c99980bdb4063b3a0eb97ed8bdcc6.png

输入 playAnimation 命令播放钟摆运动的动画。 

1802195a04a1460c9f83e9708914ec06.gif

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/657579.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据 - Hadoop系列《四》- MapReduce(分布式计算引擎)的核心思想

上一篇: 大数据 - Hadoop系列《三》- MapReduce(分布式计算引擎)概述-CSDN博客 目录 13.1 MapReduce实例进程 13.2 阶段组成 13.4 概述 13.4.1 🥙Map阶段(映射) 13.4.2 🥙Reduce阶段执行过…

【Spark系列6】如何做SQL查询优化和执行计划分析

Apache Spark SQL 使用 Catalyst 优化器来生成逻辑执行计划和物理执行计划。逻辑执行计划描述了逻辑上如何执行查询,而物理执行计划则是 Spark 实际执行的步骤。 一、查询优化 示例 1:过滤提前 未优化的查询 val salesData spark.read.parquet(&quo…

Vue2:请求接口的两种方式axios和vue-resource

一、场景描述 前端和后端的交互,肯定是要发生接口调用的 这个时候,就要涉及前端如何向后端接口发送请求,获取数据 二、请求方式 1、axios方式(推荐) 这个方式本质就是ajax,底层就是对xhr(XMLHttpRequest)的封装 1、安装axios…

STM32F407移植OpenHarmony笔记3

接上一篇,搭建完环境,找个DEMO能跑,现在我准备尝试从0开始搬砖。 首先把/device和/vendor之前的代码全删除,这个时候用hb set命令看不到任何项目了。 /device目录是硬件设备目录,包括soc芯片厂商和board板级支持代码…

JAVA线程执行中断方式和ElasticSearch未捕获异常的处理方式

JAVA线程执行中断方式 Java中只能通过协作的方式取消 第一种是通过标志位实现,假设有个计算所有素数的任务,每次计算前检查下是否取消的标志位,如果为true则退出计算。调用方想要取消任务的话,则将标志位设为true。但这种方法无法…

Linux 系统相关的命令

参考资料 Linux之chmod使用【linux】chmod命令详细用法 目录 一. 系统用户相关1.1 查看当前访问的主机和用户1.2 切换用户1.2.1 设置root用户密码1.2.2 普通用户和root用户切换 1.4 系统状态1.4.1 vmstat 查看当前系统的状态1.4.2 history 查看系统中输入过的命令 二. 系统文件…

React18-列表数据实现用户删除、批量删除

用户删除、批量删除接口 删除、批量删除接口 接口地址 POST/users/delete请求参数 {userIds: [] }参数为数组,删除和批量删除共用 功能介绍 单个删除 删除按钮绑定事件,点击显示弹框确认。 // 删除 const handleDel (values: DataType) > {//…

图扑 HT UI 5.0 全新升级,开箱即用!

为顺应数字时代的不断发展,图扑 HT UI 5.0 在原有功能强大的界面组件库的基础上进行了全面升级,融入了更先进的技术、创新的设计理念以及更加智能的功能。HT UI 5.0 使用户体验更为直观、个性化,并在性能、稳定性和安全性等方面达到新的高度。…

githacker安装详细教程,linux添加环境变量详细教程(见标题三)

笔者是ctf小白,这两天也是遇到.git泄露的题目,需要工具来解决问题,在下载和使用的过程中也是遇到很多问题,写此篇记录经验,以供学习 在本篇标题三中有详细介绍了Linux系统添加环境变量的操作教程,以供学习 …

TensorFlow2实战-系列教程6:猫狗识别3------迁移学习

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 猫狗识别1 数据增强 猫狗识别2------数据增强 猫狗识别3------迁移学习 1、迁移学习 …

TensorFlow2实战-系列教程15:Resnet实战3

🧡💛💚TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 Resnet实战1 Resnet实战2 Resnet实战3 7、训练脚本train.py解读------配置训练参数 …

解读4篇混合类型文件Polyglot相关的论文

0. 引入 Polyglot文件指的是混合类型文件,关于混合类型文件的基础,请参考文末给出的第一个链接(参考1)。 1. Toward the Detection of Polyglot Files 1.1 主题 这篇2022年的论文,提出了Polyglot文件的检测方法。虽…

C++核心编程:文件操作 笔记

5.文件操作 程序运行时产生的数据都属于临时数据&#xff0c;程序一旦允许结束都会被释放。通过文件可以将数据持久化 C中对文件操作需要包含头文件<fstream> 文件类型分为两种&#xff1a; 文本文件 - 文件以文本的ASCII码形式存储在计算机中二进制文件 - 文件以文本…

openssl3.2 - .pod文件的查看方法

文章目录 .pod文件的查看方法概述笔记初步的解决方法备注 - pod2html.bat的详细用法好像Perl就自带这个BATEND .pod文件的查看方法 概述 看到openssl源码目录下有很多.pod文件, 软件发布的帮助内容都在里面. 当make install后, 大部分的.pod都会转成html文件, 但是有一部分…

【Java程序设计】【C00215】基于SSM的勤工助学管理系统(论文+PPT)

基于SSM的勤工助学管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这个一个基于SSM的勤工助学管理系统&#xff0c;本系统共分为三种权限&#xff1a;管理员、教师和学生 管理员&#xff1a;首页、个人中心、教师管理、学生管理…

逆置字符串

将字符串逆序,比如输入abcd,返回dcba void reverse(char*left,char *right) { while (right>left) { char temp *left; *left *right; *right temp; right--; left; } } int main() { char arr[100] { 0 };//定义…

gdp调试—Linux

目录 介绍 使用 介绍 代码分为debug模式和release模式 如果一份代码要被调试&#xff0c;这份代码必须是debug Linux下编译代码默认是是release模式 如果你想代码是debug模式 必须加上 - g 小提&#xff1a; vim默认&#xff1a;命令模式 gcc默认&#xff1a;releas…

操作系统--进程、线程基础知识

一、进程 我们编写的代码只是一个存储在硬盘的静态文件&#xff0c;通过编译后就会生成二进制可执行文件&#xff0c;当我们运行这个可执行文件后&#xff0c;它会被装载到内存中&#xff0c;接着 CPU 会执行程序中的每一条指令&#xff0c;那么这个运行中的程序&#xff0c;就…

ModelArts加速识别,助力新零售电商业务功能的实现

前言 如果说为客户提供最好的商品是产品眼中零售的本质&#xff0c;那么用户的思维是什么呢&#xff1f; 在用户眼中&#xff0c;极致的服务体验与优质的商品同等重要。 企业想要满足上面两项服务&#xff0c;关键在于提升效率&#xff0c;也就是需要有更高效率的零售&#…

C++ //练习 3.8 分别用while循环和传统的for循环重写第一题的程序,你觉得哪种形式更好呢?为什么?

C Primer&#xff08;第5版&#xff09; 练习 3.8 练习 3.8 分别用while循环和传统的for循环重写第一题的程序&#xff0c;你觉得哪种形式更好呢&#xff1f;为什么? 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /********…