Modelica多体系统问题:IdealGearR2T+Inertia组成的Inerter受激无阻尼无转动
Modelica多体系统TMD-I仿真问题排查与修复
问题现象
- 上部质量块无阻尼运动
- Inertia模块无转动动力学表现,未产生运动阻力
- 可视化用BodyBox完全不转动
- 惯容器(IdealGearR2T+Inertia)仿佛断开失效
- 移除激励、将SpringDamper的
s_rel0设为-1时系统能缓慢稳定,但动态激励下表现不符合预期
预期效果
- IdealGearR2T+Inertia与弹簧阻尼器配合,提供与相对速度成正比的惯容器阻力,以及与相对位移成正比的弹簧阻尼阻力
- 小幅正弦激励下,上部质量块振荡且受惯容器影响产生阻尼,符合TMD-I特性
- BodyBox呈现与IdealGearR2T传递运动成正比的小幅转动
- 系统在
s_rel0=0(弹簧初始相对位移为0)的条件下,正弦激励下可正常工作
系统参数
- IdealGearR2T传动比:
2π*10≈62.832 - Inertia转动惯量J:13.5
- SpringDamper:刚度c=20N/m,阻尼d=10N·s/m,初始
s_rel0=-1 - 正弦位置输入:振幅0.1m,频率0.2Hz
- 上部质量块质量:100kg
- 重力设置:无重力(NoGravity)
模型代码
model BuildingCase3 inner Modelica.Mechanics.MultiBody.World world(gravityType = Modelica.Mechanics.MultiBody.Types.GravityTypes.NoGravity) annotation( Placement(transformation(origin = {-132, -26}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar2(r = {0.3, 0, 0}) annotation( Placement(transformation(origin = {-108, -56}, extent = {{0, 20}, {20, 40}}))); // Rotation angle in radians Modelica.Mechanics.MultiBody.Joints.Prismatic prismatic1(n = {0, 1, 0}, useAxisFlange = true, s(fixed = true)) annotation( Placement(transformation(origin = {-54, -26}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Parts.Body body1(m = 150, sphereDiameter = 0.2) annotation( Placement(transformation(origin = {-16, -26}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Joints.Prismatic prismatic(n = {0, 1, 0}, useAxisFlange = true) annotation( Placement(transformation(origin = {40, 2}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Joints.Revolute revolute(cylinderLength = 0.2, n = {0, 1, 0}, useAxisFlange = true) annotation( Placement(transformation(origin = {76, 2}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Sensors.AbsoluteSensor absoluteSensorTop(get_a = true, get_r = true, get_v = true) annotation( Placement(transformation(origin = {120, 28}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Parts.Body body(m = 100, sphereDiameter = 0.2) annotation( Placement(transformation(origin = {120, 2}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.MultiBody.Parts.BodyBox bodyBox(density = 0, height = 0.06, length = 0.06, r = {0, -0.01, 0}, width = 0.2) annotation( Placement(transformation(origin = {98, -40}, extent = {{-10, -10}, {10, 10}}, rotation = -90))); Modelica.Mechanics.MultiBody.Sensors.AbsoluteSensor absoluteSensorBottom(get_a = true, get_r = true, get_v = true) annotation( Placement(transformation(origin = {-36, -56}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); Modelica.Mechanics.MultiBody.Parts.FixedTranslation bar21(r = {0, 1, 0}, animation = true) annotation( Placement(transformation(origin = {-4, -28}, extent = {{0, 20}, {20, 40}}))); Modelica.Mechanics.Translational.Components.SpringDamper springDamper(c = 20, d = 10, s_rel0 = -1) annotation( Placement(transformation(origin = {40, 30}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Components.IdealGearR2T idealGearR2T(ratio = 62.832) annotation( Placement(transformation(origin = {60, 58}, extent = {{-10, -10}, {10, 10}}, rotation = 180))); Modelica.Mechanics.Rotational.Components.Inertia inertia(J = 13.5) annotation( Placement(transformation(origin = {114, 58}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Components.Spring spring(c = 20) annotation( Placement(transformation(origin = {-52, 4}, extent = {{-10, -10}, {10, 10}}))); Modelica.Blocks.Sources.Sine sine(amplitude = 0.1, f = 0.2) annotation( Placement(transformation(origin = {-106, -61}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Sources.Position position annotation( Placement(transformation(origin = {-78, -61}, extent = {{-10, -10}, {10, 10}}))); equation connect(world.frame_b, bar2.frame_a) annotation( Line(points = {{-122, -26}, {-108, -26}}, color = {95, 95, 95})); connect(prismatic1.frame_b, body1.frame_a) annotation( Line(points = {{-44, -26}, {-44, -27}, {-26, -27}, {-26, -26}}, color = {95, 95, 95})); connect(bar2.frame_b, prismatic1.frame_a) annotation( Line(points = {{-88, -26}, {-64, -26}}, color = {95, 95, 95})); connect(prismatic.frame_b, revolute.frame_a) annotation( Line(points = {{50, 2}, {66, 2}}, color = {95, 95, 95})); connect(absoluteSensorTop.frame_a, body.frame_a) annotation( Line(points = {{110, 28}, {110, 2}}, color = {95, 95, 95})); connect(body.frame_a, revolute.frame_b) annotation( Line(points = {{110, 2}, {86, 2}}, color = {95, 95, 95})); connect(absoluteSensorBottom.frame_a, body1.frame_a) annotation( Line(points = {{-26, -56}, {-26, -26}}, color = {95, 95, 95})); connect(prismatic.frame_a, bar21.frame_b) annotation( Line(points = {{30, 2}, {16, 2}}, color = {95, 95, 95})); connect(bar21.frame_a, body1.frame_a) annotation( Line(points = {{-4, 2}, {-9, 2}, {-9, -26}, {-26, -26}}, color = {95, 95, 95})); connect(bodyBox.frame_a, body.frame_a) annotation( Line(points = {{98, -30}, {98, 2}, {110, 2}}, color = {95, 95, 95})); connect(springDamper.flange_a, prismatic.support) annotation( Line(points = {{30, 30}, {30, 8}, {36, 8}}, color = {0, 127, 0})); connect(springDamper.flange_b, prismatic.axis) annotation( Line(points = {{50, 30}, {52, 30}, {52, 8}, {48, 8}}, color = {0, 127, 0})); connect(inertia.flange_a, idealGearR2T.flangeR) annotation( Line(points = {{104, 58}, {70, 58}})); connect(prismatic.axis, idealGearR2T.flangeT) annotation( Line(points = {{48, 8}, {48, 58}, {50, 58}}, color = {0, 127, 0})); connect(idealGearR2T.flangeR, revolute.axis) annotation( Line(points = {{70, 58}, {70, 43}, {76, 43}, {76, 12}})); connect(prismatic1.support, spring.flange_a) annotation( Line(points = {{-58, -20}, {-62, -20}, {-62, 4}}, color = {0, 127, 0})); connect(prismatic1.axis, spring.flange_b) annotation( Line(points = {{-46, -20}, {-42, -20}, {-42, 4}}, color = {0, 127, 0})); connect(sine.y, position.s_ref) annotation( Line(points = {{-95, -61}, {-91, -61}}, color = {0, 0, 127})); connect(position.flange, prismatic1.axis) annotation( Line(points = {{-68, -61}, {-46, -61}, {-46, -20}}, color = {0, 127, 0})); annotation( experiment(StartTime = 0, StopTime = 200, Tolerance = 1e-6, Interval = 0.002), uses(Modelica(version = "4.0.0")), Diagram(coordinateSystem(extent = {{-160, 100}, {160, -120}})), version = ""); end BuildingCase3;
核心疑问
- 为何本配置中惯容器(IdealGearR2T+Inertia)无法正常工作?
- 如何正确配置该多体系统以实现TMD-I在激励下的正常性能?
- 模型在机械因果性、帧连接或参数设置中存在哪些错误?
问题分析
1. 惯容器连接逻辑错误
当前模型中,idealGearR2T.flangeR同时连接了inertia.flange_a和revolute.axis,导致转动自由度冗余:
- Revolute关节的axis法兰已约束上部质量块的转动,此时将惯容器转动法兰接入,相当于直接固定惯容器的转动自由度,Inertia无法产生转动动力学响应
- 惯容器的转动端应仅受自身Inertia约束,而非被多体关节限制
2. 多体与平移组件接口不匹配
prismatic.axis(多体关节平移法兰)直接连接到idealGearR2T.flangeT(平移组件法兰),存在因果性冲突:
- 多体关节的axis法兰是输出型力/流变量,平移组件法兰是双向接口,直接连接会导致方程求解矛盾,系统自动忽略部分约束,最终导致惯容器失效
3. 可视化组件关联错误
bodyBox.frame_a直接连接到body.frame_a,但body的转动被Revolute关节约束,且惯容器的转动未传递到body,因此BodyBox无法跟随惯容器转动
修复方案
步骤1:修正惯容器转动端连接
移除idealGearR2T.flangeR与revolute.axis的连接,将inertia.flange_b连接到转动固定端(如新增Rotational.Fixed组件),确保惯容器转动端仅受Inertia约束:
// 新增转动固定组件 Modelica.Mechanics.Rotational.Components.Fixed fixedRot annotation( Placement(transformation(origin = {134, 58}, extent = {{-10, -10}, {10, 10}}))); // 修改连接 connect(inertia.flange_b, fixedRot.flange) annotation(Line(points = {{124,58},{134,58}})); // 删除原错误连接:connect(idealGearR2T.flangeR, revolute.axis)
步骤2:修正多体与平移组件接口
使用MultiBody.Interfaces.TranslationalFlange作为中间接口,解决因果性冲突:
// 新增平移接口组件 Modelica.Mechanics.MultiBody.Interfaces.TranslationalFlange transFlange(n={0,1,0}) annotation( Placement(transformation(origin={48,8}, extent={{-5,-5},{5,5}}))); // 重新连接接口 connect(prismatic.axis, transFlange.flange) annotation(Line(points={{48,8},{48,8}})); connect(transFlange.translational, idealGearR2T.flangeT) annotation(Line(points={{48,8},{48,58},{50,58}}));
步骤3:修正BodyBox可视化关联
将bodyBox连接到惯容器的Inertia转动端,实现跟随转动:
// 新增与Inertia关联的转动Body Modelica.Mechanics.MultiBody.Parts.Body inertiaBody(m=0, J={0,13.5,0}, sphereDiameter=0) annotation( Placement(transformation(origin={114,58}, extent={{-10,-10},{10,10}}))); // 连接BodyBox到转动Body connect(bodyBox.frame_a, inertiaBody.frame_a) annotation(Line(points={{98,-30},{98,58},{104,58}})); // 关联Inertia与转动Body的转动自由度 connect(inertia.flange_a, inertiaBody.revolute.flange) annotation(Line(points={{104,58},{104,58}}));
步骤4:调整弹簧初始参数
将springDamper.s_rel0设为0,验证系统在无初始预载下的动态响应
验证要点
- 查看
inertia.phi(转动角度)曲线,确认Inertia产生转动动力学响应 - 查看上部质量块的速度/加速度曲线,确认振荡幅值随时间衰减(阻尼特性)
- 观察BodyBox动画,确认其跟随惯容器转动
- 测试
s_rel0=0的配置,验证系统正常工作
内容的提问来源于stack exchange,提问作者xrp.
相关产品推荐
相关产品推荐

