My for loop calculating heading seems to be outputting only zeros to the table in app designer, not sure why

1 次查看(过去 30 天)
app.comb in a combined x by 8 table. the heading table was created to store the heading calculation result of each row in the app.comb table. When the heading table is used later it only had zeros in it, suggesting the for loop wasn't read.
Not sure what the problem is, guessing it's an oversight.
app.headingtable = table('Size',[height(app.comb) 1],'VariableTypes',{'double'});
for i = 1:1:height(app.comb)
app.bow_easting = str2double(app.comb(i,3));
app.stern_easting = str2double(app.comb(i,7));
app.bow_northing = str2double(app.comb(i,4));
app.stern_northing = str2double(app.comb(i,8));
app.heading = atan2d(((app.bow_northing)-(app.stern_northing)),((app.bow_easting)-(app.stern_easting))); %heading calc using atan2
if app.heading > 0
app.headingtable(i,1) = 360 - (app.heading - 90);
elseif app.heading < 0 %if loop to bring atan2 result into heading terms
app.headingtable(i,1) = 90 - app.heading;
elseif app.heading == 0
app.headingtable(i,1) = 90;
end
end

采纳的回答

Voss
Voss 2022-2-11
编辑:Voss 2022-2-11
I believe the problem is that none of the conditions in the if/elseif/elseif block are ever true, so app.headingtable doesn't get updated.
The reason none of the conditions are true is that app.heading is always NaN (and comparing NaN to 0 is always false, i.e., NaN > 0, NaN < 0, and NaN == 0 are all false).
The reason app.heading is always NaN is that app.bow_easting, app.stern_easting, app.bow_northing, app.stern_northing are all always NaN.
The reason those are NaN is because indexing a table using parentheses gives you another table (i.e., a sub-table of the table being indexed) rather than the contents of the table, and str2double() on a table returns NaN. You should use curly brace indexing to get the contents of the table.
A few simple tests follow.
(I don't know what class(es) the data in the table app.comb is, but it looks like it's probably strings or character arrays based on the fact that you use str2double() on it. If instead it is numeric class(es), then you should omit str2double(). In either case, however, you should index app.comb with curly braces {} in order to get its contents.)
data = randn(10,8);
% a table with numeric data:
comb_num = array2table(data);
comb_num
comb_num = 10×8 table
data1 data2 data3 data4 data5 data6 data7 data8 _________ _________ ________ _________ ________ _________ _______ ________ -1.7478 -1.2755 -0.51834 -0.45398 -1.0332 1.4273 1.0947 0.51786 -0.014236 -0.18733 2.3808 1.0227 -1.7086 -0.24865 1.1064 -1.4645 -0.6451 -0.019395 0.53902 -0.48537 2.1271 1.2442 0.11351 -0.72802 -0.19405 0.33435 0.094783 -0.010012 0.71856 0.011306 0.76556 0.05861 1.04 -0.77334 0.56971 -0.45208 0.72484 1.9849 0.88378 -0.20397 1.522 0.47177 -0.46697 1.6271 -0.21198 -0.71522 1.2388 0.32256 1.1103 -0.1057 -1.533 0.087088 -0.64538 0.0075652 -1.5311 -0.40956 1.0623 -0.22408 0.016705 -0.060793 -0.67937 1.1481 -1.2928 -1.6002 0.42895 1.8445 0.039137 -1.3365 -0.96699 0.24401 -1.3933 -1.0872 0.17691 1.6486 -0.4502 -1.9596 0.81952 -0.95567 -1.726 1.8408
% a table with character array data:
comb_char = cell2table(arrayfun(@num2str,data,'UniformOutput',false));
comb_char
comb_char = 10×8 table
Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 _____________ _____________ ____________ _____________ ____________ _____________ ___________ ____________ {'-1.7478' } {'-1.2755' } {'-0.51834'} {'-0.45398' } {'-1.0332' } {'1.4273' } {'1.0947' } {'0.51786' } {'-0.014236'} {'-0.18733' } {'2.3808' } {'1.0227' } {'-1.7086' } {'-0.24865' } {'1.1064' } {'-1.4645' } {'-0.6451' } {'-0.019395'} {'0.53902' } {'-0.48537' } {'2.1271' } {'1.2442' } {'0.11351'} {'-0.72802'} {'-0.19405' } {'0.33435' } {'0.094783'} {'-0.010012'} {'0.71856' } {'0.011306' } {'0.76556'} {'0.05861' } {'1.04' } {'-0.77334' } {'0.56971' } {'-0.45208' } {'0.72484' } {'1.9849' } {'0.88378'} {'-0.20397'} {'1.522' } {'0.47177' } {'-0.46697'} {'1.6271' } {'-0.21198'} {'-0.71522' } {'1.2388' } {'0.32256' } {'1.1103' } {'-0.1057' } {'-1.533' } {'0.087088' } {'-0.64538'} {'0.0075652'} {'-1.5311'} {'-0.40956'} {'1.0623' } {'-0.22408' } {'0.016705'} {'-0.060793'} {'-0.67937'} {'1.1481' } {'-1.2928'} {'-1.6002' } {'0.42895' } {'1.8445' } {'0.039137'} {'-1.3365' } {'-0.96699'} {'0.24401' } {'-1.3933'} {'-1.0872' } {'0.17691' } {'1.6486' } {'-0.4502' } {'-1.9596' } {'0.81952' } {'-0.95567' } {'-1.726' } {'1.8408' }
% indexing with () on a table returns another table:
comb_num(1,1)
ans = table
data1 _______ -1.7478
comb_char(1,1)
ans = table
Var1 ___________ {'-1.7478'}
% indexing with {} on a table returns the contents:
comb_num{1,1}
ans = -1.7478
comb_char{1,1}
ans = 1×1 cell array
{'-1.7478'}
% str2double on a table returns NaN:
str2double(comb_num(1,1))
ans = NaN
str2double(comb_char(1,1))
ans = NaN
% str2double on a numeric type returns NaN:
str2double(comb_num{1,1})
ans = NaN
% str2double on a string or character array is ok:
str2double(comb_char{1,1})
ans = -1.7478
So the solution is to change your table indexing from () to {} (and omit str2double() if the comb table already contains numerics):
app.comb = comb_char;
app.headingtable = table('Size',[height(app.comb) 1],'VariableTypes',{'double'});
for i = 1:1:height(app.comb)
app.bow_easting = str2double(app.comb{i,3});
app.stern_easting = str2double(app.comb{i,7});
app.bow_northing = str2double(app.comb{i,4});
app.stern_northing = str2double(app.comb{i,8});
app.heading = atan2d(((app.bow_northing)-(app.stern_northing)),((app.bow_easting)-(app.stern_easting))); %heading calc using atan2
if app.heading > 0
app.headingtable{i,1} = 360 - (app.heading - 90);
elseif app.heading < 0 %if loop to bring atan2 result into heading terms
app.headingtable{i,1} = 90 - app.heading;
elseif app.heading == 0
app.headingtable{i,1} = 90;
end
end
app.headingtable
ans = 10×1 table
Var1 ______ 238.93 387.13 420.31 264.16 231.69 307.41 359.78 400.39 99.873 161.44
(or, in case app.comb contains numeric type data:)
app.comb = comb_num;
app.headingtable = table('Size',[height(app.comb) 1],'VariableTypes',{'double'});
for i = 1:1:height(app.comb)
app.bow_easting = app.comb{i,3};
app.stern_easting = app.comb{i,7};
app.bow_northing = app.comb{i,4};
app.stern_northing = app.comb{i,8};
app.heading = atan2d(((app.bow_northing)-(app.stern_northing)),((app.bow_easting)-(app.stern_easting))); %heading calc using atan2
if app.heading > 0
app.headingtable{i,1} = 360 - (app.heading - 90);
elseif app.heading < 0 %if loop to bring atan2 result into heading terms
app.headingtable{i,1} = 90 - app.heading;
elseif app.heading == 0
app.headingtable{i,1} = 90;
end
end
app.headingtable
ans = 10×1 table
Var1 ______ 238.93 387.13 420.31 264.16 231.69 307.41 359.78 400.39 99.873 161.44
And for what it's worth you probably don't need to be storing the variables bow/stern_easting/northing and heading as fields in your app structure; they can just be regular local variables since they get overwritten each time through the loop anyway. Seems like app.headingtable is the only one that needs to be used later so it can stay as a field in the app structure. For instance:
app.comb = comb_num;
app.headingtable = table('Size',[height(app.comb) 1],'VariableTypes',{'double'});
for i = 1:1:height(app.comb)
heading = atan2d(app.comb{i,4}-app.comb{i,8},app.comb{i,3}-app.comb{i,7}); %heading calc using atan2
if heading > 0
app.headingtable{i,1} = 360 - (heading - 90);
elseif heading < 0 %if loop to bring atan2 result into heading terms
app.headingtable{i,1} = 90 - heading;
elseif heading == 0
app.headingtable{i,1} = 90;
end
end
app.headingtable
ans = 10×1 table
Var1 ______ 238.93 387.13 420.31 264.16 231.69 307.41 359.78 400.39 99.873 161.44

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Matrix Indexing 的更多信息

产品


版本

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by