Help with matlab script
Show older comments
Good day, we were given an assignment to complete. I was able to complete most of it but I was having some trouble approaching the end. I'm not very good using MATLAB and was hoping for some help. The problems I was having were:
1) When I run the program, I get no errors but I'm not seeing the values appear in the workspace.
2) I was trying to perform the least squares method after step 5 using while loops but i'm also having some trouble with that.
3) I wanted to have the program in separate m files like having one main m file, then other supporting m files but I'm also having some trouble with that.
Asking for help because im not fully sure how to complete it.
This is what I have so far:
% compute_drag_script
D = [ 0; 0.5; 1.1; 1.7; 2.3; 2.9; 3.5; 4.0; 4.6; 5.2;...
5.7; 6.3; 6.8; 7.4; 7.9; 8.4; 9.0; 9.5; 10.0; 10.6;...
11.1; 11.6; 12.1; 12.6; 13.1; 13.6; 14.1; 14.6; 15.1; 15.6;...
16.1; 16.5; 17.0; 17.5; 18.0; 18.4; 18.9; 19.4];
V = [108; 107; 106; 105; 104; 104; 103; 102; 101; 100;...
99; 99; 98; 97; 97; 96; 95; 94; 94; 93;...
92; 92; 91; 91; 90; 89; 89; 88; 88; 87;...
87; 86; 86; 85; 85; 84; 83; 82];
interp_speeds = compute_drag(D,V,0.0095,30);
function interp_speeds = compute_drag(...
true_distances,true_speeds, k,theta_degrees)
arguments
true_distances(:,1) {mustBeNonnegative}
true_speeds(:,1) {mustBeNonnegative}
k (1,1) {mustBeNonnegative}
%drag_coeff
theta_degrees(1,1) {mustBeInRange(theta_degrees,0,180)}
end
%% Input validation
if length(true_distances) ~= length(true_speeds)
error('Distance and speed vectors must be the same length.');
end
if any(diff(true_distances) < 0)
error('Distance should never go down!');
end
%% Constants and parameters
g = 9.81; % meters per second-squared
m = 0.45; % kilograms
v0_kph = 108; % kilometers per hour, will convert to meters per second
k = 0.00000001;
ro = 1.293 % kg/(m)^3
d = 0.7/pi % m
%% Conversions
v0 = v0_kph * 1000 / 3600; % kph to meters per second
% We could also convert theta_guess to radians, but there's no reason we
% have to, since Matlab has degree variants of the trig functions.
%% Initial Conditions
x0 = 0;
y0 = 0;
dxdt0 = v0*cosd(theta_degrees);
dydt0 = v0*sind(theta_degrees);
init_vals = [ x0; y0; dxdt0; dydt0];
%% Step 2
% setup for diffeq that will be fed to ode45:
% val(1) x: x' (i.e. val(3))
% val(2) y: y' (i.e. val(4))
% val(3) x': (-k|v|/m) * x'
% val(4) y': -g - (k|v|/m) * y'
all_diffeq = @(t,VALS) [
VALS(3);
VALS(4);
-k * sqrt( VALS(3)^2 + VALS(4)^2 ) * VALS(3) / m;
-g - ( k*sqrt(VALS(3)^2+VALS(4)^2) * VALS(4) / m);
];
% To get an appropriate time range, I'm using the worst case scenario:
% the slowest speed (e.g. 82 kph) taking the ball the full distance
% (e.g. 19.4 meters).
minspeed = min(true_speeds) * 1000 / 3600;
max_necessary_time = (true_distances(end)) / minspeed;
tspan = [0, max_necessary_time];
[t,vals] = ode45(all_diffeq, tspan, init_vals);
x = vals(:,1);
y = vals(:,2);
dxdt = vals(:,3);
dydt = vals(:,4);
% s = sqrt(x.^2 + y.^2);
%% Step 3
s_segments = sqrt(1 + (dydt./dxdt).^2);
s_step = [0;diff(x)];
s = cumsum( s_segments .* s_step );
v = sqrt(dxdt.^2 + dydt.^2);
v_kph = v * 3600 / 1000;
%% Step 4
interp_speeds = interp1(s,v_kph,true_distances);
if any(isnan(interp_speeds))
warning('NaN encountered. You should increase upper bound on time.');
end
end
% Step 5
while V_interpolated >= 0
E = cumsum(V_interpolated - V_var).^2
end
% E_theta0 = theta + 0.0001
% E_theta =
% dE_dtheta = (E_theta - E_base) / 0.0001
% E_k = k + 0.0000008
% dE_dk = (E_k - E_base) / 0.00000001
4 Comments
"When I run the program, I get no errors but I'm not seeing the values appear in the workspace."
Weird, it gives an error here -
% compute_drag_script
D = [ 0; 0.5; 1.1; 1.7; 2.3; 2.9; 3.5; 4.0; 4.6; 5.2;...
5.7; 6.3; 6.8; 7.4; 7.9; 8.4; 9.0; 9.5; 10.0; 10.6;...
11.1; 11.6; 12.1; 12.6; 13.1; 13.6; 14.1; 14.6; 15.1; 15.6;...
16.1; 16.5; 17.0; 17.5; 18.0; 18.4; 18.9; 19.4];
V = [108; 107; 106; 105; 104; 104; 103; 102; 101; 100;...
99; 99; 98; 97; 97; 96; 95; 94; 94; 93;...
92; 92; 91; 91; 90; 89; 89; 88; 88; 87;...
87; 86; 86; 85; 85; 84; 83; 82];
interp_speeds = compute_drag(D,V,0.0095,30);
function interp_speeds = compute_drag(...
true_distances,true_speeds, k,theta_degrees)
arguments
true_distances(:,1) {mustBeNonnegative}
true_speeds(:,1) {mustBeNonnegative}
k (1,1) {mustBeNonnegative}
%drag_coeff
theta_degrees(1,1) {mustBeInRange(theta_degrees,0,180)}
end
%% Input validation
if length(true_distances) ~= length(true_speeds)
error('Distance and speed vectors must be the same length.');
end
if any(diff(true_distances) < 0)
error('Distance should never go down!');
end
%% Constants and parameters
g = 9.81; % meters per second-squared
m = 0.45; % kilograms
v0_kph = 108; % kilometers per hour, will convert to meters per second
k = 0.00000001;
ro = 1.293 % kg/(m)^3
d = 0.7/pi % m
%% Conversions
v0 = v0_kph * 1000 / 3600; % kph to meters per second
% We could also convert theta_guess to radians, but there's no reason we
% have to, since Matlab has degree variants of the trig functions.
%% Initial Conditions
x0 = 0;
y0 = 0;
dxdt0 = v0*cosd(theta_degrees);
dydt0 = v0*sind(theta_degrees);
init_vals = [ x0; y0; dxdt0; dydt0];
%% Step 2
% setup for diffeq that will be fed to ode45:
% val(1) x: x' (i.e. val(3))
% val(2) y: y' (i.e. val(4))
% val(3) x': (-k|v|/m) * x'
% val(4) y': -g - (k|v|/m) * y'
all_diffeq = @(t,VALS) [
VALS(3);
VALS(4);
-k * sqrt( VALS(3)^2 + VALS(4)^2 ) * VALS(3) / m;
-g - ( k*sqrt(VALS(3)^2+VALS(4)^2) * VALS(4) / m);
];
% To get an appropriate time range, I'm using the worst case scenario:
% the slowest speed (e.g. 82 kph) taking the ball the full distance
% (e.g. 19.4 meters).
minspeed = min(true_speeds) * 1000 / 3600;
max_necessary_time = (true_distances(end)) / minspeed;
tspan = [0, max_necessary_time];
[t,vals] = ode45(all_diffeq, tspan, init_vals);
x = vals(:,1);
y = vals(:,2);
dxdt = vals(:,3);
dydt = vals(:,4);
% s = sqrt(x.^2 + y.^2);
%% Step 3
s_segments = sqrt(1 + (dydt./dxdt).^2);
s_step = [0;diff(x)];
s = cumsum( s_segments .* s_step );
v = sqrt(dxdt.^2 + dydt.^2);
v_kph = v * 3600 / 1000;
%% Step 4
interp_speeds = interp1(s,v_kph,true_distances);
if any(isnan(interp_speeds))
warning('NaN encountered. You should increase upper bound on time.');
end
end
% Step 5
while V_interpolated >= 0
E = cumsum(V_interpolated - V_var).^2
end
And as the error states, All function defined in a script must be at the end of the file.
Also, you are using the variables "V_interpolated" and "V_var", but you have not defined them?
"I wanted to have the program in separate m files like having one main m file, then other supporting m files but I'm also having some trouble with that."
Save the function "compute_drag" in the file "compute_drag.m". (Note that a function file must be saved with the name of the first function.) Then open a new file, and insert the values/inputs there and call the function. Save the second file and call it in the workspace.
Light
on 24 Apr 2023
Light
on 24 Apr 2023
Light
on 24 Apr 2023
Accepted Answer
More Answers (1)
Image Analyst
on 24 Apr 2023
You had an extra "end" between step 4 and 5, and V_interpolated is not defined. Was it supposed to be interp_speeds instead of V_interpolated?
% compute_drag_script
D = [ 0; 0.5; 1.1; 1.7; 2.3; 2.9; 3.5; 4.0; 4.6; 5.2;...
5.7; 6.3; 6.8; 7.4; 7.9; 8.4; 9.0; 9.5; 10.0; 10.6;...
11.1; 11.6; 12.1; 12.6; 13.1; 13.6; 14.1; 14.6; 15.1; 15.6;...
16.1; 16.5; 17.0; 17.5; 18.0; 18.4; 18.9; 19.4];
V = [108; 107; 106; 105; 104; 104; 103; 102; 101; 100;...
99; 99; 98; 97; 97; 96; 95; 94; 94; 93;...
92; 92; 91; 91; 90; 89; 89; 88; 88; 87;...
87; 86; 86; 85; 85; 84; 83; 82];
interp_speeds = compute_drag(D,V,0.0095,30);
%==========================================================================================
% Function definition must occur after the script and end with an "end" statement.
function interp_speeds = compute_drag(...
true_distances,true_speeds, k,theta_degrees)
arguments
true_distances(:,1) {mustBeNonnegative}
true_speeds(:,1) {mustBeNonnegative}
k (1,1) {mustBeNonnegative}
%drag_coeff
theta_degrees(1,1) {mustBeInRange(theta_degrees,0,180)}
end
%% Input validation
if length(true_distances) ~= length(true_speeds)
error('Distance and speed vectors must be the same length.');
end
if any(diff(true_distances) < 0)
error('Distance should never go down!');
end
%% Constants and parameters
g = 9.81; % meters per second-squared
m = 0.45; % kilograms
v0_kph = 108; % kilometers per hour, will convert to meters per second
k = 0.00000001;
ro = 1.293 % kg/(m)^3
d = 0.7/pi % m
%% Conversions
v0 = v0_kph * 1000 / 3600; % kph to meters per second
% We could also convert theta_guess to radians, but there's no reason we
% have to, since Matlab has degree variants of the trig functions.
%% Initial Conditions
x0 = 0;
y0 = 0;
dxdt0 = v0*cosd(theta_degrees);
dydt0 = v0*sind(theta_degrees);
init_vals = [ x0; y0; dxdt0; dydt0];
%% Step 2
% setup for diffeq that will be fed to ode45:
% val(1) x: x' (i.e. val(3))
% val(2) y: y' (i.e. val(4))
% val(3) x': (-k|v|/m) * x'
% val(4) y': -g - (k|v|/m) * y'
all_diffeq = @(t,VALS) [
VALS(3);
VALS(4);
-k * sqrt( VALS(3)^2 + VALS(4)^2 ) * VALS(3) / m;
-g - ( k*sqrt(VALS(3)^2+VALS(4)^2) * VALS(4) / m);
];
% To get an appropriate time range, I'm using the worst case scenario:
% the slowest speed (e.g. 82 kph) taking the ball the full distance
% (e.g. 19.4 meters).
minspeed = min(true_speeds) * 1000 / 3600;
max_necessary_time = (true_distances(end)) / minspeed;
tspan = [0, max_necessary_time];
[t,vals] = ode45(all_diffeq, tspan, init_vals);
x = vals(:,1);
y = vals(:,2);
dxdt = vals(:,3);
dydt = vals(:,4);
% s = sqrt(x.^2 + y.^2);
%% Step 3
s_segments = sqrt(1 + (dydt./dxdt).^2);
s_step = [0;diff(x)];
s = cumsum( s_segments .* s_step );
v = sqrt(dxdt.^2 + dydt.^2);
v_kph = v * 3600 / 1000;
%% Step 4
interp_speeds = interp1(s,v_kph,true_distances);
if any(isnan(interp_speeds))
warning('NaN encountered. You should increase upper bound on time.');
end
% Step 5
while V_interpolated >= 0
E = cumsum(V_interpolated - V_var).^2
end
% E_theta0 = theta + 0.0001
% E_theta =
% dE_dtheta = (E_theta - E_base) / 0.0001
% E_k = k + 0.0000008
% dE_dk = (E_k - E_base) / 0.00000001
end
3 Comments
Light
on 24 Apr 2023
Image Analyst
on 24 Apr 2023
OK, so does that answer your question/fix your issue?
If this Answer solves your original question, then could you please click the "Accept this answer" link to award the answerer with "reputation points" for their efforts in helping you? They'd appreciate it. Thanks in advance. 🙂 Note: you can only accept one answer (so pick the best one) but you can click the "Vote" icon for as many Answers as you want. Voting for an answer will also award reputation points.
Categories
Find more on Loops and Conditional Statements 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!
