Writing a lap time sim tool

I'm trying to write a lap time sim tool for race tracks. I have it in excel, so, most of the maths is done, except for the parts where excel cant work stuff out (as far as I know) like braking and acceleration zones but that can be worked on at a later date.
The main problem is that I need to allow the user to input section lengths: corners and straights, and preferably in order.
But, as people who have very kindly helped so far have pointed out, I need to explain the whole problem :)
So, as my Matlab and programming knowledge is limited, I'd like to know what approaches I can do for this, what functions would I need, and how would I need to use them. While it would be great for code to be provided, I dont want to ask other people to do the work for me, and I wont learn anything, but, I do learn best from examples so any similar examples I can expand on would be great.
There could be upto 100 or so sections of the track, for the straights it's a straight forward length and calculation. For corners, I need to determine the radius of that corner, so, need to be able to identify which section is which.
After that, I should have a resulting value (the top speed) for each section which I need to use in further calculations.
Any help would be appreciated.

4 Comments

At which stage of the design are you at the moment?
If I were to design what you describe, I'd start with writing the simulation main function. This would take as input the track details, so something like:
function [someoutput, maybesomeotheroutput] = simulate(trackdetails, otherinput, somethingelsemaybe)
Have you got that yet and decided what type these input/output variables are going to be?
After that, I would design a user input function that makes it easy for the user to specify the track details. Probably, a GUI. That user input function would then call the simulation function that do the work an display the result.
I'm pretty much at stage 1 of everything, other than doing the maths part in excel.
I wouldn't know where to start writing the simulation main function or how to make a bunch of numbers into inputs without using a lot of variables, which I'm aware is bad coding practice.
Well, what inputs does your simulation need? You said the track details, that's one. What else?
Car details will be the others. At the moment, I have: Tyre co-efficient of friction, co-efficient of drag, frontal area and mass. Other details: Gravity and air density.
But, as I study more into vehicle dynamics and what other factors I could use, especially when it comes into braking and acceleration forces, I would need to add to these in at a later date reasonably easily.

Sign in to comment.

Answers (1)

Probably, the first thing you need to settle on is what form your inputs will take. If I understand your requirements, I would have three inputs to the simulation function:
  • track details. I would have that as a structure array with fields:
type: a scalar categorical with possible values: 'straight' or 'corner'
length: a scalar double
radius: a scalar double
inclination:? if that's needed, a scalar double
type may not even be needed since a corner with infinite radius is a straight.
  • car details, a scalar structure (unless you simulate more than one car, in which case it's another structure array), with fields
friction
drag
frontalarea
mass
all scalar doubles
  • environment, another scalar structure with fields
gravity
air density
humidity (?)
air temperature (?)
and the signature of your function would be:
function [someresult, maybesomeotherresult] = tracksimulation(track, car, environment)
%TRACKSIMULATION: Simulate the car racing along the specified track under given environment conditions
%with:
% track: and Nx1 structure with fields
% type: scalar categorical with possible values 'straight' or 'corner'
% ... you can write the rest
% first thing you should do when you start writing a function is document its inputs/outputs
You can even have a helper function to help you build that track structure:
function track = addsection(track, type, length, radius)
%ADDSECTION: add a section to the given track (or start the track)
%with:
% track: a previously constructed track structure or an empty array to start the track
% type: the type of section to add, char array with value: 'straight' (or 's') or 'corner' (or 'c')
% length: length of section to add, scalar double
% radius: radius of section to add, ignored and can be omitted if type is 'straight'.
if isempty(track)
track = structure('type', {}, 'length', {}, 'radius', {});
else
assert(isstruct(track) && all(ismember({'type', 'length', 'radius'}, fieldnames(track))), 'track input must be a structure with correct fields');
end
validateattributes(type, {'char', 'string'}, {'scalartext'}, 2)
if strcmp(type, 's'), type = 'straight'; elseif strcmp(type, 'c'), type = 'corner'; end
validateattributes(length, {'numeric'}, {'scalar', 'positive', 'finite'}, 3);
if nargin < 3
if strcmp(type, 'corner'), error('radius must be specified when type is ''corner''); end
radius = Inf;
else
validateattributes(radius, {'numeric'}, {'scalar', 'positive', 'finite'}, 4);
end
track = [track; struct('type', categorical({type}, {'straight', 'corner'}), 'length', length, 'radius', radius)];
end

11 Comments

Ok, thanks for the information. Will study all that in detail and see what happens :) And try to understand how the functions work etc...
Although, I don't get what a scalar double is? I've had a look over documentation and Google searches but nothing seems to answer that?
Guillaume
Guillaume on 22 Oct 2018
Edited: Guillaume on 22 Oct 2018
scalar: a 1x1 anything, a single value. Can be tested with isscalar.
vector: a 1xN or Nx1 anything. Can be tested with isvector.
matrix: a MxN anything
array: something of any dimension
double: standard numeric type.
I probably should have written scalar numeric instead of scalar double since the code I wrote accepts any numeric type (double, single, integer).
Thanks.
I've been trying to understand how to write the track variable, as, making a TRACK(1), TRACK(2) for each section seems very impracticable.
So, is the following possible?
TRACK(1).name = "Track Name";
TRACK(1).length = {'4200',}; % metres
TRACK(1).sections = {(300, 's'), (400, 'c')};
And if so, then, how do I access each field of the sections part, and is it possible to populate this using inputs from the user via a GUI?
My advice is that for now you don't worry about the user interface and you work solely on the processing algorithm. In a well designed program, the processing and the UI are completely independent, so you can completely change one without affecting the other.
So for now, you need to decide what sort of data format works well for the simulation code. It will be the interface between the processing and the UI. Once that's settled and your processing code works, you can then decide on a what sort of UI you want so that it generates the correct format. It can be command line, it can be a GUI, you can read the input from a file. All of this can be done.
There are plenty of options for that data format. For the track, there's the structure I suggested initially. You could also use a table:
track = table([300;400;150;1000], 'sccs'.', [0;90;-30;0], 'VariableNames', {'length', 'type', 'radius'})
track.Properties.Description = 'Wiggles';
Or you can use your proposed structure. There's no need to have it a structure array if your simulation only needs one track, so it would be:
track.name = "Track Name";
track.length = 4200; %I would recommend you don't have that field
track.sections = {300, 's'; 400, 'c'; 150, 'c'; 1000, 's'};
I would not have an explicit length field as you run the risk that it may be different from the sum of the section lengths if you're not careful to keep the two in sync. It's trivially calculated anyway.
In each case, accesssing each section is simply an iteration over the rows of the structure/table/cell array.
Again, whatever data format you choose you can adapt a UI to it. A table may be the easiest to make a GUI for as it maps directly onto a UITable but whichever you chose doesn't really matter for the UI.
Thanks so far.
I've been trying to work out how to use a for loop to go through the structure array, to calculate the radius if it's a corner, but getting no where. Is this any where near correct?
for radius = TRACK(1).sections
if TRACK(1).sections(:,1) == 'c'
% if it's corner, calculate radius
radius = ;% maths goes here
else
% its a straight, and dont need to do anything
end %end if
end % end for
First, you need to clarify which of the several storage schemes I proposed you're using.
for radius = TRACK(1).sections
The name of the iterating variable, radius, does not make sense. As it's a name you can call it what you want, but calling it radius is misleading. I would have:
for section = TRACK(1).sections
Note that sections needs to be a row vector for the above to works. Otherwise, it's:
for sectionidx = 1:numel(TRACK(1).sections
section = TRACK(1).sections(sectionidx);
I thought the radius would be stored in the section structure, so I'm not sure why you want to calculate it, and what from.
If section is a structure, then the code would continue with:
if section.type == 'c';
%calculate something
else
As it is, what you wrote doesn't make sense.
The radius is calculated from the length of the corner. Otherwise, half of the work is already done by the user before using the script. The idea is for this script to do that work for the user, hence using the iterating variable name of "radius".
I could implement something where if they had the radius already then to use that instead of length, but, that's just an idea and something for the future.
I was intending on using the structure array. I dont understand how the table works for storage.
I also dont understand what this code does:
for sectionidx = 1:numel(TRACK(1).sections
section = TRACK(1).sections(sectionidx);
What is the idx for? Does the 'x' need to be a number? I dont know what the 1:nume1 does? Or the 2nd line at all.
I get an error in Matlab when trying to run those 2 lines (after setting the initial TRACK(1).sections variable/structure), and its pointing at the end of the first line.
Error: Invalid expression. When calling a function or indexing a variable, use parentheses. Otherwise, check for mismatched delimiters.
Again, before you write any code, you need to clarify which storage model you're using. What actual properties of the track you're storing? Is there one or can there be several tracks. Which attributes of the section did store, length obviously but it seems not radius, so perhaps angle as well?
If you don't have that clear, you can't really write the code. Once you've settled on what you need to store, whether you use a structure or table doesn't really matter, it will result in only minor differences to the code.
As for your other questions:
I made a mistake and forgot the closing ). As the error message tells you, check for mismatched delimiter. It should have been:
for sectionidx = 1:numel(TRACK(1).sections)
Of course, for the above I sort of followed your code. I'm not sure why you're indexing TRACK. I thought there would be only one track. And I don't know what you intend to store in the section field.
doc for numel (not nume1)
sectionidx is just a variable name for the iterating variable. People often use i which I think is not a good variable name. You could use sectionindex or sectioniter or sectioniterator. Whatever you want.
The code iterates over the sections of the track. I assume that's what you intended with your original code.
If we assume that a corner is a circular arc, then in order to calculate the radius, you need the length and the subtending angle.
Ok, that all makes sense to me, I think.
How do I tell the code to do maths calculation on the numbers inside the TRACK(1).sections variable if it's a 'c' ??
That part is still confusing me.
If I try to display section or section.type or sectionidx, then they appear empty. No warnings are given, so, I assume the code is run, it's just that there's nothing been done by the code?
Again, I'm really not clear on which data model you're using So, please clarify. What are the fields of your structures (TRACK and sections)? What are the possible values of each field?

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Release

R2018b

Asked:

on 22 Oct 2018

Commented:

on 6 Nov 2018

Community Treasure Hunt

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

Start Hunting!