function bht_kine_check(varargin)
% BHT_KINE_CHECK
%
% Display the articulated bodies at their initial positions and the fluid's
% boundaries.
%
% Syntax
%
% BHT_KINE_CHECK('DataFilename',filename1,'ControlsFilename',filename2)
%
% BHT_KINE_CHECK(...,'ControlsParameters',cont_parameter)
%
% BHT_KINE_CHECK(...,'axis',[xmin xmax ymin ymax])
%
% Description
%
% After compiling the DAT-File with bht_data_compile and before
% lauching computations by running BHT_TRAJECT_COMPUTE, the function
% BHT_KINE_CHECK allows you to check if most of the experiment's
% features described in the DAT-File comply with your expectations. The
% command line
%
% BHT_KINE_CHECK('DataFilename',filename1,'ControlsFilename',filename2)
%
% opens a GUI with a graphic window in which are displayed the
% articulated bodies and the fluid's boundaries described in the
% DAT-File filename1 at the time t = 0. The articulated bodies are
% ploted at the initial positions given in the DAT-File and the links'
% labels (also given in the DAT-File) are displayed. The articulation
% points are ploted as well. The GUI is endowed with four push buttons.
% The two firsts, labeled time + and time -, make the time increase or
% decrease and make the articulated bodies modify their shapes
% accordingly to the controls M-File filename2. The third push button,
% labeled v, allows to display the velocity vectors (in red) at the
% center of mass of the solids and the fourth one, labeled gamma,
% allows to display the acceleration vectors (in blue). When the
% controls M-File requires a parameters matrix cont_parameter, modify
% the previous command line as follows:
%
% BHT_KINE_CHECK(...,'ControlsParameters',cont_parameter)
%
% You can also specify axis limits by adding the option 'axis':
%
% BHT_KINE_CHECK(...,'axis',[xmin xmax ymin ymax]).
%
% BhT is not able to detect boundaries' overlaps which cause
% computations to crash. With BHT_KINE_CHECK, you can make sure that
% all of the boundaries are disconnected, at least at the initial time.
%
% See also BHT_DATA_COMPILE, BHT_TRAJECT_COMPUTE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% BIOHYDRODYNAMICS MATLAB TOOLBOX %
% %
% A. MUNNIER and B. PINCON %
% %
% alexandre.munnier@iecn.u-nancy.fr bruno.pincon@iecn.u-nancy.fr %
% http://www.iecn.u-nancy.fr/~munnier http://www.iecn.u-nancy.fr/~pincon %
% %
% %
% INSTITUT ELIE CARTAN, NANCY 1 %
% http://www.iecn.u-nancy.fr/ %
% %
% INRIA Lorraine, Projet CORIDA %
% http://www.iecn.u-nancy.fr/~corida/ %
% %
% %
% %
% %
% August 15th 2008 %
% %
% GNU GPL v3 licence %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%##########################################################################
cont_parameters = [];
no_filename = 1;
no_contfilename = 1;
axis_param = [];
%==========================================================================
% reading options
%================
nb_varargin = numel(varargin);
kk = 1;
while kk < nb_varargin
if ~ischar(varargin{kk})
error(['Unknown option ',num2str(varargin{kk})]) %#ok<ST2NM>
end
%------------------------------------------------------------------
switch lower(varargin{kk})
%--------------------------------------------------------------
case 'datafilename'
if ischar(varargin{kk+1})
filename = varargin{kk+1};
exten = regexp(filename,'\w*\.(\w*)', 'tokens');
no_filename = 0;
if isempty(exten)
filename = [filename,'.dat']; %#ok<AGROW>
end
else
error('Unexpected expression for option DataFilename.')
end
kk = kk+2;
%--------------------------------------------------------------
case 'controlsfilename'
if ischar(varargin{kk+1})
cont_filename = varargin{kk+1};
no_contfilename = 0;
else
error('Unexpected expression for option ControlsFilename.')
end
kk = kk+2;
%----------------------------------------------------------
case 'controlsparameters'
if isfloat(varargin{kk+1})
cont_parameters = varargin{kk+1};
else
error('Unexpected value for option ControlsParameters. Must be a matrix.')
end
kk = kk+2;
%---------------------------------------------------------
case 'axis'
if isvector(varargin{kk+1})
if length(varargin{kk+1}) == 4
axis_param = varargin{kk+1};
else
error('Unexpected value for option Axis. Must be a vector [Xmin Xmax Ymin Ymax].')
end
else
error('Unexpected value for option Axis. Must be a vector [Xmin Xmax Ymin Ymax].')
end
kk = kk+2;
%----------------------------------------------------------
otherwise
error(['Unknown option ''',varargin{kk},''''])
end
end
% =========================================================================
% DataFilename is missing
if no_filename
filename = input('Enter data file''s name (hit Return to browse): ','s');
if isempty(filename);
filename = uigetfile('*.dat','Select data file');
end
end
% =========================================================================
% ControlsFilename is missing
if no_contfilename
cont_filename = input('Enter controls file''s name (hit Return to browse): ','s');
if isempty(cont_filename);
cont_filename = uigetfile('*.m','Select controls m file');
cont_filename = regexp(cont_filename,'(\w*)\.', 'tokens');
cont_filename = cont_filename{1}{1};
end
end
%==========================================================================
% fish kinematic filename =================================================
base_filename = regexp(filename,'(\w*)(?:\.)?', 'tokens');
base_filename = base_filename{1}{1};
kine_filename = [base_filename,'_kine'];
% need datacompil =========================================================
filename1 = [base_filename,'_data'];
load(filename1,'gene_data','discret_data','bound_data','ode_data',...
'phys_data','fish');
% =========================================================================
p0 = ode_data.initial_positions;
dp0 = ode_data.initial_velocities;
Tmax = ode_data.Tmax;
dT = ode_data.dT;
% =========================================================================
nb_fishes = gene_data.nb_fishes; %#ok<USENS>
nb_boundaries = gene_data.nb_boundaries;
nb_solids = gene_data.nb_solids;
% =========================================================================
% draw fishes and fluid's boundaries
t = 0;
[c,dc] = feval(cont_filename,t,cont_parameters);
[q] = feval(kine_filename,p0,dp0,c,dc);
main_figure = figure(1);
set(main_figure,'Position',[400 188 726 585],'Visible','off','name','Geometry of the fish(es)');
% fluid's boundaries ==================================================
for j = nb_solids+1:nb_boundaries
fill(bound_data(j).X(1,:),bound_data(j).X(2,:),bound_data(j).color)
hold on
end
% fishes ==============================================================
j = 0;
for k = 1:nb_fishes
nb_solids_loc = gene_data.array_fishes_solids(k);
for kk = 1:nb_solids_loc;
j = j+1;
h = [q(3*(j-1)+1);q(3*(j-1)+2)];
theta = q(3*(j-1)+3);
R = [cos(theta),-sin(theta);...
sin(theta), cos(theta)];
Y = R*bound_data(j).X + h*ones(1,bound_data(j).nbr_points);
if kk>1
l_hinge = R*fish{k}(kk).local_hinge+h; %#ok<USENS>
plot(l_hinge(1),l_hinge(2),'or','MarkerFaceColor','k','Markersize',7)
end
fill(Y(1,:),Y(2,:),bound_data(j).color)
text(h(1),h(2),fish{k}(kk).label,'HorizontalAlignment','center',...
'fontname','arial') %#ok<USENS>
hold on
end
end
axis equal
if ~isempty(axis_param)
axis(axis_param);
end
axis_param = axis;
hold off;
but1 = uicontrol('Parent',main_figure ,'Style', 'pushbutton','String','Time -', 'Position',[250 15 50 30],'callback',{@buttonminus});
but2 = uicontrol('Parent',main_figure ,'Style', 'pushbutton','String','Time +', 'Position',[320 15 50 30],'callback',{@buttonplus});
but3 = uicontrol('Parent',main_figure ,'Style', 'pushbutton','String','gamma', 'Position',[390 15 50 30],'callback',{@buttongamma});
but4 = uicontrol('Parent',main_figure ,'Style', 'pushbutton','String','v', 'Position',[460 15 50 30],'callback',{@buttonvelocity});
align([but1,but2,but3,but4],'Distribute','Center');
set([main_figure,but1,but2,but3,but4],...
'Units','normalized');
% Move the GUI to the center of the screen.
movegui(main_figure,'center')
% Make the GUI visible.
set(main_figure,'Visible','on');
velo_param =0;
gamma_param = 0;
function buttonplus(source, eventdata, handles) %#ok<INUSD>
button_state = get(source,'Value');
if button_state == get(source,'Max')
if t < Tmax
t = t + dT;
t = min([t,Tmax]);
end
redrawfigure
end
end
function buttonminus(source, eventdata, handles) %#ok<INUSD>
button_state = get(source,'Value');
if button_state == get(source,'Max')
if t > 0
t = t - dT;
t = max([t,0]);
end
redrawfigure
end
end
function buttongamma(source, eventdata, handles) %#ok<INUSD>
button_state = get(source,'Value');
if button_state == get(source,'Max')
if gamma_param == 0
gamma_param = 1;
else
gamma_param = 0;
end
redrawfigure
end
end
function buttonvelocity(source, eventdata, handles) %#ok<INUSD>
button_state = get(source,'Value');
if button_state == get(source,'Max')
if velo_param == 0
velo_param = 1;
else
velo_param = 0;
end
redrawfigure
end
end
function redrawfigure
%==========================================================================
figure(1)
% compt = 0;
% for t = 0:dT:Tmax;
%compt = compt + 1;
[c,dc,dttc] = feval(cont_filename,t,cont_parameters );
[q,dpq,dcq,dppqdp,dpcqdc,dccqdc] = feval(kine_filename,p0,dp0,c,dc);
% compute velocity and acceleration of each solid
velocity = dcq*dc;
acceleration = dcq*dttc+dccqdc*dc;
%=================================
% draw fluid's boundaries
% =============================================
for jj = nb_solids+1:nb_boundaries
fill(bound_data(jj).X(1,:),bound_data(jj).X(2,:),bound_data(jj).color)
hold on
end
% draw fishes =========================================================
for jj = 1:nb_solids
h = [q(3*(jj-1)+1) ; q(3*(jj-1)+2)];
theta = q(3*(jj-1)+3);
R = [cos(theta),-sin(theta);...
sin(theta), cos(theta)];
Y = R*bound_data(jj).X + h*ones(1,bound_data(jj).nbr_points);
%plot(Y(1,:),Y(2,:),'-k')
fill(Y(1,:),Y(2,:),bound_data(jj).color)
hold on
if velo_param
v = [velocity(3*(jj-1)+1) ; velocity(3*(jj-1)+2)];
quiver(h(1,:),h(2,:),v(1,:),v(2,:),'-r','linewidth',2)
end
if gamma_param
gamma = [acceleration(3*(jj-1)+1) ; acceleration(3*(jj-1)+2)];
quiver(h(1,:),h(2,:),gamma(1,:),gamma(2,:),'-b','linewidth',2)
end
end
axis equal
axis(axis_param)
title('Kinematics checking','fontsize',20)
text(0.98*(axis_param(2)-axis_param(1))+axis_param(1),...
0.98*(axis_param(4)-axis_param(3))+axis_param(3),['t = ',num2str(t,'%6.2f')],...
'HorizontalAlignment','right','verticalalignment','top',...
'fontname','arial','BackgroundColor',[.7 .9 .7])
hold off;
end
end