How to solve the erro about fzero function?

I am making code that simple pendulum throwing ball to target point.
The simple pendulum is controlled by adding a constant torque to the equation of motion.
I have defined a function to find the difference between the target point and the arrival point of the ball.
Torque is the input variable for that function.
Therefore, I tried to find the torque that makes the target and the ball reach 0 using fzero, but the following error occurred.
What does this error mean?
What should I do to fix it?  Please someone teach me.
error: fzero (行 307)
elseif ~isfinite(fx) || ~isreal(fx)
error: hairetu (行 8)
Trq = fzero(fun,Trq0)
clear ;
close all;
clc;
fun = @fun_ball
Trq0 = 10;
Trq = fzero(fun,Trq0)
%% function for mesuaring distance between ball arivin point and target-point
function ball_gosa = fun_ball(Trq)
g = 9.81; l = 1; % g is gravity , l is length of pendulum
theta_ic = [0; 0]; tspan = [0 2]; % theta_ic is initial value for (Angle angular velocity)
[t, theta] = ode45(@(t,theta) ode_function(t,theta,g,l,Trq),tspan,theta_ic); % slove the Equation of motion using ode
w = theta(:,2); theta = theta(:,1);
ball_x =1*sin(theta); ball_y = -1*cos(theta); % point of throwing ball
ball_time = sqrt(2*abs(ball_y)/g); % time of ball fall
ball_reach =ball_x + abs(w).*ball_time; % distance of ball's arrival point
ball_target = 1.5; % target point
ball_gosa = ball_target - ball_reach; % Distance difference between the arrival point of the ball and the target
end
%% simple pendulum
function [dtheta_dt] = ode_function(t, theta,g,l,Trq)
theta1 = theta(1);
theta2 = theta(2);
dtheta1_dt = theta2;
dtheta2_dt =-(g/l)*(theta1)-Trq;
dtheta_dt = [dtheta1_dt; dtheta2_dt];
end

Answers (1)

Your custom function should return a scalar value, but it doesn't:
fun = @fun_ball;
Trq0 = 10;
fun(Trq0)
ans = 65×1
1.5000 1.5000 1.5000 1.4999 1.4999 1.4998 1.4997 1.4996 1.4995 1.4989

5 Comments

Is it all right to change the array of trq to a scalar?
Could you teach me how to change array to scalar?
The function should only return one value. I don't know which of the values of the array you want to know. Do you want the last? The mean? The maximum?
I made the function definition return the maximum value. Then I got the following error.
Exiting fzero: No sign change detected during search
The search for the section containing the code change is stopped.
The function may not have roots
@ryunosuke tazawa: The function fun_ball replies the maximum distance? This is never zero. The minimum would sound more logical to get a:
"function for mesuaring distance between ball arivin point and target-point"
But the distance depends on the step size of the ODE integrator an is not smooth in conseuqence. Therefor fzero has no chance to estimate the derivatives correctly to find the root.
I have no clue, what you calcutale here:
w = theta(:,2); theta = theta(:,1);
ball_x =1*sin(theta); ball_y = -1*cos(theta); % point of throwing ball
ball_time = sqrt(2*abs(ball_y)/g); % time of ball fall
ball_reach =ball_x + abs(w).*ball_time;
I'd expect t to be the "ball_time".
You are looking for a zero of your function. How certain are you that it exists?
Because fzero only found positive values, you could try fminsearch to find the lowest point in your function and see how close it is to 0.
fun = @fun_ball;
Trq0 = 10;
%Trq = fzero(fun,Trq0)
x_min=fminsearch(fun,Trq0);
fun(x_min)
ans = 2.2484
%% function for mesuaring distance between ball arivin point and target-point
function ball_gosa = fun_ball(Trq)
g = 9.81; l = 1; % g is gravity , l is length of pendulum
theta_ic = [0; 0]; tspan = [0 2]; % theta_ic is initial value for (Angle angular velocity)
[t, theta] = ode45(@(t,theta) ode_function(t,theta,g,l,Trq),tspan,theta_ic); % slove the Equation of motion using ode
w = theta(:,2); theta = theta(:,1);
ball_x =1*sin(theta); ball_y = -1*cos(theta); % point of throwing ball
ball_time = sqrt(2*abs(ball_y)/g); % time of ball fall
ball_reach =ball_x + abs(w).*ball_time; % distance of ball's arrival point
ball_target = 1.5; % target point
ball_gosa = max(ball_target - ball_reach); % Distance difference between the arrival point of the ball and the target
% ^^^^ this is my edit ^
end
%% simple pendulum
function [dtheta_dt] = ode_function(t, theta,g,l,Trq)
theta1 = theta(1);
theta2 = theta(2);
dtheta1_dt = theta2;
dtheta2_dt =-(g/l)*(theta1)-Trq;
dtheta_dt = [dtheta1_dt; dtheta2_dt];
end
So, it turns out your function doesn't have a 0 close to Trq0.

Sign in to comment.

Asked:

on 22 Jul 2021

Commented:

Rik
on 23 Jul 2021

Community Treasure Hunt

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

Start Hunting!