MATLAB Answers

Orpheus
0

Getting an error of 'Reference to non-existent field'

Asked by Orpheus
on 18 Sep 2019
Latest activity Edited by Guillaume
on 18 Sep 2019
The function when invoked gives the error 'Reference to non-existent field 'vel'.'
function [ desired_state ] = traj_generator(t, state, waypoints)
% This function is called with variable number of input arguments.
% During initialization, it is called with arguments
% trajectory_generator([], [], waypoints) and later, while testing, it will be
% called with only t and state as arguments.
% t,state: time and current state that is used for computing desired_state
% waypoints: The 3xP matrix listing all the points needed in order
% to generate the trajectory
% desired_state: Contains all the information that is passed as output
function[t_m] =t_mat1(t)
t_m=[1 t^1 t^2 t^3 t^4 t^5 t^6 t^7]';
end
function[t_m_dot] =t_mat2(t)
t_m_dot = [0 1 2*t 3*t^2 4*t^3 5*t^4 6*t^5 7*t^6]';
end
function[t_m_ddot] =t_mat3(t)
t_m_ddot = [0 0 2 6*t 12*t^2 20*t^3 30*t^4 42*t^5]';
end
function[C]=pols_coef_retrn(n,wayp)
A = zeros(8*n,8*n);
B = zeros(1,8*n);
p=1;
l=0;
for i=1:n
k=1;
for j=1:8
if j==1
A(p,p)=1;
B(p)=wayp(i);
A(p+1,p:p+7)=[1 1 1 1 1 1 1 1];
B(p+1)=wayp(i+1);
end
p=p+1;
if j>=3
for theta = l+k:l+6
if i==1 && k<=4
A(j,k+1)=1;
elseif i==n
if k<=4
A(l+j,theta)= factorial(theta-l)/(factorial(k)^2);
elseif k==5
A(l+j,l+7)=1;
A(l+j,8)=-1;
elseif k==6
A(l+j,l+6)=1;
A(l+j,l-3)=-1;
A(l+j,l+j)=-1;
end
else
A(l+j,theta)=-(factorial(theta-l)/(factorial(k)^2));
if theta==(l+6)
A(l+j,theta+2+k)=1;
end
end
end
k=k+1;
end
end
l=l+8;
end
C=inv(A)*B';
end
persistent waypoints0 traj_time d0
if nargin > 2
d = waypoints(:,2:end) - waypoints(:,1:end-1);
d0 = 2 * sqrt(d(1,:).^2 + d(2,:).^2 + d(3,:).^2);
traj_time = [0, cumsum(d0)];
waypoints0 = waypoints;
else
if (t >= traj_time(end))
t = traj_time(end)-0.0001;
end
t_index = find(traj_time>t,1) - 1;
t_index = max(t_index,1);
scale = (t-traj_time(t_index)) / d0(t_index);
if(t == 0)
desired_state.pos = waypoints0(:,1);
else
index = ((t_index-1)*8+1:t_index*8);
nn=size(waypoints0(1,:));
n=nn(2)-1;
coeff_x = pols_coef_retrn(n,waypoints0(1,:)');
coeff_y = pols_coef_retrn(n,waypoints0(2,:)');
coeff_z = pols_coef_retrn(n,waypoints0(3,:)');
desired_state.pos = [coeff_x(index)'*t_mat1(scale);coeff_y(index)'*t_mat1(scale);coeff_z(index)'*t_mat1(scale);];
desired_state.vel = [coeff_x(index)'*t_mat2(scale);coeff_y(index)'*t_mat2(scale);coeff_z(index)'*t_mat2(scale);].*(1/d0(t_index));
desired_state.acc = [coeff_x(index)'*t_mat3(scale);coeff_y(index)'*t_mat3(scale);coeff_z(index)'*t_mat3(scale);].*((1/d0(t_index))^2);
end
desired_state.yaw = 0;
desired_state.yawdot = 0;
end
end
the error message is as follows
Reference to non-existent field 'vel'.
Error in simulation_3d (line 70)
QP.UpdateQuadPlot(x, [desired_state.pos; desired_state.vel], time);
Error in runsim (line 28)
[t, state] = simulation_3d(trajhandle, controlhandle);
where runsim and in simulation_3d invoke the function

  5 Comments

The function in simulation_3d works fine when any other function is passed as traj_generator. It shows an error with this hence i assumed it would be an error in this function.
The function in simulation_3d is as follows
function [t_out, s_out] = simulation_3d(trajhandle, controlhandle)
addpath('utils');
% real-time
real_time = true;
% max time
max_time = 20;
% parameters for simulation
params = sys_params;
%% **************************** FIGURES *****************************
disp('Initializing figures...');
h_fig = figure;
h_3d = gca;
axis equal
grid on
view(3);
xlabel('x [m]'); ylabel('y [m]'); zlabel('z [m]')
quadcolors = lines(1);
set(gcf,'Renderer','OpenGL')
%% *********************** INITIAL CONDITIONS ***********************
disp('Setting initial conditions...');
tstep = 0.01; % this determines the time step at which the solution is given
cstep = 0.05; % image capture time interval
max_iter = max_time/cstep; % max iteration
nstep = cstep/tstep;
time = 0; % current time
err = []; % runtime errors
% Get start and stop position
des_start = trajhandle(0, []);
des_stop = trajhandle(inf, []);
stop_pos = des_stop.pos;
x0 = init_state(des_start.pos, 0);
xtraj = zeros(max_iter*nstep, length(x0));
ttraj = zeros(max_iter*nstep, 1);
x = x0; % state
pos_tol = 0.01;
vel_tol = 0.01;
%% ************************* RUN SIMULATION *************************
disp('Simulation Running....');
% Main loop
for iter = 1:max_iter
timeint = time:tstep:time+cstep;
tic;
% Initialize quad plot
if iter == 1
QP = QuadPlot(1, x0, 0.1, 0.04, quadcolors(1,:), max_iter, h_3d);
current_state = stateToQd(x);
desired_state = trajhandle(time, current_state);
QP.UpdateQuadPlot(x, [desired_state.pos; desired_state.vel], time);
h_title = title(sprintf('iteration: %d, time: %4.2f', iter, time));
end
% Run simulation
[tsave, xsave] = ode45(@(t,s) quadEOM(t, s, controlhandle, trajhandle, params), timeint, x);
x = xsave(end, :)';
% Save to traj
xtraj((iter-1)*nstep+1:iter*nstep,:) = xsave(1:end-1,:);
ttraj((iter-1)*nstep+1:iter*nstep) = tsave(1:end-1);
% Update quad plot
current_state = stateToQd(x);
desired_state = trajhandle(time + cstep, current_state);
QP.UpdateQuadPlot(x, [desired_state.pos; desired_state.vel], time + cstep);
set(h_title, 'String', sprintf('iteration: %d, time: %4.2f', iter, time + cstep))
time = time + cstep; % Update simulation time
t = toc;
% Check to make sure ode45 is not timing out
if(t> cstep*50)
err = 'Ode45 Unstable';
break;
end
% Pause to make real-time
if real_time && (t < cstep)
pause(cstep - t);
end
% Check termination criteria
if terminate_check(x, time, stop_pos, pos_tol, vel_tol, max_time)
break
end
end
%% ************************* POST PROCESSING *************************
% Truncate xtraj and ttraj
xtraj = xtraj(1:iter*nstep,:);
ttraj = ttraj(1:iter*nstep);
% Truncate saved variables
QP.TruncateHist();
% Plot position
h_pos = figure('Name', ['Quad position']);
plot_state(h_pos, QP.state_hist(1:3,:), QP.time_hist, 'pos', 'vic');
plot_state(h_pos, QP.state_des_hist(1:3,:), QP.time_hist, 'pos', 'des');
% Plot velocity
h_vel = figure('Name', ['Quad velocity']);
plot_state(h_vel, QP.state_hist(4:6,:), QP.time_hist, 'vel', 'vic');
plot_state(h_vel, QP.state_des_hist(4:6,:), QP.time_hist, 'vel', 'des');
if(~isempty(err))
error(err);
end
disp('finished.')
t_out = ttraj;
s_out = xtraj;
end
Is trajhandle equal to @traj_generator ?

Sign in to comment.

Tags

Products


Release

R2019a

1 Answer

Answer by Guillaume
on 18 Sep 2019
 Accepted Answer

The way traj_generator is coded, when t is 0, it returns a structure with only 3 fields: pos, yaw and yawdot (these last two are always 0). It's only when t is not 0 that it creates the fields vel and acc.
So, indeed if t is 0 and you try to use the vel field you'll get your error. Either you mustn't use vel or acc if t is 0, or you must modify traj_generator so that it creates these fields even when t is 0:
%original code in traj_generator
if(t == 0)
desired_state.pos = waypoints0(:,1);
else
replace with
if t == 0 %brackets were completely unnecessary
desired_state.pos = waypoints0(:,1);
desired_state.vel = ????; %no idea what you want there
desired_state.acc = ????; %no idea what you want there
else
%...

  0 Comments

Sign in to comment.