Array indices must be positive integers or logical values.

I am writing a program to simulate an F1 car laptime. Imagibe the car has come out of a corner and is accelerating doen a straight until it has to brake for the next corner. The times for this acceleration and deceleration have to be counted seperately as they are governed by seperate functions. There is a part of the code where the time taken to accelerate on a staright (t1) has to be reset to 0 to then start the the clock for the time taken to decelerate for the upcoming corner (t2) to be counted. I keep getting the same error "Array indices must be positive integers or logical values." no matter what i do.
% Calculate the straights
strTimes = zeros(num_str,1);
sLap = zeros(nseg*nds,1); %sLap = distance around lap
vCar = zeros(nseg*nds,1); %vCar = velocity of car around lap
str = 1;
smax = 0;
for i=1:nseg
rad = track(i,2);
dist = track(i,1);
s = linspace(0,dist,nds)'; %nds = 500 (no. of iterations)
nstart = ((i-1)*nds+1);
nend = (i*nds);
sLap(nstart:nend) = smax + s;
smax = max(sLap);
% Straight
if rad == 0
ds = s(2)-s(1);
% Corner segment numbers
pcsn = i-1; %previous corner segment number
ncsn = i+1; %next corner segment number
if pcsn < 1
pcsn = max(cnrNum);
end
if ncsn>nseg
ncsn = min(cnrNum);
end
pcn = find(pcsn==cnrNum);
ncn = find(ncsn==cnrNum);
[Va,P,G,WE,t1] = calc_acceleration(nds,rho,cd,A,m,s,Rw,cnrVel(pcn));
[Vd,t2] = calc_deceleration(ds,cnrVel(ncn),nds,rho,A,cd,m,cz);
[V,I] = min([Va,Vd],[],2);
vCar(nstart:nend) = V;
% Reset the clock for the braking time, ncn = next corner number
%cnrVel = corner velocity, t1 = acceleration time
%t2 = deceleration time
if max(V) > cnrVel(ncn)
ta = t1(I==3);
tb = t2(I==3);
tb = tb+(ta(end)-tb(1));
t = [ta;tb];
else
t = t1;
end
strTimes(str) = max(t);
str = str+1;
else
vCar(nstart:nend) = ones(nds,1)*cnrVel(i==cnrNum);
end
end

6 Comments

Use the debugging tools to find the line on which the error is, then look at the relevant components on the command line. You will very quickly find where the problem is. Just glancing at code here though it is almost impossible since there isn't a blindingly obvious loop from 0 or the kind of thing people often do like that and then use as an index into an array.
Another source of this kind of error is if you accidentally over-wrote a function with a variable name, then you call the function (or think you are calling the function), but the code actually tries to index into the array you overwrote the function name with instead.
tb =
0×1 empty double column vector
>> ta
ta =
0×1 empty double column vector
>> ta(end)
Array indices must be positive integers or logical values.
>> tb(1)
Index exceeds the number of array elements (0).
This is the line where he error crops up
So you either need to find out why they are empty, if this is not supposed to happen, or add in some code of the kind
if ~isempty( tb )
...
end
if it is valid for these to be empty at some point so that you need to handle this case.
They're not meant to be empty they should have values of time in them.
Maybe I is never 3 ? Or t1 and t2 don't have the same length as I ? We don't know.
There was a problem with that as well, i put 3 in to stop an error occuring there as well, it was originally 1. it creates
> I==1
ans =
500×1 logical array
I==3
ans =
500×1 logical array
The only difference is that I==1 creates some 1's and 0's in the array as opposed to I==3 creates a list of only 0's

Sign in to comment.

 Accepted Answer

They're not meant to be empty
Well, then you go back through the code to find out why they're empty.
Going up we see,
ta = t1(I==3);
So clearly if I doesn't contain 3 exactly, ta will be empty. So what is I?
[V,I] = min([Va,Vd],[],2);
It's the colum index where a minimum is found. I don't know what Va and Vd are. if they are column vectors then [Va, Vd] only has two columns, and obviously, you're never going to find a minimum in the 3rd column. If Va and or Vd have more than one column, the the minimum could be found in column 3 but there is absolutely no guarantee of that.
As it is, either you're guaranteed they're empty (if Va and Vb both have only one column) or they could be empty if no row of [Va, Vb] has its minimum in the 3rd column.

11 Comments

Va and Vd are both 500*1 vectors so it should work with I==1 i agree with what you said there however it still gives this error.
The logical indices contain a true value outside of the array bounds.
Error in SLPM3 (line 103)
ta = t1(I==1);
On the same part of the code as discussed before. This is what is so confusing as I==1 should match up with the dimensions of Va and Vd
I, t1 and t2 must have the same size.
Try
size(I)
size(t1)
size(t2)
at the appropriate position in your code.
Va is the velocity accelerating up to the corner and Vd is the velocity decelerating to the corner
We don't know what t1 is, but yes if it has less than 500 rows, your code will most likely error.
Note: Technically, I, t1 and t2 don't have to be the same size. I being shorter than t wouldn't cause a problem, and I being longer would only cause a problem if a true value is beyond the last element of t. However, them not being the same size would be very suspect and most likely a bug with your code.
Found the issue, t1 is only a 1*1 array or some reason whereas I and t2 are both 500*1, how would i correct this so all three are the same dimensions?
By modifiying the function "calc_acceleration" from which t1 is an output.
"how would i correct this so all three are the same dimensions?"
Same procedure. Go back through the code and find out what is happening.
As Adam wrote in the very first comment, use the debugging tools to find out where it goes wrong. Step through the code one line at a time and observe what is happening to t1.
Using the debugging tool t1 comes out as a huge single number of 6124.3 s every time no matter what value V0 is. t2 comes out as a 1*500 array and fills out with more reasonable values. This program used to work and produce a lap time without having to state an initial value of V0 before but i changed something and now cant get it back towhat it was. Completely lost here
function [V,P,G,WE,D,t] = calc_acceleration(nds,rho,cd,A,m,s,Rw,V0)
ni = [13.506352;
10.34140225;
9.606723481;
7.908904582;
6.739277848;
5.762254242;
5.042848362;
4.468644723];
V = zeros(nds,1);
P = zeros(nds,1);
G = zeros(nds,1);
WE = zeros(nds,1);
D = zeros(nds,1);
gear = 1;
ds = s(2)-s(1);
t = zeros(nds,1);
gchange_time = 0.001;
tsgc = 0;
% Loop
for i=1:nds
dt = ds/V0;
% Calculate drag
D = 0.5*rho*cd*(V0^2)*A;
% Choose gear and get power
if tsgc < gchange_time
power = getPower((ni(gear)*V0)/Rw);
tsgc = tsgc + dt;
else
power = zeros(numel(ni),1);
for g=1:numel(ni)
power(g) = getPower((ni(g)*V0)/Rw);
end
[power,newgear] = max(power);
if newgear ~= gear
tsgc = 0;
end
gear = newgear;
end
We = (ni(gear)*V0)/Rw;
WE(i) = We;
P(i) = power;
G(i) = gear;
% Calculate torque at wheel
Te = (power/We)*0.85;
Tw = Te*ni(gear);
%Add wheel inertia
WI = 4*(10*(0.335)^2);
% Calculate net force
Fw = (Tw+WI)/Rw;
F = Fw-D;
% Calculate acceleration
a = F/m;
% Calculate new veloicty
V(i) = V0;
V0 = sqrt(V0^2 + (2*a*ds));
if i>1
t(i) = t(i-1) + dt;
end
end
end
This is calc_acceleration
calc_acceleration has 6 outputs while your call to calc_acceleration only uses five of them.
Use
[Va,P,G,WE,~,t1] = calc_acceleration(nds,rho,cd,A,m,s,Rw,cnrVel(pcn));
instead of your call.
That was it, it's running now and producing a time. Thanks very much!

Sign in to comment.

More Answers (0)

Categories

Find more on Historical Contests in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!