C#调用Matlab ROV数学模型时遇mod函数错误求助
C#调用Matlab ROV模型报错排查
我在Matlab 2022a中搭建了一套ROV(遥控潜水器)数学模型,想要在Visual Studio 2022的C#程序中调用该模型,实现参数传递与结果复用。但运行C#程序时出现调用失败的错误,尝试过检查路径、确认mod函数授权等方案,均无法解决问题。
C#调用代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WayPointModel { public class ROV { public static Data ROVmini(double[] x, double[] tau, double[] vCurrNed) { object[] x1 = x.Select(d => (object)d).ToArray(); object[] tau1 = tau.Select(d => (object)d).ToArray(); object[] vCurrNed1 = vCurrNed.Select(d => (object)d).ToArray(); MLApp.MLApp matlab = new MLApp.MLApp(); matlab.Execute(@"cd C:\Users\abdhab\Documents\MATLAB\DP\1DautodepthTest"); object result = null; matlab.Feval("ARSmini", 2, out result, x1, tau1, vCurrNed1); double[] res = result as double[]; double[] xDot = res[..12]; double[] vCurrBody = res[11..]; return new Data { xDot = xDot, vCurrBody = vCurrBody }; } } }
Matlab函数代码
function [xdot, v_curr_body] = ARSmini(x, tau, v_curr_ned) if (length(x) ~= 12),error('x-vector must have dimension 12!'); end if (length(tau) ~= 6),error('tau-vector must have dimension 6!'); end nu = x(1:6); u = nu(1); v = nu(2); w = nu(3); p = nu(4); q = nu(5); %nu(6) = 0.1; r = nu(6); eta = x(7:12); phi = mod(eta(4),2*pi); theta = mod(eta(5),2*pi); psi = mod(eta(6),2*pi); tau_u = tau(1); tau_v = tau(2); tau_w = tau(3); tau_p = tau(4); tau_q = tau(5); %tau(6)=0.01; tau_r = tau(6); if (nargin == 2) v_curr_ned = [0 0 0]'; else R_n_b = Rzyx(phi, theta, psi)'; v_curr_body = R_n_b*v_curr_ned; end nu_r = nu - [v_curr_body' 0 0 0]'; M_RB = [... 90 0 0 0 0 0 0 90 0 0 0 0 0 0 90 0 0 0 0 0 0 10 0 0 0 0 0 0 15 0 0 0 0 0 0 13]; M_A = [... 54 0 0 0 0 0 0 72 0 0 0 0 0 0 360 0 0 0 0 0 0 11 0 0 0 0 0 0 43.5 0 0 0 0 0 0 5.2]; M = M_RB + M_A; D_lin = [... 250 0 0 0 0 0 0 200 0 0 0 0 0 0 175 0 0 0 0 0 0 20 0 0 0 0 0 0 20 0 0 0 0 0 0 15]; D_n = [... 350*abs(nu_r(1)) 0 0 0 0 0 0 350*abs(nu_r(2)) 0 0 0 0 0 0 400*abs(nu_r(3)) 0 0 0 0 0 0 100*abs(nu_r(4)) 0 0 0 0 0 0 100*abs(nu_r(5)) 0 0 0 0 0 0 75*abs(nu_r(6))]; D = D_lin + D_n; W = 90*9.81; B = W/0.99; r_bg = [0 0 0.18]; r_bb = [0 0 0]; g = gvect(W, B, theta, phi, r_bg, r_bb); C = [... 0 0 0 0 450*nu_r(3) -162*nu_r(2) 0 0 0 -450*nu_r(3) 0 144*nu_r(1) 0 0 0 162*nu_r(2) -144*nu_r(1) 0 0 450*nu_r(3) -162*nu_r(2) 0 18.2*nu_r(6) -66.5*nu_r(5) -450*nu_r(3) 0 144*nu_r(1) -18.2*nu_r(6) 0 21*nu_r(4) 162*nu_r(2) -144*nu_r(1) 0 66.5*nu_r(5) -21*nu_r(4) 0]; J = eulerang(eta(4),eta(5),eta(6)); area_rov = [0.65*0.5; 0.9*0.5; 0.9*0.65]; cd = [1.05; 1.05; 1.75]; f_curr = 0.5 * 1000.*area_rov.*nu_r(1:3).*abs(nu_r(1:3)).*cd; xdot = zeros(12,1); xdot = [... M \ (tau - D * nu - g - C*nu_r - [f_curr;0 ; 0 ;0]) J * nu];% + [v_curr_ned' 0 0 0]'; end
可能的解决方向
- 检查Matlab依赖函数:Matlab函数中调用了
Rzyx、gvect、eulerang三个自定义函数,必须确保这些函数和ARSmini.m在同一目录下,或者已添加到Matlab的搜索路径中,否则会因找不到函数报错。 - 修正参数传递格式:C#传递的数组是行向量,而Matlab中默认处理列向量,建议在Matlab函数开头添加:
确保输入参数统一为列向量格式。x = x(:); tau = tau(:); v_curr_ned = v_curr_ned(:); - 修复返回值处理逻辑:Matlab返回的
result是包含两个二维数组的object[],而非一维double[],原C#代码的类型转换会失败,需修改为:object[] results = result as object[]; double[,] xDotMat = results[0] as double[,]; double[] xDot = Enumerable.Range(0, xDotMat.Length).Select(i => xDotMat[i / xDotMat.GetLength(1), i % xDotMat.GetLength(1)]).ToArray(); double[,] vCurrBodyMat = results[1] as double[,]; double[] vCurrBody = Enumerable.Range(0, vCurrBodyMat.Length).Select(i => vCurrBodyMat[i / vCurrBodyMat.GetLength(1), i % vCurrBodyMat.GetLength(1)]).ToArray(); - 优化Matlab实例管理:每次调用新建
MLApp实例可能导致资源冲突,建议复用实例,或调用后通过matlab.Quit()关闭进程。 - 权限验证:确保C#程序拥有访问Matlab安装目录和脚本目录的权限,关闭UAC限制或以管理员身份运行程序。
内容的提问来源于stack exchange,提问作者A.H
相关产品推荐
相关产品推荐

