在 MATLAB 中使用 UI 表时出现错误“无法从字符串转换为逻辑”

问题描述 投票:0回答:1

我正在尝试构建一个应用程序,该应用程序收集连续数据并校准,然后在应用程序轴上显示该数据并将数据写入基础工作区,以便可以进一步操作。我希望能够打开和关闭通道,并且能够“打开”或“关闭”每个单独通道的校准。目前,我正在努力让每个通道能够打开和关闭其校准。

我使用以下函数来制作并允许我的 UI 表格可编辑。

function UpdateUITable(app, subsystem)
         % Return the initial logical values for checkboxes
    app.IndvCal = false(size(subsystem.ChannelNames));
    
    %Channels = cellstr(string(subsystem.ChannelNames));
    app.Channels = string(subsystem.ChannelNames);
    % Create a cell array with channel names and logical values for the checkboxes
    UIData = [app.Channels, app.IndvCal];
    % Set the CellEditCallback for the UITable
    app.UITable.Data = UIData;
end
function UITableCellEdit(app, event)
    indices = event.Indices;
    newData = event.NewData;
    % Update the logical array based on checkbox changes
    app.IndvCal(indices(1)) = newData;
    % Update the selected channels variables
    app.SelectedCal = app.Channels(app.IndvCal);
    app.SelectedChannels = app.Channels(indices(1));
    % Call the function that uses the selected channels (e.g., data calibration)
    updateChannelMeasurementComponents(app)
end

我使用这些值来确定我拥有的哪些数据将使用以下函数进行校准。我收到此逻辑字符串错误,但我不确定原因。我希望所选的通道显示在我的图表中

function updateLivePlot(app)
   % Update the live plot
   if isempty(app.DataFIFOBufferch1) || isempty(app.SelectedChannels)
       return
   end
   % Disable interactivity
   disableDefaultInteractivity(app.LiveAxes);
   % Keep the colors the same after each new data point
   app.LiveAxes.ColorOrderIndex = 1;
   if isempty(app.LivePlotLine)
       % First-Time Setup
       app.LivePlotLine = plot(app.LiveAxes, app.TimestampsFIFOBuffer, app.DataFIFOBufferch1(:, app.SelectedChannels));
   else
       % Update existing plot
       for j = 1:numel(app.SelectedChannels)
           % Check if the line needs to be extended
           if numel(app.LivePlotLine) < j || isempty(app.LivePlotLine(j))
               % Use existing axes to plot
               app.LivePlotLine(j) = plot(app.LiveAxes, app.TimestampsFIFOBuffer, app.DataFIFOBufferch1(:, app.SelectedChannels(j,1)));
           else
               % Update existing line
               set(app.LivePlotLine(j), 'XData', app.TimestampsFIFOBuffer, 'YData', app.DataFIFOBufferch1(:, app.SelectedChannels(j,1)));
           end
       end
   end
   if numel(app.TimestampsFIFOBuffer) > 1
       xlim(app.LiveAxes, [app.TimestampsFIFOBuffer(1), app.TimestampsFIFOBuffer(end)]);
   end
end

并且该图根据以下函数绘制了校准数据和原始数据。数据连续输入所有功能,并且当在 UI 表中选择通道时(理论上)会改变图表上显示的内容。我想知道是否应该在 UI 表中添加另一列,该列可以是另一个逻辑,可以跟踪通道是否关闭并保持校准逻辑?

unction calibratedData = calibrateData(app,data, slopes, intercepts)
% Calibrate the data using slopes and intercepts
calibratedData = data;
for j = 1:numel(app.SelectedChannels)
    if app.SelectedChannels(j,1) == true 
        calibratedData(:,j) = calibratedData(:,j) * slopes(:,j) + intercepts(:,j);
    elseif app.SelectedChannels(j,1) == false
        calibratedData = app.data; 
        app.TimewindowEditField.Value = 10;
    else
        calibratedData = app.data; 
    end
end
end

我的startupFCn中也有以下内容

app.UITable.ColumnFormat = {'char', 'logical'};
app.UITable.ColumnEditable = [true, true];

谢谢

logical-operators indices matlab-app-designer matlab-uitable
1个回答
0
投票

对于处理实时数据收集、校准和可视化的动态应用程序来说,您的方法似乎结构良好。包括打开或关闭单个通道校准的功能是一项细致入微的功能,可增强用户对所呈现数据的控制。为了解决您在打开和关闭每个通道校准时遇到的困难,让我们通过一些建议来完善您的策略:

1. UI表结构

除了跟踪校准之外,在 UI 表中添加另一列来跟踪通道是打开还是关闭是一个好主意。这将使用户能够清晰地控制每个通道的可见性和校准状态。您的表格将包含三列:

  • 频道名称(不可编辑文本)
  • 校准(可编辑布尔值)
  • 可见性(可编辑布尔值)

2.更新
UpdateUITable
功能

修改您的

UpdateUITable
函数以初始化并填充这个新的可见性列。

function UpdateUITable(app, subsystem)
    % Initialize visibility and calibration logical arrays
    app.IndvCal = false(size(subsystem.ChannelNames));
    app.ChannelVisibility = true(size(subsystem.ChannelNames)); % Assuming you want all channels visible by default
    
    app.Channels = string(subsystem.ChannelNames);
    
    % Create a cell array with channel names, calibration, and visibility values
    UIData = [app.Channels, app.IndvCal, app.ChannelVisibility];
    
    % Update the UITable data
    app.UITable.Data = UIData;
end

3.处理表格单元格编辑

您的

UITableCellEdit
函数需要区分对校准列和可见性列所做的编辑。使用
indices
参数确定编辑了哪一列。

4.修改
updateLivePlot
功能

在绘图函数中,您应该考虑每个通道的校准状态和可见性状态。仅绘制标记为可见的通道的数据。绘图时,检查每个通道的校准状态并根据需要进行校准。

5.校准逻辑

在您的

calibrateData
函数中,您尝试基于布尔标志应用校准,但逻辑似乎略有偏差。您应该迭代每个通道,检查是否选择它进行校准,然后应用相应的斜率和截距(如果是)。

这是您可以如何处理它的简化版本:

function calibratedData = calibrateData(app, data, slopes, intercepts)
    % Initialize calibrated data array
    calibratedData = data;
    
    for j = 1:numel(app.SelectedChannels)
        if app.IndvCal(j) % Check if calibration is enabled for this channel
            % Apply calibration
            calibratedData(:,j) = data(:,j) * slopes(j) + intercepts(j);
        end
        % Note: No need for an 'else' block if we're not changing data for non-calibrated channels
    end
end

如果

slopes
intercepts
是数组,请确保它们的索引正确。

6.考虑持续数据更新

对于处理连续数据更新的应用程序,请确保您的数据结构(如 FIFO 缓冲区)和绘图更新机制针对性能进行了优化。这包括最大限度地减少复制或移动的数据,并有效地更新绘图数据点,而不是重新绘制整个绘图。

最后的想法

调整您的应用程序以区分通道可见性和校准状态将显着提高其灵活性。始终牢记用户体验,确保 UI 直观且响应灵敏。彻底测试您的应用程序,尤其是实时数据处理和 UI 交互部分,以微调性能和可用性。

© www.soinside.com 2019 - 2024. All rights reserved.