Code covered by the BSD License  

Highlights from
Biohydrodynamics Toolbox

image thumbnail
from Biohydrodynamics Toolbox by Alexandre Munnier
Tool to simulate easily the motion of moving solids or swimming robots in a potential fluid flow.

bht_kine_check(varargin)
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

Contact us at files@mathworks.com