MATLAB使用lsqnonlin优化时迭代显示数值及自定义绘图传参问询
替代全局变量的3种可行实现方案
- 方案1:使用嵌套函数封装参数(最推荐)
将你修改后的骨骼绘图逻辑直接写在调用lsqnonlin的主函数内部作为嵌套函数,嵌套函数可以直接访问父函数工作区的所有变量,包括骨骼模型参数、正向运动学函数、原始参考数据等,不需要额外修改入参格式。示例结构如下:
function main_optimization(skeleton_model, raw_joint_data, fk_func) % 主函数内的参数,嵌套函数可直接访问 options = optimoptions('lsqnonlin','PlotFcn',@custom_skeleton_plot); % 调用lsqnonlin执行优化 lsqnonlin(@objective_func, init_theta, [], [], options); % 嵌套的绘图函数,入参严格符合优化器要求 function stop = custom_skeleton_plot(x, optimValues, state) stop = false; % 直接用父函数的fk_func和skeleton_model计算关节位置 joint_pos = fk_func(x, skeleton_model); % 这里写你自己的骨骼绘制逻辑:画原始数据、画当前迭代的刚体模型 plot3(raw_joint_data(:,1), raw_joint_data(:,2), raw_joint_data(:,3), 'b.'); hold on; plot_skeleton(joint_pos, 'r'); hold off; end % 目标函数也可以用嵌套函数,同样不需要传额外参数 function res = objective_func(theta) model_pos = fk_func(theta, skeleton_model); res = model_pos(:) - raw_joint_data(:); end end
- 方案2:使用匿名函数做参数绑定
如果你已经把绘图逻辑写成了独立的m文件(比如改名为optimplot_skeleton.m,入参除了固定的x, optimValues, state外新增了模型、正向函数等参数),可以通过匿名函数将额外参数绑定后再传给PlotFcn,不需要修改优化器调用规则:
% 提前定义好你的模型参数和正向函数 skeleton_model = % 你的骨骼参数 fk_func = @your_forward_kinematics; raw_data = % 你的原始关节数据 % 匿名函数接收优化器的三个固定入参,自动传入额外参数 my_plotfcn = @(x, optimValues, state) optimplot_skeleton(x, optimValues, state, skeleton_model, fk_func, raw_data); % 配置选项 options = optimoptions('lsqnonlin','PlotFcn',my_plotfcn);
- 方案3:使用持久变量(比全局变量更安全)
如果你的绘图函数是独立m文件,不想用嵌套或匿名函数,可以在绘图函数内定义持久变量存储模型参数,仅在第一次调用时赋值:
function stop = optimplot_skeleton(x, optimValues, state) persistent skeleton_model fk_func raw_data stop = false; % 仅在迭代初始化阶段赋值一次 if strcmp(state,'init') % 从base工作区获取参数,或者你也可以改成其他赋值方式 skeleton_model = evalin('base','skeleton_model'); fk_func = evalin('base','fk_func'); raw_data = evalin('base','raw_data'); end % 后续迭代直接用持久变量计算绘图即可 joint_pos = fk_func(x, skeleton_model); % 绘图逻辑省略 end
注意每次重新跑优化前要执行clear optimplot_skeleton清空持久变量,避免残留上一次的参数。
额外注意事项
如果是逐帧执行优化,每帧切换时要对应更新传入绘图函数的原始数据和模型初始状态,避免用前一帧数据错绘。迭代绘图时建议每次先清空当前坐标轴再绘制,避免多轮迭代的结果重叠导致观察困难。
内容的提问来源于stack exchange,提问作者Evan
相关产品推荐
相关产品推荐

