OpenModelica船舶装卸龙门架小车逆模型编译报错求助
港口龙门架小车驱动系统逆Modelica模型编译报错问题
背景
研究船舶装卸龙门架小车X轴驱动系统:龙门架在码头轨道移动,承载32吨起重机小车,可起吊50吨载荷,仅关注X轴运动。已完成正向模型(输入电机扭矩,输出小车运动),但逆模型(输入小车速度曲线,输出电机转速)编译报错。
正向模型代码
model chariot_portique constant Real rpm_max = 1450.0; constant Real v_max = 3.0; Modelica.Mechanics.Rotational.Components.IdealGearR2T idealGearR2T(ratio = (rpm_max*2*Modelica.Constants.pi/60)/v_max) annotation( Placement(visible = true, transformation(origin = {28, -36}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Modelica.Mechanics.Rotational.Components.LossyGear lossyGear(lossTable = [0, 0.8, 0.8, 0, 0], ratio = 1) annotation( Placement(visible = true, transformation(origin = {-6, -36}, extent = {{-10, -10}, {10, 10}}, rotation = 0))); Modelica.Mechanics.Translational.Components.Mass mass(m = 82000) annotation( Placement(transformation(origin = {98, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Blocks.Sources.CombiTimeTable combiTimeTable(extrapolation = Modelica.Blocks.Types.Extrapolation.HoldLastPoint, table = [0, 0; 0, 1520; 4, 1520; 4, 0; 8, 0; 8, -974; 12, -974; 12, 0; 16, 0; 16, -1520; 20, -1520; 20, 0; 24, 0; 24, 974; 28, 974; 28, 0; 32, 0], tableOnFile = false) annotation( Placement(transformation(origin = {-40, -66}, extent = {{-80, 20}, {-60, 40}}))); Modelica.Mechanics.Rotational.Sources.Torque torque annotation( Placement(transformation(origin = {-74, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Rotational.Sensors.MultiSensor multiSensor_moteur annotation( Placement(transformation(origin = {-38, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Sensors.MultiSensor multiSensor_chariot annotation( Placement(transformation(origin = {64, -36}, extent = {{-10, -10}, {10, 10}}))); equation connect(lossyGear.flange_b, idealGearR2T.flangeR) annotation( Line(points = {{4, -36}, {18, -36}})); connect(combiTimeTable.y[1], torque.tau) annotation( Line(points = {{-99, -36}, {-86, -36}}, color = {0, 0, 127})); connect(torque.flange, multiSensor_moteur.flange_a) annotation( Line(points = {{-64, -36}, {-48, -36}})); connect(multiSensor_moteur.flange_b, lossyGear.flange_a) annotation( Line(points = {{-28, -36}, {-16, -36}})); connect(idealGearR2T.flangeT, multiSensor_chariot.flange_a) annotation( Line(points = {{38, -36}, {54, -36}}, color = {0, 127, 0})); connect(mass.flange_a, multiSensor_chariot.flange_b) annotation( Line(points = {{88, -36}, {74, -36}}, color = {0, 127, 0})); annotation( experiment(StopTime = 32), uses(Modelica(version = "4.0.0")), Diagram(coordinateSystem(extent = {{-200, -100}, {200, 100}})), Icon(coordinateSystem(extent = {{-200, -100}, {200, 100}})), version = "", __OpenModelica_simulationFlags(lv = "LOG_STDOUT,LOG_ASSERT,LOG_STATS", s = "dassl", variableFilter = ".*")); end chariot_portique;
逆模型代码
model chariot_portique_inverse constant Real rpm_max = 1450.0; constant Real v_max = 3.0; Modelica.Blocks.Sources.CombiTimeTable combiTimeTable( table = [0, 0; 4, 3; 8, 3; 12, 0; 16, 0; 20, -3; 24, -3; 28, 0; 32, 0], tableOnFile = false) annotation( Placement(transformation(origin = {92, -66}, extent = {{80, 20}, {60, 40}}, rotation = -0))); Modelica.Mechanics.Translational.Sensors.MultiSensor multiSensor_chariot annotation( Placement(transformation(origin = {60, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Rotational.Components.IdealGearR2T idealGearR2T(ratio = (rpm_max*2*Modelica.Constants.pi/60)/v_max) annotation( Placement(transformation(origin = {28, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Rotational.Components.LossyGear lossyGear(lossTable = [0, 0.8, 0.8, 0, 0], ratio = 1) annotation( Placement(transformation(origin = {-6, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Sources.Speed speed(exact = true) annotation( Placement(transformation(origin = {126, -36}, extent = {{10, -10}, {-10, 10}}))); Modelica.Mechanics.Rotational.Sensors.MultiSensor multiSensor_moteur annotation( Placement(transformation(origin = {-44, -36}, extent = {{-10, -10}, {10, 10}}))); Modelica.Mechanics.Translational.Components.Mass mass(m = 82000, s(start = 0), v(start = 0), a(start = 0)) annotation( Placement(transformation(origin = {90, -36}, extent = {{-10, -10}, {10, 10}}))); equation connect(lossyGear.flange_b, idealGearR2T.flangeR) annotation( Line(points = {{4, -36}, {18, -36}})); connect(multiSensor_moteur.flange_b, lossyGear.flange_a) annotation( Line(points = {{-34, -36}, {-16, -36}})); connect(idealGearR2T.flangeT, multiSensor_chariot.flange_a) annotation( Line(points = {{38, -36}, {50, -36}}, color = {0, 127, 0})); connect(combiTimeTable.y[1], speed.v_ref) annotation( Line(points = {{152, -36}, {138, -36}}, color = {0, 0, 127})); connect(mass.flange_a, multiSensor_chariot.flange_b) annotation( Line(points = {{80, -36}, {70, -36}}, color = {0, 127, 0})); connect(mass.flange_b, speed.flange) annotation( Line(points = {{100, -36}, {116, -36}}, color = {0, 127, 0})); annotation( experiment(StopTime = 32), uses(Modelica(version = "4.0.0")), Diagram(coordinateSystem(extent = {{-200, -100}, {200, 100}})), Icon(coordinateSystem(extent = {{-200, -100}, {200, 100}})), version = "", __OpenModelica_simulationFlags(lv = "LOG_STDOUT,LOG_ASSERT,LOG_STATS", s = "dassl", variableFilter = ".*")); end chariot_portique_inverse;
编译错误信息
仿真进程失败,退出代码0xffffffffffffffff。 在时间t=0时求解非线性系统47失败。如需更多信息,请使用-lv LOG_NLS。 仿真因初始化时的断言终止 同伦求解器全主元:初始化时矩阵(接近)奇异。 仍继续执行。如需更多信息,请使用-lv LOG_NLS_V。 欠定线性系统无法求解! 同伦求解器全主元:初始化时矩阵(接近)奇异。 欠定线性系统无法求解! 同伦求解器全主元:初始化时矩阵(接近)奇异。 欠定线性系统无法求解! 非线性系统47求解失败:t=0 为以下部分迭代变量设置合适的初始值可能有所帮助
问题原因
- 系统欠定,约束不足:逆模型仅在平移端添加了
Speed驱动源,但旋转端(lossyGear、multiSensor_moteur)处于自由状态,无任何驱动或约束,导致系统存在冗余自由度,求解时矩阵奇异。 - 初始化缺失:仅给
Mass设置了初始值,但旋转侧的角度、转速等变量未设置初始约束,加剧了初始化阶段的求解难度。
解决办法
方案1:运动学逆解(推荐,高效无冗余)
直接通过齿轮运动学比例关系,从小车速度计算电机转速,无需保留动力学组件:
model chariot_portique_inverse_fixed constant Real rpm_max = 1450.0; constant Real v_max = 3.0; constant Real gear_ratio = (rpm_max*2*Modelica.Constants.pi/60)/v_max; // 电机转速与小车速度的比例 Modelica.Blocks.Sources.CombiTimeTable combiTimeTable( table = [0, 0; 4, 3; 8, 3; 12, 0; 16, 0; 20, -3; 24, -3; 28, 0; 32, 0], tableOnFile = false ) annotation(Placement(transformation(origin = {92, -66}, extent = {{80, 20}, {60, 40}}))); Modelica.Mechanics.Translational.Sources.Speed speed(exact = true) annotation( Placement(transformation(origin = {126, -36}, extent = {{10, -10}, {-10, 10}}))); Modelica.Mechanics.Translational.Components.Mass mass(m = 82000, s(start = 0), v(start = 0)) annotation( Placement(transformation(origin = {90, -36}, extent = {{-10, -10}, {10, 10}}))); // 增益模块实现运动学比例转换 Modelica.Blocks.Math.Gain gearGain(k = gear_ratio) annotation( Placement(transformation(origin = {-20, -36}, extent = {{-10, -10}, {10, 10}}))); // 观测电机转速 Modelica.Blocks.Sinks.Scope motorSpeedScope annotation( Placement(transformation(origin = {-60, -36}, extent = {{-20, -20}, {20, 20}}))); equation connect(combiTimeTable.y[1], speed.v_ref) annotation( Line(points = {{152, -36}, {138, -36}}, color = {0, 0, 127})); connect(mass.flange_b, speed.flange) annotation( Line(points = {{100, -36}, {116, -36}}, color = {0, 127, 0})); // 从小车实际速度计算电机转速 connect(speed.v_actual, gearGain.u) annotation( Line(points = {{116, -36}, {0, -36}}, color = {0, 0, 127})); connect(gearGain.y, motorSpeedScope.u[1]) annotation( Line(points = {{-10, -36}, {-40, -36}}, color = {0, 0, 127})); annotation( experiment(StopTime = 32), uses(Modelica(version = "4.0.0"))); end chariot_portique_inverse_fixed;
方案2:保留动力学结构,补充约束与初始值
若需保留原动力学组件,需给旋转侧变量添加初始值并闭合约束环:
- 给
lossyGear的法兰添加初始角度和转速:lossyGear.flange_a.phi(start=0), lossyGear.flange_a.w(start=0) - 给
multiSensor_moteur的对应变量设置初始值 - 确保旋转端无自由自由度,可添加虚设的转速约束或反馈
关键提示
- 若仅需运动学逆解(从轨迹反推电机转速),优先用方案1,避免动力学组件带来的求解复杂度
- 若需动力学逆解(从轨迹反推所需电机扭矩),需确保系统是闭环结构,平移端的约束能传递到旋转端,同时旋转端需有对应的动力学反馈
内容的提问来源于stack exchange,提问作者scls
相关产品推荐
相关产品推荐

