【问题标题】:How do I pass a variable number of outputs through two functions (MATLAB)?如何通过两个函数(MATLAB)传递可变数量的输出?
【发布时间】:2020-10-15 09:16:28
【问题描述】:

我正在尝试返回可变数量的输出,但有时这些输出必须通过中间函数传递,有时则不需要。 A similar question was asked here but never answered because no specific example was given.

我正在使用 MATLAB 内置的传感器数据收集功能,并不断在手机上记录加速度计数据和 GPS 数据(实际上有 7 种传感器类型,但我为这个问题将其简化为 2 种类型)。使用独特的功能检索此数据。加速度计数据(3个输出数组)从“accellog”内置函数输出,GPS数据(7个输出数组)从“poslog”内置函数输出,其中n是测量次数。

我有两个函数用于从这些数据集中提取数据:

功能1:“GetData”从指定的数据集中提取所有数据。字符串“sensorDataString”指定所请求的数据类型(这是必需的,以便可以为不同的传感器泛化功能)。

function varargout = GetData(mobileObj, sensorDataString)
    switch sensorDataString
        case 'Acceleration'
            [varargout{1:2}] = accellog(mobileObj);
        case 'GPS'
            [varargout{1:7}] = poslog(mobileObj);
    end
end

函数2:“GetSecondsOfData”根据等待指定的时间间隔返回一部分数据集,但首先依赖“GetData”函数来抓取数据。

% Return a set of mobile sensor measurements that span the specified number of seconds
function varargout = GetSecondsOfData(mobileObj, sensorDataString, numSeconds)
    [tempdata, ~] = GetData(mobileObj, sensorDataString);
    startIndx = size(tempdata,1) + 1; % Determine the starting index of measurements

    pause(numSeconds) % Collect data for the specified number of seconds
    varargout = GetData(mobileObj, sensorDataString);
    for i = 1:size(varargout)
        varargout{i} = varargout{i}(startIndx:end,:); % Pull out desired section of data
    end
end

尝试从“GetData”和“GetSecondsOfData”分配可变参数时发生错误。

是否有一种通用的方法可以从一个函数传递可变数量的输出,然后通过调用函数传递这些输出? (或者有没有更好的方法来解决这个问题?)

我可以使用 switch-case 结构来确定“GetSecondsofData”函数中的输出数量,但这对于 7 个传感器来说看起来很混乱。我也可以以不同的形式(单元格数组)输出数据,但是使用 varargout 输出多个变量是最简单的处理方式,特别是因为我有时会使用“GetData”,有时会使用“GetSecondsOfData”,所以我必须分配单元格的输出.

如果您知道输出的数量,您可以使用如下代码:

[varargout{1:7}] = poslog(mobileObj);

我正在寻找看起来更像这样的东西,其中不必指定单元格的数量:

varargout = GetData(mobileObj, sensorDataString);

【问题讨论】:

    标签: matlab arguments


    【解决方案1】:

    好的,这是一个完整的重写,因为我上次似乎没有理解你的实际问题。

    varargout 变量,当它还在被调用函数中时,只是一个元胞数组。当函数返回时,它只会在多个输出中分派。如果处理可变数量的输出参数会给您带来问题,您可以使用相同的方式构造输出(单元格数组),但不要使用varargout,保持单元格数组原样固定个输出(确实有可变数量的元素,但这不会影响你调用函数的方式,只会影响你在收到数据后如何解析它)。

    如果你愿意,你可以添加一些可选的输出信息来帮助以后的解析。

    考虑:

    function [SensorData, SensorDataInfo] = GetData(mobileObj, sensorDataString)
        switch sensorDataString
            
            case 'Acceleration'
                nSensors = 2 ;
                % Simulate your 2 sensors output: [varargout{1:2}] = accellog(mobileObj);
                for k=1:nSensors
                    SensorData{k} = randi(10,10,1) ;
                end
                
            case 'GPS'
                nSensors = 7 ;
                % Simulate your 7 sensors output: [varargout{1:2}] = poslog(mobileObj);
                for k=1:nSensors
                    SensorData{k} = randi(10,10,1) ;
                end
        end
        
        if nargout > 1
            SensorDataInfo.nSensor    = 7 ;
            SensorDataInfo.SensorType = sensorDataString ;
        end
    end
    

    现在您可以始终以相同的方式调用该函数。对于 GPS 数据:

    >> [SensData , SensInfo] = GetData([], 'GPS')
    SensData = 
        [10x1 double]    [10x1 double]    [10x1 double]    [10x1 double]    [10x1 double]    [10x1 double]    [10x1 double]
    SensInfo = 
           nSensor: 7
        SensorType: 'GPS'
    

    或加速度计数据:

    >> [SensData , SensInfo] = GetData([], 'Acceleration')
    SensData = 
        [10x1 double]    [10x1 double]
    SensInfo = 
           nSensor: 2
        SensorType: 'Acceleration'
    

    【讨论】:

    • 使用输出数量设置可变参数本身就是问题所在。如果同时输出 nSensors 和 varargout,您将无法使用 nSensors 数据来指定分配的 varargout 的大小。对吗?
    • 是的,对不起,我第一次没有正确理解您的问题。我重写了答案,提出了另一种解决方法。
    猜你喜欢
    • 2014-06-03
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多